OpenNI 1.5.2
XnList.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 *                                                                           *
00003 *  OpenNI 1.x Alpha                                                         *
00004 *  Copyright (C) 2011 PrimeSense Ltd.                                       *
00005 *                                                                           *
00006 *  This file is part of OpenNI.                                             *
00007 *                                                                           *
00008 *  OpenNI is free software: you can redistribute it and/or modify           *
00009 *  it under the terms of the GNU Lesser General Public License as published *
00010 *  by the Free Software Foundation, either version 3 of the License, or     *
00011 *  (at your option) any later version.                                      *
00012 *                                                                           *
00013 *  OpenNI is distributed in the hope that it will be useful,                *
00014 *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
00015 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the             *
00016 *  GNU Lesser General Public License for more details.                      *
00017 *                                                                           *
00018 *  You should have received a copy of the GNU Lesser General Public License *
00019 *  along with OpenNI. If not, see <http://www.gnu.org/licenses/>.           *
00020 *                                                                           *
00021 ****************************************************************************/
00022 #ifndef _XN_LIST_H
00023 #define _XN_LIST_H
00024 
00025 //---------------------------------------------------------------------------
00026 // Includes
00027 //---------------------------------------------------------------------------
00028 #include <XnDataTypes.h>
00029 #include <IXnNodeAllocator.h>
00030 #include <XnNodeAllocator.h>
00031 #include <XnNode.h>
00032 #include <XnStatusCodes.h>
00033 
00034 //---------------------------------------------------------------------------
00035 // Types
00036 //---------------------------------------------------------------------------
00037 
00041 class XnList
00042 {
00043 public:
00044     class ConstIterator
00045     {
00046     public:
00047         friend class XnList;
00048 
00054         ConstIterator(const ConstIterator& other) : m_pCurrent(other.m_pCurrent) {}
00055 
00059         ConstIterator& operator++()
00060         {
00061             m_pCurrent = m_pCurrent->Next();
00062             return *this;
00063         }
00064 
00068         ConstIterator operator++(int)
00069         {
00070             ConstIterator other(m_pCurrent);
00071             m_pCurrent = m_pCurrent->Next();
00072             return other;
00073         }
00074 
00078         ConstIterator& operator--()
00079         {
00080             m_pCurrent = m_pCurrent->Previous();
00081             return *this;
00082         }
00083 
00087         ConstIterator operator--(int)
00088         {
00089             ConstIterator other = *this;
00090             --*this;
00091             return other;
00092         }
00093 
00099         XnBool operator==(const ConstIterator& other) const
00100         {
00101             return m_pCurrent == other.m_pCurrent;
00102         }
00108         XnBool operator!=(const ConstIterator& other) const
00109         {
00110             return m_pCurrent != other.m_pCurrent;
00111         }
00112 
00116         const XnValue& operator*() const
00117         {
00118             return m_pCurrent->Data();
00119         }
00120 
00121 
00125         const XnNode* GetNode() const
00126         {
00127             return m_pCurrent;
00128         }
00129 
00133         XnNode* GetNode()
00134         {
00135             return m_pCurrent;
00136         }
00137 
00138     protected:
00144         ConstIterator(XnNode* pNode) : m_pCurrent(pNode) {}
00145 
00147         XnNode* m_pCurrent;
00148     };
00149 
00153     class Iterator : public ConstIterator
00154     {
00155     public:
00156         friend class XnList;
00157 
00163         inline Iterator(const Iterator& other) : ConstIterator(other) {}
00164 
00168         inline Iterator& operator++() 
00169         { 
00170             ++(*(ConstIterator*)this);
00171             return (*this);
00172         }
00176         inline Iterator operator++(int) 
00177         { 
00178             Iterator result = *this;
00179             ++*this;
00180             return (result);
00181         }
00182         
00186         inline Iterator& operator--() 
00187         { 
00188             --(*(ConstIterator*)this); 
00189             return (*this);
00190         }
00194         inline Iterator operator--(int)
00195         { 
00196             Iterator result = *this;
00197             --*this;
00198             return (result);
00199         }
00200 
00204         inline XnValue& operator*() const { return ((XnValue&)**(ConstIterator*)this); }
00205 
00206     protected:
00212         inline Iterator(XnNode* pNode) : ConstIterator(pNode) {}
00213     };
00214 
00215 public:
00219     XnList()
00220     {
00221         //Default node allocator is XnNodeAllocator
00222         Init(XN_NEW(XnNodeAllocator));
00223         m_bOwnsAllocator = TRUE;
00224     }
00225 
00229     virtual ~XnList()
00230     {
00231         Clear();
00232 
00233         // Return base node to the pool
00234         m_pNodeAllocator->Deallocate(m_pBase);
00235 
00236         if (m_bOwnsAllocator)
00237         {
00238             //We created the allocator in this object, so we must release it
00239             XN_DELETE(m_pNodeAllocator);
00240         }
00241     }
00242 
00250     XnStatus AddFirst(const XnValue& value)
00251     {
00252         return Add(m_pBase, value);
00253     }
00254 
00262     XnStatus AddLast(const XnValue& value)
00263     {
00264         return Add(rbegin().m_pCurrent, value);
00265     }
00266 
00276     XnStatus AddAfter(ConstIterator where, const XnValue& val)
00277     {
00278         if (where == end())
00279         {
00280             return XN_STATUS_ILLEGAL_POSITION;
00281         }
00282 
00283         return Add(where.m_pCurrent, val);
00284     }
00285 
00294     XnStatus AddBefore(ConstIterator where, const XnValue& val)
00295     {
00296         if (where == end())
00297         {
00298             return XN_STATUS_ILLEGAL_POSITION;
00299         }
00300 
00301         return Add(where.m_pCurrent->Previous(), val);
00302     }
00303 
00304 
00312     Iterator Find(const XnValue& value)
00313     {
00314         if (IsEmpty())
00315         {
00316             return end();
00317         }
00318 
00319         Iterator iter = begin();
00320         for (; iter != end(); ++iter)
00321         {
00322             if (*iter == value)
00323                 break;
00324         }
00325         return iter;
00326     }
00327 
00328 
00336     ConstIterator Find(const XnValue& value) const
00337     {
00338         if (IsEmpty())
00339         {
00340             return end();
00341         }
00342 
00343         ConstIterator iter = begin();
00344         for (; iter != end(); ++iter)
00345         {
00346             if (*iter == value)
00347                 break;
00348         }
00349         return iter;
00350     }
00351 
00352 
00361     XnStatus Remove(ConstIterator where, XnValue& value)
00362     {
00363         value = *where;
00364         return Remove(where);
00365     }
00366 
00374     virtual XnStatus Remove(ConstIterator where)
00375     {
00376         // Verify iterator is valid
00377         if (where == end())
00378         {
00379             return XN_STATUS_ILLEGAL_POSITION;
00380         }
00381         if (IsEmpty())
00382         {
00383             return XN_STATUS_IS_EMPTY;
00384         }
00385 
00386         XnNode* pToRemove = where.m_pCurrent;
00387 
00388         // Connect other nodes to bypass the one removed
00389         pToRemove->Previous()->Next() = pToRemove->Next();
00390         pToRemove->Next()->Previous() = pToRemove->Previous();
00391 
00392         // Return removed node to the pool
00393         m_pNodeAllocator->Deallocate(pToRemove);
00394 
00395         return XN_STATUS_OK;
00396     }
00397 
00398 
00402     XnStatus Clear()
00403     {
00404         while (!IsEmpty())
00405             Remove(begin());
00406 
00407         return XN_STATUS_OK;
00408     }
00409 
00413     XnBool IsEmpty() const
00414     {
00415         return (begin() == end());
00416     }
00417 
00421     XnUInt32 Size() const
00422     {
00423         XnUInt32 nSize = 0;
00424         for (ConstIterator iter = begin(); iter != end(); ++iter, ++nSize)
00425             ;
00426 
00427         return nSize;
00428     }
00429 
00433     Iterator begin()
00434     {
00435         return Iterator(m_pBase->Next());
00436     }
00437 
00441     ConstIterator begin() const
00442     {
00443         return ConstIterator(m_pBase->Next());
00444     }
00445 
00449     Iterator end()
00450     {
00451         return Iterator(m_pBase);
00452     }
00453 
00457     ConstIterator end() const
00458     {
00459         return ConstIterator(m_pBase);
00460     }
00461 
00465     Iterator rbegin()
00466     {
00467         return Iterator(m_pBase->Previous());
00468     }
00469 
00473     ConstIterator rbegin() const
00474     {
00475         return ConstIterator(m_pBase->Previous());
00476     }
00477 
00481     Iterator rend()
00482     {
00483         return Iterator(m_pBase);
00484     }
00485 
00489     ConstIterator rend() const
00490     {
00491         return ConstIterator(m_pBase);
00492     }
00493     
00494 protected:
00495     friend class XnNodeManager;
00496     
00500     XnList(INiNodeAllocator* pNodeAllocator)
00501     {
00502         Init(pNodeAllocator);
00503         m_bOwnsAllocator = FALSE;
00504     }
00505     
00506     void Init(INiNodeAllocator* pNodeAllocator)
00507     {
00508         m_pNodeAllocator = pNodeAllocator;
00509         // Allocate a node to act as base node.
00510         m_pBase = m_pNodeAllocator->Allocate();
00511         if (m_pBase == NULL)
00512         {
00513             // OZOZ: Allocation failed in ctor...
00514         }
00515 
00516         m_pBase->Next() = m_pBase->Previous() = m_pBase;
00517     }
00518 
00527     XnStatus Add(XnNode* pWhere, const XnValue& val)
00528     {
00529         // Get a node from the pool for the entry
00530         XnNode* pNewNode = m_pNodeAllocator->Allocate();
00531         if (pNewNode == NULL)
00532         {
00533             return XN_STATUS_ALLOC_FAILED;
00534         }
00535         // push new node to position
00536         pNewNode->Data() = val;
00537         pNewNode->Next() = pWhere->Next();
00538         pNewNode->Previous() = pWhere;
00539         pWhere->Next()->Previous() = pNewNode;
00540         pWhere->Next() = pNewNode;
00541 
00542         return XN_STATUS_OK;
00543     }
00544 
00545 
00547     XnNode* m_pBase;
00548     
00549     INiNodeAllocator* m_pNodeAllocator;
00550     XnBool m_bOwnsAllocator;
00551 };
00552 
00557 #define XN_DECLARE_LIST_WITH_TRANSLATOR_DECL(decl, Type, ClassName, Translator)                 \
00558     class decl ClassName : public XnList                                                        \
00559     {                                                                                           \
00560     public:                                                                                     \
00561         class decl ConstIterator : public XnList::ConstIterator                                 \
00562         {                                                                                       \
00563         public:                                                                                 \
00564             friend class ClassName;                                                             \
00565             inline ConstIterator(const ConstIterator& other) : XnList::ConstIterator(other) {}  \
00566             inline ConstIterator& operator++()                                                  \
00567             {                                                                                   \
00568                 ++(*(XnList::ConstIterator*)this);                                              \
00569                 return (*this);                                                                 \
00570             }                                                                                   \
00571             inline ConstIterator operator++(int)                                                \
00572             {                                                                                   \
00573                 ConstIterator result = *this;                                                   \
00574                 ++*this;                                                                        \
00575                 return result;                                                                  \
00576             }                                                                                   \
00577             inline ConstIterator& operator--()                                                  \
00578             {                                                                                   \
00579                 --(*(XnList::ConstIterator*)this);                                              \
00580                 return (*this);                                                                 \
00581             }                                                                                   \
00582             inline ConstIterator operator--(int)                                                \
00583             {                                                                                   \
00584                 ConstIterator result = *this;                                                   \
00585                 --*this;                                                                        \
00586                 return result;                                                                  \
00587             }                                                                                   \
00588             inline Type const& operator*() const                                                \
00589             {                                                                                   \
00590                 return Translator::GetFromValue(**((XnList::ConstIterator*)this));              \
00591             }                                                                                   \
00592             inline Type const* operator->() const { return (&**this); }                         \
00593         protected:                                                                              \
00594             inline ConstIterator(XnNode* pNode) : XnList::ConstIterator(pNode) {}               \
00595             inline ConstIterator(const XnList::ConstIterator& other) :                          \
00596                 XnList::ConstIterator(other)                                                    \
00597             {}                                                                                  \
00598         };                                                                                      \
00599         class decl Iterator : public ConstIterator                                              \
00600         {                                                                                       \
00601         public:                                                                                 \
00602             friend class ClassName;                                                             \
00603             Iterator(const Iterator& other) : ConstIterator(other) {}                           \
00604             inline Iterator& operator++()                                                       \
00605             {                                                                                   \
00606                 ++(*(ConstIterator*)this);                                                      \
00607                 return (*this);                                                                 \
00608             }                                                                                   \
00609             inline Iterator operator++(int)                                                     \
00610             {                                                                                   \
00611                 Iterator result = *this;                                                        \
00612                 ++*this;                                                                        \
00613                 return result;                                                                  \
00614             }                                                                                   \
00615             inline Iterator& operator--()                                                       \
00616             {                                                                                   \
00617                 --(*(ConstIterator*)this);                                                      \
00618                 return (*this);                                                                 \
00619             }                                                                                   \
00620             inline Iterator operator--(int)                                                     \
00621             {                                                                                   \
00622                 Iterator result = *this;                                                        \
00623                 --*this;                                                                        \
00624                 return result;                                                                  \
00625             }                                                                                   \
00626             inline Type& operator*() const { return ((Type&)**(ConstIterator*)this); }          \
00627             inline Type* operator->() const { return (&**this); }                               \
00628         protected:                                                                              \
00629             inline Iterator(XnNode* pNode) : ConstIterator(pNode) {}                            \
00630             inline Iterator(const XnList::Iterator& other) : ConstIterator(other) {}            \
00631         };                                                                                      \
00632     public:                                                                                     \
00633         ClassName()                                                                             \
00634         {                                                                                       \
00635         }                                                                                       \
00636         ClassName(const ClassName& other)                                                       \
00637         {                                                                                       \
00638             *this = other;                                                                      \
00639         }                                                                                       \
00640         ~ClassName()                                                                            \
00641         {                                                                                       \
00642             while (!IsEmpty())                                                                  \
00643                 Remove(begin());                                                                \
00644         }                                                                                       \
00645         ClassName& operator=(const ClassName& other)                                            \
00646         {                                                                                       \
00647             Clear();                                                                            \
00648             for (ConstIterator it = other.begin(); it != other.end(); ++it)                     \
00649             {                                                                                   \
00650                 AddLast(*it);                                                                   \
00651             }                                                                                   \
00652             return *this;                                                                       \
00653         }                                                                                       \
00654         inline XnStatus AddFirst(Type const& value)                                             \
00655         {                                                                                       \
00656             XnValue val = Translator::CreateValueCopy(value);                                   \
00657             XnStatus nRetVal = XnList::AddFirst(val);                                           \
00658             if (nRetVal != XN_STATUS_OK)                                                        \
00659             {                                                                                   \
00660                 Translator::FreeValue(val);                                                     \
00661                 return (nRetVal);                                                               \
00662             }                                                                                   \
00663             return XN_STATUS_OK;                                                                \
00664         }                                                                                       \
00665         inline XnStatus AddLast(Type const& value)                                              \
00666         {                                                                                       \
00667             XnValue val = Translator::CreateValueCopy(value);                                   \
00668             XnStatus nRetVal = XnList::AddLast(val);                                            \
00669             if (nRetVal != XN_STATUS_OK)                                                        \
00670             {                                                                                   \
00671                 Translator::FreeValue(val);                                                     \
00672                 return (nRetVal);                                                               \
00673             }                                                                                   \
00674             return XN_STATUS_OK;                                                                \
00675         }                                                                                       \
00676         inline XnStatus AddAfter(ConstIterator where, Type const& value)                        \
00677         {                                                                                       \
00678             XnValue val = Translator::CreateValueCopy(value);                                   \
00679             XnStatus nRetVal = XnList::AddAfter(where, val);                                    \
00680             if (nRetVal != XN_STATUS_OK)                                                        \
00681             {                                                                                   \
00682                 Translator::FreeValue(val);                                                     \
00683                 return (nRetVal);                                                               \
00684             }                                                                                   \
00685             return XN_STATUS_OK;                                                                \
00686         }                                                                                       \
00687         inline XnStatus AddBefore(ConstIterator where, Type const& value)                       \
00688         {                                                                                       \
00689             XnValue val = Translator::CreateValueCopy(value);                                   \
00690             XnStatus nRetVal = XnList::AddBefore(where, val);                                   \
00691             if (nRetVal != XN_STATUS_OK)                                                        \
00692             {                                                                                   \
00693                 Translator::FreeValue(val);                                                     \
00694                 return (nRetVal);                                                               \
00695             }                                                                                   \
00696             return XN_STATUS_OK;                                                                \
00697         }                                                                                       \
00698         inline ConstIterator Find(Type const& value) const                                      \
00699         {                                                                                       \
00700             XnValue _value = Translator::GetAsValue(value);                                     \
00701             return XnList::Find(_value);                                                        \
00702         }                                                                                       \
00703         inline Iterator Find(Type const& value)                                                 \
00704         {                                                                                       \
00705             XnValue _value = Translator::GetAsValue(value);                                     \
00706             return XnList::Find(_value);                                                        \
00707         }                                                                                       \
00708         inline XnStatus Remove(ConstIterator where)                                             \
00709         {                                                                                       \
00710             XnValue val = Translator::GetAsValue(*where);                                       \
00711             XnStatus nRetVal = XnList::Remove(where);                                           \
00712             if (nRetVal != XN_STATUS_OK) return (nRetVal);                                      \
00713             Translator::FreeValue(val);                                                         \
00714             return XN_STATUS_OK;                                                                \
00715         }                                                                                       \
00716         inline XnStatus Remove(Type const& value)                                               \
00717         {                                                                                       \
00718             Iterator it = Find(value);                                                          \
00719             return Remove(it);                                                                  \
00720         }                                                                                       \
00721         inline Iterator begin() { return XnList::begin(); }                                     \
00722         inline ConstIterator begin() const { return XnList::begin(); }                          \
00723         inline Iterator end() { return XnList::end(); }                                         \
00724         inline ConstIterator end() const { return XnList::end(); }                              \
00725         inline Iterator rbegin() { return XnList::rbegin(); }                                   \
00726         inline ConstIterator rbegin() const { return XnList::rbegin(); }                        \
00727         inline Iterator rend() { return XnList::rend(); }                                       \
00728         inline ConstIterator rend() const { return XnList::rend(); }                            \
00729     protected:                                                                                  \
00730         virtual XnStatus Remove(XnList::ConstIterator where)                                    \
00731         {                                                                                       \
00732             return Remove(ConstIterator(where));                                                \
00733         }                                                                                       \
00734     };
00735 
00739 #define XN_DECLARE_LIST_WITH_TRANSLATOR(Type, ClassName, Translator)                            \
00740     XN_DECLARE_LIST_WITH_TRANSLATOR_DECL(, Type, ClassName, Translator)
00741 
00746 #define XN_DECLARE_LIST_DECL(decl, Type, ClassName)                                                     \
00747     XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, Type, XN_DEFAULT_TRANSLATOR_NAME(ClassName))         \
00748     XN_DECLARE_LIST_WITH_TRANSLATOR_DECL(decl, Type, ClassName, XN_DEFAULT_TRANSLATOR_NAME(ClassName))
00749 
00753 #define XN_DECLARE_LIST(Type, ClassName)        \
00754     XN_DECLARE_LIST_DECL(, Type, ClassName)
00755                                                                                             
00756 #endif // _XN_LIST_H                                                                        
00757