MINT2
counted_ptr.h
Go to the documentation of this file.
1 // author: Jonas Rademacker (Jonas.Rademacker@bristol.ac.uk)
2 // status: Mon 9 Feb 2009 19:17:56 GMT
3 /*
4  * counted_ptr - simple reference counted pointer.
5  *
6  * The is a non-intrusive implementation that allocates an additional
7  * int and pointer for every counted object.
8  */
9 
10 /* Got this originally from:
11  http://ootips.org/yonat/4dev/counted_ptr.h
12 
13  applied a few changes ('signed' with //jr)
14  o removed friend that's specialisation of the own class (with Y)
15  o added conversion to bool (well, to void*, apparently that's safer)
16  o conversions between counted_ptr<classX> and counted_ptr<classY> should work like those between normal pointers.
17  Jonas.
18 */
19 
20 #ifndef COUNTED_PTR_H
21 #define COUNTED_PTR_H
22 
23 /* For ANSI-challenged compilers, you may want to #define
24  * NO_MEMBER_TEMPLATES or explicit */
25 
26 //#define NO_MEMBER_TEMPLATES
27 
28 //#include <iostream>
29 
30 namespace MINT{
31 
33  public:
34  counted_ptr_counter(unsigned c = 1) : count(c) {}
35  unsigned count;
36 };
37 
38 
39 template <typename X> class counted_ptr
40 {
41 
42  public: // many of these should be protected, but doesn't work.
43  X* ptr;
45 
46  bool ok() const{
47  return (0 != itsCounter) && (0 != ptr);
48  }
49 
50  void acquire(const counted_ptr<X>& other) throw()
51  { // increment the count
52  // std::cout << "acquiring" << std::endl;
53  itsCounter = other.itsCounter;
54  ptr = other.ptr;
55  if (ok()) ++(itsCounter->count);
56  }
57 
58  template<typename Y>
59  void acquire(const counted_ptr<Y>& other) throw()
60  { // increment the count
61  // std::cout << "acquiring different type" << std::endl;
62  itsCounter = other.itsCounter;
63  ptr = (X*) (other.ptr);
64  if (ok()) ++(itsCounter->count);
65  }
66 
67  void release()
68  { // decrement the count, delete if it is 0
69  // std::cout << "releasing" << std::endl;
70  if (ok()) {
71  if (--(itsCounter->count) == 0) {
72  delete ptr;
73  delete itsCounter;
74  }
75  ptr=0;
76  itsCounter = 0;
77  }
78  }
79 
80  counted_ptr(X* p = 0) // allocate a new counter
81  : ptr(p)
82  , itsCounter(0){
83  if (0 != p){
85  ptr = p;
86  }
87  }
89  {release();}
90  counted_ptr(const counted_ptr& r) throw()
91  {
92  // std::cout << "copy-constructing" << std::endl;
93  acquire(r);
94  }
96  {
97  // std::cout << "copy- = " << std::endl;
98  if (this != &r) {
99  release();
100  acquire(r);
101  }
102  return *this;
103  }
104 
105 #ifndef NO_MEMBER_TEMPLATES
106  //template <class Y> friend class counted_ptr<Y>; // jr
107  template <typename Y> counted_ptr(const counted_ptr<Y>& r) throw()
108  {
109  // std::cout << "copy-constructing other" << std::endl;
110  acquire(r);
111  }
112  template <typename Y> counted_ptr& operator=(const counted_ptr<Y>& r)
113  {
114  if ((const void*)this != (const void*) (&r)) {
115  release();
116  // std::cout << "copy = other" << std::endl;
117  acquire(r);
118  }
119  return *this;
120  }
121 #endif // NO_MEMBER_TEMPLATES
122 
123  X* get()const throw(){return (this->ok() ? ptr : 0);}
124  X& operator*() const throw(){return *(get());}
125  X* operator->() const throw(){return get();}
126  bool unique() const throw()
127  {return (itsCounter ? itsCounter->count == 1 : true);}
128 
129 
130  operator const void*() const{ // jr
131  return (const void*) get();
132  }
133 
134 
135 
136  // operator bool() const{ // jr
137  // return 0 != get();
138  // }
139 
140 
141  /* wise? not sure.
142  operator X*() const{ // jr
143  return (X*) get();
144  }
145  */
146 
147 
148 };
149 
150 template <typename X> class const_counted_ptr : public counted_ptr<X>{
151  public:
152  bool ok() const{
153  return counted_ptr<X>::ok();
154  }
155  void acquire(const counted_ptr<X>& c) throw(){
157 
158  template<typename Y>
159  void acquire(const counted_ptr<Y>& other) throw(){
160  counted_ptr<X>::acquire(other);}
161 
162  void release(){
164 
165  explicit const_counted_ptr(X* p = 0) // allocate a new counter
166  : counted_ptr<X>(p){};
168  {release();}
169  const_counted_ptr(const const_counted_ptr& other) throw()
170  :counted_ptr<X>(other)
171  {}
172  const_counted_ptr(const counted_ptr<X>& other) throw()
173  :counted_ptr<X>(other)
174  {}
176  {
177  if (this != &r) {
178  release();
179  acquire(r);
180  }
181  return *this;
182  }
184  {
185  if (this != &r) {
186  release();
187  acquire(r);
188  }
189  return *this;
190  }
191 
192  template <typename Y> const_counted_ptr(const const_counted_ptr<Y>& r) throw()
193  {
194  acquire(r);
195  }
196  template <typename Y> const_counted_ptr(const counted_ptr<Y>& r) throw()
197  {
198  acquire(r);
199  }
200  template <typename Y> const_counted_ptr& operator=(const const_counted_ptr<Y>& r)
201  {
202  if (this != &r) {
203  release();
204  acquire(r);
205  }
206  return *this;
207  }
208  template <class Y> const_counted_ptr& operator=(const counted_ptr<Y>& r)
209  {
210  if (this != &r) {
211  release();
212  acquire(r);
213  }
214  return *this;
215  }
216 
217  const X* get() const throw(){return (this->ok() ? static_cast<const X*>(this->ptr) : 0);}
218 
219  const X& operator*() const throw(){return *(static_cast<const X*>(get()));}
220  const X* operator->() const throw(){return static_cast<const X*>(get());}
221 
222 };
223 
224 }// namespace MINT
225 
226 #endif // COUNTED_PTR_H
counted_ptr(X *p=0)
Definition: counted_ptr.h:80
const_counted_ptr(const const_counted_ptr< Y > &r)
Definition: counted_ptr.h:192
const X * get() const
Definition: counted_ptr.h:217
void acquire(const counted_ptr< X > &c)
Definition: counted_ptr.h:155
const X & operator *() const
Definition: counted_ptr.h:219
const X * operator->() const
Definition: counted_ptr.h:220
counted_ptr & operator=(const counted_ptr< Y > &r)
Definition: counted_ptr.h:112
counted_ptr & operator=(const counted_ptr &r)
Definition: counted_ptr.h:95
X & operator *() const
Definition: counted_ptr.h:124
const_counted_ptr & operator=(const const_counted_ptr< Y > &r)
Definition: counted_ptr.h:200
const_counted_ptr(const counted_ptr< X > &other)
Definition: counted_ptr.h:172
const_counted_ptr(const const_counted_ptr &other)
Definition: counted_ptr.h:169
bool ok() const
Definition: counted_ptr.h:46
const_counted_ptr & operator=(const counted_ptr< Y > &r)
Definition: counted_ptr.h:208
const_counted_ptr & operator=(const counted_ptr< X > &r)
Definition: counted_ptr.h:183
void acquire(const counted_ptr< X > &other)
Definition: counted_ptr.h:50
const_counted_ptr(const counted_ptr< Y > &r)
Definition: counted_ptr.h:196
void acquire(const counted_ptr< Y > &other)
Definition: counted_ptr.h:59
counted_ptr(const counted_ptr &r)
Definition: counted_ptr.h:90
counted_ptr(const counted_ptr< Y > &r)
Definition: counted_ptr.h:107
counted_ptr_counter(unsigned c=1)
Definition: counted_ptr.h:34
X * operator->() const
Definition: counted_ptr.h:125
const_counted_ptr & operator=(const const_counted_ptr &r)
Definition: counted_ptr.h:175
bool unique() const
Definition: counted_ptr.h:126
void acquire(const counted_ptr< Y > &other)
Definition: counted_ptr.h:159
X * get() const
Definition: counted_ptr.h:123
counted_ptr_counter * itsCounter
Definition: counted_ptr.h:44