![]() |
pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
|
00001 /* 00002 ------------------------------------------------------------------------------- 00003 This file is part of the Plink, Plonk, Plank libraries 00004 by Martin Robinson 00005 00006 http://code.google.com/p/pl-nk/ 00007 00008 Copyright University of the West of England, Bristol 2011-14 00009 All rights reserved. 00010 00011 Redistribution and use in source and binary forms, with or without 00012 modification, are permitted provided that the following conditions are met: 00013 00014 * Redistributions of source code must retain the above copyright 00015 notice, this list of conditions and the following disclaimer. 00016 * Redistributions in binary form must reproduce the above copyright 00017 notice, this list of conditions and the following disclaimer in the 00018 documentation and/or other materials provided with the distribution. 00019 * Neither the name of University of the West of England, Bristol nor 00020 the names of its contributors may be used to endorse or promote products 00021 derived from this software without specific prior written permission. 00022 00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00024 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00025 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00026 DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF THE WEST OF ENGLAND, BRISTOL BE 00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00033 00034 This software makes use of third party libraries. For more information see: 00035 doc/license.txt included in the distribution. 00036 ------------------------------------------------------------------------------- 00037 */ 00038 00039 #ifndef PLONK_SIMPLELINKEDLIST_H 00040 #define PLONK_SIMPLELINKEDLIST_H 00041 00042 #include "../core/plonk_CoreForwardDeclarations.h" 00043 #include "plonk_ContainerForwardDeclarations.h" 00044 00045 #include "../core/plonk_SmartPointer.h" 00046 #include "../core/plonk_WeakPointer.h" 00047 00048 template<class ValueType> 00049 class SimpleLinkedListInternal : public SmartPointer 00050 { 00051 public: 00052 typedef SimpleLinkedList<ValueType> LinkedListType; 00053 00054 SimpleLinkedListInternal() throw() 00055 { 00056 pl_SimpleLinkedList_Init (&list); 00057 pl_SimpleLinkedList_SetFreeElementDataFunction (&list, SimpleLinkedListInternal::freeElement); 00058 } 00059 00060 ~SimpleLinkedListInternal() 00061 { 00062 ResultCode result; 00063 00064 result = pl_SimpleLinkedList_Clear (&list); 00065 plonk_assert (result == PlankResult_OK); 00066 00067 result = pl_SimpleLinkedList_DeInit (&list); 00068 plonk_assert (result == PlankResult_OK); 00069 00070 #ifndef PLONK_DEBUG 00071 (void)result; 00072 #endif 00073 } 00074 00075 void add (ValueType const& value) throw() 00076 { 00077 ResultCode result = pl_SimpleLinkedList_Add (&list, createElement (value)); 00078 plonk_assert (result == PlankResult_OK); 00079 #ifndef PLONK_DEBUG 00080 (void)result; 00081 #endif 00082 } 00083 00084 void insertAtIndex (const LongLong index, ValueType const& value) throw() 00085 { 00086 ResultCode result = pl_SimpleLinkedList_InsertAtIndex (&list, index, createElement (value)); 00087 plonk_assert (result == PlankResult_OK); 00088 #ifndef PLONK_DEBUG 00089 (void)result; 00090 #endif 00091 } 00092 00093 ValueType atIndex (const LongLong index) throw() 00094 { 00095 PlankSimpleLinkedListElementRef element; 00096 ResultCode result = pl_SimpleLinkedList_AtIndex (&list, index, &element); 00097 plonk_assert (result == PlankResult_OK); 00098 #ifndef PLONK_DEBUG 00099 (void)result; 00100 #endif 00101 return getValueFromElement (element); 00102 } 00103 00104 ValueType getFirst() throw() 00105 { 00106 PlankSimpleLinkedListElementRef element; 00107 ResultCode result = pl_SimpleLinkedList_GetFirst (&list, &element); 00108 plonk_assert (result == PlankResult_OK); 00109 #ifndef PLONK_DEBUG 00110 (void)result; 00111 #endif 00112 return getValueFromElement (element); 00113 } 00114 00115 ValueType getLast() throw() 00116 { 00117 PlankSimpleLinkedListElementRef element; 00118 ResultCode result = pl_SimpleLinkedList_GetLast (&list, &element); 00119 plonk_assert (result == PlankResult_OK); 00120 #ifndef PLONK_DEBUG 00121 (void)result; 00122 #endif 00123 return getValueFromElement (element); 00124 } 00125 00126 ValueType removeAtIndex (const LongLong index) throw() 00127 { 00128 PlankSimpleLinkedListElementRef element; 00129 ResultCode result = pl_SimpleLinkedList_RemoveAtIndex (&list, index, &element); 00130 plonk_assert (result == PlankResult_OK); 00131 #ifndef PLONK_DEBUG 00132 (void)result; 00133 #endif 00134 return removeValueFromElement (element); 00135 } 00136 00137 ValueType removeFirst() throw() 00138 { 00139 PlankSimpleLinkedListElementRef element; 00140 ResultCode result = pl_SimpleLinkedList_RemoveFirst (&list, &element); 00141 plonk_assert (result == PlankResult_OK); 00142 #ifndef PLONK_DEBUG 00143 (void)result; 00144 #endif 00145 return removeValueFromElement (element); 00146 } 00147 00148 ValueType removeLast() throw() 00149 { 00150 PlankSimpleLinkedListElementRef element; 00151 ResultCode result = pl_SimpleLinkedList_RemoveLast (&list, &element); 00152 plonk_assert (result == PlankResult_OK); 00153 #ifndef PLONK_DEBUG 00154 (void)result; 00155 #endif 00156 return removeValueFromElement (element); 00157 } 00158 00159 LongLong indexOf (ValueType const& value) throw() 00160 { 00161 PlankSimpleLinkedListElementRef element; 00162 ResultCode result = pl_SimpleLinkedList_GetFirst (&list, &element); 00163 plonk_assert (result == PlankResult_OK); 00164 00165 LongLong index = 0; 00166 00167 while (element != 0) 00168 { 00169 if (value == getValueFromElement (element)) 00170 return index; 00171 00172 ++index; 00173 element = pl_SimpleLinkedListElement_GetNext (element); 00174 } 00175 00176 #ifndef PLONK_DEBUG 00177 (void)result; 00178 #endif 00179 return -1; 00180 } 00181 00182 inline LongLong size() throw() 00183 { 00184 return pl_SimpleLinkedList_GetSize (&list); 00185 } 00186 00187 friend class SimpleLinkedList<ValueType>; 00188 00189 private: 00190 PlankSimpleLinkedList list; 00191 00192 inline PlankSimpleLinkedListElementRef createElement (ValueType const& value) throw() 00193 { 00194 PlankSimpleLinkedListElementRef element = pl_SimpleLinkedListElement_CreateAndInit(); 00195 plonk_assert (element != 0); 00196 pl_SimpleLinkedListElement_SetData (element, new ValueType (value)); 00197 return element; 00198 } 00199 00200 inline ValueType getValueFromElement (PlankSimpleLinkedListElementRef element) throw() 00201 { 00202 if (element == 0) 00203 return ValueType(); 00204 00205 ValueType* const value = static_cast<ValueType*> (pl_SimpleLinkedListElement_GetData (element)); 00206 00207 if (value != 0) 00208 return *value; 00209 else 00210 return ValueType(); 00211 } 00212 00213 inline ValueType removeValueFromElement (PlankSimpleLinkedListElementRef element) throw() 00214 { 00215 if (element == 0) 00216 return ValueType(); 00217 00218 ValueType* const value = static_cast<ValueType*> (pl_SimpleLinkedListElement_GetData (element)); 00219 00220 ResultCode result = pl_SimpleLinkedListElement_Destroy (element); 00221 plonk_assert (result == PlankResult_OK); 00222 #ifndef PLONK_DEBUG 00223 (void)result; 00224 #endif 00225 00226 if (value != 0) 00227 { 00228 ValueType result = *value; 00229 delete value; 00230 return result; 00231 } 00232 else 00233 { 00234 return ValueType(); 00235 } 00236 } 00237 00238 static ResultCode freeElement (Pointer data) 00239 { 00240 delete static_cast<ValueType*> (data); 00241 return PlankResult_OK; 00242 } 00243 }; 00244 00245 00246 template<class ValueType> 00247 class SimpleLinkedListInternal<ValueType*> : public SmartPointer 00248 { 00249 public: 00250 typedef SimpleLinkedList<ValueType*> LinkedListType; 00251 00252 SimpleLinkedListInternal() throw() 00253 { 00254 pl_SimpleLinkedList_Init (&list); 00255 } 00256 00257 ~SimpleLinkedListInternal() 00258 { 00259 plonk_assert (pl_SimpleLinkedList_GetSize (&list) == 0); // pointers were left in the list 00260 pl_SimpleLinkedList_Clear (&list); 00261 pl_SimpleLinkedList_DeInit (&list); 00262 } 00263 00264 void add (ValueType* const& value) throw() 00265 { 00266 ResultCode result = pl_SimpleLinkedList_Add (&list, createElement (value)); 00267 plonk_assert (result == PlankResult_OK); 00268 #ifndef PLONK_DEBUG 00269 (void)result; 00270 #endif 00271 } 00272 00273 void insertAtIndex (const LongLong index, ValueType* const& value) throw() 00274 { 00275 ResultCode result = pl_SimpleLinkedList_InsertAtIndex (&list, index, createElement (value)); 00276 plonk_assert (result == PlankResult_OK); 00277 #ifndef PLONK_DEBUG 00278 (void)result; 00279 #endif 00280 } 00281 00282 ValueType* atIndex (const LongLong index) throw() 00283 { 00284 PlankSimpleLinkedListElementRef element; 00285 ResultCode result = pl_SimpleLinkedList_AtIndex (&list, index, &element); 00286 plonk_assert (result == PlankResult_OK); 00287 #ifndef PLONK_DEBUG 00288 (void)result; 00289 #endif 00290 return getValueFromElement (element); 00291 } 00292 00293 ValueType* getFirst() throw() 00294 { 00295 PlankSimpleLinkedListElementRef element; 00296 ResultCode result = pl_SimpleLinkedList_GetFirst (&list, &element); 00297 plonk_assert (result == PlankResult_OK); 00298 #ifndef PLONK_DEBUG 00299 (void)result; 00300 #endif 00301 return getValueFromElement (element); 00302 } 00303 00304 ValueType* getLast() throw() 00305 { 00306 PlankSimpleLinkedListElementRef element; 00307 ResultCode result = pl_SimpleLinkedList_GetLast (&list, &element); 00308 plonk_assert (result == PlankResult_OK); 00309 #ifndef PLONK_DEBUG 00310 (void)result; 00311 #endif 00312 return getValueFromElement (element); 00313 } 00314 00315 ValueType* removeAtIndex (const LongLong index) throw() 00316 { 00317 PlankSimpleLinkedListElementRef element; 00318 ResultCode result = pl_SimpleLinkedList_RemoveAtIndex (&list, index, &element); 00319 plonk_assert (result == PlankResult_OK); 00320 #ifndef PLONK_DEBUG 00321 (void)result; 00322 #endif 00323 return removeValueFromElement (element); 00324 } 00325 00326 ValueType* removeFirst() throw() 00327 { 00328 PlankSimpleLinkedListElementRef element; 00329 ResultCode result = pl_SimpleLinkedList_RemoveFirst (&list, &element); 00330 plonk_assert (result == PlankResult_OK); 00331 #ifndef PLONK_DEBUG 00332 (void)result; 00333 #endif 00334 return removeValueFromElement (element); 00335 } 00336 00337 ValueType* removeLast() throw() 00338 { 00339 PlankSimpleLinkedListElementRef element; 00340 ResultCode result = pl_SimpleLinkedList_RemoveLast (&list, &element); 00341 plonk_assert (result == PlankResult_OK); 00342 #ifndef PLONK_DEBUG 00343 (void)result; 00344 #endif 00345 return removeValueFromElement (element); 00346 } 00347 00348 LongLong indexOf (ValueType* const& value) throw() 00349 { 00350 PlankSimpleLinkedListElementRef element; 00351 ResultCode result = pl_SimpleLinkedList_GetFirst (&list, &element); 00352 plonk_assert (result == PlankResult_OK); 00353 00354 LongLong index = 0; 00355 00356 while (element != 0) 00357 { 00358 if (value == getValueFromElement (element)) 00359 return index; 00360 00361 ++index; 00362 element = pl_SimpleLinkedListElement_GetNext (element); 00363 } 00364 00365 #ifndef PLONK_DEBUG 00366 (void)result; 00367 #endif 00368 return -1; 00369 } 00370 00371 inline LongLong size() throw() 00372 { 00373 return pl_SimpleLinkedList_GetSize (&list); 00374 } 00375 00376 friend class SimpleLinkedList<ValueType*>; 00377 00378 private: 00379 PlankSimpleLinkedList list; 00380 00381 PlankSimpleLinkedListElementRef createElement (ValueType* const& value) throw() 00382 { 00383 PlankSimpleLinkedListElementRef element = pl_SimpleLinkedListElement_CreateAndInit(); 00384 plonk_assert (element != 0); 00385 pl_SimpleLinkedListElement_SetData (element, value); 00386 return element; 00387 } 00388 00389 inline ValueType* getValueFromElement (PlankSimpleLinkedListElementRef element) throw() 00390 { 00391 if (element == 0) 00392 return 0; 00393 00394 return static_cast<ValueType*> (pl_SimpleLinkedListElement_GetData (element)); 00395 } 00396 00397 inline ValueType removeValueFromElement (PlankSimpleLinkedListElementRef element) throw() 00398 { 00399 if (element == 0) 00400 return ValueType(); 00401 00402 ValueType* const value = static_cast<ValueType*> (pl_SimpleLinkedListElement_GetData (element)); 00403 00404 ResultCode result = pl_SimpleLinkedListElement_Destroy (element); 00405 plonk_assert (result == PlankResult_OK); 00406 #ifndef PLONK_DEBUG 00407 (void)result; 00408 #endif 00409 00410 return value; 00411 } 00412 }; 00413 00414 00415 00416 //------------------------------------------------------------------------------ 00417 00419 template<class ValueType> 00420 class SimpleLinkedList : public SmartPointerContainer<SimpleLinkedListInternal<ValueType> > 00421 { 00422 public: 00423 typedef SimpleLinkedListInternal<ValueType> Internal; 00424 typedef SmartPointerContainer<Internal> Base; 00425 typedef WeakPointerContainer<SimpleLinkedList> Weak; 00426 00427 SimpleLinkedList() 00428 : Base (new Internal()) 00429 { 00430 } 00431 00432 explicit SimpleLinkedList (Internal* internalToUse) throw() 00433 : Base (internalToUse) 00434 { 00435 } 00436 00440 static SimpleLinkedList fromWeak (Weak const& weak) throw() 00441 { 00442 return weak.fromWeak(); 00443 } 00444 00447 SimpleLinkedList (SimpleLinkedList const& copy) throw() 00448 : Base (static_cast<Base const&> (copy)) 00449 { 00450 } 00451 00452 SimpleLinkedList (Dynamic const& other) throw() 00453 : Base (other.as<SimpleLinkedList>().getInternal()) 00454 { 00455 } 00456 00458 SimpleLinkedList& operator= (SimpleLinkedList const& other) throw() 00459 { 00460 if (this != &other) 00461 this->setInternal (other.getInternal()); 00462 00463 return *this; 00464 } 00465 00466 inline void add (ValueType const& value) throw() 00467 { 00468 this->getInternal()->add (value); 00469 } 00470 00471 inline void insertAtIndex (const LongLong index, ValueType const& value) throw() 00472 { 00473 this->getInternal()->insertAtIndex (index, value); 00474 } 00475 00476 inline ValueType atIndex (const LongLong index) throw() 00477 { 00478 return this->getInternal()->atIndex (index); 00479 } 00480 00481 inline ValueType getFirst() throw() 00482 { 00483 return this->getInternal()->getFirst(); 00484 } 00485 00486 inline ValueType getLast() throw() 00487 { 00488 return this->getInternal()->getFirst(); 00489 } 00490 00491 inline ValueType removeAtIndex (const LongLong index) throw() 00492 { 00493 return this->getInternal()->removeAtIndex (index); 00494 } 00495 00496 inline ValueType removeFirst() throw() 00497 { 00498 return this->getInternal()->removeFirst(); 00499 } 00500 00501 inline ValueType removeLast() throw() 00502 { 00503 return this->getInternal()->removeFirst(); 00504 } 00505 00506 inline LongLong indexOf (ValueType const& value) throw() 00507 { 00508 return this->getInternal()->indexOf (value); 00509 } 00510 00511 inline bool contains (ValueType const& value) throw() 00512 { 00513 return this->getInternal()->indexOf (value) >= 0; 00514 } 00515 00516 inline LongLong size() throw() 00517 { 00518 return this->getInternal()->size(); 00519 } 00520 00521 PLONK_OBJECTARROWOPERATOR(SimpleLinkedList); 00522 00523 }; 00524 00525 00526 #endif // PLONK_SIMPLELINKEDLIST_H