OpenNI 1.5.7
XnList.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 _XN_LIST_H
00022 #define _XN_LIST_H
00023 
00024 //---------------------------------------------------------------------------
00025 // Includes
00026 //---------------------------------------------------------------------------
00027 #include <XnDataTypes.h>
00028 #include <IXnNodeAllocator.h>
00029 #include <XnNodeAllocator.h>
00030 #include <XnNode.h>
00031 #include <XnStatusCodes.h>
00032 
00033 //---------------------------------------------------------------------------
00034 // Types
00035 //---------------------------------------------------------------------------
00036 
00040 class XnList
00041 {
00042 public:
00043     class ConstIterator
00044     {
00045     public:
00046         friend class XnList;
00047 
00053         ConstIterator(const ConstIterator& other) : m_pCurrent(other.m_pCurrent) {}
00054 
00058         ConstIterator& operator++()
00059         {
00060             m_pCurrent = m_pCurrent->Next();
00061             return *this;
00062         }
00063 
00067         ConstIterator operator++(int)
00068         {
00069             ConstIterator other(m_pCurrent);
00070             m_pCurrent = m_pCurrent->Next();
00071             return other;
00072         }
00073 
00077         ConstIterator& operator--()
00078         {
00079             m_pCurrent = m_pCurrent->Previous();
00080             return *this;
00081         }
00082 
00086         ConstIterator operator--(int)
00087         {
00088             ConstIterator other = *this;
00089             --*this;
00090             return other;
00091         }
00092 
00098         XnBool operator==(const ConstIterator& other) const
00099         {
00100             return m_pCurrent == other.m_pCurrent;
00101         }
00107         XnBool operator!=(const ConstIterator& other) const
00108         {
00109             return m_pCurrent != other.m_pCurrent;
00110         }
00111 
00115         const XnValue& operator*() const
00116         {
00117             return m_pCurrent->Data();
00118         }
00119 
00120 
00124         const XnNode* GetNode() const
00125         {
00126             return m_pCurrent;
00127         }
00128 
00132         XnNode* GetNode()
00133         {
00134             return m_pCurrent;
00135         }
00136 
00137     protected:
00143         ConstIterator(XnNode* pNode) : m_pCurrent(pNode) {}
00144 
00146         XnNode* m_pCurrent;
00147     };
00148 
00152     class Iterator : public ConstIterator
00153     {
00154     public:
00155         friend class XnList;
00156 
00162         inline Iterator(const Iterator& other) : ConstIterator(other) {}
00163 
00167         inline Iterator& operator++() 
00168         { 
00169             ++(*(ConstIterator*)this);
00170             return (*this);
00171         }
00175         inline Iterator operator++(int) 
00176         { 
00177             Iterator result = *this;
00178             ++*this;
00179             return (result);
00180         }
00181         
00185         inline Iterator& operator--() 
00186         { 
00187             --(*(ConstIterator*)this); 
00188             return (*this);
00189         }
00193         inline Iterator operator--(int)
00194         { 
00195             Iterator result = *this;
00196             --*this;
00197             return (result);
00198         }
00199 
00203         inline XnValue& operator*() const { return ((XnValue&)**(ConstIterator*)this); }
00204 
00205     protected:
00211         inline Iterator(XnNode* pNode) : ConstIterator(pNode) {}
00212     };
00213 
00214 public:
00218     XnList()
00219     {
00220         //Default node allocator is XnNodeAllocator
00221         Init(XN_NEW(XnNodeAllocator));
00222         m_bOwnsAllocator = TRUE;
00223     }
00224 
00228     virtual ~XnList()
00229     {
00230         Clear();
00231 
00232         // Return base node to the pool
00233         m_pNodeAllocator->Deallocate(m_pBase);
00234 
00235         if (m_bOwnsAllocator)
00236         {
00237             //We created the allocator in this object, so we must release it
00238             XN_DELETE(m_pNodeAllocator);
00239         }
00240     }
00241 
00249     XnStatus AddFirst(const XnValue& value)
00250     {
00251         return Add(m_pBase, value);
00252     }
00253 
00261     XnStatus AddLast(const XnValue& value)
00262     {
00263         return Add(rbegin().m_pCurrent, value);
00264     }
00265 
00275     XnStatus AddAfter(ConstIterator where, const XnValue& val)
00276     {
00277         if (where == end())
00278         {
00279             return XN_STATUS_ILLEGAL_POSITION;
00280         }
00281 
00282         return Add(where.m_pCurrent, val);
00283     }
00284 
00293     XnStatus AddBefore(ConstIterator where, const XnValue& val)
00294     {
00295         if (where == end())
00296         {
00297             return XN_STATUS_ILLEGAL_POSITION;
00298         }
00299 
00300         return Add(where.m_pCurrent->Previous(), val);
00301     }
00302 
00303 
00311     Iterator Find(const XnValue& value)
00312     {
00313         if (IsEmpty())
00314         {
00315             return end();
00316         }
00317 
00318         Iterator iter = begin();
00319         for (; iter != end(); ++iter)
00320         {
00321             if (*iter == value)
00322                 break;
00323         }
00324         return iter;
00325     }
00326 
00327 
00335     ConstIterator Find(const XnValue& value) const
00336     {
00337         if (IsEmpty())
00338         {
00339             return end();
00340         }
00341 
00342         ConstIterator iter = begin();
00343         for (; iter != end(); ++iter)
00344         {
00345             if (*iter == value)
00346                 break;
00347         }
00348         return iter;
00349     }
00350 
00351 
00360     XnStatus Remove(ConstIterator where, XnValue& value)
00361     {
00362         value = *where;
00363         return Remove(where);
00364     }
00365 
00373     virtual XnStatus Remove(ConstIterator where)
00374     {
00375         // Verify iterator is valid
00376         if (where == end())
00377         {
00378             return XN_STATUS_ILLEGAL_POSITION;
00379         }
00380         if (IsEmpty())
00381         {
00382             return XN_STATUS_IS_EMPTY;
00383         }
00384 
00385         XnNode* pToRemove = where.m_pCurrent;
00386 
00387         // Connect other nodes to bypass the one removed
00388         pToRemove->Previous()->Next() = pToRemove->Next();
00389         pToRemove->Next()->Previous() = pToRemove->Previous();
00390 
00391         // Return removed node to the pool
00392         m_pNodeAllocator->Deallocate(pToRemove);
00393 
00394         return XN_STATUS_OK;
00395     }
00396 
00397 
00401     XnStatus Clear()
00402     {
00403         while (!IsEmpty())
00404             Remove(begin());
00405 
00406         return XN_STATUS_OK;
00407     }
00408 
00412     XnBool IsEmpty() const
00413     {
00414         return (begin() == end());
00415     }
00416 
00420     XnUInt32 Size() const
00421     {
00422         XnUInt32 nSize = 0;
00423         for (ConstIterator iter = begin(); iter != end(); ++iter, ++nSize)
00424             ;
00425 
00426         return nSize;
00427     }
00428 
00432     Iterator begin()
00433     {
00434         return Iterator(m_pBase->Next());
00435     }
00436 
00440     ConstIterator begin() const
00441     {
00442         return ConstIterator(m_pBase->Next());
00443     }
00444 
00448     Iterator end()
00449     {
00450         return Iterator(m_pBase);
00451     }
00452 
00456     ConstIterator end() const
00457     {
00458         return ConstIterator(m_pBase);
00459     }
00460 
00464     Iterator rbegin()
00465     {
00466         return Iterator(m_pBase->Previous());
00467     }
00468 
00472     ConstIterator rbegin() const
00473     {
00474         return ConstIterator(m_pBase->Previous());
00475     }
00476 
00480     Iterator rend()
00481     {
00482         return Iterator(m_pBase);
00483     }
00484 
00488     ConstIterator rend() const
00489     {
00490         return ConstIterator(m_pBase);
00491     }
00492     
00493 protected:
00494     friend class XnNodeManager;
00495     
00499     XnList(INiNodeAllocator* pNodeAllocator)
00500     {
00501         Init(pNodeAllocator);
00502         m_bOwnsAllocator = FALSE;
00503     }
00504     
00505     void Init(INiNodeAllocator* pNodeAllocator)
00506     {
00507         m_pNodeAllocator = pNodeAllocator;
00508         // Allocate a node to act as base node.
00509         m_pBase = m_pNodeAllocator->Allocate();
00510         if (m_pBase == NULL)
00511         {
00512             // OZOZ: Allocation failed in ctor...
00513         }
00514 
00515         m_pBase->Next() = m_pBase->Previous() = m_pBase;
00516     }
00517 
00526     XnStatus Add(XnNode* pWhere, const XnValue& val)
00527     {
00528         // Get a node from the pool for the entry
00529         XnNode* pNewNode = m_pNodeAllocator->Allocate();
00530         if (pNewNode == NULL)
00531         {
00532             return XN_STATUS_ALLOC_FAILED;
00533         }
00534         // push new node to position
00535         pNewNode->Data() = val;
00536         pNewNode->Next() = pWhere->Next();
00537         pNewNode->Previous() = pWhere;
00538         pWhere->Next()->Previous() = pNewNode;
00539         pWhere->Next() = pNewNode;
00540 
00541         return XN_STATUS_OK;
00542     }
00543 
00544 
00546     XnNode* m_pBase;
00547     
00548     INiNodeAllocator* m_pNodeAllocator;
00549     XnBool m_bOwnsAllocator;
00550 
00551 private:
00552     XN_DISABLE_COPY_AND_ASSIGN(XnList);
00553 };
00554 
00559 #define XN_DECLARE_LIST_WITH_TRANSLATOR_DECL(decl, Type, ClassName, Translator)                 \
00560     class decl ClassName : public XnList                                                        \
00561     {                                                                                           \
00562     public:                                                                                     \
00563         class decl ConstIterator : public XnList::ConstIterator                                 \
00564         {                                                                                       \
00565         public:                                                                                 \
00566             friend class ClassName;                                                             \
00567             inline ConstIterator(const ConstIterator& other) : XnList::ConstIterator(other) {}  \
00568             inline ConstIterator& operator++()                                                  \
00569             {                                                                                   \
00570                 ++(*(XnList::ConstIterator*)this);                                              \
00571                 return (*this);                                                                 \
00572             }                                                                                   \
00573             inline ConstIterator operator++(int)                                                \
00574             {                                                                                   \
00575                 ConstIterator result = *this;                                                   \
00576                 ++*this;                                                                        \
00577                 return result;                                                                  \
00578             }                                                                                   \
00579             inline ConstIterator& operator--()                                                  \
00580             {                                                                                   \
00581                 --(*(XnList::ConstIterator*)this);                                              \
00582                 return (*this);                                                                 \
00583             }                                                                                   \
00584             inline ConstIterator operator--(int)                                                \
00585             {                                                                                   \
00586                 ConstIterator result = *this;                                                   \
00587                 --*this;                                                                        \
00588                 return result;                                                                  \
00589             }                                                                                   \
00590             inline Type const& operator*() const                                                \
00591             {                                                                                   \
00592                 return Translator::GetFromValue(**((XnList::ConstIterator*)this));              \
00593             }                                                                                   \
00594             inline Type const* operator->() const { return (&**this); }                         \
00595         protected:                                                                              \
00596             inline ConstIterator(XnNode* pNode) : XnList::ConstIterator(pNode) {}               \
00597             inline ConstIterator(const XnList::ConstIterator& other) :                          \
00598                 XnList::ConstIterator(other)                                                    \
00599             {}                                                                                  \
00600         };                                                                                      \
00601         class decl Iterator : public ConstIterator                                              \
00602         {                                                                                       \
00603         public:                                                                                 \
00604             friend class ClassName;                                                             \
00605             Iterator(const Iterator& other) : ConstIterator(other) {}                           \
00606             inline Iterator& operator++()                                                       \
00607             {                                                                                   \
00608                 ++(*(ConstIterator*)this);                                                      \
00609                 return (*this);                                                                 \
00610             }                                                                                   \
00611             inline Iterator operator++(int)                                                     \
00612             {                                                                                   \
00613                 Iterator result = *this;                                                        \
00614                 ++*this;                                                                        \
00615                 return result;                                                                  \
00616             }                                                                                   \
00617             inline Iterator& operator--()                                                       \
00618             {                                                                                   \
00619                 --(*(ConstIterator*)this);                                                      \
00620                 return (*this);                                                                 \
00621             }                                                                                   \
00622             inline Iterator operator--(int)                                                     \
00623             {                                                                                   \
00624                 Iterator result = *this;                                                        \
00625                 --*this;                                                                        \
00626                 return result;                                                                  \
00627             }                                                                                   \
00628             inline Type& operator*() const { return ((Type&)**(ConstIterator*)this); }          \
00629             inline Type* operator->() const { return (&**this); }                               \
00630         protected:                                                                              \
00631             inline Iterator(XnNode* pNode) : ConstIterator(pNode) {}                            \
00632             inline Iterator(const XnList::Iterator& other) : ConstIterator(other) {}            \
00633         };                                                                                      \
00634     public:                                                                                     \
00635         ClassName()                                                                             \
00636         {                                                                                       \
00637         }                                                                                       \
00638         ~ClassName()                                                                            \
00639         {                                                                                       \
00640             while (!IsEmpty())                                                                  \
00641                 Remove(begin());                                                                \
00642         }                                                                                       \
00643         inline XnStatus AddFirst(Type const& value)                                             \
00644         {                                                                                       \
00645             XnValue val = Translator::CreateValueCopy(value);                                   \
00646             XnStatus nRetVal = XnList::AddFirst(val);                                           \
00647             if (nRetVal != XN_STATUS_OK)                                                        \
00648             {                                                                                   \
00649                 Translator::FreeValue(val);                                                     \
00650                 return (nRetVal);                                                               \
00651             }                                                                                   \
00652             return XN_STATUS_OK;                                                                \
00653         }                                                                                       \
00654         inline XnStatus AddLast(Type const& value)                                              \
00655         {                                                                                       \
00656             XnValue val = Translator::CreateValueCopy(value);                                   \
00657             XnStatus nRetVal = XnList::AddLast(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 AddAfter(ConstIterator where, Type const& value)                        \
00666         {                                                                                       \
00667             XnValue val = Translator::CreateValueCopy(value);                                   \
00668             XnStatus nRetVal = XnList::AddAfter(where, 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 AddBefore(ConstIterator where, Type const& value)                       \
00677         {                                                                                       \
00678             XnValue val = Translator::CreateValueCopy(value);                                   \
00679             XnStatus nRetVal = XnList::AddBefore(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 ConstIterator Find(Type const& value) const                                      \
00688         {                                                                                       \
00689             XnValue _value = Translator::GetAsValue(value);                                     \
00690             return XnList::Find(_value);                                                        \
00691         }                                                                                       \
00692         inline Iterator Find(Type const& value)                                                 \
00693         {                                                                                       \
00694             XnValue _value = Translator::GetAsValue(value);                                     \
00695             return XnList::Find(_value);                                                        \
00696         }                                                                                       \
00697         inline XnStatus Remove(ConstIterator where)                                             \
00698         {                                                                                       \
00699             XnValue val = Translator::GetAsValue(*where);                                       \
00700             XnStatus nRetVal = XnList::Remove(where);                                           \
00701             if (nRetVal != XN_STATUS_OK) return (nRetVal);                                      \
00702             Translator::FreeValue(val);                                                         \
00703             return XN_STATUS_OK;                                                                \
00704         }                                                                                       \
00705         inline XnStatus Remove(Type const& value)                                               \
00706         {                                                                                       \
00707             Iterator it = Find(value);                                                          \
00708             return Remove(it);                                                                  \
00709         }                                                                                       \
00710         inline Iterator begin() { return XnList::begin(); }                                     \
00711         inline ConstIterator begin() const { return XnList::begin(); }                          \
00712         inline Iterator end() { return XnList::end(); }                                         \
00713         inline ConstIterator end() const { return XnList::end(); }                              \
00714         inline Iterator rbegin() { return XnList::rbegin(); }                                   \
00715         inline ConstIterator rbegin() const { return XnList::rbegin(); }                        \
00716         inline Iterator rend() { return XnList::rend(); }                                       \
00717         inline ConstIterator rend() const { return XnList::rend(); }                            \
00718     protected:                                                                                  \
00719         virtual XnStatus Remove(XnList::ConstIterator where)                                    \
00720         {                                                                                       \
00721             return Remove(ConstIterator(where));                                                \
00722         }                                                                                       \
00723     private:                                                                                    \
00724         XN_DISABLE_COPY_AND_ASSIGN(ClassName);                                                  \
00725     };
00726 
00730 #define XN_DECLARE_LIST_WITH_TRANSLATOR(Type, ClassName, Translator)                            \
00731     XN_DECLARE_LIST_WITH_TRANSLATOR_DECL(, Type, ClassName, Translator)
00732 
00737 #define XN_DECLARE_LIST_DECL(decl, Type, ClassName)                                                     \
00738     XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, Type, XN_DEFAULT_TRANSLATOR_NAME(ClassName))         \
00739     XN_DECLARE_LIST_WITH_TRANSLATOR_DECL(decl, Type, ClassName, XN_DEFAULT_TRANSLATOR_NAME(ClassName))
00740 
00744 #define XN_DECLARE_LIST(Type, ClassName)        \
00745     XN_DECLARE_LIST_DECL(, Type, ClassName)
00746                                                                                             
00747 #endif // _XN_LIST_H                                                                        
00748