1 /*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: ut_ResArray.h 4 5 Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain proprietary 8 information of Nintendo and/or its licensed developers and are protected by 9 national and international copyright laws. They may not be disclosed to third 10 parties or copied or duplicated in any form, in whole or in part, without the 11 prior written consent of Nintendo. 12 13 The content herein is highly confidential and should be handled accordingly. 14 15 $Revision: 31311 $ 16 *---------------------------------------------------------------------------*/ 17 18 #ifndef NW_UT_RESARRAY_H_ 19 #define NW_UT_RESARRAY_H_ 20 21 #include <nw/types.h> 22 #include <nw/ut/ut_ResTypes.h> 23 #include <iterator> 24 25 namespace nw { 26 namespace ut { 27 28 namespace internal { 29 30 template <typename T> 31 class ResArrayPrimitiveTraits 32 { 33 public: 34 typedef T* pointer; 35 typedef const T* const_pointer; 36 typedef T& reference; 37 typedef const T& const_reference; 38 typedef T& iter_pointer; 39 typedef const T& const_iter_pointer; 40 typedef int difference_type; 41 typedef std::input_iterator_tag iterator_category; 42 GetValue(void * ptr)43 static reference GetValue(void* ptr) { return GetValue( reinterpret_cast<pointer>(ptr) ); } GetValue(pointer ptr)44 static reference GetValue(pointer ptr) { return *ptr; } GetValue(const void * ptr)45 static const_reference GetValue(const void* ptr) { return GetValue( reinterpret_cast<const_pointer>(ptr) ); } GetValue(const_pointer ptr)46 static const_reference GetValue(const_pointer ptr) { return *ptr; } 47 GetPointer(pointer ptr)48 static iter_pointer GetPointer(pointer ptr) { return ptr; } GetPointer(const_pointer ptr)49 static const_iter_pointer GetPointer(const_pointer ptr) { return ptr; } 50 GetNext(pointer ptr)51 static pointer GetNext(pointer ptr) { return ptr + 1; } GetNext(const_pointer ptr)52 static const_pointer GetNext(const_pointer ptr) { return ptr + 1; } ValueSize()53 static size_t ValueSize() { return sizeof(T); } 54 }; 55 56 template <typename T> 57 class ResArrayPrimitiveTraits<const T> 58 { 59 public: 60 typedef T* pointer; 61 typedef const T* const_pointer; 62 typedef T& reference; 63 typedef const T& const_reference; 64 typedef T& iter_pointer; 65 typedef const T& const_iter_pointer; 66 typedef int difference_type; 67 typedef std::input_iterator_tag iterator_category; 68 GetValue(const void * ptr)69 static const_reference GetValue(const void* ptr) { return GetValue( reinterpret_cast<const_pointer>(ptr) ); } GetValue(const_pointer ptr)70 static const_reference GetValue(const_pointer ptr) { return *ptr; } GetPointer(const_pointer ptr)71 static const_iter_pointer GetPointer(const_pointer ptr) { return ptr; } 72 GetNext(const_pointer ptr)73 static const_pointer GetNext(const_pointer ptr) { return ptr + 1; } ValueSize()74 static size_t ValueSize() { return sizeof(T); } 75 }; 76 77 #if 0 78 // NOTE: Resクラスの iterator でアロー演算子が使えるようにする為の実装です。 79 // (*it). の記述に比べて、パフォーマンス面で僅かにコストがかかる可能性があるので、 80 // アロー演算子が必須な algorithm があるなどのニーズがあるまでコメントアウトしています。 81 82 #define NW_UT_RESARRAY_ENABLE_ARROW_OP_ 83 84 template <typename TRes> 85 class ResPtr 86 { 87 public: 88 ResPtr(void* ptr) : m_Res(ptr) {} 89 TRes* operator->() { return &m_Res; } 90 private: 91 TRes m_Res; 92 }; 93 94 template <typename TRes> 95 class ResPtr<const TRes> 96 { 97 public: 98 ResPtr(const void* ptr) : m_Res(ptr) {} 99 const TRes* operator->() const { return &m_Res; } 100 private: 101 TRes m_Res; 102 }; 103 #endif 104 105 template<typename T> 106 class ResArrayClassTraits 107 { 108 public: 109 typedef Offset* pointer; 110 typedef const Offset* const_pointer; 111 typedef T reference; 112 typedef const T const_reference; 113 typedef int difference_type; 114 typedef std::input_iterator_tag iterator_category; 115 116 #if defined(NW_UT_RESARRAY_ENABLE_ARROW_OP_) 117 typedef ResPtr<T> iter_pointer; 118 typedef ResPtr<const T> const_iter_pointer; 119 GetPointer(pointer ptr)120 static iter_pointer GetPointer(pointer ptr) { return ResPtr<T>( ptr->to_ptr() ); } GetPointer(const_pointer ptr)121 static const_iter_pointer GetPointer(const_pointer ptr) { return ResPtr<T>( ptr->to_ptr() ); } 122 #endif 123 GetValue(void * ptr)124 static reference GetValue(void* ptr) { return GetValue( reinterpret_cast<pointer>(ptr) ); } GetValue(pointer ptr)125 static reference GetValue(pointer ptr) { return T( ptr->to_ptr() ); } GetValue(const void * ptr)126 static const_reference GetValue(const void* ptr) { return GetValue( reinterpret_cast<const_pointer>(ptr) ); } GetValue(const_pointer ptr)127 static const_reference GetValue(const_pointer ptr) { return T( ptr->to_ptr() ); } 128 GetNext(pointer ptr)129 static pointer GetNext(pointer ptr) { return ptr + 1; } GetNext(const_pointer ptr)130 static const_pointer GetNext(const_pointer ptr) { return ptr + 1; } ValueSize()131 static size_t ValueSize() { return sizeof(Offset); } 132 }; 133 134 template<typename T> 135 class ResArrayClassTraits<const T> 136 { 137 public: 138 typedef Offset* pointer; 139 typedef const Offset* const_pointer; 140 typedef T reference; 141 typedef const T const_reference; 142 typedef int difference_type; 143 typedef std::bidirectional_iterator_tag iterator_category; 144 GetValue(const void * ptr)145 static const_reference GetValue(const void* ptr) { return GetValue( reinterpret_cast<const_pointer>(ptr) ); } GetValue(const_pointer ptr)146 static const_reference GetValue(const_pointer ptr) { return T( ptr->to_ptr() ); } 147 GetNext(const_pointer ptr)148 static const_pointer GetNext(const_pointer ptr) { return ptr + 1; } ValueSize()149 static size_t ValueSize() { return sizeof(Offset); } 150 }; 151 152 153 //========================================== 154 // ResArray クラスです。 155 // IsOffset が true の場合は、nw::ut::Offsetの 156 // 配列として扱います。 157 //========================================== 158 template <typename T, template <typename> class TTraits> 159 class ResArray 160 { 161 public: 162 163 typedef T value_type; 164 typedef typename TTraits<T>::pointer pointer; 165 typedef typename TTraits<T>::reference reference; 166 typedef typename TTraits<T>::const_pointer const_pointer; 167 typedef typename TTraits<T>::const_reference const_reference; 168 typedef typename TTraits<T>::difference_type difference_type; 169 typedef typename TTraits<T>::iterator_category iterator_category; 170 171 #if defined(NW_UT_RESARRAY_ENABLE_ARROW_OP_) 172 typedef typename TTraits<T>::iter_pointer iter_pointer; 173 typedef typename TTraits<T>::const_iter_pointer const_iter_pointer; 174 #endif 175 ResArray(void * pBegin,void * pEnd)176 /* ctor */ ResArray( void* pBegin, void* pEnd ) 177 : m_pBegin( static_cast<pointer>(pBegin) ), 178 m_pEnd( static_cast<pointer>(pEnd) ) 179 {} ResArray(void * pBegin,s32 num)180 /* ctor */ ResArray( void* pBegin, s32 num ) 181 : m_pBegin( static_cast<pointer>(pBegin) ), 182 m_pEnd( m_pBegin + num ) 183 {} 184 pointer()185 operator pointer() { return m_pBegin; } pointer()186 operator const pointer() const { return m_pBegin; } 187 188 reference operator[](int index) 189 { 190 NW_MINMAXLT_ASSERT(index, 0, size()); 191 return TTraits<T>::GetValue(m_pBegin + index); 192 } 193 194 const_reference operator[](int index) const 195 { 196 NW_MINMAXLT_ASSERT(index, 0, size()); 197 return TTraits<T>::GetValue(m_pBegin + index); 198 } 199 200 class const_iterator; 201 class iterator 202 { 203 public: 204 typedef iterator TIt; 205 typedef T value_type; 206 typedef typename TTraits<T>::pointer pointer; 207 typedef typename TTraits<T>::reference reference; 208 typedef typename TTraits<T>::const_pointer const_pointer; 209 typedef typename TTraits<T>::const_reference const_reference; 210 typedef typename TTraits<T>::difference_type difference_type; 211 typedef typename TTraits<T>::iterator_category iterator_category; 212 iterator()213 /* ctor */ iterator() : m_pCurrent( NULL ) {} 214 const_iterator()215 operator const_iterator() { return const_iterator(m_pCurrent); } 216 217 reference operator*() const { NW_NULL_ASSERT(m_pCurrent); return TTraits<T>::GetValue(m_pCurrent); } 218 219 #if defined(NW_UT_RESARRAY_ENABLE_ARROW_OP_) 220 iter_pointer operator->() const { return TTraits<T>::GetPointer(m_pCurrent); } 221 #endif 222 223 TIt &operator++() { ++m_pCurrent; return *this; } 224 TIt operator++(int) { TIt it(*this); (void)++*this; return it; } 225 TIt &operator--() { --m_pCurrent; return *this; } 226 TIt operator--(int) { TIt it(*this); (void)--*this; return it; } 227 228 friend bool operator==(TIt it1, TIt it2) { return it1.m_pCurrent == it2.m_pCurrent; } 229 friend bool operator!=(TIt it1_, TIt it2_) { return !(it1_ == it2_); } 230 231 private: iterator(pointer p)232 explicit iterator(pointer p) : m_pCurrent(p) {} 233 234 pointer m_pCurrent; 235 236 friend class const_iterator; 237 friend class ResArray<T, TTraits>; 238 }; 239 240 class const_iterator 241 { 242 public: 243 typedef const_iterator TIt; 244 typedef const T value_type; 245 typedef typename TTraits<T>::pointer pointer; 246 typedef typename TTraits<T>::reference reference; 247 typedef typename TTraits<T>::const_pointer const_pointer; 248 typedef typename TTraits<T>::const_reference const_reference; 249 typedef typename TTraits<T>::difference_type difference_type; 250 typedef typename TTraits<T>::iterator_category iterator_category; 251 const_iterator()252 /* ctor */ const_iterator() : m_pCurrent( NULL ) {} 253 254 const_reference operator*() const { NW_NULL_ASSERT(m_pCurrent); return TTraits<T>::GetValue(m_pCurrent); } 255 256 #if defined(NW_UT_RESARRAY_ENABLE_ARROW_OP_) 257 const_iter_pointer operator->() const { return TTraits<T>::GetPointer(m_pCurrent); } 258 #endif 259 260 TIt &operator++() { ++m_pCurrent; return *this; } 261 TIt operator++(int) { TIt it(*this); (void)++*this; return it; } 262 TIt &operator--() { --m_pCurrent; return *this; } 263 TIt operator--(int) { TIt it(*this); (void)--*this; return it; } 264 265 friend bool operator==(TIt it1, TIt it2) { return it1.m_pCurrent == it2.m_pCurrent; } 266 friend bool operator!=(TIt it1_, TIt it2_) { return !(it1_ == it2_); } 267 268 private: const_iterator(const_pointer p)269 explicit const_iterator(const_pointer p) : m_pCurrent(p) {} 270 271 const_pointer m_pCurrent; 272 273 friend class ResArray<T, TTraits>; 274 }; 275 276 typedef internal::reverse_iterator<iterator> reverse_iterator; 277 typedef internal::reverse_iterator<const_iterator> const_reverse_iterator; 278 size()279 s32 size() const { return (size_t(m_pEnd) - size_t(m_pBegin)) / TTraits<T>::ValueSize(); } empty()280 bool empty() const { return (m_pBegin == m_pEnd); } 281 begin()282 iterator begin() { return iterator(m_pBegin); } begin()283 const_iterator begin() const { return const_iterator(m_pBegin); } end()284 iterator end() { return iterator(m_pEnd); } end()285 const_iterator end() const { return const_iterator(m_pEnd); } 286 rbegin()287 reverse_iterator rbegin() { return reverse_iterator(end()); } rbegin()288 const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } rend()289 reverse_iterator rend() { return reverse_iterator(begin()); } rend()290 const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } 291 292 private: 293 pointer m_pBegin; 294 pointer m_pEnd; 295 296 friend class ResArray<const T, TTraits>; 297 }; 298 299 //========================================== 300 // const 版 301 //========================================== 302 template <typename T, template <typename> class TTraits> 303 class ResArray<const T, TTraits> 304 { 305 public: 306 typedef T value_type; 307 typedef typename TTraits<T>::pointer pointer; 308 typedef typename TTraits<T>::reference reference; 309 typedef typename TTraits<T>::const_pointer const_pointer; 310 typedef typename TTraits<T>::const_reference const_reference; 311 typedef typename TTraits<T>::difference_type difference_type; 312 typedef typename TTraits<T>::iterator_category iterator_category; 313 314 #if defined(NW_UT_RESARRAY_ENABLE_ARROW_OP_) 315 typedef typename TTraits<T>::iter_pointer iter_pointer; 316 typedef typename TTraits<T>::const_iter_pointer const_iter_pointer; 317 #endif 318 ResArray(const void * pBegin,const void * pEnd)319 /* ctor */ ResArray( const void* pBegin, const void* pEnd ) 320 : m_pBegin( static_cast<const_pointer>(pBegin) ), 321 m_pEnd( static_cast<const_pointer>(pEnd) ) 322 {} ResArray(const void * pBegin,s32 num)323 /* ctor */ ResArray( const void* pBegin, s32 num ) 324 : m_pBegin( static_cast<const_pointer>(pBegin) ), 325 m_pEnd( m_pBegin + num ) 326 {} 327 ResArray(const ResArray<T,TTraits> & rhs)328 /* ctor */ ResArray( const ResArray<T, TTraits>& rhs ) 329 : m_pBegin( rhs.m_pBegin ), 330 m_pEnd( rhs.m_pEnd ) 331 { 332 } 333 pointer()334 operator const pointer() const { return m_pBegin; } 335 336 const_reference operator[](int index) const 337 { 338 NW_MINMAXLT_ASSERT(index, 0, size()); 339 return TTraits<T>::GetValue(m_pBegin + index); 340 } 341 342 class const_iterator 343 { 344 public: 345 typedef const_iterator TIt; 346 typedef T value_type; 347 typedef typename TTraits<T>::pointer pointer; 348 typedef typename TTraits<T>::reference reference; 349 typedef typename TTraits<T>::const_pointer const_pointer; 350 typedef typename TTraits<T>::const_reference const_reference; 351 typedef typename TTraits<T>::difference_type difference_type; 352 typedef typename TTraits<T>::iterator_category iterator_category; 353 const_iterator()354 /* ctor */ const_iterator() : m_pCurrent( NULL ) {} 355 356 const_reference operator*() const { NW_NULL_ASSERT(m_pCurrent); return TTraits<T>::GetValue(m_pCurrent); } 357 358 #if defined(NW_UT_RESARRAY_ENABLE_ARROW_OP_) 359 const_iter_pointer operator->() const { return TTraits<T>::GetPointer(m_pCurrent); } 360 #endif 361 362 TIt &operator++() { ++m_pCurrent; return *this; } 363 TIt operator++(int) { TIt it(*this); (void)++*this; return it; } 364 TIt &operator--() { --m_pCurrent; return *this; } 365 TIt operator--(int) { TIt it(*this); (void)--*this; return it; } 366 367 friend bool operator==(TIt it1, TIt it2) { return it1.m_pCurrent == it2.m_pCurrent; } 368 friend bool operator!=(TIt it1_, TIt it2_) { return !(it1_ == it2_); } 369 370 private: const_iterator(const_pointer p)371 explicit const_iterator(const_pointer p) : m_pCurrent(p) {} 372 373 const_pointer m_pCurrent; 374 375 friend class ResArray<const T, TTraits>; 376 }; 377 378 typedef internal::reverse_iterator<const_iterator> const_reverse_iterator; 379 size()380 s32 size() const { return (size_t(m_pEnd) - size_t(m_pBegin)) / TTraits<T>::ValueSize(); } empty()381 bool empty() const { return (m_pBegin == m_pEnd); } 382 begin()383 const_iterator begin() const { return const_iterator(m_pBegin); } end()384 const_iterator end() const { return const_iterator(m_pEnd); } 385 rbegin()386 const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } rend()387 const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } 388 389 private: 390 const_pointer m_pBegin; 391 const_pointer m_pEnd; 392 393 friend class ResArray<T, TTraits>; 394 }; 395 396 } // namespace internal 397 398 } // namespace ut 399 } // namespace nw 400 401 #endif // NW_UT_RESARRAY_H_ 402 403