lemon/refptr.h
changeset 2001 c9e5de6e3eac
child 2151 38ec4a930c05
equal deleted inserted replaced
-1:000000000000 0:5aa253225491
       
     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