00001 /***************************************************************************** 00002 * Copyright (C) 2011 by Benjamin Hadorn (b_hadorn@bluewin.ch) 00003 ***************************************************************************** 00004 * Project : Zeus Base Library 00005 * Module : AtomicLinkedList 00006 * Package : Zeus.ZeusBase.System 00007 * Author : Benjamin Hadorn 00008 * Date : 27.12.2011 00009 * System : Zeus-Framework 00010 ***************************************************************************** 00011 * Licence: * 00012 * This library is free software; you can redistribute it and/or modify * 00013 * it under the terms of the GNU Lesser General Public License as * 00014 * published by the Free Software Foundation; either version * 00015 * 2.1 of the License, or (at your option) any later version. * 00016 * * 00017 * This library is distributed in the hope that it will be useful, * 00018 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00020 * GNU Lesser General Public License for more details. * 00021 * * 00022 * You should have received a copy of the GNU Lesser General Public * 00023 * License along with this library; if not, write to the Free Software * 00024 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA * 00025 *****************************************************************************/ 00026 00027 /***************************************************************************** 00028 * Changes: 00029 * 27.12.2011 bha: created zeus 2.0 00030 *****************************************************************************/ 00031 00032 #ifndef AtomicLinkedListHPP 00033 #define AtomicLinkedListHPP 00034 00035 #include <zeusbase/System/CriticalSection.h> 00036 #include <zeusbase/System/CriticalScopeLock.hpp> 00037 #include <zeusbase/System/SingleLinkedList.hpp> 00038 00039 BEGIN_NAMESPACE_Zeus 00040 00041 /***************************************************************************/ 00044 /***************************************************************************/ 00045 template <class T> class TAtomicLinkedList : public IList<T> 00046 { 00047 public: 00048 TAtomicLinkedList(); 00049 TAtomicLinkedList(const TSingleLinkedList<T>& rList); 00050 TAtomicLinkedList(const TAtomicLinkedList<T>& rList); 00051 virtual ~TAtomicLinkedList(); 00052 00054 void setEmptyItem(const T& rEmptyItem); 00055 00056 //Methods of IList 00057 virtual Int MQUALIFIER add(const T& rItem); 00058 virtual Int MQUALIFIER addAll(const IList<T>& rlstItems); 00059 virtual Int MQUALIFIER addEmptyItem(); 00060 virtual void MQUALIFIER copyToList(IList<T>& rList) const; 00061 virtual void MQUALIFIER clear(); 00062 virtual Retval MQUALIFIER deleteItem(Int iIndex); 00063 virtual Retval MQUALIFIER remove(const T& rItem); 00064 virtual Retval MQUALIFIER removeAll(const IList<T>& rlstItems); 00065 virtual Int MQUALIFIER getCount() const; 00066 virtual T& MQUALIFIER getItem(Int iIndex); 00067 virtual const T& MQUALIFIER getItemConst(Int iIndex) const; 00068 virtual bool MQUALIFIER equalsItem(Int iIndex, const T& rItem) const; 00069 virtual bool MQUALIFIER equals(const IList<T>& rList) const; 00070 virtual Int MQUALIFIER indexOf(const T& rItem) const; 00071 virtual Int MQUALIFIER insert(Int iIndex, const T& rItem); 00072 virtual IListIterator<T>* MQUALIFIER getIterator() const; 00073 virtual const IListIterator<T>* MQUALIFIER getConstIterator() const; 00074 virtual void MQUALIFIER releaseIterator(const IListIterator<T>* pIterator) const; 00075 virtual bool MQUALIFIER isEmpty() const; 00076 virtual T& MQUALIFIER getFirstItem(); 00077 virtual const T& MQUALIFIER getFirstItemConst() const; 00078 virtual T& MQUALIFIER getLastItem(); 00079 virtual const T& MQUALIFIER getLastItemConst() const; 00080 virtual bool MQUALIFIER hasItem(const T& rItem) const; 00081 virtual bool MQUALIFIER hasAllItems(const IList<T>& rlstItems) const; 00082 00083 //Operators 00084 T& operator[] (Int iIndex); 00085 TAtomicLinkedList<T>& operator= (const TAtomicLinkedList<T>& rList); 00086 TAtomicLinkedList<T>& operator= (const TSingleLinkedList<T>& rList); 00087 bool operator== (const TAtomicLinkedList<T>& rList) const; 00088 bool operator== (const TSingleLinkedList<T>& rList) const; 00089 bool operator!= (const TAtomicLinkedList<T>& rList) const; 00090 bool operator!= (const TSingleLinkedList<T>& rList) const; 00091 T& getEmptyElement(); 00092 00093 protected: 00094 00095 private: 00097 TSingleLinkedList<T> m_lstData; 00099 TCriticalSection& m_rLock; 00100 }; 00101 00102 /******************************************************************************/ 00105 /******************************************************************************/ 00106 template <class T> inline TAtomicLinkedList<T>::TAtomicLinkedList() 00107 : m_rLock(*new TCriticalSection(TCriticalSection::etRecursive)) 00108 { 00109 } 00110 00111 00112 /******************************************************************************/ 00116 /******************************************************************************/ 00117 template <class T> inline TAtomicLinkedList<T>::TAtomicLinkedList(const TSingleLinkedList<T>& rList) 00118 : m_rLock(*new TCriticalSection(TCriticalSection::etRecursive)), 00119 m_lstData(rList) 00120 { 00121 } 00122 00123 /******************************************************************************/ 00127 /******************************************************************************/ 00128 template <class T> inline TAtomicLinkedList<T>::TAtomicLinkedList(const TAtomicLinkedList<T>& rList) 00129 : m_rLock(*new TCriticalSection(TCriticalSection::etRecursive)) 00130 { 00131 *this = rList; //this will also protect the rList object 00132 } 00133 00134 /******************************************************************************/ 00137 /******************************************************************************/ 00138 template <class T> inline TAtomicLinkedList<T>::~TAtomicLinkedList() 00139 { 00140 m_rLock.release(); 00141 } 00142 00143 00144 /******************************************************************************/ 00146 /******************************************************************************/ 00147 template <class T> inline void TAtomicLinkedList<T>::setEmptyItem(const T& rEmptyItem) 00148 { 00150 // LOCK 00151 TCriticalScopeLock Lock(m_rLock); 00152 m_lstData.setEmptyItem(rEmptyItem); 00154 } 00155 00156 00157 /******************************************************************************/ 00160 /******************************************************************************/ 00161 template <class T> inline T& TAtomicLinkedList<T>::getEmptyElement() 00162 { 00164 // LOCK 00165 TCriticalScopeLock Lock(m_rLock); 00166 return m_lstData.getEmptyElement(); 00168 } 00169 00170 /******************************************************************************/ 00173 /******************************************************************************/ 00174 template <class T> inline Int MQUALIFIER TAtomicLinkedList<T>::add(const T& rItem) 00175 { 00177 // LOCK 00178 TCriticalScopeLock Lock(m_rLock); 00179 return m_lstData.add(rItem); 00181 } 00182 00183 /******************************************************************************/ 00186 /******************************************************************************/ 00187 template <class T> inline Int MQUALIFIER TAtomicLinkedList<T>::addAll(const IList<T>& rlstItems) 00188 { 00190 // LOCK 00191 TCriticalScopeLock Lock(m_rLock); 00192 return m_lstData.addAll(rlstItems); 00194 } 00195 00196 /******************************************************************************/ 00199 /******************************************************************************/ 00200 template <class T> inline Int MQUALIFIER TAtomicLinkedList<T>::addEmptyItem() 00201 { 00203 // LOCK 00204 TCriticalScopeLock Lock(m_rLock); 00205 return m_lstData.addEmptyItem(); 00207 } 00208 00209 /******************************************************************************/ 00212 /******************************************************************************/ 00213 template <class T> inline void MQUALIFIER TAtomicLinkedList<T>::copyToList(IList<T>& rList) const 00214 { 00216 // LOCK 00217 TCriticalScopeLock Lock(m_rLock); 00218 m_lstData.copyToList(rList); 00220 } 00221 00222 /******************************************************************************/ 00225 /******************************************************************************/ 00226 template <class T> inline void MQUALIFIER TAtomicLinkedList<T>::clear() 00227 { 00229 // LOCK 00230 TCriticalScopeLock Lock(m_rLock); 00231 m_lstData.clear(); 00233 } 00234 00235 /******************************************************************************/ 00238 /******************************************************************************/ 00239 template <class T> inline Retval MQUALIFIER TAtomicLinkedList<T>::deleteItem(Int iIndex) 00240 { 00242 // LOCK 00243 TCriticalScopeLock Lock(m_rLock); 00244 return m_lstData.deleteItem(iIndex); 00246 } 00247 00248 /******************************************************************************/ 00251 /******************************************************************************/ 00252 template <class T> inline Int MQUALIFIER TAtomicLinkedList<T>::indexOf(const T& rItem) const 00253 { 00255 // LOCK 00256 TCriticalScopeLock Lock(m_rLock); 00257 return m_lstData.indexOf(rItem); 00259 } 00260 00261 /******************************************************************************/ 00264 /******************************************************************************/ 00265 template <class T> inline Int MQUALIFIER TAtomicLinkedList<T>::insert(Int iIndex, const T& rItem) 00266 { 00268 // LOCK 00269 TCriticalScopeLock Lock(m_rLock); 00270 return m_lstData.insert(iIndex, rItem); 00272 } 00273 00274 /******************************************************************************/ 00277 /******************************************************************************/ 00278 template <class T> inline Retval MQUALIFIER TAtomicLinkedList<T>::remove(const T& rItem) 00279 { 00281 // LOCK 00282 TCriticalScopeLock Lock(m_rLock); 00283 return m_lstData.remove(rItem); 00285 } 00286 00287 /***************************************************************************/ 00290 /***************************************************************************/ 00291 template <class T> inline Retval MQUALIFIER TAtomicLinkedList<T>::removeAll(const IList<T>& rlstItems) 00292 { 00294 // LOCK 00295 TCriticalScopeLock Lock(m_rLock); 00296 return m_lstData.removeAll(rlstItems); 00298 } 00299 00300 /******************************************************************************/ 00303 /******************************************************************************/ 00304 template <class T> inline Int MQUALIFIER TAtomicLinkedList<T>::getCount() const 00305 { 00307 // LOCK 00308 TCriticalScopeLock Lock(m_rLock); 00309 return m_lstData.getCount(); 00311 } 00312 00313 /******************************************************************************/ 00316 /******************************************************************************/ 00317 template <class T> inline T& MQUALIFIER TAtomicLinkedList<T>::getItem(Int iIndex) 00318 { 00320 // LOCK 00321 TCriticalScopeLock Lock(m_rLock); 00322 return m_lstData.getItem(iIndex); 00324 } 00325 00326 /******************************************************************************/ 00329 /******************************************************************************/ 00330 template <class T> inline const T& MQUALIFIER TAtomicLinkedList<T>::getItemConst(Int iIndex) const 00331 { 00333 // LOCK 00334 TCriticalScopeLock Lock(m_rLock); 00335 return m_lstData.getItemConst(iIndex); 00337 } 00338 00339 /******************************************************************************/ 00342 /******************************************************************************/ 00343 template <class T> inline bool MQUALIFIER TAtomicLinkedList<T>::equalsItem(Int iIndex, const T& rItem) const 00344 { 00346 // LOCK 00347 TCriticalScopeLock Lock(m_rLock); 00348 return m_lstData.equalsItem(iIndex, rItem); 00350 } 00351 00352 /******************************************************************************/ 00355 /******************************************************************************/ 00356 template <class T> inline bool MQUALIFIER TAtomicLinkedList<T>::equals(const IList<T>& rList) const 00357 { 00359 // LOCK 00360 TCriticalScopeLock Lock(m_rLock); 00361 return m_lstData.equals(rList); 00363 } 00364 00365 /******************************************************************************/ 00368 /******************************************************************************/ 00369 template <class T> inline IListIterator<T>* MQUALIFIER TAtomicLinkedList<T>::getIterator() const 00370 { 00372 // LOCK 00373 TCriticalScopeLock Lock(m_rLock); 00374 return m_lstData.getIterator(); 00376 } 00377 00378 /******************************************************************************/ 00381 /******************************************************************************/ 00382 template <class T> inline const IListIterator<T>* MQUALIFIER TAtomicLinkedList<T>::getConstIterator() const 00383 { 00385 // LOCK 00386 TCriticalScopeLock Lock(m_rLock); 00387 return m_lstData.getConstIterator(); 00389 } 00390 00391 /******************************************************************************/ 00394 /******************************************************************************/ 00395 template <class T> inline void MQUALIFIER TAtomicLinkedList<T>::releaseIterator(const IListIterator<T>* pIterator) const 00396 { 00398 // LOCK 00399 TCriticalScopeLock Lock(m_rLock); 00400 return m_lstData.releaseIterator(pIterator); 00402 } 00403 00404 /******************************************************************************/ 00407 /******************************************************************************/ 00408 template <class T> inline bool MQUALIFIER TAtomicLinkedList<T>::isEmpty() const 00409 { 00411 // LOCK 00412 TCriticalScopeLock Lock(m_rLock); 00413 return m_lstData.isEmpty(); 00415 } 00416 00417 /******************************************************************************/ 00420 /******************************************************************************/ 00421 template <class T> inline T& MQUALIFIER TAtomicLinkedList<T>::getFirstItem() 00422 { 00424 // LOCK 00425 TCriticalScopeLock Lock(m_rLock); 00426 return m_lstData.getFirstItem(); 00428 } 00429 00430 /******************************************************************************/ 00433 /******************************************************************************/ 00434 template <class T> inline const T& MQUALIFIER TAtomicLinkedList<T>::getFirstItemConst() const 00435 { 00437 // LOCK 00438 TCriticalScopeLock Lock(m_rLock); 00439 return m_lstData.getFirstItemConst(); 00441 } 00442 00443 /******************************************************************************/ 00446 /******************************************************************************/ 00447 template <class T> inline T& MQUALIFIER TAtomicLinkedList<T>::getLastItem() 00448 { 00450 // LOCK 00451 TCriticalScopeLock Lock(m_rLock); 00452 return m_lstData.getLastItem(); 00454 } 00455 00456 /******************************************************************************/ 00459 /******************************************************************************/ 00460 template <class T> inline const T& MQUALIFIER TAtomicLinkedList<T>::getLastItemConst() const 00461 { 00463 // LOCK 00464 TCriticalScopeLock Lock(m_rLock); 00465 return m_lstData.getLastItemConst(); 00467 } 00468 00469 /******************************************************************************/ 00472 /******************************************************************************/ 00473 template <class T> inline bool MQUALIFIER TAtomicLinkedList<T>::hasItem(const T& rItem) const 00474 { 00476 // LOCK 00477 TCriticalScopeLock Lock(m_rLock); 00478 return m_lstData.hasItem(rItem); 00480 } 00481 00482 /******************************************************************************/ 00485 /******************************************************************************/ 00486 template <class T> inline bool MQUALIFIER TAtomicLinkedList<T>::hasAllItems(const IList<T>& rlstItems) const 00487 { 00489 // LOCK 00490 TCriticalScopeLock Lock(m_rLock); 00491 return m_lstData.hasAllItems(rlstItems); 00493 } 00494 00495 /******************************************************************************/ 00500 /******************************************************************************/ 00501 template <class T> inline T& TAtomicLinkedList<T>::operator[](Int iIndex) 00502 { 00504 // LOCK 00505 TCriticalScopeLock Lock(m_rLock); 00506 return m_lstData[iIndex]; 00508 } 00509 00510 /******************************************************************************/ 00515 /******************************************************************************/ 00516 template <class T> inline TAtomicLinkedList<T>& TAtomicLinkedList<T>::operator=(const TSingleLinkedList<T>& rList) 00517 { 00519 // LOCK 00520 TCriticalScopeLock Lock(m_rLock); 00521 m_lstData = rList; 00522 return *this; 00524 } 00525 00526 /******************************************************************************/ 00531 /******************************************************************************/ 00532 template <class T> TAtomicLinkedList<T>& TAtomicLinkedList<T>::operator=(const TAtomicLinkedList<T>& rList) 00533 { 00535 // LOCK 00536 m_rLock.enter(); 00537 rList.m_rLock.enter(); 00538 00539 m_lstData = rList.m_lstData; 00540 00541 rList.m_rLock.leave(); 00542 m_rLock.leave(); 00544 00545 return *this; 00546 } 00547 00548 /******************************************************************************/ 00554 /******************************************************************************/ 00555 template <class T> inline bool TAtomicLinkedList<T>::operator==(const TSingleLinkedList<T>& rList) const 00556 { 00558 // LOCK 00559 TCriticalScopeLock Lock(m_rLock); 00560 return m_lstData == rList; 00562 } 00563 00564 /******************************************************************************/ 00570 /******************************************************************************/ 00571 template <class T> bool TAtomicLinkedList<T>::operator==(const TAtomicLinkedList<T>& rList) const 00572 { 00574 // LOCK 00575 m_rLock.enter(); 00576 rList.m_rLock.enter(); 00577 00578 bool bRetval = (m_lstData == rList.m_lstData); 00579 00580 rList.m_rLock.leave(); 00581 m_rLock.leave(); 00583 00584 return bRetval; 00585 } 00586 00587 /******************************************************************************/ 00591 /******************************************************************************/ 00592 template <class T> inline bool TAtomicLinkedList<T>::operator!=(const TSingleLinkedList<T>& rList) const 00593 { 00595 // LOCK 00596 TCriticalScopeLock Lock(m_rLock); 00597 return m_lstData != rList; 00599 } 00600 00601 /******************************************************************************/ 00605 /******************************************************************************/ 00606 template <class T> bool TAtomicLinkedList<T>::operator!=(const TAtomicLinkedList<T>& rList) const 00607 { 00609 // LOCK 00610 m_rLock.enter(); 00611 rList.m_rLock.enter(); 00612 00613 bool bRetval = (m_lstData != rList.m_lstData); 00614 00615 rList.m_rLock.leave(); 00616 m_rLock.leave(); 00618 00619 return bRetval; 00620 } 00621 00622 END_NAMESPACE_Zeus 00623 00624 00625 #endif