COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/refptr.h @ 2229:4dbb6dd2dd4b

Last change on this file since 2229:4dbb6dd2dd4b was 2151:38ec4a930c05, checked in by Alpar Juttner, 13 years ago

exceptionName() has been thrown away

File size: 3.5 KB
Line 
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
29namespace 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
Note: See TracBrowser for help on using the repository browser.