lemon/refptr.h
author deba
Mon, 15 May 2006 16:21:50 +0000
changeset 2085 1970a93dfaa8
child 2151 38ec4a930c05
permissions -rw-r--r--
Bug fix by Jano
     1 /* -*- C++ -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2003-2006
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     9  * Permission to use, modify and distribute this software is granted
    10  * provided that this copyright notice appears in all copies. For
    11  * precise terms see the accompanying LICENSE file.
    12  *
    13  * This software is provided "AS IS" with no warranty of any kind,
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    16  *
    17  */
    18 
    19 #ifndef LEMON_REFPTR_H
    20 #define LEMON_REFPTR_H
    21 
    22 ///\ingroup misc
    23 ///\file
    24 ///\brief A reference counted pointer implementation.
    25 ///
    26 ///\todo Undocumented
    27 
    28 
    29 namespace lemon {
    30 
    31   
    32   ///Reference counted pointer
    33 
    34   ///This is a simple implementation of a reference counted pointer.
    35   ///
    36   ///\warning Current implementation is far from being thread-safe.
    37   template<class T>
    38   class RefPtr 
    39   {
    40     mutable RefPtr *prev, *next;
    41     T *ref;
    42 
    43     void lock() {}
    44     void unlock() {}
    45     
    46     void attach(RefPtr &r) 
    47     {
    48       prev=&r; next=r.next; ref=r.ref;
    49       r.next=this;
    50     }
    51     void attach(const T *p) 
    52     {
    53       prev=0; next=0; ref=p;
    54     }
    55     void release() 
    56     {
    57       if(ref) {
    58 	bool fr=true;
    59 	if(prev) { fr=false; prev->next=next; }
    60 	if(next) { fr=false; next->prev=prev; }
    61 	if(fr) delete ref;
    62 	ref=0;
    63       }
    64     }
    65   
    66   public:
    67     ///\e
    68     RefPtr() : ref(0) {}
    69 
    70     ///\e
    71     RefPtr(const RefPtr &r) {
    72       lock();
    73       attach(const_cast<RefPtr&>(r));
    74       unlock();
    75     }
    76 
    77     ///\e
    78     RefPtr(T *p) : prev(0), next(0), ref(p) {}
    79 
    80     ///\e
    81     ~RefPtr() {
    82       lock();
    83       release();
    84       unlock();
    85     }
    86 
    87     ///\e
    88     const RefPtr &operator=(const RefPtr &r) { 
    89       if(ref!=r.ref) {
    90 	lock();
    91 	release(); attach(const_cast<RefPtr&>(r));
    92 	unlock();
    93       }
    94       return *this;
    95     }
    96   
    97     ///\e
    98     const RefPtr &operator=(const T* &p) { 
    99       if(ref!=p) { lock(); release(); attach(p); unlock(); }
   100       return *this;
   101     }
   102   
   103     ///\e
   104     void swap(RefPtr &r) {
   105       RefPtr *p;
   106       T *tp;
   107       lock();
   108       p=prev; prev=r.prev; r.prev=p;
   109       p=next; next=r.next; r.next=p;
   110       tp=ref; ref=r.ref; r.ref=tp;
   111       unlock();
   112     }
   113 
   114     ///\e
   115     void clear() { lock(); release(); unlock(); }
   116 
   117     ///\e
   118     T * operator->() { return ref; }
   119     ///\e
   120     const T * operator->() const { return ref; }
   121     ///\e
   122     operator T *() { return ref; }
   123     ///\e
   124     operator const T *() const { return ref; }
   125     
   126     ///\e
   127     bool operator<(const RefPtr &r) const { return this->ref < r.ref; }
   128     ///\e
   129     bool operator<=(const RefPtr &r) const { return this->ref <= r.ref; }
   130     ///\e
   131     bool operator==(const RefPtr &r) const { return this->ref == r.ref; }
   132     ///\e
   133     bool operator>=(const RefPtr &r) const { return this->ref >= r.ref; }
   134     ///\e
   135     bool operator>(const RefPtr &r) const { return this->ref > r.ref; }
   136     ///\e
   137     bool operator!=(const RefPtr &r) const { return this->ref != r.ref; }
   138     
   139     ///\e
   140     operator bool() const { return ref; }
   141 
   142   };  //END OF CLASS REFPTR
   143   
   144 } //END OF NAMESPACE LEMON
   145 
   146 #endif