|
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 |