- Main Page
- Classes
- Files
- Directories

- File List
- File Members

# fbxintrusivelist.h

Go to the documentation of this file.

    00001 /****************************************************************************************
    00002
    00003    Copyright (C) 2013 Autodesk, Inc.
    00004    All rights reserved.
    00005
    00006    Use of this software is subject to the terms of the Autodesk license agreement
    00007    provided at the time of installation or download, or which otherwise accompanies
    00008    this software in either electronic or hard copy form.
    00009
    00010 ****************************************************************************************/
    00011
    00013 #ifndef _FBXSDK_CORE_BASE_INTRUSIVE_LIST_H_
    00014 #define _FBXSDK_CORE_BASE_INTRUSIVE_LIST_H_
    00015
    00016 #include <fbxsdk/fbxsdk_def.h>
    00017
    00018 #include <fbxsdk/fbxsdk_nsbegin.h>
    00019
    00020 /*****************************************************************************************************************************
    00021 ** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
    00022 *****************************************************************************************************************************/
    00023 #ifndef DOXYGEN_SHOULD_SKIP_THIS
    00024
    00025 #define FBXSDK_INTRUSIVE_LIST_NODE(Class, NodeCount)\
    00026     public: inline FbxListNode<Class>& GetListNode(int index = 0){ return this->mNode[index]; }\
    00027     private: FbxListNode<Class> mNode[NodeCount];
    00028
    00029 template <typename T> class FbxListNode
    00030 {
    00031     typedef FbxListNode<T> NodeT;
    00032
    00033 public:
    00034     explicit FbxListNode(T* pData = 0):mNext(0),mPrev(0),mData(pData){}
    00035     ~FbxListNode(){ Disconnect(); }
    00036
    00037     void Disconnect()
    00038     {
    00039         if ( mPrev != 0 )
    00040             mPrev->mNext = mNext;
    00041
    00042         if ( mNext != 0 )
    00043             mNext->mPrev = mPrev;
    00044
    00045         mPrev = mNext = 0;
    00046     }
    00047
    00048     NodeT*  mNext;
    00049     NodeT*  mPrev;
    00050     T*      mData;
    00051 };
    00052
    00053 //-----------------------------------------------------------------
    00054 // template arg T: Type listed
    00055 //          arg NodeIndex: If an object listed has  multiple list node, which
    00056 //                         index corresponds to the right node
    00057 template <typename T, int NodeIndex=0> class FbxIntrusiveList
    00058 {
    00059 public:
    00060     typedef T         allocator_type;
    00061     typedef T         value_type;
    00062     typedef T&        reference;
    00063     typedef const T&  const_reference;
    00064     typedef T*        pointer;
    00065     typedef const T*  const_pointer;
    00066
    00067     typedef FbxListNode<T> NodeT;
    00068
    00069     // Construction / Destruction
    00070     FbxIntrusiveList():mHead(0)
    00071     {
    00072         mHead.mNext = mHead.mPrev = &mHead;
    00073     }
    00074     ~FbxIntrusiveList()
    00075     {
    00076         while(!Empty())
    00077             Begin().Get()->Disconnect();  // LINUXNote:  should be Erase(Begin()); but there's an issue with gcc 4.2
    00078     };
    00079
    00080     // true if the list's size is 0.
    00081     bool Empty() const
    00082     {
    00083         return ((mHead.mNext==&mHead)&&(mHead.mPrev==&mHead));
    00084     }
    00085
    00086     // Back Insertion Sequence  Inserts a new element at the end.
    00087     void PushBack(T& pElement)
    00088     {
    00089         NodeT* pNode = &pElement.GetListNode(NodeIndex);
    00090         pNode->mData = &pElement;
    00091
    00092         if (Empty())
    00093         {
    00094             pNode->mNext = &mHead;
    00095             pNode->mPrev = &mHead;
    00096             mHead.mNext = pNode;
    00097             mHead.mPrev = pNode;
    00098         }
    00099         else
    00100         {
    00101             pNode->mNext = &mHead;
    00102             pNode->mPrev = mHead.mPrev;
    00103
    00104             pNode->mPrev->mNext = pNode;
    00105             mHead.mPrev = pNode;
    00106         }
    00107     }
    00108
    00109     void PushFront(T& pElement)
    00110     {
    00111         NodeT* pNode = &pElement.GetListNode(NodeIndex);
    00112         pNode->mData = &pElement;
    00113
    00114         if (Empty())
    00115         {
    00116             pNode->mNext = &mHead;
    00117             pNode->mPrev = &mHead;
    00118             mHead.mNext = pNode;
    00119             mHead.mPrev = pNode;
    00120         }
    00121         else
    00122         {
    00123             pNode->mNext = mHead.mNext;
    00124             pNode->mPrev = &mHead;
    00125
    00126             pNode->mNext->mPrev = pNode;
    00127             mHead.mNext = pNode;
    00128         }
    00129     }
    00130
    00131     void PopFront()
    00132     {
    00133         iterator begin = Begin();
    00134         Erase(begin);
    00135     }
    00136
    00137     void PopBack()
    00138     {
    00139         Erase(--(End()));
    00140     }
    00141
    00142 public:
    00143     class IntrusiveListIterator
    00144     {
    00145     public:
    00146         explicit IntrusiveListIterator(NodeT* ptr=0):mPtr(ptr){}
    00147
    00148         // pre-increment
    00149         IntrusiveListIterator& operator++()
    00150         {
    00151             mPtr = mPtr->mNext;return (*this);
    00152         }
    00153         // post-increment
    00154         const IntrusiveListIterator operator++(int)
    00155         {
    00156             IntrusiveListIterator temp = *this;
    00157             ++*this;
    00158             return (temp);
    00159         }
    00160         // pre-decrement
    00161         IntrusiveListIterator& operator--()
    00162         {
    00163             mPtr = mPtr->mPrev;return *this;
    00164         }
    00165         // post-decrement
    00166         const IntrusiveListIterator operator--(int)
    00167         {
    00168             IntrusiveListIterator temp = *this;
    00169             --*this;
    00170             return (temp);
    00171         }
    00172         IntrusiveListIterator& operator=(const IntrusiveListIterator &other){mPtr = other.mPtr; return *this;}
    00173
    00174         reference operator*() const { return *(mPtr->mData); }
    00175         pointer operator->() const { return (&**this); }
    00176         bool operator==(const IntrusiveListIterator& other)const{ return mPtr==other.mPtr; }
    00177         bool operator!=(const IntrusiveListIterator& other)const{ return !(*this == other); }
    00178
    00179         inline NodeT* Get()const { return mPtr; }
    00180
    00181     private:
    00182         NodeT* mPtr;
    00183     };
    00184
    00185     class  IntrusiveListConstIterator
    00186     {
    00187     public:
    00188         explicit IntrusiveListConstIterator(const NodeT* ptr=0):mPtr(ptr){}
    00189
    00190        // pre-increment
    00191         IntrusiveListConstIterator& operator++()
    00192         {
    00193             mPtr = mPtr->mNext;return (*this);
    00194         }
    00195         // post-increment
    00196         const IntrusiveListConstIterator operator++(int)
    00197         {
    00198             IntrusiveListConstIterator temp = *this;
    00199             ++*this;
    00200             return (temp);
    00201         }
    00202         // pre-decrement
    00203         IntrusiveListConstIterator& operator--()
    00204         {
    00205             mPtr = mPtr->mPrev;return *this;
    00206         }
    00207         // post-decrement
    00208         const IntrusiveListConstIterator operator--(int)
    00209         {
    00210             IntrusiveListConstIterator temp = *this;
    00211             --*this;
    00212             return (temp);
    00213         }
    00214         IntrusiveListConstIterator& operator=(const IntrusiveListConstIterator &other){mPtr = other.mPtr; return *this;}
    00215
    00216         const_reference operator*() const { return *(mPtr->mData); }
    00217         const_pointer operator->() const { return (&**this); }
    00218         bool operator==(const IntrusiveListConstIterator& other)const{ return mPtr==other.mPtr; }
    00219         bool operator!=(const IntrusiveListConstIterator& other)const{ return !(*this == other); }
    00220
    00221         inline const NodeT* Get()const { return mPtr; }
    00222
    00223     private:
    00224         mutable const NodeT* mPtr;
    00225     };
    00226
    00227     // --- Iterator definitions ---
    00228     typedef IntrusiveListIterator iterator;
    00229     typedef IntrusiveListConstIterator const_iterator;
    00230
    00231     // iterator support
    00232     inline iterator Begin() { return iterator(mHead.mNext); }
    00233     inline const_iterator Begin() const { return const_iterator(mHead.mNext); }
    00234     inline iterator End() { return iterator(&mHead); }
    00235     inline const_iterator End() const { return const_iterator(&mHead); }
    00236
    00237     // Because there is no real use, for the reverse iterators,
    00238     // they have not been implemented.
    00239
    00240     reference Front(){return (*Begin());}
    00241     const_reference Front() const { return (*Begin()); }
    00242     reference Back(){ return (*(--End())); }
    00243     const_reference Back() const{ return (*(--End())); }
    00244
    00245     iterator& Erase(iterator& it)
    00246     {
    00247         it.Get()->Disconnect();
    00248         return (++it);
    00249     }
    00250 private:
    00251     NodeT mHead;
    00252
    00253     // Not copyable
    00254     FbxIntrusiveList(const FbxIntrusiveList&);
    00255     FbxIntrusiveList& operator=(const FbxIntrusiveList& Right){return (*this);}
    00256 };
    00257
    00258 #endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
    00259
    00260 #include <fbxsdk/fbxsdk_nsend.h>
    00261
    00262 #endif /* _FBXSDK_CORE_BASE_INTRUSIVE_LIST_H_ */