src_other/tuplebase/ZDList.h

00001 /*  @(#) $Id: ZDList.h,v 1.10 2007/04/06 20:20:57 agreen Exp $ */
00002 
00003 /* ------------------------------------------------------------
00004 Copyright (c) 2006 Andrew Green and Learning in Motion, Inc.
00005 http://www.zoolib.org
00006 
00007 Permission is hereby granted, free of charge, to any person obtaining a copy
00008 of this software and associated documentation files (the "Software"), to deal
00009 in the Software without restriction, including without limitation the rights
00010 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00011 copies of the Software, and to permit persons to whom the Software is
00012 furnished to do so, subject to the following conditions:
00013 
00014 The above copyright notice and this permission notice shall be included in
00015 all copies or substantial portions of the Software.
00016 
00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00018 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00020 COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00021 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00022 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00023 ------------------------------------------------------------ */
00024 
00025 #ifndef __ZDList__
00026 #define __ZDList__
00027 #include "zconfig.h"
00028 
00029 #include "ZCompat_operator_bool.h"
00030 #include "ZDebug.h"
00031 #include "ZTypes.h"
00032 
00033 namespace ZooLib {
00034 
00035 // In these templates, P is Pointer and L is Link.
00036 
00037 // =================================================================================================
00038 #pragma mark -
00039 #pragma mark * DListHead
00040 
00041 template <typename L>
00042 struct DListHead
00043         {
00044     ZOOLIB_DEFINE_OPERATOR_BOOL_TYPES_T(DListHead, operator_bool_generator_type, operator_bool_type);
00045 
00046         DListHead() : fHeadL(nil), fSize(0) {}
00047 
00048         operator operator_bool_type() const { return operator_bool_generator_type::translate(fHeadL); }
00049 
00050         size_t Size() const { return fSize; }
00051 
00052         bool Empty() const
00053                 {
00054                 ZAssertStop(L::kDebug, (!fSize && !fHeadL) || (fSize && fHeadL));
00055                 return !fHeadL;
00056                 }
00057 
00058         bool Contains(L* iL) const
00059                 {
00060                 return iL->fNext;
00061                 }
00062 
00063         void Insert(L* iL)
00064                 {
00065                 ZAssertStop(L::kDebug, !iL->fPrev);
00066                 ZAssertStop(L::kDebug, !iL->fNext);
00067 
00068                 if (!fHeadL)
00069                         {
00070                         ZAssertStop(L::kDebug, fSize == 0);
00071                         fSize = 1;
00072                         fHeadL = iL;
00073                         iL->fPrev = iL;
00074                         iL->fNext = iL;
00075                         }
00076                 else
00077                         {
00078                         ZAssertStop(L::kDebug, fSize != 0);
00079                         ++fSize;
00080                         iL->fNext = fHeadL;
00081                         iL->fPrev = fHeadL->fPrev;
00082                         fHeadL->fPrev->fNext = iL;
00083                         fHeadL->fPrev = iL;
00084                         }
00085                 }
00086 
00087         void InsertIfNotContains(L* iL)
00088                 {
00089                 if (!iL->fNext)
00090                         this->Insert(iL);
00091                 }
00092 
00093         void Remove(L* iL)
00094                 {
00095                 ZAssertStop(L::kDebug, fHeadL);
00096                 ZAssertStop(L::kDebug, iL->fPrev);
00097                 ZAssertStop(L::kDebug, iL->fNext);
00098 
00099                 if (iL->fPrev == iL)
00100                         {
00101                         // We have a list with a single element
00102                         ZAssertStop(L::kDebug, iL->fNext == iL);
00103                         ZAssertStop(L::kDebug, fHeadL == iL);
00104                         ZAssertStop(L::kDebug, fSize == 1);
00105                         fHeadL = nil;
00106                         fSize = 0;
00107                         }
00108                 else
00109                         {
00110                         ZAssertStop(L::kDebug, fSize > 1);
00111                         --fSize;
00112                         if (fHeadL == iL)
00113                                 fHeadL = iL->fNext;
00114                         iL->fNext->fPrev = iL->fPrev;
00115                         iL->fPrev->fNext = iL->fNext;
00116                         }
00117                 iL->fNext = nil;
00118                 iL->fPrev = nil;
00119                 }
00120 
00121         void RemoveIfContains(L* iL)
00122                 {
00123                 if (iL->fNext)
00124                         this->Remove(iL);
00125                 }
00126 
00127         void PushFront(L* iL)
00128                 {
00129                 this->Insert(iL);
00130                 fHeadL = iL;
00131                 }
00132 
00133         void PushBack(L* iL)
00134                 {
00135                 this->Insert(iL);
00136                 }
00137 
00138         template <typename P>
00139         P* PopFront()
00140                 {
00141                 ZAssertStop(L::kDebug, fHeadL);
00142                 L* theL = fHeadL;
00143                 this->Remove(theL);
00144                 return static_cast<P*>(theL);
00145                 }
00146 
00147         template <typename P>
00148         P* PopBack()
00149                 {
00150                 ZAssertStop(L::kDebug, fHeadL);
00151                 L* theL = fHeadL->fPrev;
00152                 this->Remove(theL);
00153                 return static_cast<P*>(theL);
00154                 }
00155 
00156         L* fHeadL;
00157         size_t fSize;
00158         };
00159 
00160 // =================================================================================================
00161 #pragma mark -
00162 #pragma mark * DListLink
00163 
00164 template <typename P, typename L, int kDebug_T = 1>
00165 class DListLink
00166         {
00167 public:
00168 //      DListLink(const DListLink&); // not implemented/implementable
00169 //      DListLink& operator=(const DListLink&); // not implemented/implementable
00170 public:
00171         enum { kDebug = kDebug_T };
00172 
00173         DListLink() : fPrev(nil), fNext(nil) {}
00174         ~DListLink() { ZAssertStop(kDebug, !fPrev && !fNext); }
00175         void Clear() { fPrev = nil; fNext = nil; }
00176 
00177         L* fPrev;
00178         L* fNext;
00179         };
00180 
00181 // =================================================================================================
00182 #pragma mark -
00183 #pragma mark * DListIterator
00184 
00185 template <typename P, typename L>
00186 class DListIterator
00187         {
00188     ZOOLIB_DEFINE_OPERATOR_BOOL_TYPES_T(DListIterator, operator_bool_generator_type, operator_bool_type);
00189 public:
00190         enum { kDebug = L::kDebug };
00191 
00192         DListIterator(const ZooLib::DListHead<L>& iDListHead)
00193         :       fDListHead(iDListHead),
00194                 fCurrent(iDListHead.fHeadL)
00195                 {}
00196 
00197         operator operator_bool_type() const
00198                 { return operator_bool_generator_type::translate(fCurrent); }
00199 
00200         P* Current() const
00201                 { return static_cast<P*>(fCurrent); }
00202 
00203         void Advance()
00204                 {
00205                 ZAssertStop(kDebug, fCurrent);
00206                 ZAssertStop(kDebug, fCurrent->fNext);
00207                 fCurrent = fCurrent->fNext;
00208                 if (fCurrent == fDListHead.fHeadL)
00209                         fCurrent = nil;
00210                 }
00211 
00212 private:
00213         const ZooLib::DListHead<L>& fDListHead;
00214         L* fCurrent;
00215         };
00216 
00217 // =================================================================================================
00218 #pragma mark -
00219 #pragma mark * DListIteratorEraseAll
00220 
00221 template <typename P, typename L>
00222 class DListIteratorEraseAll
00223         {
00224     ZOOLIB_DEFINE_OPERATOR_BOOL_TYPES_T(DListIteratorEraseAll, operator_bool_generator_type, operator_bool_type);
00225 public:
00226         enum { kDebug = L::kDebug };
00227 
00228         DListIteratorEraseAll(ZooLib::DListHead<L>& ioDListHead)
00229         :       fDListHead(ioDListHead),
00230                 fCurrent(ioDListHead.fHeadL)
00231                 {
00232                 if (fCurrent)
00233                         {
00234                         ZAssertStop(kDebug, fCurrent->fNext);
00235                         ZAssertStop(kDebug, fCurrent->fPrev);
00236                         fNext = fCurrent->fNext;
00237                         fCurrent->fNext = nil;
00238                         fCurrent->fPrev = nil;
00239                         }
00240                 else
00241                         {
00242                         fNext = nil;
00243                         }
00244                 }
00245 
00246         ~DListIteratorEraseAll()
00247                 {
00248                 fDListHead.fHeadL = nil;
00249                 fDListHead.fSize = 0;
00250                 }
00251 
00252         operator operator_bool_type() const
00253                 {
00254                 ZAssertStop(kDebug, fCurrent && fNext || !fCurrent && !fNext);
00255                 return operator_bool_generator_type::translate(fCurrent);
00256                 }
00257 
00258         P* Current() const
00259                 { return static_cast<P*>(fCurrent); }
00260 
00261         void Advance()
00262                 {
00263                 ZAssertStop(kDebug, fCurrent);
00264                 ZAssertStop(kDebug, fNext);
00265                 if (fNext == fDListHead.fHeadL)
00266                         {
00267                         fCurrent = nil;
00268                         fNext = nil;
00269                         }
00270                 else
00271                         {
00272                         ZAssertStop(kDebug, fNext->fNext);
00273                         fCurrent = fNext;
00274                         fNext = fNext->fNext;
00275                         fCurrent->fNext = nil;
00276                         fCurrent->fPrev = nil;
00277                         }
00278                 }
00279 
00280 private:
00281         ZooLib::DListHead<L>& fDListHead;
00282         L* fCurrent;
00283         L* fNext;
00284         };
00285 
00286 } // namespace ZooLib
00287 
00288 #endif // __ZDList__

Generated on Thu Jul 26 11:21:56 2007 for ZooLib by  doxygen 1.4.7