OpenNI 1.0.0
|
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