lemon/refptr.h
author deba
Fri, 03 Nov 2006 15:21:52 +0000
changeset 2292 38d985e82205
parent 1977 8ef02f0c4245
child 2391 14a343be7a5a
permissions -rw-r--r--
General mapping based variant type
     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       if(r.ref) {
    49 	prev=&r; next=r.next; ref=r.ref;
    50 	r.next=this;
    51       }
    52     }
    53     void attach(const T *p) 
    54     {
    55       prev=0; next=0; ref=p;
    56     }
    57     void release() 
    58     {
    59       if(ref) {
    60 	bool fr=true;
    61 	if(prev) { fr=false; prev->next=next; }
    62 	if(next) { fr=false; next->prev=prev; }
    63 	if(fr) delete ref;
    64 	ref=0;
    65       }
    66     }
    67   
    68   public:
    69     ///\e
    70     RefPtr() : ref(0) {}
    71 
    72     ///\e
    73     RefPtr(const RefPtr &r) {
    74       lock();
    75       attach(const_cast<RefPtr&>(r));
    76       unlock();
    77     }
    78 
    79     ///\e
    80     RefPtr(T *p) : prev(0), next(0), ref(p) {}
    81 
    82     ///\e
    83     ~RefPtr() {
    84       lock();
    85       release();
    86       unlock();
    87     }
    88 
    89     ///\e
    90     const RefPtr &operator=(const RefPtr &r) { 
    91       if(ref!=r.ref) {
    92 	lock();
    93 	release(); attach(const_cast<RefPtr&>(r));
    94 	unlock();
    95       }
    96       return *this;
    97     }
    98   
    99     ///\e
   100     const RefPtr &operator=(const T* &p) { 
   101       if(ref!=p) { lock(); release(); attach(p); unlock(); }
   102       return *this;
   103     }
   104   
   105     ///\e
   106     void swap(RefPtr &r) {
   107       RefPtr *p;
   108       T *tp;
   109       lock();
   110       p=prev; prev=r.prev; r.prev=p;
   111       p=next; next=r.next; r.next=p;
   112       tp=ref; ref=r.ref; r.ref=tp;
   113       unlock();
   114     }
   115 
   116     ///\e
   117     void clear() { lock(); release(); unlock(); }
   118 
   119     ///\e
   120     T * operator->() { return ref; }
   121     ///\e
   122     const T * operator->() const { return ref; }
   123     ///\e
   124     operator T *() { return ref; }
   125     ///\e
   126     operator const T *() const { return ref; }
   127     
   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     ///\e
   139     bool operator!=(const RefPtr &r) const { return this->ref != r.ref; }
   140     
   141     ///\e
   142     operator bool() const { return ref; }
   143 
   144     ///\e
   145     const RefPtr &borrow(const T* &p) { 
   146       lock();
   147       if(ref==p) {
   148 	if(prev) prev->next=next;
   149 	if(next) next->prev=prev;
   150       }
   151       else release();
   152       ref=p;
   153       next=prev=this;
   154       unlock();
   155       return *this;
   156     }
   157     
   158     ///\e
   159     const RefPtr &borrow() { 
   160       lock();
   161       if(prev) prev->next=next;
   162       if(next) next->prev=prev;
   163       next=prev=this;
   164       unlock();
   165       return *this;
   166     }
   167     
   168   };  //END OF CLASS REFPTR
   169   
   170 } //END OF NAMESPACE LEMON
   171 
   172 #endif