1 /*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: ut_Children.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: 18106 $ 14 *---------------------------------------------------------------------------*/ 15 16 #ifndef NW_UT_CHILDREN_H_ 17 #define NW_UT_CHILDREN_H_ 18 19 #include <nw/ut/ut_MoveArray.h> 20 21 #include <nw/ut/ut_Preprocessor.h> 22 #include <nw/ut/ut_TypeTraits.h> 23 24 namespace nw 25 { 26 namespace ut 27 { 28 29 //--------------------------------------------------------------------------- 30 //! @brief 子を削除するためのクラスです。 31 //! 32 //! @tparam TChild 削除する子の型です。 33 //--------------------------------------------------------------------------- 34 template<typename TChild> 35 class ChildDeleter 36 { 37 public: ChildDeleter()38 ChildDeleter() : m_Allocator(0) {} ChildDeleter(os::IAllocator * allocator)39 ChildDeleter(os::IAllocator* allocator) : m_Allocator(allocator) { } 40 operator()41 void operator() (TChild* child) 42 { 43 child->~TChild(); 44 if (m_Allocator) 45 { 46 m_Allocator->Free(child); 47 } 48 } 49 50 os::IAllocator* m_Allocator; 51 }; 52 53 //--------------------------------------------------------------------------- 54 //! @brief 子を外すためのクラスです。 55 //! 56 //! @tparam TChild 外す子の型です。 57 //--------------------------------------------------------------------------- 58 template<typename TChild> 59 class ChildDetacher 60 { 61 public: ChildDetacher()62 ChildDetacher() {} ChildDetacher(os::IAllocator * allocator)63 ChildDetacher(os::IAllocator* allocator) { NW_UNUSED_VARIABLE(allocator); } 64 operator()65 void operator() (TChild* child) 66 { 67 if (child) 68 { 69 child->SetParent(NULL); 70 } 71 } 72 }; 73 74 //--------------------------------------------------------------------------- 75 //! @brief 子のリストクラスです。 76 //! 77 //! @tparam TChild 子の型です。 78 //! @tparam TParent 親の型です。 79 //! @tparam TDeleter 削除用の関数オブジェクトです。 80 //! @tparam TChildList 子のリストの型です。 81 //--------------------------------------------------------------------------- 82 template< 83 typename TChild, 84 typename TParent, 85 typename TDeleter = ChildDeleter<TChild>, 86 typename TChildList = MoveArray<TChild*> > 87 class Children 88 { 89 public: 90 typedef TChild*& reference; 91 typedef TChild* difference_type; 92 typedef TChild* value_type; 93 typedef typename TChildList::iterator iterator; 94 typedef typename TChildList::const_iterator const_iterator; 95 96 #if defined(_MSC_VER) && _MSC_VER <= 1201 97 typedef std::reverse_iterator<iterator, TChild*> reverse_iterator; 98 typedef std::reverse_iterator<const_iterator, TChild*> const_reverse_iterator; 99 #else 100 typedef std::reverse_iterator<iterator> reverse_iterator; 101 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 102 #endif 103 typedef TDeleter deleter_type; 104 typedef TDeleter& deleter_reference; 105 typedef const TDeleter& deleter_const_reference; 106 107 public: Children()108 Children() : m_Children(), m_Deleter() {} 109 110 //! @brief コンストラクタです。 111 //! 112 //! @param[in] parent 親です。 113 //! @param[in] elements 子のリストとして利用する確保されたメモリです。 114 //! @param[in] size 子の数です。 115 //! @param[in] allocator アロケータです。 116 //! @param[in] kind 子のリストの種類です。 117 //! 118 Children( 119 TParent* parent, 120 void* elements, 121 size_t size, 122 os::IAllocator* allocator = 0, 123 ArrayKind kind = ARRAY_WRAPPER) m_Parent(parent)124 : m_Parent(parent), m_Children(elements, size, allocator, kind), m_Deleter(allocator) {} 125 126 //! @brief コンストラクタです。 127 //! 128 //! @param[in] parent 親です。 129 //! @param[in] size 子の数です。 130 //! @param[in] allocator アロケータです。 131 //! @param[in] kind 子のリストの種類です。 132 //! 133 Children( 134 TParent* parent, 135 size_t size, 136 os::IAllocator* allocator, 137 ArrayKind kind = ARRAY_WRAPPER) m_Parent(parent)138 : m_Parent(parent), m_Children(size, allocator, kind), m_Deleter(allocator) {} 139 140 //! @brief コンストラクタです。 141 //! 142 //! @param[in] parent 親です。 143 //! @param[in] allocator アロケータです。 144 //! Children(TParent * parent,os::IAllocator * allocator)145 Children( 146 TParent* parent, 147 os::IAllocator* allocator) 148 : m_Parent(parent), m_Children(allocator), m_Deleter(allocator) {} 149 150 //! @brief コピーコンストラクタです。 151 //! 152 //! コピー元から要素を移動します。 153 //! 154 //! @param[in] children コピー元の Children オブジェクトです。 155 //! Children(const Children & children)156 Children(const Children& children) 157 : m_Parent(children.m_Parent), 158 m_Children(children.m_Children), 159 m_Deleter(children.m_Deleter) 160 { 161 } 162 163 //! デストラクタです。 ~Children()164 ~Children() 165 { 166 std::for_each(this->m_Children.begin(), this->m_Children.end(), m_Deleter); 167 } 168 169 public: 170 struct SafeBoolHelper { int x; }; 171 typedef int SafeBoolHelper::* SafeBool; SafeBool()172 operator SafeBool() const { return m_Children; } 173 174 //---------------------------------------- 175 //! @name STLコンテナ互換機能 176 //@{ 177 begin()178 iterator begin() { return m_Children.begin(); } begin()179 const_iterator begin() const { return m_Children.begin(); } end()180 iterator end() { return m_Children.end(); } end()181 const_iterator end() const { return m_Children.end(); } 182 clear()183 void clear() 184 { 185 std::for_each(this->m_Children.begin(), this->m_Children.end(), ChildDetacher<TChild>()); 186 this->m_Children.clear(); 187 } 188 Begin()189 iterator Begin() { return this->begin(); } Begin()190 const_iterator Begin() const { return this->begin(); } End()191 iterator End() { return this->end(); } End()192 const_iterator End() const { return this->end(); } 193 Clear()194 void Clear() { this->clear(); } 195 196 //@} 197 198 //! @brief 子を追加します。 199 //! 200 //! @param[in] child 追加する子です。 201 //! Attach(TChild * child)202 bool Attach(TChild* child) 203 { 204 if (child->GetParent() != 0) 205 { 206 return false; 207 } 208 209 bool pushed = m_Children.push_back(child); 210 if (pushed) 211 { 212 child->SetParent(m_Parent); 213 } 214 215 return pushed; 216 } 217 218 //! @brief 子を取り外します。 219 //! 220 //! @param[in] child 外す子です。 221 //! Detach(TChild * child)222 bool Detach(TChild* child) 223 { 224 bool result = m_Children.erase_find(child); 225 if (result) 226 { 227 child->SetParent(NULL); 228 } 229 230 return result; 231 } 232 233 //! @brief 親を設定します。 234 //! 235 //! 親が設定できるのは一度きりです。 236 //! すでに設定されている場合は、 ASSERT となります。 237 //! 238 //! @param[in] parent 親です。 239 //! SetParent(TParent * parent)240 void SetParent(TParent* parent) 241 { 242 NW_NULL_ASSERT(parent); 243 //NW_ASSERT(m_Children); 244 NW_ASSERT(m_Parent == NULL); 245 m_Parent = parent; 246 } 247 248 //! @brief デリータを取得します。 GetDeleter()249 deleter_reference GetDeleter() { return m_Deleter; } 250 251 //! @brief デリータを取得します。 GetDeleter()252 deleter_const_reference GetDeleter() const { return m_Deleter; } 253 254 private: 255 256 TParent* m_Parent; 257 TChildList m_Children; 258 deleter_type m_Deleter; 259 }; 260 261 #define NW_CHILD_DECLARE_PARENT(MParent) \ 262 public:\ 263 const MParent* GetParent() const { return m_Parent; }\ 264 MParent* GetParent() { return m_Parent; }\ 265 void SetParent(MParent* parent) { m_Parent = parent; }\ 266 private:\ 267 MParent* m_Parent 268 269 } // namespace ut 270 } // namespace nw 271 272 #endif // NW_UT_CHILDREN_H_ 273