00001 #ifndef FBXFILESDK_COMPONENTS_KBASELIB_KLIB_KINTRUSIVELIST_H 00002 #define FBXFILESDK_COMPONENTS_KBASELIB_KLIB_KINTRUSIVELIST_H 00003 00004 /************************************************************************************** 00005 00006 Copyright (C) 2001 - 2009 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/fbxfilesdk_def.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 iterator begin = Begin(); 00168 Erase(begin); 00169 } 00170 00171 void PopBack() 00172 { 00173 Erase(--(End())); 00174 } 00175 00176 public: 00177 class IntrusiveListIterator 00178 { 00179 public: 00180 /* VC6Note: 00181 typedef typename std::forward_iterator_tag iterator_category; 00182 typedef typename KIntrusiveList::value_type value_type; 00183 typedef typename KIntrusiveList::difference_type difference_type; 00184 typedef typename KIntrusiveList::reference reference; 00185 typedef typename KIntrusiveList::const_reference const_reference; 00186 typedef typename KIntrusiveList::pointer pointer; 00187 typedef typename KIntrusiveList::const_pointer const_pointer;*/ 00188 00189 explicit IntrusiveListIterator(NodeT* ptr=0):mPtr(ptr){} 00190 00191 // pre-increment 00192 IntrusiveListIterator& operator++() 00193 { 00194 mPtr = mPtr->mNext;return (*this); 00195 } 00196 // post-increment 00197 IntrusiveListIterator operator++(int) 00198 { 00199 IntrusiveListIterator temp = *this; 00200 ++*this; 00201 return (temp); 00202 } 00203 // pre-decrement 00204 IntrusiveListIterator& operator--() 00205 { 00206 mPtr = mPtr->mPrev;return *this; 00207 } 00208 // post-decrement 00209 IntrusiveListIterator operator--(int) 00210 { 00211 IntrusiveListIterator temp = *this; 00212 --*this; 00213 return (temp); 00214 } 00215 IntrusiveListIterator& operator=(const IntrusiveListIterator &other){mPtr = other.mPtr; return *this;} 00216 00217 reference operator*() const { return *(mPtr->mData); } 00218 pointer operator->() const { return (&**this); } 00219 bool operator==(const IntrusiveListIterator& other)const{ return mPtr==other.mPtr; } 00220 bool operator!=(const IntrusiveListIterator& other)const{ return !(*this == other); } 00221 00222 inline NodeT* Get()const { return mPtr; } 00223 00224 private: 00225 NodeT* mPtr; 00226 }; 00227 00228 class IntrusiveListConstIterator 00229 { 00230 public: 00231 /* VC6Note: 00232 typedef typename std::forward_iterator_tag iterator_category; 00233 typedef typename KIntrusiveList::value_type value_type; 00234 typedef typename KIntrusiveList::difference_type difference_type; 00235 typedef typename KIntrusiveList::reference reference; 00236 typedef typename KIntrusiveList::const_reference const_reference; 00237 typedef typename KIntrusiveList::pointer pointer; 00238 typedef typename KIntrusiveList::const_pointer const_pointer;*/ 00239 00240 explicit IntrusiveListConstIterator(const NodeT* ptr=0):mPtr(ptr){} 00241 00242 // pre-increment 00243 IntrusiveListConstIterator& operator++() 00244 { 00245 mPtr = mPtr->mNext;return (*this); 00246 } 00247 // post-increment 00248 IntrusiveListConstIterator& operator++(int) 00249 { 00250 IntrusiveListConstIterator temp = *this; 00251 ++*this; 00252 return (temp); 00253 } 00254 // pre-decrement 00255 IntrusiveListConstIterator& operator--() 00256 { 00257 mPtr = mPtr->mPrev;return *this; 00258 } 00259 // pre-decrement 00260 IntrusiveListConstIterator& operator--(int) 00261 { 00262 IntrusiveListConstIterator temp = *this; 00263 --*this; 00264 return (temp); 00265 } 00266 IntrusiveListConstIterator& operator=(const IntrusiveListConstIterator &other){mPtr = other.mPtr; return *this;} 00267 00268 const_reference operator*() const { return *(mPtr->mData); } 00269 const_pointer operator->() const { return (&**this); } 00270 bool operator==(const IntrusiveListConstIterator& other)const{ return mPtr==other.mPtr; } 00271 bool operator!=(const IntrusiveListConstIterator& other)const{ return !(*this == other); } 00272 00273 inline const NodeT* Get()const { return mPtr; } 00274 00275 private: 00276 mutable const NodeT* mPtr; 00277 }; 00278 00279 // --- Iterator definitions --- 00280 typedef IntrusiveListIterator iterator; 00281 typedef IntrusiveListConstIterator const_iterator; 00282 00283 // iterator support 00284 inline iterator Begin() { return iterator(mHead.mNext); } 00285 inline const_iterator Begin() const { return const_iterator(mHead.mNext); } 00286 inline iterator End() { return iterator(&mHead); } 00287 inline const_iterator End() const { return const_iterator(&mHead); } 00288 00289 // Because there is no real use, for the reverse iterators, 00290 // they have not been implemented. 00291 00292 reference Front(){return (*Begin());} 00293 const_reference Front() const { return (*Begin()); } 00294 reference Back(){ return (*(--End())); } 00295 const_reference Back() const{ return (*(--End())); } 00296 00297 iterator& Erase(iterator& it) 00298 { 00299 it.Get()->Disconnect(); 00300 return (++it); 00301 } 00302 private: 00303 NodeT mHead; 00304 00305 // Not copyable 00306 KIntrusiveList(const KIntrusiveList&); 00307 KIntrusiveList& operator=(const KIntrusiveList& Right){return (*this);} 00308 }; 00309 00310 // FBX namespace end 00311 #include <fbxfilesdk/fbxfilesdk_nsend.h> 00312 00313 00314 00315 00316 #endif // FBXFILESDK_COMPONENTS_KBASELIB_KLIB_KINTRUSIVELIST_H 00317