![]() |
OpenNI 1.5.7
|
00001 /***************************************************************************** 00002 * * 00003 * OpenNI 1.x Alpha * 00004 * Copyright (C) 2012 PrimeSense Ltd. * 00005 * * 00006 * This file is part of OpenNI. * 00007 * * 00008 * Licensed under the Apache License, Version 2.0 (the "License"); * 00009 * you may not use this file except in compliance with the License. * 00010 * You may obtain a copy of the License at * 00011 * * 00012 * http://www.apache.org/licenses/LICENSE-2.0 * 00013 * * 00014 * Unless required by applicable law or agreed to in writing, software * 00015 * distributed under the License is distributed on an "AS IS" BASIS, * 00016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 00017 * See the License for the specific language governing permissions and * 00018 * limitations under the License. * 00019 * * 00020 *****************************************************************************/ 00021 #ifndef _XN_LIST_H 00022 #define _XN_LIST_H 00023 00024 //--------------------------------------------------------------------------- 00025 // Includes 00026 //--------------------------------------------------------------------------- 00027 #include <XnDataTypes.h> 00028 #include <IXnNodeAllocator.h> 00029 #include <XnNodeAllocator.h> 00030 #include <XnNode.h> 00031 #include <XnStatusCodes.h> 00032 00033 //--------------------------------------------------------------------------- 00034 // Types 00035 //--------------------------------------------------------------------------- 00036 00040 class XnList 00041 { 00042 public: 00043 class ConstIterator 00044 { 00045 public: 00046 friend class XnList; 00047 00053 ConstIterator(const ConstIterator& other) : m_pCurrent(other.m_pCurrent) {} 00054 00058 ConstIterator& operator++() 00059 { 00060 m_pCurrent = m_pCurrent->Next(); 00061 return *this; 00062 } 00063 00067 ConstIterator operator++(int) 00068 { 00069 ConstIterator other(m_pCurrent); 00070 m_pCurrent = m_pCurrent->Next(); 00071 return other; 00072 } 00073 00077 ConstIterator& operator--() 00078 { 00079 m_pCurrent = m_pCurrent->Previous(); 00080 return *this; 00081 } 00082 00086 ConstIterator operator--(int) 00087 { 00088 ConstIterator other = *this; 00089 --*this; 00090 return other; 00091 } 00092 00098 XnBool operator==(const ConstIterator& other) const 00099 { 00100 return m_pCurrent == other.m_pCurrent; 00101 } 00107 XnBool operator!=(const ConstIterator& other) const 00108 { 00109 return m_pCurrent != other.m_pCurrent; 00110 } 00111 00115 const XnValue& operator*() const 00116 { 00117 return m_pCurrent->Data(); 00118 } 00119 00120 00124 const XnNode* GetNode() const 00125 { 00126 return m_pCurrent; 00127 } 00128 00132 XnNode* GetNode() 00133 { 00134 return m_pCurrent; 00135 } 00136 00137 protected: 00143 ConstIterator(XnNode* pNode) : m_pCurrent(pNode) {} 00144 00146 XnNode* m_pCurrent; 00147 }; 00148 00152 class Iterator : public ConstIterator 00153 { 00154 public: 00155 friend class XnList; 00156 00162 inline Iterator(const Iterator& other) : ConstIterator(other) {} 00163 00167 inline Iterator& operator++() 00168 { 00169 ++(*(ConstIterator*)this); 00170 return (*this); 00171 } 00175 inline Iterator operator++(int) 00176 { 00177 Iterator result = *this; 00178 ++*this; 00179 return (result); 00180 } 00181 00185 inline Iterator& operator--() 00186 { 00187 --(*(ConstIterator*)this); 00188 return (*this); 00189 } 00193 inline Iterator operator--(int) 00194 { 00195 Iterator result = *this; 00196 --*this; 00197 return (result); 00198 } 00199 00203 inline XnValue& operator*() const { return ((XnValue&)**(ConstIterator*)this); } 00204 00205 protected: 00211 inline Iterator(XnNode* pNode) : ConstIterator(pNode) {} 00212 }; 00213 00214 public: 00218 XnList() 00219 { 00220 //Default node allocator is XnNodeAllocator 00221 Init(XN_NEW(XnNodeAllocator)); 00222 m_bOwnsAllocator = TRUE; 00223 } 00224 00228 virtual ~XnList() 00229 { 00230 Clear(); 00231 00232 // Return base node to the pool 00233 m_pNodeAllocator->Deallocate(m_pBase); 00234 00235 if (m_bOwnsAllocator) 00236 { 00237 //We created the allocator in this object, so we must release it 00238 XN_DELETE(m_pNodeAllocator); 00239 } 00240 } 00241 00249 XnStatus AddFirst(const XnValue& value) 00250 { 00251 return Add(m_pBase, value); 00252 } 00253 00261 XnStatus AddLast(const XnValue& value) 00262 { 00263 return Add(rbegin().m_pCurrent, value); 00264 } 00265 00275 XnStatus AddAfter(ConstIterator where, const XnValue& val) 00276 { 00277 if (where == end()) 00278 { 00279 return XN_STATUS_ILLEGAL_POSITION; 00280 } 00281 00282 return Add(where.m_pCurrent, val); 00283 } 00284 00293 XnStatus AddBefore(ConstIterator where, const XnValue& val) 00294 { 00295 if (where == end()) 00296 { 00297 return XN_STATUS_ILLEGAL_POSITION; 00298 } 00299 00300 return Add(where.m_pCurrent->Previous(), val); 00301 } 00302 00303 00311 Iterator Find(const XnValue& value) 00312 { 00313 if (IsEmpty()) 00314 { 00315 return end(); 00316 } 00317 00318 Iterator iter = begin(); 00319 for (; iter != end(); ++iter) 00320 { 00321 if (*iter == value) 00322 break; 00323 } 00324 return iter; 00325 } 00326 00327 00335 ConstIterator Find(const XnValue& value) const 00336 { 00337 if (IsEmpty()) 00338 { 00339 return end(); 00340 } 00341 00342 ConstIterator iter = begin(); 00343 for (; iter != end(); ++iter) 00344 { 00345 if (*iter == value) 00346 break; 00347 } 00348 return iter; 00349 } 00350 00351 00360 XnStatus Remove(ConstIterator where, XnValue& value) 00361 { 00362 value = *where; 00363 return Remove(where); 00364 } 00365 00373 virtual XnStatus Remove(ConstIterator where) 00374 { 00375 // Verify iterator is valid 00376 if (where == end()) 00377 { 00378 return XN_STATUS_ILLEGAL_POSITION; 00379 } 00380 if (IsEmpty()) 00381 { 00382 return XN_STATUS_IS_EMPTY; 00383 } 00384 00385 XnNode* pToRemove = where.m_pCurrent; 00386 00387 // Connect other nodes to bypass the one removed 00388 pToRemove->Previous()->Next() = pToRemove->Next(); 00389 pToRemove->Next()->Previous() = pToRemove->Previous(); 00390 00391 // Return removed node to the pool 00392 m_pNodeAllocator->Deallocate(pToRemove); 00393 00394 return XN_STATUS_OK; 00395 } 00396 00397 00401 XnStatus Clear() 00402 { 00403 while (!IsEmpty()) 00404 Remove(begin()); 00405 00406 return XN_STATUS_OK; 00407 } 00408 00412 XnBool IsEmpty() const 00413 { 00414 return (begin() == end()); 00415 } 00416 00420 XnUInt32 Size() const 00421 { 00422 XnUInt32 nSize = 0; 00423 for (ConstIterator iter = begin(); iter != end(); ++iter, ++nSize) 00424 ; 00425 00426 return nSize; 00427 } 00428 00432 Iterator begin() 00433 { 00434 return Iterator(m_pBase->Next()); 00435 } 00436 00440 ConstIterator begin() const 00441 { 00442 return ConstIterator(m_pBase->Next()); 00443 } 00444 00448 Iterator end() 00449 { 00450 return Iterator(m_pBase); 00451 } 00452 00456 ConstIterator end() const 00457 { 00458 return ConstIterator(m_pBase); 00459 } 00460 00464 Iterator rbegin() 00465 { 00466 return Iterator(m_pBase->Previous()); 00467 } 00468 00472 ConstIterator rbegin() const 00473 { 00474 return ConstIterator(m_pBase->Previous()); 00475 } 00476 00480 Iterator rend() 00481 { 00482 return Iterator(m_pBase); 00483 } 00484 00488 ConstIterator rend() const 00489 { 00490 return ConstIterator(m_pBase); 00491 } 00492 00493 protected: 00494 friend class XnNodeManager; 00495 00499 XnList(INiNodeAllocator* pNodeAllocator) 00500 { 00501 Init(pNodeAllocator); 00502 m_bOwnsAllocator = FALSE; 00503 } 00504 00505 void Init(INiNodeAllocator* pNodeAllocator) 00506 { 00507 m_pNodeAllocator = pNodeAllocator; 00508 // Allocate a node to act as base node. 00509 m_pBase = m_pNodeAllocator->Allocate(); 00510 if (m_pBase == NULL) 00511 { 00512 // OZOZ: Allocation failed in ctor... 00513 } 00514 00515 m_pBase->Next() = m_pBase->Previous() = m_pBase; 00516 } 00517 00526 XnStatus Add(XnNode* pWhere, const XnValue& val) 00527 { 00528 // Get a node from the pool for the entry 00529 XnNode* pNewNode = m_pNodeAllocator->Allocate(); 00530 if (pNewNode == NULL) 00531 { 00532 return XN_STATUS_ALLOC_FAILED; 00533 } 00534 // push new node to position 00535 pNewNode->Data() = val; 00536 pNewNode->Next() = pWhere->Next(); 00537 pNewNode->Previous() = pWhere; 00538 pWhere->Next()->Previous() = pNewNode; 00539 pWhere->Next() = pNewNode; 00540 00541 return XN_STATUS_OK; 00542 } 00543 00544 00546 XnNode* m_pBase; 00547 00548 INiNodeAllocator* m_pNodeAllocator; 00549 XnBool m_bOwnsAllocator; 00550 00551 private: 00552 XN_DISABLE_COPY_AND_ASSIGN(XnList); 00553 }; 00554 00559 #define XN_DECLARE_LIST_WITH_TRANSLATOR_DECL(decl, Type, ClassName, Translator) \ 00560 class decl ClassName : public XnList \ 00561 { \ 00562 public: \ 00563 class decl ConstIterator : public XnList::ConstIterator \ 00564 { \ 00565 public: \ 00566 friend class ClassName; \ 00567 inline ConstIterator(const ConstIterator& other) : XnList::ConstIterator(other) {} \ 00568 inline ConstIterator& operator++() \ 00569 { \ 00570 ++(*(XnList::ConstIterator*)this); \ 00571 return (*this); \ 00572 } \ 00573 inline ConstIterator operator++(int) \ 00574 { \ 00575 ConstIterator result = *this; \ 00576 ++*this; \ 00577 return result; \ 00578 } \ 00579 inline ConstIterator& operator--() \ 00580 { \ 00581 --(*(XnList::ConstIterator*)this); \ 00582 return (*this); \ 00583 } \ 00584 inline ConstIterator operator--(int) \ 00585 { \ 00586 ConstIterator result = *this; \ 00587 --*this; \ 00588 return result; \ 00589 } \ 00590 inline Type const& operator*() const \ 00591 { \ 00592 return Translator::GetFromValue(**((XnList::ConstIterator*)this)); \ 00593 } \ 00594 inline Type const* operator->() const { return (&**this); } \ 00595 protected: \ 00596 inline ConstIterator(XnNode* pNode) : XnList::ConstIterator(pNode) {} \ 00597 inline ConstIterator(const XnList::ConstIterator& other) : \ 00598 XnList::ConstIterator(other) \ 00599 {} \ 00600 }; \ 00601 class decl Iterator : public ConstIterator \ 00602 { \ 00603 public: \ 00604 friend class ClassName; \ 00605 Iterator(const Iterator& other) : ConstIterator(other) {} \ 00606 inline Iterator& operator++() \ 00607 { \ 00608 ++(*(ConstIterator*)this); \ 00609 return (*this); \ 00610 } \ 00611 inline Iterator operator++(int) \ 00612 { \ 00613 Iterator result = *this; \ 00614 ++*this; \ 00615 return result; \ 00616 } \ 00617 inline Iterator& operator--() \ 00618 { \ 00619 --(*(ConstIterator*)this); \ 00620 return (*this); \ 00621 } \ 00622 inline Iterator operator--(int) \ 00623 { \ 00624 Iterator result = *this; \ 00625 --*this; \ 00626 return result; \ 00627 } \ 00628 inline Type& operator*() const { return ((Type&)**(ConstIterator*)this); } \ 00629 inline Type* operator->() const { return (&**this); } \ 00630 protected: \ 00631 inline Iterator(XnNode* pNode) : ConstIterator(pNode) {} \ 00632 inline Iterator(const XnList::Iterator& other) : ConstIterator(other) {} \ 00633 }; \ 00634 public: \ 00635 ClassName() \ 00636 { \ 00637 } \ 00638 ~ClassName() \ 00639 { \ 00640 while (!IsEmpty()) \ 00641 Remove(begin()); \ 00642 } \ 00643 inline XnStatus AddFirst(Type const& value) \ 00644 { \ 00645 XnValue val = Translator::CreateValueCopy(value); \ 00646 XnStatus nRetVal = XnList::AddFirst(val); \ 00647 if (nRetVal != XN_STATUS_OK) \ 00648 { \ 00649 Translator::FreeValue(val); \ 00650 return (nRetVal); \ 00651 } \ 00652 return XN_STATUS_OK; \ 00653 } \ 00654 inline XnStatus AddLast(Type const& value) \ 00655 { \ 00656 XnValue val = Translator::CreateValueCopy(value); \ 00657 XnStatus nRetVal = XnList::AddLast(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 AddAfter(ConstIterator where, Type const& value) \ 00666 { \ 00667 XnValue val = Translator::CreateValueCopy(value); \ 00668 XnStatus nRetVal = XnList::AddAfter(where, 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 AddBefore(ConstIterator where, Type const& value) \ 00677 { \ 00678 XnValue val = Translator::CreateValueCopy(value); \ 00679 XnStatus nRetVal = XnList::AddBefore(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 ConstIterator Find(Type const& value) const \ 00688 { \ 00689 XnValue _value = Translator::GetAsValue(value); \ 00690 return XnList::Find(_value); \ 00691 } \ 00692 inline Iterator Find(Type const& value) \ 00693 { \ 00694 XnValue _value = Translator::GetAsValue(value); \ 00695 return XnList::Find(_value); \ 00696 } \ 00697 inline XnStatus Remove(ConstIterator where) \ 00698 { \ 00699 XnValue val = Translator::GetAsValue(*where); \ 00700 XnStatus nRetVal = XnList::Remove(where); \ 00701 if (nRetVal != XN_STATUS_OK) return (nRetVal); \ 00702 Translator::FreeValue(val); \ 00703 return XN_STATUS_OK; \ 00704 } \ 00705 inline XnStatus Remove(Type const& value) \ 00706 { \ 00707 Iterator it = Find(value); \ 00708 return Remove(it); \ 00709 } \ 00710 inline Iterator begin() { return XnList::begin(); } \ 00711 inline ConstIterator begin() const { return XnList::begin(); } \ 00712 inline Iterator end() { return XnList::end(); } \ 00713 inline ConstIterator end() const { return XnList::end(); } \ 00714 inline Iterator rbegin() { return XnList::rbegin(); } \ 00715 inline ConstIterator rbegin() const { return XnList::rbegin(); } \ 00716 inline Iterator rend() { return XnList::rend(); } \ 00717 inline ConstIterator rend() const { return XnList::rend(); } \ 00718 protected: \ 00719 virtual XnStatus Remove(XnList::ConstIterator where) \ 00720 { \ 00721 return Remove(ConstIterator(where)); \ 00722 } \ 00723 private: \ 00724 XN_DISABLE_COPY_AND_ASSIGN(ClassName); \ 00725 }; 00726 00730 #define XN_DECLARE_LIST_WITH_TRANSLATOR(Type, ClassName, Translator) \ 00731 XN_DECLARE_LIST_WITH_TRANSLATOR_DECL(, Type, ClassName, Translator) 00732 00737 #define XN_DECLARE_LIST_DECL(decl, Type, ClassName) \ 00738 XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, Type, XN_DEFAULT_TRANSLATOR_NAME(ClassName)) \ 00739 XN_DECLARE_LIST_WITH_TRANSLATOR_DECL(decl, Type, ClassName, XN_DEFAULT_TRANSLATOR_NAME(ClassName)) 00740 00744 #define XN_DECLARE_LIST(Type, ClassName) \ 00745 XN_DECLARE_LIST_DECL(, Type, ClassName) 00746 00747 #endif // _XN_LIST_H 00748