reSIProcate/rutil  9694
IntrusiveListElement.hxx
Go to the documentation of this file.
00001 #ifndef RESIP_IntrusiveListElement
00002 #define RESIP_IntrusiveListElement
00003 
00057 namespace resip
00058 {
00059 
00060 template <class P>
00061 class IntrusiveListElement
00062 {
00063    public:
00064       IntrusiveListElement() 
00065          : mNext(0),
00066            mPrev(0)
00067       {}
00068 
00069       virtual ~IntrusiveListElement() 
00070       {
00071          remove();
00072       }
00073 
00074       // make this element an empty list
00075       static P makeList(P elem)
00076       {
00077          assert(!elem->IntrusiveListElement<P>::mNext);
00078 
00079          elem->IntrusiveListElement<P>::mPrev = elem;
00080          elem->IntrusiveListElement<P>::mNext = elem;
00081 
00082          return elem;
00083       }
00084 
00085       bool empty() const
00086       {
00087          assert(mPrev);
00088          assert(mNext);
00089 
00090          return static_cast<const IntrusiveListElement<P>*>(mNext) == static_cast<const IntrusiveListElement<P>*>(this);
00091       }
00092       
00093       // .dlb. add reverse_iterator?
00094 
00095       class iterator
00096       {
00097          public:
00098             explicit iterator(const P start)
00099                : mPos(start)
00100             {}
00101 
00102             iterator& operator=(const iterator& rhs)
00103             {
00104                mPos = rhs.mPos;
00105                return *this;
00106             }
00107 
00108             iterator& operator++()
00109             {
00110                mPos = mPos->IntrusiveListElement<P>::mNext;
00111                return *this;
00112             }
00113 
00114             bool operator==(const iterator& rhs)
00115             {
00116                return mPos == rhs.mPos;
00117             }
00118 
00119             bool operator!=(const iterator& rhs)
00120             {
00121                return mPos != rhs.mPos;
00122             }
00123 
00124             P operator*()
00125             {
00126                return mPos;
00127             }
00128 
00129          private:
00130             P mPos;
00131       };
00132 
00133       iterator begin()
00134       {
00135          assert(mPrev);
00136          assert(mNext);
00137          return iterator(mNext);
00138       }
00139 
00140       iterator end()
00141       {
00142          assert(mPrev);
00143          assert(mNext);
00144          return iterator(static_cast<P>(this));
00145       }
00146 
00147       friend class iterator;
00148 
00149       // pushing an element onto the same list twice is undefined
00150       void push_front(P elem)
00151       {
00152          assert(mPrev);
00153          assert(mNext);
00154 
00155          elem->IntrusiveListElement<P>::mNext = mNext;
00156          elem->IntrusiveListElement<P>::mPrev = static_cast<P>(this);
00157          
00158          elem->IntrusiveListElement<P>::mNext->IntrusiveListElement<P>::mPrev = elem;
00159          elem->IntrusiveListElement<P>::mPrev->IntrusiveListElement<P>::mNext = elem;
00160       }
00161 
00162       // putting an element onto the same list twice is undefined
00163       void push_back(P elem)
00164       {
00165          assert(mPrev);
00166          assert(mNext);
00167 
00168          elem->IntrusiveListElement<P>::mPrev = mPrev;
00169          elem->IntrusiveListElement<P>::mNext = static_cast<P>(this);
00170          
00171          elem->IntrusiveListElement<P>::mPrev->IntrusiveListElement<P>::mNext = elem;
00172          elem->IntrusiveListElement<P>::mNext->IntrusiveListElement<P>::mPrev = elem;
00173       }
00174 
00175       void remove()
00176       {
00177          if (mNext)
00178          {
00179             // prev  -> this -> next
00180             //       <-      <-
00181             //
00182             // prev -> next
00183             //      <-
00184             mNext->IntrusiveListElement<P>::mPrev = mPrev;
00185             mPrev->IntrusiveListElement<P>::mNext = mNext;
00186          }
00187 
00188          mNext = 0;
00189          mPrev = 0;
00190       }
00191 
00192    protected:
00193       mutable P mNext;
00194       mutable P mPrev;
00195 };
00196 
00197 template <class P>
00198 class IntrusiveListElement1
00199 {
00200    public:
00201       IntrusiveListElement1() 
00202          : mNext(0),
00203            mPrev(0)
00204       {}
00205 
00206       virtual ~IntrusiveListElement1() 
00207       {
00208          remove();
00209       }
00210 
00211       // make this element an empty list
00212       static P makeList(P elem)
00213       {
00214          assert(!elem->IntrusiveListElement1<P>::mNext);
00215 
00216          elem->IntrusiveListElement1<P>::mPrev = elem;
00217          elem->IntrusiveListElement1<P>::mNext = elem;
00218 
00219          return elem;
00220       }
00221 
00222       bool empty() const
00223       {
00224          assert(mPrev);
00225          assert(mNext);
00226 
00227          return static_cast<const IntrusiveListElement1<P>*>(mNext) == static_cast<const IntrusiveListElement1<P>*>(this);
00228       }
00229 
00230       // .dlb. add reverse_iterator?
00231 
00232       class iterator
00233       {
00234          public:
00235             explicit iterator(const P start)
00236                : mPos(start)
00237             {}
00238 
00239             iterator& operator=(const iterator& rhs)
00240             {
00241                mPos = rhs.mPos;
00242                return *this;
00243             }
00244 
00245             iterator& operator++()
00246             {
00247                mPos = mPos->IntrusiveListElement1<P>::mNext;
00248                return *this;
00249             }
00250 
00251             bool operator==(const iterator& rhs)
00252             {
00253                return mPos == rhs.mPos;
00254             }
00255 
00256             bool operator!=(const iterator& rhs)
00257             {
00258                return mPos != rhs.mPos;
00259             }
00260 
00261             P operator*()
00262             {
00263                return mPos;
00264             }
00265 
00266          private:
00267             P mPos;
00268       };
00269 
00270       iterator begin()
00271       {
00272          assert(mPrev);
00273          assert(mNext);
00274          return iterator(mNext);
00275       }
00276 
00277       iterator end()
00278       {
00279          assert(mPrev);
00280          assert(mNext);
00281          return iterator(static_cast<P>(this));
00282       }
00283 
00284       friend class iterator;
00285 
00286       // pushing an element onto the same list twice is undefined
00287       void push_front(P elem)
00288       {
00289          assert(mPrev);
00290          assert(mNext);
00291 
00292          elem->IntrusiveListElement1<P>::mNext = mNext;
00293          elem->IntrusiveListElement1<P>::mPrev = static_cast<P>(this);
00294          
00295          elem->IntrusiveListElement1<P>::mNext->IntrusiveListElement1<P>::mPrev = elem;
00296          elem->IntrusiveListElement1<P>::mPrev->IntrusiveListElement1<P>::mNext = elem;
00297       }
00298 
00299       // putting an element onto the same list twice is undefined
00300       void push_back(P elem)
00301       {
00302          assert(mPrev);
00303          assert(mNext);
00304 
00305          elem->IntrusiveListElement1<P>::mPrev = mPrev;
00306          elem->IntrusiveListElement1<P>::mNext = static_cast<P>(this);
00307          
00308          elem->IntrusiveListElement1<P>::mPrev->IntrusiveListElement1<P>::mNext = elem;
00309          elem->IntrusiveListElement1<P>::mNext->IntrusiveListElement1<P>::mPrev = elem;
00310       }
00311 
00312       void remove()
00313       {
00314          if (mNext)
00315          {
00316             // prev  -> this -> next
00317             //       <-      <-
00318             //
00319             // prev -> next
00320             //      <-
00321             mNext->IntrusiveListElement1<P>::mPrev = mPrev;
00322             mPrev->IntrusiveListElement1<P>::mNext = mNext;
00323          }
00324 
00325          mNext = 0;
00326          mPrev = 0;
00327       }
00328 
00329    protected:
00330       mutable P mNext;
00331       mutable P mPrev;
00332 };
00333 
00334 template <class P>
00335 class IntrusiveListElement2
00336 {
00337    public:
00338       IntrusiveListElement2() 
00339          : mNext(0),
00340            mPrev(0)
00341       {}
00342 
00343       virtual ~IntrusiveListElement2() 
00344       {
00345          remove();
00346       }
00347 
00348       // make this element an empty list
00349       static P makeList(P elem)
00350       {
00351          assert(!elem->IntrusiveListElement2<P>::mNext);
00352 
00353          elem->IntrusiveListElement2<P>::mPrev = elem;
00354          elem->IntrusiveListElement2<P>::mNext = elem;
00355 
00356          return elem;
00357       }
00358 
00359       bool empty() const
00360       {
00361          assert(mPrev);
00362          assert(mNext);
00363 
00364          return static_cast<const IntrusiveListElement2<P>*>(mNext) == static_cast<const IntrusiveListElement2<P>*>(this);
00365       }
00366 
00367       // .dlb. add reverse_iterator?
00368 
00369       class iterator
00370       {
00371          public:
00372             explicit iterator(const P start)
00373                : mPos(start)
00374             {}
00375 
00376             iterator& operator=(const iterator& rhs)
00377             {
00378                mPos = rhs.mPos;
00379                return *this;
00380             }
00381 
00382             iterator& operator++()
00383             {
00384                mPos = mPos->IntrusiveListElement2<P>::mNext;
00385                return *this;
00386             }
00387 
00388             bool operator==(const iterator& rhs)
00389             {
00390                return mPos == rhs.mPos;
00391             }
00392 
00393             bool operator!=(const iterator& rhs)
00394             {
00395                return mPos != rhs.mPos;
00396             }
00397 
00398             P operator*()
00399             {
00400                return mPos;
00401             }
00402 
00403          private:
00404             P mPos;
00405       };
00406 
00407       iterator begin()
00408       {
00409          assert(mPrev);
00410          assert(mNext);
00411          return iterator(mNext);
00412       }
00413 
00414       iterator end()
00415       {
00416          assert(mPrev);
00417          assert(mNext);
00418          return iterator(static_cast<P>(this));
00419       }
00420 
00421       friend class iterator;
00422 
00423       // pushing an element onto the same list twice is undefined
00424       void push_front(P elem)
00425       {
00426          assert(mPrev);
00427          assert(mNext);
00428 
00429          elem->IntrusiveListElement2<P>::mNext = mNext;
00430          elem->IntrusiveListElement2<P>::mPrev = static_cast<P>(this);
00431          
00432          elem->IntrusiveListElement2<P>::mNext->IntrusiveListElement2<P>::mPrev = elem;
00433          elem->IntrusiveListElement2<P>::mPrev->IntrusiveListElement2<P>::mNext = elem;
00434       }
00435 
00436       // putting an element onto the same list twice is undefined
00437       void push_back(P elem)
00438       {
00439          assert(mPrev);
00440          assert(mNext);
00441 
00442          elem->IntrusiveListElement2<P>::mPrev = mPrev;
00443          elem->IntrusiveListElement2<P>::mNext = static_cast<P>(this);
00444          
00445          elem->IntrusiveListElement2<P>::mPrev->IntrusiveListElement2<P>::mNext = elem;
00446          elem->IntrusiveListElement2<P>::mNext->IntrusiveListElement2<P>::mPrev = elem;
00447       }
00448 
00449       void remove()
00450       {
00451          if (mNext)
00452          {
00453             // prev  -> this -> next
00454             //       <-      <-
00455             //
00456             // prev -> next
00457             //      <-
00458             mNext->IntrusiveListElement2<P>::mPrev = mPrev;
00459             mPrev->IntrusiveListElement2<P>::mNext = mNext;
00460          }
00461 
00462          mNext = 0;
00463          mPrev = 0;
00464       }
00465 
00466    protected:
00467       mutable P mNext;
00468       mutable P mPrev;
00469 };
00470 
00471 template <class P>
00472 class IntrusiveListElement3
00473 {
00474    public:
00475       IntrusiveListElement3() 
00476          : mNext(0),
00477            mPrev(0)
00478       {}
00479 
00480       virtual ~IntrusiveListElement3() 
00481       {
00482          remove();
00483       }
00484 
00485       // make this element an empty list
00486       static P makeList(P elem)
00487       {
00488          assert(!elem->IntrusiveListElement3<P>::mNext);
00489 
00490          elem->IntrusiveListElement3<P>::mPrev = elem;
00491          elem->IntrusiveListElement3<P>::mNext = elem;
00492 
00493          return elem;
00494       }
00495 
00496       bool empty() const
00497       {
00498          assert(mPrev);
00499          assert(mNext);
00500 
00501          return static_cast<const IntrusiveListElement3<P>*>(mNext) == static_cast<const IntrusiveListElement3<P>*>(this);
00502       }
00503 
00504       // .dlb. add reverse_iterator?
00505 
00506       class iterator
00507       {
00508          public:
00509             explicit iterator(const P start)
00510                : mPos(start)
00511             {}
00512 
00513             iterator& operator=(const iterator& rhs)
00514             {
00515                mPos = rhs.mPos;
00516                return *this;
00517             }
00518 
00519             iterator& operator++()
00520             {
00521                mPos = mPos->IntrusiveListElement3<P>::mNext;
00522                return *this;
00523             }
00524 
00525             bool operator==(const iterator& rhs)
00526             {
00527                return mPos == rhs.mPos;
00528             }
00529 
00530             bool operator!=(const iterator& rhs)
00531             {
00532                return mPos != rhs.mPos;
00533             }
00534 
00535             P operator*()
00536             {
00537                return mPos;
00538             }
00539 
00540          private:
00541             P mPos;
00542       };
00543 
00544       iterator begin()
00545       {
00546          assert(mPrev);
00547          assert(mNext);
00548          return iterator(mNext);
00549       }
00550 
00551       iterator end()
00552       {
00553          assert(mPrev);
00554          assert(mNext);
00555          return iterator(static_cast<P>(this));
00556       }
00557 
00558       friend class iterator;
00559 
00560       // pushing an element onto the same list twice is undefined
00561       void push_front(P elem)
00562       {
00563          assert(mPrev);
00564          assert(mNext);
00565 
00566          elem->IntrusiveListElement3<P>::mNext = mNext;
00567          elem->IntrusiveListElement3<P>::mPrev = static_cast<P>(this);
00568          
00569          elem->IntrusiveListElement3<P>::mNext->IntrusiveListElement3<P>::mPrev = elem;
00570          elem->IntrusiveListElement3<P>::mPrev->IntrusiveListElement3<P>::mNext = elem;
00571       }
00572 
00573       // putting an element onto the same list twice is undefined
00574       void push_back(P elem)
00575       {
00576          assert(mPrev);
00577          assert(mNext);
00578 
00579          elem->IntrusiveListElement3<P>::mPrev = mPrev;
00580          elem->IntrusiveListElement3<P>::mNext = static_cast<P>(this);
00581          
00582          elem->IntrusiveListElement3<P>::mPrev->IntrusiveListElement3<P>::mNext = elem;
00583          elem->IntrusiveListElement3<P>::mNext->IntrusiveListElement3<P>::mPrev = elem;
00584       }
00585 
00586       void remove()
00587       {
00588          if (mNext)
00589          {
00590             // prev  -> this -> next
00591             //       <-      <-
00592             //
00593             // prev -> next
00594             //      <-
00595             mNext->IntrusiveListElement3<P>::mPrev = mPrev;
00596             mPrev->IntrusiveListElement3<P>::mNext = mNext;
00597          }
00598 
00599          mNext = 0;
00600          mPrev = 0;
00601       }
00602 
00603    protected:
00604       mutable P mNext;
00605       mutable P mPrev;
00606 };
00607 
00608 }
00609 
00610 #endif
00611 
00612 
00613 /* ====================================================================
00614  * The Vovida Software License, Version 1.0 
00615  * 
00616  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
00617  * 
00618  * Redistribution and use in source and binary forms, with or without
00619  * modification, are permitted provided that the following conditions
00620  * are met:
00621  * 
00622  * 1. Redistributions of source code must retain the above copyright
00623  *    notice, this list of conditions and the following disclaimer.
00624  * 
00625  * 2. Redistributions in binary form must reproduce the above copyright
00626  *    notice, this list of conditions and the following disclaimer in
00627  *    the documentation and/or other materials provided with the
00628  *    distribution.
00629  * 
00630  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00631  *    and "Vovida Open Communication Application Library (VOCAL)" must
00632  *    not be used to endorse or promote products derived from this
00633  *    software without prior written permission. For written
00634  *    permission, please contact vocal@vovida.org.
00635  *
00636  * 4. Products derived from this software may not be called "VOCAL", nor
00637  *    may "VOCAL" appear in their name, without prior written
00638  *    permission of Vovida Networks, Inc.
00639  * 
00640  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00641  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00642  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00643  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00644  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00645  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00646  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00647  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00648  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00649  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00650  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00651  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00652  * DAMAGE.
00653  * 
00654  * ====================================================================
00655  * 
00656  * This software consists of voluntary contributions made by Vovida
00657  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00658  * Inc.  For more information on Vovida Networks, Inc., please see
00659  * <http://www.vovida.org/>.
00660  *
00661  */