OpenNI 1.5.7
XnListT.h
Go to the documentation of this file.
00001 /*****************************************************************************
00002 *                                                                            *
00003 *  OpenNI 1.x Alpha                                                          *
00004 *  Copyright (C) 2012 PrimeSense Ltd.                                        *
00005 *                                                                            *
00006 *  This file is part of OpenNI.                                              *
00007 *                                                                            *
00008 *  Licensed under the Apache License, Version 2.0 (the "License");           *
00009 *  you may not use this file except in compliance with the License.          *
00010 *  You may obtain a copy of the License at                                   *
00011 *                                                                            *
00012 *      http://www.apache.org/licenses/LICENSE-2.0                            *
00013 *                                                                            *
00014 *  Unless required by applicable law or agreed to in writing, software       *
00015 *  distributed under the License is distributed on an "AS IS" BASIS,         *
00016 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  *
00017 *  See the License for the specific language governing permissions and       *
00018 *  limitations under the License.                                            *
00019 *                                                                            *
00020 *****************************************************************************/
00021 #ifndef _XNLISTT_H_
00022 #define _XNLISTT_H_ 
00023 
00024 //---------------------------------------------------------------------------
00025 // Includes
00026 //---------------------------------------------------------------------------
00027 #include <XnPlatform.h>
00028 #include <XnDataTypes.h>
00029 #include <XnOS.h>
00030 
00031 //---------------------------------------------------------------------------
00032 // Code
00033 //---------------------------------------------------------------------------
00034 
00040 template<class T>
00041 struct XnLinkedNodeT
00042 {
00043     XnLinkedNodeT() : pPrev(NULL), pNext(NULL) {}
00044     XnLinkedNodeT(T const& value) : pPrev(NULL), pNext(NULL), value(value) {}
00045 
00046     struct XnLinkedNodeT<T>* pPrev;
00047     struct XnLinkedNodeT<T>* pNext;
00048     T value;
00049 };
00050 
00059 template<class T>
00060 class XnLinkedNodeDefaultAllocatorT
00061 {
00062 public:
00063     typedef XnLinkedNodeT<T> LinkedNode;
00064 
00065     static LinkedNode* Allocate(T const& value)
00066     {
00067         return XN_NEW(LinkedNode, value);
00068     }
00069 
00070     static void Deallocate(LinkedNode* pNode)
00071     {
00072         XN_DELETE(pNode);
00073     }
00074 };
00075 
00083 template<class T, class TAlloc = XnLinkedNodeDefaultAllocatorT<T> >
00084 class XnListT
00085 {
00086 public:
00087     typedef XnLinkedNodeT<T> LinkedNode;
00088     typedef T TValue;
00089     typedef TAlloc TAllocator;
00090 
00094     class ConstIterator
00095     {
00096     public:
00097         inline ConstIterator() : m_pCurrent(NULL) {}
00098 
00099         inline ConstIterator(LinkedNode* pNode) : m_pCurrent(pNode) {}
00100 
00101         inline ConstIterator(const ConstIterator& other) : m_pCurrent(other.m_pCurrent) {}
00102 
00106         inline ConstIterator& operator++()
00107         {
00108             m_pCurrent = m_pCurrent->pNext;
00109             return *this;
00110         }
00111 
00115         inline ConstIterator operator++(int)
00116         {
00117             ConstIterator retVal(*this);
00118             ++*this;
00119             return retVal;
00120         }
00121 
00125         inline ConstIterator& operator--()
00126         {
00127             m_pCurrent = m_pCurrent->pPrev;
00128             return *this;
00129         }
00130 
00134         inline ConstIterator operator--(int)
00135         {
00136             ConstIterator retVal(*this);
00137             --*this;
00138             return retVal;
00139         }
00140 
00146         inline XnBool operator==(const ConstIterator& other) const
00147         {
00148             return m_pCurrent == other.m_pCurrent;
00149         }
00150 
00156         inline XnBool operator!=(const ConstIterator& other) const
00157         {
00158             return m_pCurrent != other.m_pCurrent;
00159         }
00160 
00164         inline T const& operator*() const
00165         {
00166             return m_pCurrent->value;
00167         }
00168 
00172         inline T const* operator->() const
00173         {
00174             return &m_pCurrent->value;
00175         }
00176 
00177     protected:
00178         friend class XnListT;
00179 
00181         LinkedNode* m_pCurrent;
00182     };
00183 
00187     class Iterator : public ConstIterator
00188     {
00189     public:
00190         inline Iterator() : ConstIterator() {}
00191 
00192         inline Iterator(LinkedNode* pNode) : ConstIterator(pNode) {}
00193 
00194         inline Iterator(const Iterator& other) : ConstIterator(other) {}
00195 
00199         inline Iterator& operator++() 
00200         {
00201             ++(*(ConstIterator*)this);
00202             return (*this);
00203         }
00204 
00208         inline Iterator operator++(int) 
00209         { 
00210             Iterator retVal(*this);
00211             ++*this;
00212             return (retVal);
00213         }
00214         
00218         inline Iterator& operator--() 
00219         { 
00220             --(*(ConstIterator*)this); 
00221             return (*this);
00222         }
00226         inline Iterator operator--(int)
00227         { 
00228             Iterator retVal(*this);
00229             --*this;
00230             return (retVal);
00231         }
00232 
00236         inline T& operator*() const 
00237         {
00238             return this->m_pCurrent->value;
00239         }
00240 
00244         inline T* operator->() const
00245         {
00246             return &this->m_pCurrent->value;
00247         }
00248     };
00249 
00250 public:
00251     XnListT()
00252     {
00253         Init();
00254     }
00255 
00256     XnListT(const XnListT& other)
00257     {
00258         Init();
00259         *this = other;
00260     }
00261 
00262     XnListT& operator=(const XnListT& other)
00263     {
00264         Clear();
00265 
00266         XnStatus nRetVal = XN_STATUS_OK;
00267 
00268         for (ConstIterator it = other.Begin(); it != other.End(); ++it)
00269         {
00270             nRetVal = AddLast(*it);
00271             XN_ASSERT(nRetVal == XN_STATUS_OK);
00272         }
00273 
00274         return *this;
00275     }
00276 
00277     ~XnListT()
00278     {
00279         Clear();
00280     }
00281 
00285     Iterator Begin()
00286     {
00287         return Iterator(m_anchor.pNext);
00288     }
00289 
00293     ConstIterator Begin() const
00294     {
00295         return ConstIterator(const_cast<LinkedNode*>(m_anchor.pNext));
00296     }
00297 
00301     Iterator End()
00302     {
00303         return Iterator(&m_anchor);
00304     }
00305 
00309     ConstIterator End() const
00310     {
00311         return ConstIterator(const_cast<LinkedNode*>(&m_anchor));
00312     }
00313 
00317     Iterator ReverseBegin()
00318     {
00319         return Iterator(m_anchor.pPrev);
00320     }
00321 
00325     ConstIterator ReverseBegin() const
00326     {
00327         return ConstIterator(const_cast<LinkedNode*>(m_anchor.pPrev));
00328     }
00329 
00333     Iterator ReverseEnd()
00334     {
00335         return Iterator(&m_anchor);
00336     }
00337 
00341     ConstIterator ReverseEnd() const
00342     {
00343         return ConstIterator(const_cast<LinkedNode*>(&m_anchor));
00344     }
00345 
00355     XnStatus AddAfter(ConstIterator where, T const& value)
00356     {
00357         if (where == End())
00358         {
00359             return XN_STATUS_ILLEGAL_POSITION;
00360         }
00361 
00362         return InsertAfter(where.m_pCurrent, value);
00363     }
00364 
00374     XnStatus AddBefore(ConstIterator where, T const& value)
00375     {
00376         if (where == End())
00377         {
00378             return XN_STATUS_ILLEGAL_POSITION;
00379         }
00380 
00381         return InsertAfter(where.m_pCurrent->pPrev, value);
00382     }
00383 
00391     XnStatus AddFirst(T const& value)
00392     {
00393         return InsertAfter(&m_anchor, value);
00394     }
00395 
00403     XnStatus AddLast(T const& value)
00404     {
00405         return InsertAfter(ReverseBegin().m_pCurrent, value);
00406     }
00407 
00415     ConstIterator Find(T const& value) const
00416     {
00417         ConstIterator iter = Begin();
00418         for (; iter != End(); ++iter)
00419         {
00420             if (*iter == value)
00421                 break;
00422         }
00423         return iter;
00424     }
00425 
00433     Iterator Find(T const& value)
00434     {
00435         ConstIterator iter = const_cast<const XnListT<T>*>(this)->Find(value);
00436         return Iterator(iter.m_pCurrent);
00437     }
00438 
00446     XnStatus Remove(ConstIterator where)
00447     {
00448         // Verify iterator is valid
00449         if (where == End())
00450         {
00451             return XN_STATUS_ILLEGAL_POSITION;
00452         }
00453 
00454         XnLinkedNodeT<T>* pToRemove = where.m_pCurrent;
00455 
00456         // Connect other nodes to bypass the one removed
00457         pToRemove->pPrev->pNext = pToRemove->pNext;
00458         pToRemove->pNext->pPrev = pToRemove->pPrev;
00459 
00460         --m_nSize;
00461 
00462         // Free memory
00463         TAlloc::Deallocate(pToRemove);
00464 
00465         return XN_STATUS_OK;
00466     }
00467 
00475     XnStatus Remove(T const& value)
00476     {
00477         ConstIterator it = Find(value);
00478         if (it != End())
00479         {
00480             return Remove(it);
00481         }
00482         else
00483         {
00484             return XN_STATUS_NO_MATCH;
00485         }
00486     }
00487 
00491     XnStatus Clear()
00492     {
00493         while (!IsEmpty())
00494             Remove(Begin());
00495 
00496         return XN_STATUS_OK;
00497     }
00498 
00502     XnBool IsEmpty() const
00503     {
00504         return (m_nSize == 0);
00505     }
00506 
00510     XnUInt32 Size() const
00511     {
00512         return m_nSize;
00513     }
00514 
00521     void CopyTo(T* pArray) const
00522     {
00523         XN_ASSERT(pArray != NULL);
00524 
00525         XnUInt32 i = 0;
00526         for (ConstIterator iter = Begin(); iter != End(); ++iter, ++i)
00527         {
00528             pArray[i] = *iter;
00529         }
00530     }
00531     
00532 protected:
00541     XnStatus InsertAfter(LinkedNode* pAfter, T const& val)
00542     {
00543         // Get a node from the pool for the entry
00544         LinkedNode* pNewNode = TAlloc::Allocate(val);
00545         if (pNewNode == NULL)
00546         {
00547             XN_ASSERT(FALSE);
00548             return XN_STATUS_ALLOC_FAILED;
00549         }
00550         pNewNode->pPrev = pAfter;
00551         pNewNode->pNext = pAfter->pNext;
00552 
00553         // push new node to position
00554         pAfter->pNext->pPrev = pNewNode;
00555         pAfter->pNext = pNewNode;
00556 
00557         ++m_nSize;
00558 
00559         return XN_STATUS_OK;
00560     }
00561 
00562     // A dummy node, pointing to first node, and last node points back to it.
00563     LinkedNode m_anchor;
00564 
00565     XnUInt32 m_nSize;
00566 
00567 private:
00568     void Init()
00569     {
00570         m_anchor.pNext = &m_anchor;
00571         m_anchor.pPrev = &m_anchor;
00572         m_nSize = 0;
00573     }
00574 };
00575 
00576 #endif // _XNLISTT_H_