00001 #ifndef FBXFILESDK_COMPONENTS_KBASELIB_KLIB_KINTRUSIVELIST_H
00002 #define FBXFILESDK_COMPONENTS_KBASELIB_KLIB_KINTRUSIVELIST_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00043
00044 #include <fbxfilesdk/components/kbaselib/kaydaradef_h.h>
00045
00046
00047
00048
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
00087
00088
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
00100
00101 typedef KListNode<T> NodeT;
00102
00103
00104 KIntrusiveList():mHead(0)
00105 {
00106 mHead.mNext = mHead.mPrev = &mHead;
00107 }
00108 ~KIntrusiveList()
00109 {
00110 while(!Empty())
00111 Begin().Get()->Disconnect();
00112 };
00113
00114
00115 bool Empty() const
00116 {
00117 return ((mHead.mNext==&mHead)&&(mHead.mPrev==&mHead));
00118 }
00119
00120
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
00180
00181
00182
00183
00184
00185
00186
00187
00188 explicit IntrusiveListIterator(NodeT* ptr=0):mPtr(ptr){}
00189
00190
00191 IntrusiveListIterator& operator++()
00192 {
00193 mPtr = mPtr->mNext;return (*this);
00194 }
00195
00196 IntrusiveListIterator operator++(int)
00197 {
00198 IntrusiveListIterator temp = *this;
00199 ++*this;
00200 return (temp);
00201 }
00202
00203 IntrusiveListIterator& operator--()
00204 {
00205 mPtr = mPtr->mPrev;return *this;
00206 }
00207
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
00231
00232
00233
00234
00235
00236
00237
00238
00239 explicit IntrusiveListConstIterator(const NodeT* ptr=0):mPtr(ptr){}
00240
00241
00242 IntrusiveListConstIterator& operator++()
00243 {
00244 mPtr = mPtr->mNext;return (*this);
00245 }
00246
00247 IntrusiveListConstIterator& operator++(int)
00248 {
00249 IntrusiveListConstIterator temp = *this;
00250 ++*this;
00251 return (temp);
00252 }
00253
00254 IntrusiveListConstIterator& operator--()
00255 {
00256 mPtr = mPtr->mPrev;return *this;
00257 }
00258
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
00279 typedef IntrusiveListIterator iterator;
00280 typedef IntrusiveListConstIterator const_iterator;
00281
00282
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
00289
00290
00291
00292
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
00308 KIntrusiveList(const KIntrusiveList&);
00309 KIntrusiveList& operator=(const KIntrusiveList& Right){return (*this);}
00310 };
00311
00312
00313 #include <fbxfilesdk/fbxfilesdk_nsend.h>
00314
00315
00316
00317
00318 #endif // FBXFILESDK_COMPONENTS_KBASELIB_KLIB_KINTRUSIVELIST_H
00319