halapi
hierarchichalalignmentformatapi
 All Classes Namespaces Functions Pages
cpnew.h
1 /*
2  * Copyright (C) 2012 by Glenn Hickey (hickey@soe.ucsc.edu)
3  *
4  * Released under the MIT license, see LICENSE.txt
5  */
6 
7 
22 /*
23  * counted_ptr - simple reference counted pointer.
24  *
25  * The is a non-intrusive implementation that allocates an additional
26  * int and pointer for every counted object.
27  */
28 
29 #ifndef COUNTED_PTR_H
30 #define COUNTED_PTR_H
31 
32 namespace hal {
33 
34 template <typename T>
36 {
37  typedef T type;
38 };
39 template <typename T>
40 struct counted_ptr_remove_const<const T>
41 {
42  typedef T type;
43 };
44 
45 template<typename X>
46 struct ptr_counter {
47  ptr_counter(X* p = 0, unsigned c = 1) : ptr(p), count(c) {}
48  X* ptr;
49  unsigned count;
50 };
51 
52 template<typename X>
53 struct ptr_counter<const X> {
54  ptr_counter(const X* p = 0, unsigned c = 1) : ptr(p), count(c) {}
55  const X* ptr;
56  unsigned count;
57 
58  ptr_counter& operator=(const ptr_counter<typename counted_ptr_remove_const<X>::type>& other) {
59  ptr = other.ptr;
60  count = other.count;
61  }
62 };
63 
64 template <class X> class counted_ptr
65 {
66 public:
67  //friend class counted_ptr<const X>;
68  template <typename XX> friend class counted_ptr;
69 
70  typedef X element_type;
71  typedef ptr_counter<X> counter;
72 
73  explicit counted_ptr(X* p = 0) // allocate a new counter
74  : itsCounter(0) {
75  if (p) itsCounter = new counter(p);
76  }
77 
78  ~counted_ptr() {
79  release();
80  }
81 /*
82  counted_ptr(const counted_ptr& r) throw() {
83  acquire(r.itsCounter);
84  }
85 
86  counted_ptr& operator=(const counted_ptr& r) {
87  if (this != &r) {
88  release();
89  acquire(r.itsCounter);
90  }
91  return *this;
92  }
93 */
94  template <class Y>
95  counted_ptr(const counted_ptr<Y>& r) throw() {
96  acquire<Y>(r.itsCounter);
97  }
98 
99  template <class Y>
100  counted_ptr& operator=(const counted_ptr<Y>& r) {
101  if (const_cast<const counted_ptr<X>*>(this) ==
102  reinterpret_cast<const counted_ptr<X>*>(
103  const_cast<const counted_ptr<Y>*>(&r)))
104  {
105  release();
106  acquire<Y>(r.itsCounter);
107  }
108  return *this;
109  }
110 
111  X& operator*() const throw() {return *itsCounter->ptr;}
112  X* operator->() const throw() {return itsCounter->ptr;}
113  X* get() const throw() {return itsCounter ? itsCounter->ptr : 0;}
114  bool unique() const throw() {
115  return (itsCounter ? itsCounter->count == 1 : true);
116  }
117 
118 private:
119 
120  counter* itsCounter;
121 /*
122  void acquire(counter* c) throw() {
123  itsCounter = c;
124  if (c) ++c->count;
125  }
126 */
127  template <typename Y>
128  void acquire(ptr_counter<Y>* c) throw() {
129  if (c) {
130  (void)static_cast<X*>(c->ptr);
131  itsCounter = reinterpret_cast<counter*>(c);
132  ++c->count;
133  }
134  else {
135  c = NULL;
136  }
137  }
138 
139  void release() {
140  if (itsCounter) {
141  if (--itsCounter->count == 0) {
142  delete itsCounter->ptr;
143  delete itsCounter;
144  }
145  itsCounter = 0;
146  }
147  }
148 };
149 
150 /*
151 template <class X> class counted_ptr<const X>
152 {
153 public:
154  typedef const X element_type;
155  typedef ptr_counter<const X> counter;
156  friend class counted_ptr<typename counted_ptr_remove_const<X>::type>;
157  template <typename XX> friend class counted_ptr;
158 
159  explicit counted_ptr(const X* p = 0) // allocate a new counter
160  : itsCounter(0) {
161  if (p) itsCounter = new counter(p);
162  }
163 
164  ~counted_ptr() {
165  release();
166  }
167 
168  counted_ptr(const counted_ptr<const X>& r) throw() {
169  acquire(r.itsCounter);
170  }
171 
172  counted_ptr& operator=(const counted_ptr<const X>& r) {
173  if (this != &r) {
174  release();
175  acquire(r.itsCounter);
176  }
177  return *this;
178  }
179 
180  counted_ptr(const counted_ptr<typename counted_ptr_remove_const<X>::type>& r)
181  throw() {
182  acquire(r.itsCounter);
183  }
184 
185  counted_ptr& operator=(const counted_ptr<typename counted_ptr_remove_const<X>::type>& r) {
186  if (this != &r) {
187  release();
188  acquire(r.itsCounter);
189  }
190  return *this;
191  }
192 
193  template <class Y>
194  counted_ptr(const counted_ptr<Y>& r) throw() {
195  acquire<Y>(r.itsCounter);
196  }
197 
198  template <class Y>
199  counted_ptr& operator=(const counted_ptr& r) {
200  if (this != &r) {
201  release();
202  acquire<Y>(r.itsCounter);
203  }
204  return *this;
205  }
206 
207  template <class Y>
208  counted_ptr(const counted_ptr<typename counted_ptr_remove_const<Y>::type>& r)
209  throw() {
210  acquire<Y>(r.itsCounter);
211  }
212 
213  template <class Y>
214  counted_ptr& operator=(const counted_ptr<typename counted_ptr_remove_const<Y>::type>& r) {
215  if (this != &r) {
216  release();
217  acquire<Y>(r.itsCounter);
218  }
219  return *this;
220  }
221 
222  const X& operator*() const throw() {return *itsCounter->ptr;}
223  const X* operator->() const throw() {return itsCounter->ptr;}
224  const X* get() const throw() {return itsCounter ? itsCounter->ptr : 0;}
225  bool unique() const throw() {
226  return (itsCounter ? itsCounter->count == 1 : true);
227  }
228 
229 private:
230 
231  counter* itsCounter;
232 
233  void acquire(counter* c) throw() {
234  itsCounter = c;
235  if (c) ++c->count;
236  }
237 
238  void acquire(ptr_counter<typename counted_ptr_remove_const<X>::type>* c)
239  throw() {
240  itsCounter = (ptr_counter<const X>*)c;
241  if (c) ++c->count;
242  }
243 
244  template <typename Y>
245  void acquire(ptr_counter<Y>* c) throw() {
246  if (c) {
247  (void)static_cast<const X*>(c->ptr);
248  itsCounter = reinterpret_cast<counter*>(c);
249  ++c->count;
250  }
251  else {
252  c = NULL;
253  }
254  }
255 
256  template <typename Y>
257  void acquire(ptr_counter<typename counted_ptr_remove_const<Y>::type>* c)
258  throw() {
259  if (c) {
260  (void)static_cast<X*>(c->ptr);
261  itsCounter = reinterpret_cast<counter*>(c);
262  ++c->count;
263  }
264  else {
265  c = NULL;
266  }
267  }
268 
269  void release() {
270  if (itsCounter) {
271  if (--itsCounter->count == 0) {
272  delete itsCounter->ptr;
273  delete itsCounter;
274  }
275  itsCounter = 0;
276  }
277  }
278  };*/
279 }
280 #endif // COUNTED_PTR_H