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