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