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 private:
00553 XN_DISABLE_COPY_AND_ASSIGN(XnList);
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() \
00640 { \
00641 while (!IsEmpty()) \
00642 Remove(begin()); \
00643 } \
00644 inline XnStatus AddFirst(Type const& value) \
00645 { \
00646 XnValue val = Translator::CreateValueCopy(value); \
00647 XnStatus nRetVal = XnList::AddFirst(val); \
00648 if (nRetVal != XN_STATUS_OK) \
00649 { \
00650 Translator::FreeValue(val); \
00651 return (nRetVal); \
00652 } \
00653 return XN_STATUS_OK; \
00654 } \
00655 inline XnStatus AddLast(Type const& value) \
00656 { \
00657 XnValue val = Translator::CreateValueCopy(value); \
00658 XnStatus nRetVal = XnList::AddLast(val); \
00659 if (nRetVal != XN_STATUS_OK) \
00660 { \
00661 Translator::FreeValue(val); \
00662 return (nRetVal); \
00663 } \
00664 return XN_STATUS_OK; \
00665 } \
00666 inline XnStatus AddAfter(ConstIterator where, Type const& value) \
00667 { \
00668 XnValue val = Translator::CreateValueCopy(value); \
00669 XnStatus nRetVal = XnList::AddAfter(where, val); \
00670 if (nRetVal != XN_STATUS_OK) \
00671 { \
00672 Translator::FreeValue(val); \
00673 return (nRetVal); \
00674 } \
00675 return XN_STATUS_OK; \
00676 } \
00677 inline XnStatus AddBefore(ConstIterator where, Type const& value) \
00678 { \
00679 XnValue val = Translator::CreateValueCopy(value); \
00680 XnStatus nRetVal = XnList::AddBefore(where, val); \
00681 if (nRetVal != XN_STATUS_OK) \
00682 { \
00683 Translator::FreeValue(val); \
00684 return (nRetVal); \
00685 } \
00686 return XN_STATUS_OK; \
00687 } \
00688 inline ConstIterator Find(Type const& value) const \
00689 { \
00690 XnValue _value = Translator::GetAsValue(value); \
00691 return XnList::Find(_value); \
00692 } \
00693 inline Iterator Find(Type const& value) \
00694 { \
00695 XnValue _value = Translator::GetAsValue(value); \
00696 return XnList::Find(_value); \
00697 } \
00698 inline XnStatus Remove(ConstIterator where) \
00699 { \
00700 XnValue val = Translator::GetAsValue(*where); \
00701 XnStatus nRetVal = XnList::Remove(where); \
00702 if (nRetVal != XN_STATUS_OK) return (nRetVal); \
00703 Translator::FreeValue(val); \
00704 return XN_STATUS_OK; \
00705 } \
00706 inline XnStatus Remove(Type const& value) \
00707 { \
00708 Iterator it = Find(value); \
00709 return Remove(it); \
00710 } \
00711 inline Iterator begin() { return XnList::begin(); } \
00712 inline ConstIterator begin() const { return XnList::begin(); } \
00713 inline Iterator end() { return XnList::end(); } \
00714 inline ConstIterator end() const { return XnList::end(); } \
00715 inline Iterator rbegin() { return XnList::rbegin(); } \
00716 inline ConstIterator rbegin() const { return XnList::rbegin(); } \
00717 inline Iterator rend() { return XnList::rend(); } \
00718 inline ConstIterator rend() const { return XnList::rend(); } \
00719 protected: \
00720 virtual XnStatus Remove(XnList::ConstIterator where) \
00721 { \
00722 return Remove(ConstIterator(where)); \
00723 } \
00724 private: \
00725 XN_DISABLE_COPY_AND_ASSIGN(ClassName); \
00726 };
00727
00731 #define XN_DECLARE_LIST_WITH_TRANSLATOR(Type, ClassName, Translator) \
00732 XN_DECLARE_LIST_WITH_TRANSLATOR_DECL(, Type, ClassName, Translator)
00733
00738 #define XN_DECLARE_LIST_DECL(decl, Type, ClassName) \
00739 XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, Type, XN_DEFAULT_TRANSLATOR_NAME(ClassName)) \
00740 XN_DECLARE_LIST_WITH_TRANSLATOR_DECL(decl, Type, ClassName, XN_DEFAULT_TRANSLATOR_NAME(ClassName))
00741
00745 #define XN_DECLARE_LIST(Type, ClassName) \
00746 XN_DECLARE_LIST_DECL(, Type, ClassName)
00747
00748 #endif // _XN_LIST_H
00749