/*---------------------------------------------------------------------------* Project: NintendoWare File: ut_Children.h Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo and/or its licensed developers and are protected by national and international copyright laws. 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. The content herein is highly confidential and should be handled accordingly. $Revision: 31311 $ *---------------------------------------------------------------------------*/ #ifndef NW_UT_CHILDREN_H_ #define NW_UT_CHILDREN_H_ #include #include #include namespace nw { namespace ut { //--------------------------------------------------------------------------- //! @brief 子を削除するためのクラスです。 //! //! @tparam TChild 削除する子の型です。 //--------------------------------------------------------------------------- template class ChildDeleter { public: ChildDeleter() : m_Allocator(0) {} ChildDeleter(os::IAllocator* allocator) : m_Allocator(allocator) { } void operator() (TChild* child) { child->~TChild(); if (m_Allocator) { m_Allocator->Free(child); } } os::IAllocator* m_Allocator; }; //--------------------------------------------------------------------------- //! @brief 子を外すためのクラスです。 //! //! @tparam TChild 外す子の型です。 //--------------------------------------------------------------------------- template class ChildDetacher { public: ChildDetacher() {} ChildDetacher(os::IAllocator* allocator) { NW_UNUSED_VARIABLE(allocator); } void operator() (TChild* child) { if (child) { child->SetParent(NULL); } } }; //--------------------------------------------------------------------------- //! @brief 子のリストクラスです。 //! //! @tparam TChild 子の型です。 //! @tparam TParent 親の型です。 //! @tparam TDeleter 削除用の関数オブジェクトです。 //! @tparam TChildList 子のリストの型です。 //--------------------------------------------------------------------------- template< typename TChild, typename TParent, typename TDeleter = ChildDeleter, typename TChildList = MoveArray > class Children { public: typedef TChild*& reference; typedef TChild* difference_type; typedef TChild* value_type; typedef typename TChildList::iterator iterator; typedef typename TChildList::const_iterator const_iterator; #if defined(_MSC_VER) && _MSC_VER <= 1201 typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; #else typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; #endif typedef TDeleter deleter_type; typedef TDeleter& deleter_reference; typedef const TDeleter& deleter_const_reference; public: Children() : m_Children(), m_Deleter() {} //! @brief コンストラクタです。 //! //! @param[in] parent 親です。 //! @param[in] elements 子のリストとして利用する確保されたメモリです。 //! @param[in] size 子の数です。 //! @param[in] allocator アロケータです。 //! @param[in] kind 子のリストの種類です。 //! Children( TParent* parent, void* elements, size_t size, os::IAllocator* allocator = 0, ArrayKind kind = ARRAY_WRAPPER) : m_Parent(parent), m_Children(elements, size, allocator, kind), m_Deleter(allocator) {} //! @brief コンストラクタです。 //! //! @param[in] parent 親です。 //! @param[in] size 子の数です。 //! @param[in] allocator アロケータです。 //! @param[in] kind 子のリストの種類です。 //! Children( TParent* parent, size_t size, os::IAllocator* allocator, ArrayKind kind = ARRAY_WRAPPER) : m_Parent(parent), m_Children(size, allocator, kind), m_Deleter(allocator) {} //! @brief コンストラクタです。 //! //! @param[in] parent 親です。 //! @param[in] allocator アロケータです。 //! Children( TParent* parent, os::IAllocator* allocator) : m_Parent(parent), m_Children(allocator), m_Deleter(allocator) {} //! @brief コピーコンストラクタです。 //! //! コピー元から要素を移動します。 //! //! @param[in] children コピー元の Children オブジェクトです。 //! Children(const Children& children) : m_Parent(children.m_Parent), m_Children(children.m_Children), m_Deleter(children.m_Deleter) { } //! デストラクタです。 ~Children() { std::for_each(this->m_Children.begin(), this->m_Children.end(), m_Deleter); } public: struct SafeBoolHelper { int x; }; typedef int SafeBoolHelper::* SafeBool; operator SafeBool() const { return m_Children; } //---------------------------------------- //! @name STLコンテナ互換機能 //@{ iterator begin() { return m_Children.begin(); } const_iterator begin() const { return m_Children.begin(); } iterator end() { return m_Children.end(); } const_iterator end() const { return m_Children.end(); } void clear() { std::for_each(this->m_Children.begin(), this->m_Children.end(), ChildDetacher()); this->m_Children.clear(); } iterator Begin() { return this->begin(); } const_iterator Begin() const { return this->begin(); } iterator End() { return this->end(); } const_iterator End() const { return this->end(); } void Clear() { this->clear(); } //@} //! @brief 子を追加します。 //! //! @param[in] child 追加する子です。 //! //! @return 追加できたら true が返ります。 //! bool Attach(TChild* child) { if (child->GetParent() != 0) { return false; } bool pushed = m_Children.push_back(child); if (pushed) { child->SetParent(m_Parent); } return pushed; } //! @brief 子を取り外します。 //! //! @param[in] child 外す子です。 //! //! @return 子を外せたら true が返ります。 //! bool Detach(TChild* child) { bool result = m_Children.erase_find(child); if (result) { child->SetParent(NULL); } return result; } //! @brief 親を設定します。 //! //! 親が設定できるのは一度きりです。 //! すでに設定されている場合は、 ASSERT となります。 //! //! @param[in] parent 親です。 //! void SetParent(TParent* parent) { NW_NULL_ASSERT(parent); //NW_ASSERT(m_Children); NW_ASSERT(m_Parent == NULL); m_Parent = parent; } //! @brief デリータを取得します。 deleter_reference GetDeleter() { return m_Deleter; } //! @brief デリータを取得します。 deleter_const_reference GetDeleter() const { return m_Deleter; } private: TParent* m_Parent; TChildList m_Children; deleter_type m_Deleter; }; #define NW_CHILD_DECLARE_PARENT(MParent) \ public:\ const MParent* GetParent() const { return m_Parent; }\ MParent* GetParent() { return m_Parent; }\ void SetParent(MParent* parent) { m_Parent = parent; }\ private:\ MParent* m_Parent } // namespace ut } // namespace nw #endif // NW_UT_CHILDREN_H_