- Main Page
- Classes
- Files
- Directories
- Examples

- File List
- File Members

# fbxintrusivelist.h

Go to the documentation of this file.

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