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: 28041 $ 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 //! 202 //! @return 追加できたら true が返ります。 203 //! Attach(TChild * child)204 bool Attach(TChild* child) 205 { 206 if (child->GetParent() != 0) 207 { 208 return false; 209 } 210 211 bool pushed = m_Children.push_back(child); 212 if (pushed) 213 { 214 child->SetParent(m_Parent); 215 } 216 217 return pushed; 218 } 219 220 //! @brief 子を取り外します。 221 //! 222 //! @param[in] child 外す子です。 223 //! 224 //! @return 子を外せたら true が返ります。 225 //! Detach(TChild * child)226 bool Detach(TChild* child) 227 { 228 bool result = m_Children.erase_find(child); 229 if (result) 230 { 231 child->SetParent(NULL); 232 } 233 234 return result; 235 } 236 237 //! @brief 親を設定します。 238 //! 239 //! 親が設定できるのは一度きりです。 240 //! すでに設定されている場合は、 ASSERT となります。 241 //! 242 //! @param[in] parent 親です。 243 //! SetParent(TParent * parent)244 void SetParent(TParent* parent) 245 { 246 NW_NULL_ASSERT(parent); 247 //NW_ASSERT(m_Children); 248 NW_ASSERT(m_Parent == NULL); 249 m_Parent = parent; 250 } 251 252 //! @brief デリータを取得します。 GetDeleter()253 deleter_reference GetDeleter() { return m_Deleter; } 254 255 //! @brief デリータを取得します。 GetDeleter()256 deleter_const_reference GetDeleter() const { return m_Deleter; } 257 258 private: 259 260 TParent* m_Parent; 261 TChildList m_Children; 262 deleter_type m_Deleter; 263 }; 264 265 #define NW_CHILD_DECLARE_PARENT(MParent) \ 266 public:\ 267 const MParent* GetParent() const { return m_Parent; }\ 268 MParent* GetParent() { return m_Parent; }\ 269 void SetParent(MParent* parent) { m_Parent = parent; }\ 270 private:\ 271 MParent* m_Parent 272 273 } // namespace ut 274 } // namespace nw 275 276 #endif // NW_UT_CHILDREN_H_ 277