OpenNI 1.5.4: XnListT.h Source File

OpenNI

OpenNI 1.5.4
XnListT.h
Go to the documentation of this file.
00001 #ifndef _XNLISTT_H_
00002 #define _XNLISTT_H_ 
00003 
00004 //---------------------------------------------------------------------------
00005 // Includes
00006 //---------------------------------------------------------------------------
00007 #include <XnPlatform.h>
00008 #include <XnDataTypes.h>
00009 #include <XnOS.h>
00010 
00011 //---------------------------------------------------------------------------
00012 // Code
00013 //---------------------------------------------------------------------------
00014 
00020 template<class T>
00021 struct XnLinkedNodeT
00022 {
00023     XnLinkedNodeT() : pPrev(NULL), pNext(NULL) {}
00024     XnLinkedNodeT(T const& value) : pPrev(NULL), pNext(NULL), value(value) {}
00025 
00026     struct XnLinkedNodeT<T>* pPrev;
00027     struct XnLinkedNodeT<T>* pNext;
00028     T value;
00029 };
00030 
00039 template<class T>
00040 class XnLinkedNodeDefaultAllocatorT
00041 {
00042 public:
00043     typedef XnLinkedNodeT<T> LinkedNode;
00044 
00045     static LinkedNode* Allocate(T const& value)
00046     {
00047         return XN_NEW(LinkedNode, value);
00048     }
00049 
00050     static void Deallocate(LinkedNode* pNode)
00051     {
00052         XN_DELETE(pNode);
00053     }
00054 };
00055 
00063 template<class T, class TAlloc = XnLinkedNodeDefaultAllocatorT<T> >
00064 class XnListT
00065 {
00066 public:
00067     typedef XnLinkedNodeT<T> LinkedNode;
00068     typedef T TValue;
00069     typedef TAlloc TAllocator;
00070 
00074     class ConstIterator
00075     {
00076     public:
00077         inline ConstIterator() : m_pCurrent(NULL) {}
00078 
00079         inline ConstIterator(LinkedNode* pNode) : m_pCurrent(pNode) {}
00080 
00081         inline ConstIterator(const ConstIterator& other) : m_pCurrent(other.m_pCurrent) {}
00082 
00086         inline ConstIterator& operator++()
00087         {
00088             m_pCurrent = m_pCurrent->pNext;
00089             return *this;
00090         }
00091 
00095         inline ConstIterator operator++(int)
00096         {
00097             ConstIterator retVal(*this);
00098             ++*this;
00099             return retVal;
00100         }
00101 
00105         inline ConstIterator& operator--()
00106         {
00107             m_pCurrent = m_pCurrent->pPrev;
00108             return *this;
00109         }
00110 
00114         inline ConstIterator operator--(int)
00115         {
00116             ConstIterator retVal(*this);
00117             --*this;
00118             return retVal;
00119         }
00120 
00126         inline XnBool operator==(const ConstIterator& other) const
00127         {
00128             return m_pCurrent == other.m_pCurrent;
00129         }
00130 
00136         inline XnBool operator!=(const ConstIterator& other) const
00137         {
00138             return m_pCurrent != other.m_pCurrent;
00139         }
00140 
00144         inline T const& operator*() const
00145         {
00146             return m_pCurrent->value;
00147         }
00148 
00152         inline T const* operator->() const
00153         {
00154             return &m_pCurrent->value;
00155         }
00156 
00157     protected:
00158         friend class XnListT;
00159 
00161         LinkedNode* m_pCurrent;
00162     };
00163 
00167     class Iterator : public ConstIterator
00168     {
00169     public:
00170         inline Iterator() : ConstIterator() {}
00171 
00172         inline Iterator(LinkedNode* pNode) : ConstIterator(pNode) {}
00173 
00174         inline Iterator(const Iterator& other) : ConstIterator(other) {}
00175 
00179         inline Iterator& operator++() 
00180         {
00181             ++(*(ConstIterator*)this);
00182             return (*this);
00183         }
00184 
00188         inline Iterator operator++(int) 
00189         { 
00190             Iterator retVal(*this);
00191             ++*this;
00192             return (retVal);
00193         }
00194         
00198         inline Iterator& operator--() 
00199         { 
00200             --(*(ConstIterator*)this); 
00201             return (*this);
00202         }
00206         inline Iterator operator--(int)
00207         { 
00208             Iterator retVal(*this);
00209             --*this;
00210             return (retVal);
00211         }
00212 
00216         inline T& operator*() const 
00217         {
00218             return this->m_pCurrent->value;
00219         }
00220 
00224         inline T* operator->() const
00225         {
00226             return &this->m_pCurrent->value;
00227         }
00228     };
00229 
00230 public:
00231     XnListT()
00232     {
00233         Init();
00234     }
00235 
00236     XnListT(const XnListT& other)
00237     {
00238         Init();
00239         *this = other;
00240     }
00241 
00242     XnListT& operator=(const XnListT& other)
00243     {
00244         Clear();
00245 
00246         XnStatus nRetVal = XN_STATUS_OK;
00247 
00248         for (ConstIterator it = other.Begin(); it != other.End(); ++it)
00249         {
00250             nRetVal = AddLast(*it);
00251             XN_ASSERT(nRetVal == XN_STATUS_OK);
00252         }
00253 
00254         return *this;
00255     }
00256 
00257     ~XnListT()
00258     {
00259         Clear();
00260     }
00261 
00265     Iterator Begin()
00266     {
00267         return Iterator(m_anchor.pNext);
00268     }
00269 
00273     ConstIterator Begin() const
00274     {
00275         return ConstIterator(const_cast<LinkedNode*>(m_anchor.pNext));
00276     }
00277 
00281     Iterator End()
00282     {
00283         return Iterator(&m_anchor);
00284     }
00285 
00289     ConstIterator End() const
00290     {
00291         return ConstIterator(const_cast<LinkedNode*>(&m_anchor));
00292     }
00293 
00297     Iterator ReverseBegin()
00298     {
00299         return Iterator(m_anchor.pPrev);
00300     }
00301 
00305     ConstIterator ReverseBegin() const
00306     {
00307         return ConstIterator(const_cast<LinkedNode*>(m_anchor.pPrev));
00308     }
00309 
00313     Iterator ReverseEnd()
00314     {
00315         return Iterator(&m_anchor);
00316     }
00317 
00321     ConstIterator ReverseEnd() const
00322     {
00323         return ConstIterator(const_cast<LinkedNode*>(&m_anchor));
00324     }
00325 
00335     XnStatus AddAfter(ConstIterator where, T const& value)
00336     {
00337         if (where == End())
00338         {
00339             return XN_STATUS_ILLEGAL_POSITION;
00340         }
00341 
00342         return InsertAfter(where.m_pCurrent, value);
00343     }
00344 
00354     XnStatus AddBefore(ConstIterator where, T const& value)
00355     {
00356         if (where == End())
00357         {
00358             return XN_STATUS_ILLEGAL_POSITION;
00359         }
00360 
00361         return InsertAfter(where.m_pCurrent->pPrev, value);
00362     }
00363 
00371     XnStatus AddFirst(T const& value)
00372     {
00373         return InsertAfter(&m_anchor, value);
00374     }
00375 
00383     XnStatus AddLast(T const& value)
00384     {
00385         return InsertAfter(ReverseBegin().m_pCurrent, value);
00386     }
00387 
00395     ConstIterator Find(T const& value) const
00396     {
00397         ConstIterator iter = Begin();
00398         for (; iter != End(); ++iter)
00399         {
00400             if (*iter == value)
00401                 break;
00402         }
00403         return iter;
00404     }
00405 
00413     Iterator Find(T const& value)
00414     {
00415         ConstIterator iter = const_cast<const XnListT<T>*>(this)->Find(value);
00416         return Iterator(iter.m_pCurrent);
00417     }
00418 
00426     XnStatus Remove(ConstIterator where)
00427     {
00428         // Verify iterator is valid
00429         if (where == End())
00430         {
00431             return XN_STATUS_ILLEGAL_POSITION;
00432         }
00433 
00434         XnLinkedNodeT<T>* pToRemove = where.m_pCurrent;
00435 
00436         // Connect other nodes to bypass the one removed
00437         pToRemove->pPrev->pNext = pToRemove->pNext;
00438         pToRemove->pNext->pPrev = pToRemove->pPrev;
00439 
00440         --m_nSize;
00441 
00442         // Free memory
00443         TAlloc::Deallocate(pToRemove);
00444 
00445         return XN_STATUS_OK;
00446     }
00447 
00455     XnStatus Remove(T const& value)
00456     {
00457         ConstIterator it = Find(value);
00458         if (it != End())
00459         {
00460             return Remove(it);
00461         }
00462         else
00463         {
00464             return XN_STATUS_NO_MATCH;
00465         }
00466     }
00467 
00471     XnStatus Clear()
00472     {
00473         while (!IsEmpty())
00474             Remove(Begin());
00475 
00476         return XN_STATUS_OK;
00477     }
00478 
00482     XnBool IsEmpty() const
00483     {
00484         return (m_nSize == 0);
00485     }
00486 
00490     XnUInt32 Size() const
00491     {
00492         return m_nSize;
00493     }
00494 
00501     void CopyTo(T* pArray) const
00502     {
00503         XN_ASSERT(pArray != NULL);
00504 
00505         XnUInt32 i = 0;
00506         for (ConstIterator iter = Begin(); iter != End(); ++iter, ++i)
00507         {
00508             pArray[i] = *iter;
00509         }
00510     }
00511     
00512 protected:
00521     XnStatus InsertAfter(LinkedNode* pAfter, T const& val)
00522     {
00523         // Get a node from the pool for the entry
00524         LinkedNode* pNewNode = TAlloc::Allocate(val);
00525         if (pNewNode == NULL)
00526         {
00527             XN_ASSERT(FALSE);
00528             return XN_STATUS_ALLOC_FAILED;
00529         }
00530         pNewNode->pPrev = pAfter;
00531         pNewNode->pNext = pAfter->pNext;
00532 
00533         // push new node to position
00534         pAfter->pNext->pPrev = pNewNode;
00535         pAfter->pNext = pNewNode;
00536 
00537         ++m_nSize;
00538 
00539         return XN_STATUS_OK;
00540     }
00541 
00542     // A dummy node, pointing to first node, and last node points back to it.
00543     LinkedNode m_anchor;
00544 
00545     XnUInt32 m_nSize;
00546 
00547 private:
00548     void Init()
00549     {
00550         m_anchor.pNext = &m_anchor;
00551         m_anchor.pPrev = &m_anchor;
00552         m_nSize = 0;
00553     }
00554 };
00555 
00556 #endif // _XNLISTT_H_
Generated on Wed May 16 2012 10:16:05 for OpenNI 1.5.4 by   doxygen 1.7.5.1