Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef _XN_LIST_H
00023 #define _XN_LIST_H
00024
00025
00026
00027
00028 #include <XnDataTypes.h>
00029 #include <IXnNodeAllocator.h>
00030 #include <XnNodeAllocator.h>
00031 #include <XnNode.h>
00032 #include <XnStatusCodes.h>
00033
00034
00035
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
00222 Init(XN_NEW(XnNodeAllocator));
00223 m_bOwnsAllocator = TRUE;
00224 }
00225
00229 virtual ~XnList()
00230 {
00231 Clear();
00232
00233
00234 m_pNodeAllocator->Deallocate(m_pBase);
00235
00236 if (m_bOwnsAllocator)
00237 {
00238
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
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
00389 pToRemove->Previous()->Next() = pToRemove->Next();
00390 pToRemove->Next()->Previous() = pToRemove->Previous();
00391
00392
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
00510 m_pBase = m_pNodeAllocator->Allocate();
00511 if (m_pBase == NULL)
00512 {
00513
00514 }
00515
00516 m_pBase->Next() = m_pBase->Previous() = m_pBase;
00517 }
00518
00527 XnStatus Add(XnNode* pWhere, const XnValue& val)
00528 {
00529
00530 XnNode* pNewNode = m_pNodeAllocator->Allocate();
00531 if (pNewNode == NULL)
00532 {
00533 return XN_STATUS_ALLOC_FAILED;
00534 }
00535
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