/*---------------------------------------------------------------------------* Project: NintendoWare File: ut_ResArray.h Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Revision: 16429 $ *---------------------------------------------------------------------------*/ #ifndef NW_UT_RESARRAY_H_ #define NW_UT_RESARRAY_H_ #include #include #include namespace nw { namespace ut { namespace internal { template class ResArrayPrimitiveTraits { public: typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef T& iter_pointer; typedef const T& const_iter_pointer; typedef int difference_type; typedef std::input_iterator_tag iterator_category; static reference GetValue(void* ptr) { return GetValue( reinterpret_cast(ptr) ); } static reference GetValue(pointer ptr) { return *ptr; } static const_reference GetValue(const void* ptr) { return GetValue( reinterpret_cast(ptr) ); } static const_reference GetValue(const_pointer ptr) { return *ptr; } static iter_pointer GetPointer(pointer ptr) { return ptr; } static const_iter_pointer GetPointer(const_pointer ptr) { return ptr; } static pointer GetNext(pointer ptr) { return ptr + 1; } static const_pointer GetNext(const_pointer ptr) { return ptr + 1; } static size_t ValueSize() { return sizeof(T); } }; template class ResArrayPrimitiveTraits { public: typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef T& iter_pointer; typedef const T& const_iter_pointer; typedef int difference_type; typedef std::input_iterator_tag iterator_category; static const_reference GetValue(const void* ptr) { return GetValue( reinterpret_cast(ptr) ); } static const_reference GetValue(const_pointer ptr) { return *ptr; } static const_iter_pointer GetPointer(const_pointer ptr) { return ptr; } static const_pointer GetNext(const_pointer ptr) { return ptr + 1; } static size_t ValueSize() { return sizeof(T); } }; #if 0 // NOTE: Resクラスの iterator でアロー演算子が使えるようにする為の実装です。 // (*it). の記述に比べて、パフォーマンス面で僅かにコストがかかる可能性があるので、 // アロー演算子が必須な algorithm があるなどのニーズがあるまでコメントアウトしています。 #define NW_UT_RESARRAY_ENABLE_ARROW_OP_ template class ResPtr { public: ResPtr(void* ptr) : m_Res(ptr) {} TRes* operator->() { return &m_Res; } private: TRes m_Res; }; template class ResPtr { public: ResPtr(const void* ptr) : m_Res(ptr) {} const TRes* operator->() const { return &m_Res; } private: TRes m_Res; }; #endif template class ResArrayClassTraits { public: typedef Offset* pointer; typedef const Offset* const_pointer; typedef T reference; typedef const T const_reference; typedef int difference_type; typedef std::input_iterator_tag iterator_category; #if defined(NW_UT_RESARRAY_ENABLE_ARROW_OP_) typedef ResPtr iter_pointer; typedef ResPtr const_iter_pointer; static iter_pointer GetPointer(pointer ptr) { return ResPtr( ptr->to_ptr() ); } static const_iter_pointer GetPointer(const_pointer ptr) { return ResPtr( ptr->to_ptr() ); } #endif static reference GetValue(void* ptr) { return GetValue( reinterpret_cast(ptr) ); } static reference GetValue(pointer ptr) { return T( ptr->to_ptr() ); } static const_reference GetValue(const void* ptr) { return GetValue( reinterpret_cast(ptr) ); } static const_reference GetValue(const_pointer ptr) { return T( ptr->to_ptr() ); } static pointer GetNext(pointer ptr) { return ptr + 1; } static const_pointer GetNext(const_pointer ptr) { return ptr + 1; } static size_t ValueSize() { return sizeof(Offset); } }; template class ResArrayClassTraits { public: typedef Offset* pointer; typedef const Offset* const_pointer; typedef T reference; typedef const T const_reference; typedef int difference_type; typedef std::bidirectional_iterator_tag iterator_category; static const_reference GetValue(const void* ptr) { return GetValue( reinterpret_cast(ptr) ); } static const_reference GetValue(const_pointer ptr) { return T( ptr->to_ptr() ); } static const_pointer GetNext(const_pointer ptr) { return ptr + 1; } static size_t ValueSize() { return sizeof(Offset); } }; //========================================== // ResArray クラスです。 // IsOffset が true の場合は、nw::ut::Offsetの // 配列として扱います。 //========================================== template class TTraits> class ResArray { public: typedef T value_type; typedef typename TTraits::pointer pointer; typedef typename TTraits::reference reference; typedef typename TTraits::const_pointer const_pointer; typedef typename TTraits::const_reference const_reference; typedef typename TTraits::difference_type difference_type; typedef typename TTraits::iterator_category iterator_category; #if defined(NW_UT_RESARRAY_ENABLE_ARROW_OP_) typedef typename TTraits::iter_pointer iter_pointer; typedef typename TTraits::const_iter_pointer const_iter_pointer; #endif /* ctor */ ResArray( void* pBegin, void* pEnd ) : m_pBegin( static_cast(pBegin) ), m_pEnd( static_cast(pEnd) ) {} /* ctor */ ResArray( void* pBegin, s32 num ) : m_pBegin( static_cast(pBegin) ), m_pEnd( m_pBegin + num ) {} operator pointer() { return m_pBegin; } operator const pointer() const { return m_pBegin; } reference operator[](int index) { NW_MINMAXLT_ASSERT(index, 0, size()); return TTraits::GetValue(m_pBegin + index); } const_reference operator[](int index) const { NW_MINMAXLT_ASSERT(index, 0, size()); return TTraits::GetValue(m_pBegin + index); } class const_iterator; class iterator { public: typedef iterator TIt; typedef T value_type; typedef typename TTraits::pointer pointer; typedef typename TTraits::reference reference; typedef typename TTraits::const_pointer const_pointer; typedef typename TTraits::const_reference const_reference; typedef typename TTraits::difference_type difference_type; typedef typename TTraits::iterator_category iterator_category; /* ctor */ iterator() : m_pCurrent( NULL ) {} operator const_iterator() { return const_iterator(m_pCurrent); } reference operator*() const { NW_NULL_ASSERT(m_pCurrent); return TTraits::GetValue(m_pCurrent); } #if defined(NW_UT_RESARRAY_ENABLE_ARROW_OP_) iter_pointer operator->() const { return TTraits::GetPointer(m_pCurrent); } #endif TIt &operator++() { ++m_pCurrent; return *this; } TIt operator++(int) { TIt it(*this); (void)++*this; return it; } TIt &operator--() { --m_pCurrent; return *this; } TIt operator--(int) { TIt it(*this); (void)--*this; return it; } friend bool operator==(TIt it1, TIt it2) { return it1.m_pCurrent == it2.m_pCurrent; } friend bool operator!=(TIt it1_, TIt it2_) { return !(it1_ == it2_); } private: explicit iterator(pointer p) : m_pCurrent(p) {} pointer m_pCurrent; friend class const_iterator; friend class ResArray; }; class const_iterator { public: typedef const_iterator TIt; typedef const T value_type; typedef typename TTraits::pointer pointer; typedef typename TTraits::reference reference; typedef typename TTraits::const_pointer const_pointer; typedef typename TTraits::const_reference const_reference; typedef typename TTraits::difference_type difference_type; typedef typename TTraits::iterator_category iterator_category; /* ctor */ const_iterator() : m_pCurrent( NULL ) {} const_reference operator*() const { NW_NULL_ASSERT(m_pCurrent); return TTraits::GetValue(m_pCurrent); } #if defined(NW_UT_RESARRAY_ENABLE_ARROW_OP_) const_iter_pointer operator->() const { return TTraits::GetPointer(m_pCurrent); } #endif TIt &operator++() { ++m_pCurrent; return *this; } TIt operator++(int) { TIt it(*this); (void)++*this; return it; } TIt &operator--() { --m_pCurrent; return *this; } TIt operator--(int) { TIt it(*this); (void)--*this; return it; } friend bool operator==(TIt it1, TIt it2) { return it1.m_pCurrent == it2.m_pCurrent; } friend bool operator!=(TIt it1_, TIt it2_) { return !(it1_ == it2_); } private: explicit const_iterator(const_pointer p) : m_pCurrent(p) {} const_pointer m_pCurrent; friend class ResArray; }; typedef internal::reverse_iterator reverse_iterator; typedef internal::reverse_iterator const_reverse_iterator; s32 size() const { return (size_t(m_pEnd) - size_t(m_pBegin)) / TTraits::ValueSize(); } bool empty() const { return (m_pBegin == m_pEnd); } iterator begin() { return iterator(m_pBegin); } const_iterator begin() const { return const_iterator(m_pBegin); } iterator end() { return iterator(m_pEnd); } const_iterator end() const { return const_iterator(m_pEnd); } reverse_iterator rbegin() { return reverse_iterator(end()); } const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } private: pointer m_pBegin; pointer m_pEnd; friend class ResArray; }; //========================================== // const 版 //========================================== template class TTraits> class ResArray { public: typedef T value_type; typedef typename TTraits::pointer pointer; typedef typename TTraits::reference reference; typedef typename TTraits::const_pointer const_pointer; typedef typename TTraits::const_reference const_reference; typedef typename TTraits::difference_type difference_type; typedef typename TTraits::iterator_category iterator_category; #if defined(NW_UT_RESARRAY_ENABLE_ARROW_OP_) typedef typename TTraits::iter_pointer iter_pointer; typedef typename TTraits::const_iter_pointer const_iter_pointer; #endif /* ctor */ ResArray( const void* pBegin, const void* pEnd ) : m_pBegin( static_cast(pBegin) ), m_pEnd( static_cast(pEnd) ) {} /* ctor */ ResArray( const void* pBegin, s32 num ) : m_pBegin( static_cast(pBegin) ), m_pEnd( m_pBegin + num ) {} /* ctor */ ResArray( const ResArray& rhs ) : m_pBegin( rhs.m_pBegin ), m_pEnd( rhs.m_pEnd ) { } operator const pointer() const { return m_pBegin; } const_reference operator[](int index) const { NW_MINMAXLT_ASSERT(index, 0, size()); return TTraits::GetValue(m_pBegin + index); } class const_iterator { public: typedef const_iterator TIt; typedef T value_type; typedef typename TTraits::pointer pointer; typedef typename TTraits::reference reference; typedef typename TTraits::const_pointer const_pointer; typedef typename TTraits::const_reference const_reference; typedef typename TTraits::difference_type difference_type; typedef typename TTraits::iterator_category iterator_category; /* ctor */ const_iterator() : m_pCurrent( NULL ) {} const_reference operator*() const { NW_NULL_ASSERT(m_pCurrent); return TTraits::GetValue(m_pCurrent); } #if defined(NW_UT_RESARRAY_ENABLE_ARROW_OP_) const_iter_pointer operator->() const { return TTraits::GetPointer(m_pCurrent); } #endif TIt &operator++() { ++m_pCurrent; return *this; } TIt operator++(int) { TIt it(*this); (void)++*this; return it; } TIt &operator--() { --m_pCurrent; return *this; } TIt operator--(int) { TIt it(*this); (void)--*this; return it; } friend bool operator==(TIt it1, TIt it2) { return it1.m_pCurrent == it2.m_pCurrent; } friend bool operator!=(TIt it1_, TIt it2_) { return !(it1_ == it2_); } private: explicit const_iterator(const_pointer p) : m_pCurrent(p) {} const_pointer m_pCurrent; friend class ResArray; }; typedef internal::reverse_iterator const_reverse_iterator; s32 size() const { return (size_t(m_pEnd) - size_t(m_pBegin)) / TTraits::ValueSize(); } bool empty() const { return (m_pBegin == m_pEnd); } const_iterator begin() const { return const_iterator(m_pBegin); } const_iterator end() const { return const_iterator(m_pEnd); } const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } private: const_pointer m_pBegin; const_pointer m_pEnd; friend class ResArray; }; } // namespace internal } // namespace ut } // namespace nw #endif // NW_UT_RESARRAY_H_