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