![]() |
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 _XNLISTT_H_ 00022 #define _XNLISTT_H_ 00023 00024 //--------------------------------------------------------------------------- 00025 // Includes 00026 //--------------------------------------------------------------------------- 00027 #include <XnPlatform.h> 00028 #include <XnDataTypes.h> 00029 #include <XnOS.h> 00030 00031 //--------------------------------------------------------------------------- 00032 // Code 00033 //--------------------------------------------------------------------------- 00034 00040 template<class T> 00041 struct XnLinkedNodeT 00042 { 00043 XnLinkedNodeT() : pPrev(NULL), pNext(NULL) {} 00044 XnLinkedNodeT(T const& value) : pPrev(NULL), pNext(NULL), value(value) {} 00045 00046 struct XnLinkedNodeT<T>* pPrev; 00047 struct XnLinkedNodeT<T>* pNext; 00048 T value; 00049 }; 00050 00059 template<class T> 00060 class XnLinkedNodeDefaultAllocatorT 00061 { 00062 public: 00063 typedef XnLinkedNodeT<T> LinkedNode; 00064 00065 static LinkedNode* Allocate(T const& value) 00066 { 00067 return XN_NEW(LinkedNode, value); 00068 } 00069 00070 static void Deallocate(LinkedNode* pNode) 00071 { 00072 XN_DELETE(pNode); 00073 } 00074 }; 00075 00083 template<class T, class TAlloc = XnLinkedNodeDefaultAllocatorT<T> > 00084 class XnListT 00085 { 00086 public: 00087 typedef XnLinkedNodeT<T> LinkedNode; 00088 typedef T TValue; 00089 typedef TAlloc TAllocator; 00090 00094 class ConstIterator 00095 { 00096 public: 00097 inline ConstIterator() : m_pCurrent(NULL) {} 00098 00099 inline ConstIterator(LinkedNode* pNode) : m_pCurrent(pNode) {} 00100 00101 inline ConstIterator(const ConstIterator& other) : m_pCurrent(other.m_pCurrent) {} 00102 00106 inline ConstIterator& operator++() 00107 { 00108 m_pCurrent = m_pCurrent->pNext; 00109 return *this; 00110 } 00111 00115 inline ConstIterator operator++(int) 00116 { 00117 ConstIterator retVal(*this); 00118 ++*this; 00119 return retVal; 00120 } 00121 00125 inline ConstIterator& operator--() 00126 { 00127 m_pCurrent = m_pCurrent->pPrev; 00128 return *this; 00129 } 00130 00134 inline ConstIterator operator--(int) 00135 { 00136 ConstIterator retVal(*this); 00137 --*this; 00138 return retVal; 00139 } 00140 00146 inline XnBool operator==(const ConstIterator& other) const 00147 { 00148 return m_pCurrent == other.m_pCurrent; 00149 } 00150 00156 inline XnBool operator!=(const ConstIterator& other) const 00157 { 00158 return m_pCurrent != other.m_pCurrent; 00159 } 00160 00164 inline T const& operator*() const 00165 { 00166 return m_pCurrent->value; 00167 } 00168 00172 inline T const* operator->() const 00173 { 00174 return &m_pCurrent->value; 00175 } 00176 00177 protected: 00178 friend class XnListT; 00179 00181 LinkedNode* m_pCurrent; 00182 }; 00183 00187 class Iterator : public ConstIterator 00188 { 00189 public: 00190 inline Iterator() : ConstIterator() {} 00191 00192 inline Iterator(LinkedNode* pNode) : ConstIterator(pNode) {} 00193 00194 inline Iterator(const Iterator& other) : ConstIterator(other) {} 00195 00199 inline Iterator& operator++() 00200 { 00201 ++(*(ConstIterator*)this); 00202 return (*this); 00203 } 00204 00208 inline Iterator operator++(int) 00209 { 00210 Iterator retVal(*this); 00211 ++*this; 00212 return (retVal); 00213 } 00214 00218 inline Iterator& operator--() 00219 { 00220 --(*(ConstIterator*)this); 00221 return (*this); 00222 } 00226 inline Iterator operator--(int) 00227 { 00228 Iterator retVal(*this); 00229 --*this; 00230 return (retVal); 00231 } 00232 00236 inline T& operator*() const 00237 { 00238 return this->m_pCurrent->value; 00239 } 00240 00244 inline T* operator->() const 00245 { 00246 return &this->m_pCurrent->value; 00247 } 00248 }; 00249 00250 public: 00251 XnListT() 00252 { 00253 Init(); 00254 } 00255 00256 XnListT(const XnListT& other) 00257 { 00258 Init(); 00259 *this = other; 00260 } 00261 00262 XnListT& operator=(const XnListT& other) 00263 { 00264 Clear(); 00265 00266 XnStatus nRetVal = XN_STATUS_OK; 00267 00268 for (ConstIterator it = other.Begin(); it != other.End(); ++it) 00269 { 00270 nRetVal = AddLast(*it); 00271 XN_ASSERT(nRetVal == XN_STATUS_OK); 00272 } 00273 00274 return *this; 00275 } 00276 00277 ~XnListT() 00278 { 00279 Clear(); 00280 } 00281 00285 Iterator Begin() 00286 { 00287 return Iterator(m_anchor.pNext); 00288 } 00289 00293 ConstIterator Begin() const 00294 { 00295 return ConstIterator(const_cast<LinkedNode*>(m_anchor.pNext)); 00296 } 00297 00301 Iterator End() 00302 { 00303 return Iterator(&m_anchor); 00304 } 00305 00309 ConstIterator End() const 00310 { 00311 return ConstIterator(const_cast<LinkedNode*>(&m_anchor)); 00312 } 00313 00317 Iterator ReverseBegin() 00318 { 00319 return Iterator(m_anchor.pPrev); 00320 } 00321 00325 ConstIterator ReverseBegin() const 00326 { 00327 return ConstIterator(const_cast<LinkedNode*>(m_anchor.pPrev)); 00328 } 00329 00333 Iterator ReverseEnd() 00334 { 00335 return Iterator(&m_anchor); 00336 } 00337 00341 ConstIterator ReverseEnd() const 00342 { 00343 return ConstIterator(const_cast<LinkedNode*>(&m_anchor)); 00344 } 00345 00355 XnStatus AddAfter(ConstIterator where, T const& value) 00356 { 00357 if (where == End()) 00358 { 00359 return XN_STATUS_ILLEGAL_POSITION; 00360 } 00361 00362 return InsertAfter(where.m_pCurrent, value); 00363 } 00364 00374 XnStatus AddBefore(ConstIterator where, T const& value) 00375 { 00376 if (where == End()) 00377 { 00378 return XN_STATUS_ILLEGAL_POSITION; 00379 } 00380 00381 return InsertAfter(where.m_pCurrent->pPrev, value); 00382 } 00383 00391 XnStatus AddFirst(T const& value) 00392 { 00393 return InsertAfter(&m_anchor, value); 00394 } 00395 00403 XnStatus AddLast(T const& value) 00404 { 00405 return InsertAfter(ReverseBegin().m_pCurrent, value); 00406 } 00407 00415 ConstIterator Find(T const& value) const 00416 { 00417 ConstIterator iter = Begin(); 00418 for (; iter != End(); ++iter) 00419 { 00420 if (*iter == value) 00421 break; 00422 } 00423 return iter; 00424 } 00425 00433 Iterator Find(T const& value) 00434 { 00435 ConstIterator iter = const_cast<const XnListT<T>*>(this)->Find(value); 00436 return Iterator(iter.m_pCurrent); 00437 } 00438 00446 XnStatus Remove(ConstIterator where) 00447 { 00448 // Verify iterator is valid 00449 if (where == End()) 00450 { 00451 return XN_STATUS_ILLEGAL_POSITION; 00452 } 00453 00454 XnLinkedNodeT<T>* pToRemove = where.m_pCurrent; 00455 00456 // Connect other nodes to bypass the one removed 00457 pToRemove->pPrev->pNext = pToRemove->pNext; 00458 pToRemove->pNext->pPrev = pToRemove->pPrev; 00459 00460 --m_nSize; 00461 00462 // Free memory 00463 TAlloc::Deallocate(pToRemove); 00464 00465 return XN_STATUS_OK; 00466 } 00467 00475 XnStatus Remove(T const& value) 00476 { 00477 ConstIterator it = Find(value); 00478 if (it != End()) 00479 { 00480 return Remove(it); 00481 } 00482 else 00483 { 00484 return XN_STATUS_NO_MATCH; 00485 } 00486 } 00487 00491 XnStatus Clear() 00492 { 00493 while (!IsEmpty()) 00494 Remove(Begin()); 00495 00496 return XN_STATUS_OK; 00497 } 00498 00502 XnBool IsEmpty() const 00503 { 00504 return (m_nSize == 0); 00505 } 00506 00510 XnUInt32 Size() const 00511 { 00512 return m_nSize; 00513 } 00514 00521 void CopyTo(T* pArray) const 00522 { 00523 XN_ASSERT(pArray != NULL); 00524 00525 XnUInt32 i = 0; 00526 for (ConstIterator iter = Begin(); iter != End(); ++iter, ++i) 00527 { 00528 pArray[i] = *iter; 00529 } 00530 } 00531 00532 protected: 00541 XnStatus InsertAfter(LinkedNode* pAfter, T const& val) 00542 { 00543 // Get a node from the pool for the entry 00544 LinkedNode* pNewNode = TAlloc::Allocate(val); 00545 if (pNewNode == NULL) 00546 { 00547 XN_ASSERT(FALSE); 00548 return XN_STATUS_ALLOC_FAILED; 00549 } 00550 pNewNode->pPrev = pAfter; 00551 pNewNode->pNext = pAfter->pNext; 00552 00553 // push new node to position 00554 pAfter->pNext->pPrev = pNewNode; 00555 pAfter->pNext = pNewNode; 00556 00557 ++m_nSize; 00558 00559 return XN_STATUS_OK; 00560 } 00561 00562 // A dummy node, pointing to first node, and last node points back to it. 00563 LinkedNode m_anchor; 00564 00565 XnUInt32 m_nSize; 00566 00567 private: 00568 void Init() 00569 { 00570 m_anchor.pNext = &m_anchor; 00571 m_anchor.pPrev = &m_anchor; 00572 m_nSize = 0; 00573 } 00574 }; 00575 00576 #endif // _XNLISTT_H_