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
00023
00024
00025
00026 #ifndef _XN_LIST_H
00027 #define _XN_LIST_H
00028
00029
00030
00031
00032 #include <XnDataTypes.h>
00033 #include <IXnNodeAllocator.h>
00034 #include <XnNodeAllocator.h>
00035 #include <XnNode.h>
00036
00037
00038
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
00225 Init(new XnNodeAllocator);
00226 m_bOwnsAllocator = TRUE;
00227 }
00228
00232 virtual ~XnList()
00233 {
00234 Clear();
00235
00236
00237 m_pNodeAllocator->Deallocate(m_pBase);
00238
00239 if (m_bOwnsAllocator)
00240 {
00241
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
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
00392 pToRemove->Previous()->Next() = pToRemove->Next();
00393 pToRemove->Next()->Previous() = pToRemove->Previous();
00394
00395
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
00513 m_pBase = m_pNodeAllocator->Allocate();
00514 if (m_pBase == NULL)
00515 {
00516
00517 }
00518
00519 m_pBase->Next() = m_pBase->Previous() = m_pBase;
00520 }
00521
00530 XnStatus Add(XnNode* pWhere, const XnValue& val)
00531 {
00532
00533 XnNode* pNewNode = m_pNodeAllocator->Allocate();
00534 if (pNewNode == NULL)
00535 {
00536 return XN_STATUS_ALLOC_FAILED;
00537 }
00538
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 while (!IsEmpty()) \
00639 Remove(begin()); \
00640 } \
00641 inline XnStatus AddFirst(Type const& value) \
00642 { \
00643 XnValue val = Translator::CreateValueCopy(value); \
00644 XnStatus nRetVal = XnList::AddFirst(val); \
00645 if (nRetVal != XN_STATUS_OK) \
00646 { \
00647 Translator::FreeValue(val); \
00648 return (nRetVal); \
00649 } \
00650 return XN_STATUS_OK; \
00651 } \
00652 inline XnStatus AddLast(Type const& value) \
00653 { \
00654 XnValue val = Translator::CreateValueCopy(value); \
00655 XnStatus nRetVal = XnList::AddLast(val); \
00656 if (nRetVal != XN_STATUS_OK) \
00657 { \
00658 Translator::FreeValue(val); \
00659 return (nRetVal); \
00660 } \
00661 return XN_STATUS_OK; \
00662 } \
00663 inline XnStatus AddAfter(ConstIterator where, Type const& value) \
00664 { \
00665 XnValue val = Translator::CreateValueCopy(value); \
00666 XnStatus nRetVal = XnList::AddAfter(where, val); \
00667 if (nRetVal != XN_STATUS_OK) \
00668 { \
00669 Translator::FreeValue(val); \
00670 return (nRetVal); \
00671 } \
00672 return XN_STATUS_OK; \
00673 } \
00674 inline XnStatus AddBefore(ConstIterator where, Type const& value) \
00675 { \
00676 XnValue val = Translator::CreateValueCopy(value); \
00677 XnStatus nRetVal = XnList::AddBefore(where, val); \
00678 if (nRetVal != XN_STATUS_OK) \
00679 { \
00680 Translator::FreeValue(val); \
00681 return (nRetVal); \
00682 } \
00683 return XN_STATUS_OK; \
00684 } \
00685 inline ConstIterator Find(Type const& value) const \
00686 { \
00687 XnValue _value = Translator::GetAsValue(value); \
00688 return XnList::Find(_value); \
00689 } \
00690 inline Iterator Find(Type const& value) \
00691 { \
00692 XnValue _value = Translator::GetAsValue(value); \
00693 return XnList::Find(_value); \
00694 } \
00695 inline XnStatus Remove(ConstIterator where) \
00696 { \
00697 XnValue val = Translator::GetAsValue(*where); \
00698 XnStatus nRetVal = XnList::Remove(where); \
00699 if (nRetVal != XN_STATUS_OK) return (nRetVal); \
00700 Translator::FreeValue(val); \
00701 return XN_STATUS_OK; \
00702 } \
00703 inline Iterator begin() { return XnList::begin(); } \
00704 inline ConstIterator begin() const { return XnList::begin(); } \
00705 inline Iterator end() { return XnList::end(); } \
00706 inline ConstIterator end() const { return XnList::end(); } \
00707 inline Iterator rbegin() { return XnList::rbegin(); } \
00708 inline ConstIterator rbegin() const { return XnList::rbegin(); } \
00709 inline Iterator rend() { return XnList::rend(); } \
00710 inline ConstIterator rend() const { return XnList::rend(); } \
00711 protected: \
00712 virtual XnStatus Remove(XnList::ConstIterator where) \
00713 { \
00714 return Remove(ConstIterator(where)); \
00715 } \
00716 };
00717
00721 #define XN_DECLARE_LIST_WITH_TRANSLATOR(Type, ClassName, Translator) \
00722 XN_DECLARE_LIST_WITH_TRANSLATOR_DECL(, Type, ClassName, Translator)
00723
00728 #define XN_DECLARE_LIST_DECL(decl, Type, ClassName) \
00729 XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, Type, XN_DEFAULT_TRANSLATOR_NAME(ClassName)) \
00730 XN_DECLARE_LIST_WITH_TRANSLATOR_DECL(decl, Type, ClassName, XN_DEFAULT_TRANSLATOR_NAME(ClassName))
00731
00735 #define XN_DECLARE_LIST(Type, ClassName) \
00736 XN_DECLARE_LIST_DECL(, Type, ClassName)
00737
00738 #endif // _XN_LIST_H
00739