OpenNI 1.3.2
|
00001 /**************************************************************************** 00002 * * 00003 * OpenNI 1.1 Alpha * 00004 * Copyright (C) 2011 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 #ifndef _XN_LIST_H 00023 #define _XN_LIST_H 00024 00025 //--------------------------------------------------------------------------- 00026 // Includes 00027 //--------------------------------------------------------------------------- 00028 #include <XnDataTypes.h> 00029 #include <IXnNodeAllocator.h> 00030 #include <XnNodeAllocator.h> 00031 #include <XnNode.h> 00032 #include <XnStatusCodes.h> 00033 00034 //--------------------------------------------------------------------------- 00035 // Types 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 //Default node allocator is XnNodeAllocator 00222 Init(XN_NEW(XnNodeAllocator)); 00223 m_bOwnsAllocator = TRUE; 00224 } 00225 00229 virtual ~XnList() 00230 { 00231 Clear(); 00232 00233 // Return base node to the pool 00234 m_pNodeAllocator->Deallocate(m_pBase); 00235 00236 if (m_bOwnsAllocator) 00237 { 00238 //We created the allocator in this object, so we must release it 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 // Verify iterator is valid 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 // Connect other nodes to bypass the one removed 00389 pToRemove->Previous()->Next() = pToRemove->Next(); 00390 pToRemove->Next()->Previous() = pToRemove->Previous(); 00391 00392 // Return removed node to the pool 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 // Allocate a node to act as base node. 00510 m_pBase = m_pNodeAllocator->Allocate(); 00511 if (m_pBase == NULL) 00512 { 00513 // OZOZ: Allocation failed in ctor... 00514 } 00515 00516 m_pBase->Next() = m_pBase->Previous() = m_pBase; 00517 } 00518 00527 XnStatus Add(XnNode* pWhere, const XnValue& val) 00528 { 00529 // Get a node from the pool for the entry 00530 XnNode* pNewNode = m_pNodeAllocator->Allocate(); 00531 if (pNewNode == NULL) 00532 { 00533 return XN_STATUS_ALLOC_FAILED; 00534 } 00535 // push new node to position 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