]> Dogcows Code - chaz/yoink/blob - src/moof/stlplus/smart_ptr.hpp
fixes for newer versions of g++
[chaz/yoink] / src / moof / stlplus / smart_ptr.hpp
1 #ifndef STLPLUS_SMART_PTR
2 #define STLPLUS_SMART_PTR
3 ////////////////////////////////////////////////////////////////////////////////
4
5 // Author: Andy Rushton
6 // Copyright: (c) Southampton University 1999-2004
7 // (c) Andy Rushton 2004-2009
8 // License: BSD License, see ../docs/license.html
9
10 // A smart pointer is a memory-managing pointer to an object. If you like, it
11 // is a zero-dimensional container.
12
13 // Assignment of smart pointers result in multiple aliases of the same object.
14 // The term alias is used to differentiate from conventional pointers because
15 // the semantics are different.
16
17 // Aliases can be turned into copies if the pointed-to class supports copying.
18
19 // The base class is smart_ptr_base which defines the common interface. Then
20 // there are three subclasses which have the same interface but different copy
21 // semantics:
22
23 // - smart_ptr for simple types and classes which have copy constructors
24 // - smart_ptr_clone for polymorphic class hierarchies which are copied using a clone method
25 // - smart_ptr_nocopy for any class that cannot or should not be copied
26
27 ////////////////////////////////////////////////////////////////////////////////
28 #include "containers_fixes.hpp"
29 #include "exceptions.hpp"
30 #include <map>
31 #include <string>
32
33 namespace stlplus
34 {
35
36 ////////////////////////////////////////////////////////////////////////////////
37 // internals
38
39 template<typename T> class smart_ptr_holder;
40
41 ////////////////////////////////////////////////////////////////////////////////
42 // Base class
43 ////////////////////////////////////////////////////////////////////////////////
44
45 template<typename T, typename C>
46 class smart_ptr_base
47 {
48 public:
49 //////////////////////////////////////////////////////////////////////////////
50 // member type definitions
51
52 typedef T value_type;
53 typedef T& reference;
54 typedef const T& const_reference;
55 typedef C value_copy;
56
57 //////////////////////////////////////////////////////////////////////////////
58 // constructors and destructors
59
60 // create a null pointer
61 smart_ptr_base(void);
62
63 // create a pointer containing a *copy* of the object using the template parameter C
64 // this copy is taken because the pointer class maintains a dynamically allocated object
65 // and the T& may not be (usually is not) dynamically allocated
66 explicit smart_ptr_base(const T& data) throw(illegal_copy);
67
68 // create a pointer containing a dynamically created object
69 // Note: the object must be allocated *by the user* with new
70 // constructor form - must be called in the form smart_ptr_base<type> x(new type(args))
71 explicit smart_ptr_base(T* data);
72
73 // copy constructor implements aliasing so no copy is made
74 explicit smart_ptr_base(const smart_ptr_base<T,C>& r);
75
76 // destructor decrements the reference count and delete only when the last reference is destroyed
77 ~smart_ptr_base(void);
78
79 //////////////////////////////////////////////////////////////////////////////
80 // logical tests to see if there is anything contained in the pointer since it can be null
81
82 // there are two forms:explicit and implicit
83 // implicit: if(!r) or if(r)
84 // explicit: if(r.null()) or if(r.present())
85 operator bool(void) const;
86 bool operator!(void) const;
87 bool present(void) const;
88 bool null(void) const;
89
90 //////////////////////////////////////////////////////////////////////////////
91 // dereference operators and functions
92
93 // dereference the smart pointer to get the object - use in the form *p1
94 T& operator*(void) throw(null_dereference);
95 const T& operator*(void) const throw(null_dereference);
96
97 // used as a prefix to a member access to the contained object e.g. p1->print() calls T::print()
98 T* operator->(void) throw(null_dereference);
99 const T* operator->(void) const throw(null_dereference);
100
101 //////////////////////////////////////////////////////////////////////////////
102 // explicit function forms of the above assignment and dereference operators
103
104 // set the value - note that this does a copy using the C template parameter
105 void set_value(const T& data) throw(illegal_copy);
106 // get the value
107 T& value(void) throw(null_dereference);
108 const T& value(void) const throw(null_dereference);
109
110 // set the pointer
111 // deletes the previous pointer and adopts the passed pointer instead
112 // Note: the object must be allocated *by the user* with new
113 // Warning: it is very easy to break the memory management with this operation
114 void set(T* data = 0);
115 // get the pointer
116 T* pointer(void);
117 const T* pointer(void) const;
118
119 //////////////////////////////////////////////////////////////////////////////
120 // functions to manage aliases
121
122 // make this an alias of the passed object
123 void alias(const smart_ptr_base<T,C>&);
124
125 // test whether two pointers point to the same object(known as aliasing the object)
126 // used in the form if(a.aliases(b))
127 bool aliases(const smart_ptr_base<T,C>&) const;
128
129 // find the number of aliases - used when you need to know whether an
130 // object is still referred to from elsewhere (rare!)
131 unsigned alias_count(void) const;
132
133 // delete the object and make the pointer null - does not make it unique
134 // first, so all other pointers to this will be null too
135 void clear(void);
136
137 // make the pointer unique and null in one step - does not affect other
138 // pointers that were pointing to the same object
139 void clear_unique(void);
140
141 //////////////////////////////////////////////////////////////////////////////
142 // functions that involve copying
143
144 // these functions use the copy functor passed as the template parameter C
145 // to copy the object with the right copy semantics. If the copy functor
146 // is no_copy, an exception will be thrown.
147
148 // make this pointer unique with respect to any other references to the same object
149 // if this pointer is already unique, it does nothing - otherwise it copies the object
150 void make_unique(void) throw(illegal_copy);
151
152 // make this pointer a unique copy of the parameter
153 // useful for expressions like p1.copy(p2) which makes p1 a pointer to a unique copy of the contents of p2
154 void copy(const smart_ptr_base<T,C>&) throw(illegal_copy);
155
156 protected:
157 smart_ptr_holder<T>* m_holder;
158
159 public:
160 // internal use only - had to make them public because they need to be
161 // accessed by routines that could not be made friends
162 void* handle(void) const;
163 void make_alias(void* handle);
164 };
165
166 ////////////////////////////////////////////////////////////////////////////////
167 // copy functors implementing the three possible copy semantics
168
169 // constructor_copy uses the copy constructor of the object - used for simple types
170
171 template <typename T>
172 class constructor_copy
173 {
174 public:
175 T* operator() (const T& from) throw()
176 {
177 return new T(from);
178 }
179 };
180
181 // clone_copy uses the clone method of the object - used for polymorphic types
182
183 template <typename T>
184 class clone_copy
185 {
186 public:
187 T* operator() (const T& from) throw()
188 {
189 return from.clone();
190 }
191 };
192
193 // no_copy throws an exception - used for types that cannot be copied
194
195 template <typename T>
196 class no_copy
197 {
198 public:
199 T* operator() (const T& from) throw(illegal_copy)
200 {
201 throw illegal_copy("no_copy functor called");
202 return 0;
203 }
204 };
205
206 ////////////////////////////////////////////////////////////////////////////////
207 // smart_ptr for simple types and classes which have copy constructors
208
209 template <typename T>
210 class smart_ptr : public smart_ptr_base<T, constructor_copy<T> >
211 {
212 public:
213 smart_ptr(void) {}
214 explicit smart_ptr(const T& data) : smart_ptr_base<T, constructor_copy<T> >(data) {}
215 explicit smart_ptr(T* data) : smart_ptr_base<T, constructor_copy<T> >(data) {}
216 smart_ptr<T>& operator=(const T& data) {set_value(data); return *this;}
217 smart_ptr<T>& operator=(const smart_ptr<T>& r) {alias(r); return *this;}
218 ~smart_ptr(void) {}
219 };
220
221 ////////////////////////////////////////////////////////////////////////////////
222 // smart_ptr_clone for polymorphic class hierarchies which have a clone method
223
224 template <typename T>
225 class smart_ptr_clone : public smart_ptr_base<T, clone_copy<T> >
226 {
227 public:
228 smart_ptr_clone(void) {}
229 explicit smart_ptr_clone(const T& data) : smart_ptr_base<T, clone_copy<T> >(data) {}
230 explicit smart_ptr_clone(T* data) : smart_ptr_base<T, clone_copy<T> >(data) {}
231 smart_ptr_clone<T>& operator=(const T& data) {set_value(data); return *this;}
232 smart_ptr_clone<T>& operator=(const smart_ptr_clone<T>& r) {alias(r); return *this;}
233 ~smart_ptr_clone(void) {}
234 };
235
236 ////////////////////////////////////////////////////////////////////////////////
237 // smart_ptr_nocopy for any class that cannot or should not be copied
238
239 template <typename T>
240 class smart_ptr_nocopy : public smart_ptr_base<T, no_copy<T> >
241 {
242 public:
243 smart_ptr_nocopy(void) {}
244 explicit smart_ptr_nocopy(const T& data) : smart_ptr_base<T, no_copy<T> >(data) {}
245 explicit smart_ptr_nocopy(T* data) : smart_ptr_base<T, no_copy<T> >(data) {}
246 smart_ptr_nocopy<T>& operator=(const T& data) {set_value(data); return *this;}
247 smart_ptr_nocopy<T>& operator=(const smart_ptr_nocopy<T>& r) {alias(r); return *this;}
248 ~smart_ptr_nocopy(void) {}
249 };
250
251 ////////////////////////////////////////////////////////////////////////////////
252
253 } // end namespace stlplus
254
255 #include "smart_ptr.tpp"
256 #endif
This page took 0.047009 seconds and 4 git commands to generate.