OpenNI 1.0.0

XnList.h

Go to the documentation of this file.
00001 /*****************************************************************************
00002 *                                                                            *
00003 *  OpenNI 1.0 Alpha                                                          *
00004 *  Copyright (C) 2010 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 
00023 
00024 
00025 
00026 #ifndef _XN_LIST_H
00027 #define _XN_LIST_H
00028 
00029 //---------------------------------------------------------------------------
00030 // Includes
00031 //---------------------------------------------------------------------------
00032 #include <XnDataTypes.h>
00033 #include <IXnNodeAllocator.h>
00034 #include <XnNodeAllocator.h>
00035 #include <XnNode.h>
00036 
00037 //---------------------------------------------------------------------------
00038 // Types
00039 //---------------------------------------------------------------------------
00040 
00044 class XnList
00045 {
00046 public:
00047     class ConstIterator
00048     {
00049     public:
00050         friend class XnList;
00051 
00057         ConstIterator(const ConstIterator& other) : m_pCurrent(other.m_pCurrent) {}
00058 
00062         ConstIterator& operator++()
00063         {
00064             m_pCurrent = m_pCurrent->Next();
00065             return *this;
00066         }
00067 
00071         ConstIterator operator++(int)
00072         {
00073             ConstIterator other(m_pCurrent);
00074             m_pCurrent = m_pCurrent->Next();
00075             return other;
00076         }
00077 
00081         ConstIterator& operator--()
00082         {
00083             m_pCurrent = m_pCurrent->Previous();
00084             return *this;
00085         }
00086 
00090         ConstIterator operator--(int)
00091         {
00092             ConstIterator other = *this;
00093             --*this;
00094             return other;
00095         }
00096 
00102         XnBool operator==(const ConstIterator& other) const
00103         {
00104             return m_pCurrent == other.m_pCurrent;
00105         }
00111         XnBool operator!=(const ConstIterator& other) const
00112         {
00113             return m_pCurrent != other.m_pCurrent;
00114         }
00115 
00119         const XnValue& operator*() const
00120         {
00121             return m_pCurrent->Data();
00122         }
00123 
00124 
00128         const XnNode* GetNode() const
00129         {
00130             return m_pCurrent;
00131         }
00132 
00136         XnNode* GetNode()
00137         {
00138             return m_pCurrent;
00139         }
00140 
00141     protected:
00147         ConstIterator(XnNode* pNode) : m_pCurrent(pNode) {}
00148 
00150         XnNode* m_pCurrent;
00151     };
00152 
00156     class Iterator : public ConstIterator
00157     {
00158     public:
00159         friend class XnList;
00160 
00166         inline Iterator(const Iterator& other) : ConstIterator(other) {}
00167 
00171         inline Iterator& operator++() 
00172         { 
00173             ++(*(ConstIterator*)this);
00174             return (*this);
00175         }
00179         inline Iterator operator++(int) 
00180         { 
00181             Iterator result = *this;
00182             ++*this;
00183             return (result);
00184         }
00185         
00189         inline Iterator& operator--() 
00190         { 
00191             --(*(ConstIterator*)this); 
00192             return (*this);
00193         }
00197         inline Iterator operator--(int)
00198         { 
00199             Iterator result = *this;
00200             --*this;
00201             return (result);
00202         }
00203 
00207         inline XnValue& operator*() const { return ((XnValue&)**(ConstIterator*)this); }
00208 
00209     protected:
00215         inline Iterator(XnNode* pNode) : ConstIterator(pNode) {}
00216     };
00217 
00218 public:
00222     XnList()
00223     {
00224         //Default node allocator is XnNodeAllocator
00225         Init(new XnNodeAllocator);
00226         m_bOwnsAllocator = TRUE;
00227     }
00228 
00232     virtual ~XnList()
00233     {
00234         Clear();
00235 
00236         // Return base node to the pool
00237         m_pNodeAllocator->Deallocate(m_pBase);
00238 
00239         if (m_bOwnsAllocator)
00240         {
00241             //We created the allocator in this object, so we must release it
00242             delete m_pNodeAllocator;
00243         }
00244     }
00245 
00253     XnStatus AddFirst(const XnValue& value)
00254     {
00255         return Add(m_pBase, value);
00256     }
00257 
00265     XnStatus AddLast(const XnValue& value)
00266     {
00267         return Add(rbegin().m_pCurrent, value);
00268     }
00269 
00279     XnStatus AddAfter(ConstIterator where, const XnValue& val)
00280     {
00281         if (where == end())
00282         {
00283             return XN_STATUS_ILLEGAL_POSITION;
00284         }
00285 
00286         return Add(where.m_pCurrent, val);
00287     }
00288 
00297     XnStatus AddBefore(ConstIterator where, const XnValue& val)
00298     {
00299         if (where == end())
00300         {
00301             return XN_STATUS_ILLEGAL_POSITION;
00302         }
00303 
00304         return Add(where.m_pCurrent->Previous(), val);
00305     }
00306 
00307 
00315     Iterator Find(const XnValue& value)
00316     {
00317         if (IsEmpty())
00318         {
00319             return end();
00320         }
00321 
00322         Iterator iter = begin();
00323         for (; iter != end(); ++iter)
00324         {
00325             if (*iter == value)
00326                 break;
00327         }
00328         return iter;
00329     }
00330 
00331 
00339     ConstIterator Find(const XnValue& value) const
00340     {
00341         if (IsEmpty())
00342         {
00343             return end();
00344         }
00345 
00346         ConstIterator iter = begin();
00347         for (; iter != end(); ++iter)
00348         {
00349             if (*iter == value)
00350                 break;
00351         }
00352         return iter;
00353     }
00354 
00355 
00364     XnStatus Remove(ConstIterator where, XnValue& value)
00365     {
00366         value = *where;
00367         return Remove(where);
00368     }
00369 
00377     virtual XnStatus Remove(ConstIterator where)
00378     {
00379         // Verify iterator is valid
00380         if (where == end())
00381         {
00382             return XN_STATUS_ILLEGAL_POSITION;
00383         }
00384         if (IsEmpty())
00385         {
00386             return XN_STATUS_IS_EMPTY;
00387         }
00388 
00389         XnNode* pToRemove = where.m_pCurrent;
00390 
00391         // Connect other nodes to bypass the one removed
00392         pToRemove->Previous()->Next() = pToRemove->Next();
00393         pToRemove->Next()->Previous() = pToRemove->Previous();
00394 
00395         // Return removed node to the pool
00396         m_pNodeAllocator->Deallocate(pToRemove);
00397 
00398         return XN_STATUS_OK;
00399     }
00400 
00401 
00405     XnStatus Clear()
00406     {
00407         while (!IsEmpty())
00408             Remove(begin());
00409 
00410         return XN_STATUS_OK;
00411     }
00412 
00416     XnBool IsEmpty() const
00417     {
00418         return (begin() == end());
00419     }
00420 
00424     XnUInt32 Size() const
00425     {
00426         XnUInt32 nSize = 0;
00427         for (ConstIterator iter = begin(); iter != end(); ++iter, ++nSize)
00428             ;
00429 
00430         return nSize;
00431     }
00432 
00436     Iterator begin()
00437     {
00438         return Iterator(m_pBase->Next());
00439     }
00440 
00444     ConstIterator begin() const
00445     {
00446         return ConstIterator(m_pBase->Next());
00447     }
00448 
00452     Iterator end()
00453     {
00454         return Iterator(m_pBase);
00455     }
00456 
00460     ConstIterator end() const
00461     {
00462         return ConstIterator(m_pBase);
00463     }
00464 
00468     Iterator rbegin()
00469     {
00470         return Iterator(m_pBase->Previous());
00471     }
00472 
00476     ConstIterator rbegin() const
00477     {
00478         return ConstIterator(m_pBase->Previous());
00479     }
00480 
00484     Iterator rend()
00485     {
00486         return Iterator(m_pBase);
00487     }
00488 
00492     ConstIterator rend() const
00493     {
00494         return ConstIterator(m_pBase);
00495     }
00496     
00497 protected:
00498     friend class XnNodeManager;
00499     
00503     XnList(INiNodeAllocator* pNodeAllocator)
00504     {
00505         Init(pNodeAllocator);
00506         m_bOwnsAllocator = FALSE;
00507     }
00508     
00509     void Init(INiNodeAllocator* pNodeAllocator)
00510     {
00511         m_pNodeAllocator = pNodeAllocator;
00512         // Allocate a node to act as base node.
00513         m_pBase = m_pNodeAllocator->Allocate();
00514         if (m_pBase == NULL)
00515         {
00516             // OZOZ: Allocation failed in ctor...
00517         }
00518 
00519         m_pBase->Next() = m_pBase->Previous() = m_pBase;
00520     }
00521 
00530     XnStatus Add(XnNode* pWhere, const XnValue& val)
00531     {
00532         // Get a node from the pool for the entry
00533         XnNode* pNewNode = m_pNodeAllocator->Allocate();
00534         if (pNewNode == NULL)
00535         {
00536             return XN_STATUS_ALLOC_FAILED;
00537         }
00538         // push new node to position
00539         pNewNode->Data() = val;
00540         pNewNode->Next() = pWhere->Next();
00541         pNewNode->Previous() = pWhere;
00542         pWhere->Next()->Previous() = pNewNode;
00543         pWhere->Next() = pNewNode;
00544 
00545         return XN_STATUS_OK;
00546     }
00547 
00548 
00550     XnNode* m_pBase;
00551     
00552     INiNodeAllocator* m_pNodeAllocator;
00553     XnBool m_bOwnsAllocator;
00554 };
00555 
00560 #define XN_DECLARE_LIST_WITH_TRANSLATOR_DECL(decl, Type, ClassName, Translator)                 \
00561     class decl ClassName : public XnList                                                        \
00562     {                                                                                           \
00563     public:                                                                                     \
00564         class decl ConstIterator : public XnList::ConstIterator                                 \
00565         {                                                                                       \
00566         public:                                                                                 \
00567             friend class ClassName;                                                             \
00568             inline ConstIterator(const ConstIterator& other) : XnList::ConstIterator(other) {}  \
00569             inline ConstIterator& operator++()                                                  \
00570             {                                                                                   \
00571                 ++(*(XnList::ConstIterator*)this);                                              \
00572                 return (*this);                                                                 \
00573             }                                                                                   \
00574             inline ConstIterator operator++(int)                                                \
00575             {                                                                                   \
00576                 ConstIterator result = *this;                                                   \
00577                 ++*this;                                                                        \
00578                 return result;                                                                  \
00579             }                                                                                   \
00580             inline ConstIterator& operator--()                                                  \
00581             {                                                                                   \
00582                 --(*(XnList::ConstIterator*)this);                                              \
00583                 return (*this);                                                                 \
00584             }                                                                                   \
00585             inline ConstIterator operator--(int)                                                \
00586             {                                                                                   \
00587                 ConstIterator result = *this;                                                   \
00588                 --*this;                                                                        \
00589                 return result;                                                                  \
00590             }                                                                                   \
00591             inline Type const& operator*() const                                                \
00592             {                                                                                   \
00593                 return Translator::GetFromValue(**((XnList::ConstIterator*)this));              \
00594             }                                                                                   \
00595             inline Type const* operator->() const { return (&**this); }                         \
00596         protected:                                                                              \
00597             inline ConstIterator(XnNode* pNode) : XnList::ConstIterator(pNode) {}               \
00598             inline ConstIterator(const XnList::ConstIterator& other) :                          \
00599                 XnList::ConstIterator(other)                                                    \
00600             {}                                                                                  \
00601         };                                                                                      \
00602         class decl Iterator : public ConstIterator                                              \
00603         {                                                                                       \
00604         public:                                                                                 \
00605             friend class ClassName;                                                             \
00606             Iterator(const Iterator& other) : ConstIterator(other) {}                           \
00607             inline Iterator& operator++()                                                       \
00608             {                                                                                   \
00609                 ++(*(ConstIterator*)this);                                                      \
00610                 return (*this);                                                                 \
00611             }                                                                                   \
00612             inline Iterator operator++(int)                                                     \
00613             {                                                                                   \
00614                 Iterator result = *this;                                                        \
00615                 ++*this;                                                                        \
00616                 return result;                                                                  \
00617             }                                                                                   \
00618             inline Iterator& operator--()                                                       \
00619             {                                                                                   \
00620                 --(*(ConstIterator*)this);                                                      \
00621                 return (*this);                                                                 \
00622             }                                                                                   \
00623             inline Iterator operator--(int)                                                     \
00624             {                                                                                   \
00625                 Iterator result = *this;                                                        \
00626                 --*this;                                                                        \
00627                 return result;                                                                  \
00628             }                                                                                   \
00629             inline Type& operator*() const { return ((Type&)**(ConstIterator*)this); }          \
00630             inline Type* operator->() const { return (&**this); }                               \
00631         protected:                                                                              \
00632             inline Iterator(XnNode* pNode) : ConstIterator(pNode) {}                            \
00633             inline Iterator(const XnList::Iterator& other) : ConstIterator(other) {}            \
00634         };                                                                                      \
00635     public:                                                                                     \
00636         ClassName()                                                                             \
00637         {                                                                                       \
00638         }                                                                                       \
00639         ClassName(const ClassName& other)                                                       \
00640         {                                                                                       \
00641             *this = other;                                                                      \
00642         }                                                                                       \
00643         ~ClassName()                                                                            \
00644         {                                                                                       \
00645             while (!IsEmpty())                                                                  \
00646                 Remove(begin());                                                                \
00647         }                                                                                       \
00648         ClassName& operator=(const ClassName& other)                                            \
00649         {                                                                                       \
00650             Clear();                                                                            \
00651             for (ConstIterator it = other.begin(); it != other.end(); ++it)                     \
00652             {                                                                                   \
00653                 AddLast(*it);                                                                   \
00654             }                                                                                   \
00655             return *this;                                                                       \
00656         }                                                                                       \
00657         inline XnStatus AddFirst(Type const& value)                                             \
00658         {                                                                                       \
00659             XnValue val = Translator::CreateValueCopy(value);                                   \
00660             XnStatus nRetVal = XnList::AddFirst(val);                                           \
00661             if (nRetVal != XN_STATUS_OK)                                                        \
00662             {                                                                                   \
00663                 Translator::FreeValue(val);                                                     \
00664                 return (nRetVal);                                                               \
00665             }                                                                                   \
00666             return XN_STATUS_OK;                                                                \
00667         }                                                                                       \
00668         inline XnStatus AddLast(Type const& value)                                              \
00669         {                                                                                       \
00670             XnValue val = Translator::CreateValueCopy(value);                                   \
00671             XnStatus nRetVal = XnList::AddLast(val);                                            \
00672             if (nRetVal != XN_STATUS_OK)                                                        \
00673             {                                                                                   \
00674                 Translator::FreeValue(val);                                                     \
00675                 return (nRetVal);                                                               \
00676             }                                                                                   \
00677             return XN_STATUS_OK;                                                                \
00678         }                                                                                       \
00679         inline XnStatus AddAfter(ConstIterator where, Type const& value)                        \
00680         {                                                                                       \
00681             XnValue val = Translator::CreateValueCopy(value);                                   \
00682             XnStatus nRetVal = XnList::AddAfter(where, val);                                    \
00683             if (nRetVal != XN_STATUS_OK)                                                        \
00684             {                                                                                   \
00685                 Translator::FreeValue(val);                                                     \
00686                 return (nRetVal);                                                               \
00687             }                                                                                   \
00688             return XN_STATUS_OK;                                                                \
00689         }                                                                                       \
00690         inline XnStatus AddBefore(ConstIterator where, Type const& value)                       \
00691         {                                                                                       \
00692             XnValue val = Translator::CreateValueCopy(value);                                   \
00693             XnStatus nRetVal = XnList::AddBefore(where, val);                                   \
00694             if (nRetVal != XN_STATUS_OK)                                                        \
00695             {                                                                                   \
00696                 Translator::FreeValue(val);                                                     \
00697                 return (nRetVal);                                                               \
00698             }                                                                                   \
00699             return XN_STATUS_OK;                                                                \
00700         }                                                                                       \
00701         inline ConstIterator Find(Type const& value) const                                      \
00702         {                                                                                       \
00703             XnValue _value = Translator::GetAsValue(value);                                     \
00704             return XnList::Find(_value);                                                        \
00705         }                                                                                       \
00706         inline Iterator Find(Type const& value)                                                 \
00707         {                                                                                       \
00708             XnValue _value = Translator::GetAsValue(value);                                     \
00709             return XnList::Find(_value);                                                        \
00710         }                                                                                       \
00711         inline XnStatus Remove(ConstIterator where)                                             \
00712         {                                                                                       \
00713             XnValue val = Translator::GetAsValue(*where);                                       \
00714             XnStatus nRetVal = XnList::Remove(where);                                           \
00715             if (nRetVal != XN_STATUS_OK) return (nRetVal);                                      \
00716             Translator::FreeValue(val);                                                         \
00717             return XN_STATUS_OK;                                                                \
00718         }                                                                                       \
00719         inline Iterator begin() { return XnList::begin(); }                                     \
00720         inline ConstIterator begin() const { return XnList::begin(); }                          \
00721         inline Iterator end() { return XnList::end(); }                                         \
00722         inline ConstIterator end() const { return XnList::end(); }                              \
00723         inline Iterator rbegin() { return XnList::rbegin(); }                                   \
00724         inline ConstIterator rbegin() const { return XnList::rbegin(); }                        \
00725         inline Iterator rend() { return XnList::rend(); }                                       \
00726         inline ConstIterator rend() const { return XnList::rend(); }                            \
00727     protected:                                                                                  \
00728         virtual XnStatus Remove(XnList::ConstIterator where)                                    \
00729         {                                                                                       \
00730             return Remove(ConstIterator(where));                                                \
00731         }                                                                                       \
00732     };
00733 
00737 #define XN_DECLARE_LIST_WITH_TRANSLATOR(Type, ClassName, Translator)                            \
00738     XN_DECLARE_LIST_WITH_TRANSLATOR_DECL(, Type, ClassName, Translator)
00739 
00744 #define XN_DECLARE_LIST_DECL(decl, Type, ClassName)                                                     \
00745     XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, Type, XN_DEFAULT_TRANSLATOR_NAME(ClassName))         \
00746     XN_DECLARE_LIST_WITH_TRANSLATOR_DECL(decl, Type, ClassName, XN_DEFAULT_TRANSLATOR_NAME(ClassName))
00747 
00751 #define XN_DECLARE_LIST(Type, ClassName)        \
00752     XN_DECLARE_LIST_DECL(, Type, ClassName)
00753                                                                                             
00754 #endif // _XN_LIST_H                                                                        
00755