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