fbxsdk/core/base/fbxintrusivelist.h Source File
 
 
 
fbxsdk/core/base/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_ */