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