FBX SDK Reference Guide: kintrusivelist.h Source File
00001 #ifndef FBXFILESDK_COMPONENTS_KBASELIB_KLIB_KINTRUSIVELIST_H
00002 #define FBXFILESDK_COMPONENTS_KBASELIB_KLIB_KINTRUSIVELIST_H
00003 
00004 /**************************************************************************************
00005 
00006  Copyright © 2001 - 2008 Autodesk, Inc. and/or its licensors.
00007  All Rights Reserved.
00008 
00009  The coded instructions, statements, computer programs, and/or related material 
00010  (collectively the "Data") in these files contain unpublished information 
00011  proprietary to Autodesk, Inc. and/or its licensors, which is protected by 
00012  Canada and United States of America federal copyright law and by international 
00013  treaties. 
00014  
00015  The Data may not be disclosed or distributed to third parties, in whole or in
00016  part, without the prior written consent of Autodesk, Inc. ("Autodesk").
00017 
00018  THE DATA IS PROVIDED "AS IS" AND WITHOUT WARRANTY.
00019  ALL WARRANTIES ARE EXPRESSLY EXCLUDED AND DISCLAIMED. AUTODESK MAKES NO
00020  WARRANTY OF ANY KIND WITH RESPECT TO THE DATA, EXPRESS, IMPLIED OR ARISING
00021  BY CUSTOM OR TRADE USAGE, AND DISCLAIMS ANY IMPLIED WARRANTIES OF TITLE, 
00022  NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR USE. 
00023  WITHOUT LIMITING THE FOREGOING, AUTODESK DOES NOT WARRANT THAT THE OPERATION
00024  OF THE DATA WILL BE UNINTERRUPTED OR ERROR FREE. 
00025  
00026  IN NO EVENT SHALL AUTODESK, ITS AFFILIATES, PARENT COMPANIES, LICENSORS
00027  OR SUPPLIERS ("AUTODESK GROUP") BE LIABLE FOR ANY LOSSES, DAMAGES OR EXPENSES
00028  OF ANY KIND (INCLUDING WITHOUT LIMITATION PUNITIVE OR MULTIPLE DAMAGES OR OTHER
00029  SPECIAL, DIRECT, INDIRECT, EXEMPLARY, INCIDENTAL, LOSS OF PROFITS, REVENUE
00030  OR DATA, COST OF COVER OR CONSEQUENTIAL LOSSES OR DAMAGES OF ANY KIND),
00031  HOWEVER CAUSED, AND REGARDLESS OF THE THEORY OF LIABILITY, WHETHER DERIVED
00032  FROM CONTRACT, TORT (INCLUDING, BUT NOT LIMITED TO, NEGLIGENCE), OR OTHERWISE,
00033  ARISING OUT OF OR RELATING TO THE DATA OR ITS USE OR ANY OTHER PERFORMANCE,
00034  WHETHER OR NOT AUTODESK HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSS
00035  OR DAMAGE. 
00036 
00037 **************************************************************************************/
00038 
00043 
00044 #include <fbxfilesdk/components/kbaselib/kaydaradef_h.h>
00045 // STL
00046 // VC6Note:  #include <xutility>
00047 
00048 // FBX namespace begin
00049 #include <fbxfilesdk/fbxfilesdk_nsbegin.h>
00050 
00051 #define KFBX_LISTNODE(classT, NodeCount)\
00052     public: inline KListNode<classT>& GetListNode(int index = 0){ return this->mNode[index]; }\
00053     private:  KListNode<classT> mNode[NodeCount];
00054 
00055 //-----------------------------------------------------------------
00056 template <typename T>
00057 class KListNode
00058 {
00059     typedef KListNode<T> NodeT; 
00060 
00061 public:
00062     explicit KListNode(T* pData = 0):mNext(0),mPrev(0),mData(pData){}
00063     ~KListNode()
00064     {
00065         Disconnect();
00066     }
00067 
00068     void Disconnect()
00069     {
00070         if ( mPrev != 0 )
00071             mPrev->mNext = mNext;
00072 
00073         if ( mNext != 0 )
00074             mNext->mPrev = mPrev;
00075 
00076         mPrev = mNext = 0;
00077     }
00078 
00079     NodeT* mNext;
00080     NodeT* mPrev;
00081 
00082     T* mData;
00083 };
00084 
00085 //-----------------------------------------------------------------
00086 // template arg T: Type listed
00087 //          arg NodeIndex: If an object listed has  multiple list node, which
00088 //                         index corresponds to the right node
00089 template <typename T, int NodeIndex=0>
00090 class KIntrusiveList
00091 {
00092 public:
00093     typedef T         allocator_type;
00094     typedef T         value_type;
00095     typedef T&        reference;
00096     typedef const T&  const_reference;
00097     typedef T*        pointer;
00098     typedef const T*  const_pointer;
00099 // VC6Note :  typedef ptrdiff_t difference_type;
00100 
00101     typedef KListNode<T> NodeT;
00102 
00103     // Construction / Destruction
00104     KIntrusiveList():mHead(0)
00105     {
00106         mHead.mNext = mHead.mPrev = &mHead;
00107     }
00108     ~KIntrusiveList()
00109     {
00110         while(!Empty())
00111             Begin().Get()->Disconnect();  // LINUXNote:  should be Erase(Begin()); but there's an issue with gcc 4.2
00112     };
00113 
00114     // true if the list's size is 0.
00115     bool Empty() const
00116     {
00117         return ((mHead.mNext==&mHead)&&(mHead.mPrev==&mHead));
00118     }
00119 
00120     // Back Insertion Sequence  Inserts a new element at the end.  
00121     void PushBack(T& pElement)
00122     {
00123         NodeT* pNode = &pElement.GetListNode(NodeIndex);
00124         pNode->mData = &pElement;
00125 
00126         if (Empty())
00127         {
00128             pNode->mNext = &mHead;
00129             pNode->mPrev = &mHead;
00130             mHead.mNext = pNode;
00131             mHead.mPrev = pNode;
00132         }
00133         else
00134         {
00135             pNode->mNext = &mHead;
00136             pNode->mPrev = mHead.mPrev;
00137 
00138             pNode->mPrev->mNext = pNode;
00139             mHead.mPrev = pNode;
00140         }
00141     }
00142 
00143     void PushFront(T& pElement)
00144     {
00145         NodeT* pNode = &pElement.GetListNode(NodeIndex);
00146         pNode->mData = &pElement;
00147 
00148         if (Empty())
00149         {
00150             pNode->mNext = &mHead;
00151             pNode->mPrev = &mHead;
00152             mHead.mNext = pNode;
00153             mHead.mPrev = pNode;
00154         }
00155         else
00156         {
00157             pNode->mNext = mHead.mNext;
00158             pNode->mPrev = &mHead;
00159 
00160             pNode->mNext->mPrev = pNode;
00161             mHead.mNext = pNode;
00162         }
00163     }
00164 
00165     void PopFront()
00166     {
00167         Erase(Begin());
00168     }
00169 
00170     void PopBack()
00171     {
00172         Erase(--(End()));
00173     }
00174 
00175 public:
00176     class IntrusiveListIterator
00177     {
00178     public:
00179      /* VC6Note: 
00180         typedef typename std::forward_iterator_tag       iterator_category;
00181         typedef typename KIntrusiveList::value_type      value_type;
00182         typedef typename KIntrusiveList::difference_type difference_type;
00183         typedef typename KIntrusiveList::reference       reference;
00184         typedef typename KIntrusiveList::const_reference const_reference;
00185         typedef typename KIntrusiveList::pointer         pointer;
00186         typedef typename KIntrusiveList::const_pointer   const_pointer;*/
00187 
00188         explicit IntrusiveListIterator(NodeT* ptr=0):mPtr(ptr){}
00189 
00190         // pre-increment
00191         IntrusiveListIterator& operator++()
00192         {
00193             mPtr = mPtr->mNext;return (*this);
00194         }
00195         // post-increment
00196         IntrusiveListIterator operator++(int)
00197         {
00198             IntrusiveListIterator temp = *this;
00199             ++*this;
00200             return (temp);
00201         }
00202         // pre-decrement
00203         IntrusiveListIterator& operator--()
00204         {
00205             mPtr = mPtr->mPrev;return *this;
00206         }
00207         // post-decrement
00208         IntrusiveListIterator operator--(int)
00209         {
00210             IntrusiveListIterator temp = *this;
00211             --*this;
00212             return (temp);
00213         }
00214         IntrusiveListIterator& operator=(const IntrusiveListIterator &other){mPtr = other.mPtr; return *this;}
00215 
00216         reference operator*() const { return *(mPtr->mData); }
00217         pointer operator->() const { return (&**this); }
00218         bool operator==(const IntrusiveListIterator& other)const{ return mPtr==other.mPtr; } 
00219         bool operator!=(const IntrusiveListIterator& other)const{ return !(*this == other); } 
00220 
00221         inline NodeT* Get()const { return mPtr; }
00222 
00223     private:
00224         NodeT* mPtr;
00225     };
00226 
00227     class  IntrusiveListConstIterator
00228     {
00229     public:
00230         /* VC6Note:
00231         typedef typename std::forward_iterator_tag       iterator_category;
00232         typedef typename KIntrusiveList::value_type      value_type;
00233         typedef typename KIntrusiveList::difference_type difference_type;
00234         typedef typename KIntrusiveList::reference       reference;
00235         typedef typename KIntrusiveList::const_reference const_reference;
00236         typedef typename KIntrusiveList::pointer         pointer;
00237         typedef typename KIntrusiveList::const_pointer   const_pointer;*/
00238 
00239         explicit IntrusiveListConstIterator(const NodeT* ptr=0):mPtr(ptr){}
00240 
00241        // pre-increment
00242         IntrusiveListConstIterator& operator++()
00243         {
00244             mPtr = mPtr->mNext;return (*this);
00245         }
00246         // post-increment
00247         IntrusiveListConstIterator& operator++(int)
00248         {
00249             IntrusiveListConstIterator temp = *this;
00250             ++*this;
00251             return (temp);
00252         }
00253         // pre-decrement
00254         IntrusiveListConstIterator& operator--()
00255         {
00256             mPtr = mPtr->mPrev;return *this;
00257         }
00258         // pre-decrement
00259         IntrusiveListConstIterator& operator--(int)
00260         {
00261             IntrusiveListConstIterator temp = *this;
00262             --*this;
00263             return (temp);
00264         }
00265         IntrusiveListConstIterator& operator=(const IntrusiveListConstIterator &other){mPtr = other.mPtr; return *this;}
00266 
00267         const_reference operator*() const { return *(mPtr->mData); }
00268         const_pointer operator->() const { return (&**this); }
00269         bool operator==(const IntrusiveListConstIterator& other)const{ return mPtr==other.mPtr; } 
00270         bool operator!=(const IntrusiveListConstIterator& other)const{ return !(*this == other); } 
00271 
00272         inline const NodeT* Get()const { return mPtr; }
00273 
00274     private:
00275         mutable const NodeT* mPtr;
00276     };
00277 
00278     // --- Iterator definitions ---
00279     typedef IntrusiveListIterator iterator;
00280     typedef IntrusiveListConstIterator const_iterator;
00281 
00282     // iterator support
00283     inline iterator Begin() { return iterator(mHead.mNext); }
00284     inline const_iterator Begin() const { return const_iterator(mHead.mNext); }
00285     inline iterator End() { return iterator(&mHead); }
00286     inline const_iterator End() const { return const_iterator(&mHead); }
00287 
00288     // TODO: reverse iterators NOT IMPLEMENTED
00289   /*  reverse_iterator rbegin() { return (reverse_iterator(end()));}
00290     const_reverse_iterator rbegin() const {return (const_reverse_iterator(end())); }
00291     reverse_iterator rend(){ return (reverse_iterator(begin()));}
00292     const_reverse_iterator rend() const{return (const_reverse_iterator(begin()));}*/
00293 
00294     reference Front(){return (*Begin());}
00295     const_reference Front() const { return (*Begin()); }
00296     reference Back(){ return (*(--End())); }
00297     const_reference Back() const{ return (*(--End())); }
00298 
00299     iterator& Erase(iterator& it)
00300     {
00301         it.Get()->Disconnect();
00302         return (++it);
00303     }
00304 private:
00305     NodeT mHead;
00306 
00307     // Not copyable
00308     KIntrusiveList(const KIntrusiveList&);
00309     KIntrusiveList& operator=(const KIntrusiveList& Right){return (*this);}
00310 };
00311 
00312 // FBX namespace end
00313 #include <fbxfilesdk/fbxfilesdk_nsend.h>
00314 
00315 
00316 
00317 
00318 #endif // FBXFILESDK_COMPONENTS_KBASELIB_KLIB_KINTRUSIVELIST_H
00319