]> Dogcows Code - chaz/yoink/blob - src/stlplus/containers/smart_ptr.hpp
testing new non-autotools build system
[chaz/yoink] / src / stlplus / containers / 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 "copy_functors.hpp"
31 #include <map>
32 #include <string>
33
34 namespace stlplus
35 {
36
37 ////////////////////////////////////////////////////////////////////////////////
38 // internals
39
40 template<typename T> class smart_ptr_holder;
41
42 ////////////////////////////////////////////////////////////////////////////////
43 // Base class
44 ////////////////////////////////////////////////////////////////////////////////
45
46 template<typename T, typename C>
47 class smart_ptr_base
48 {
49 public:
50 //////////////////////////////////////////////////////////////////////////////
51 // member type definitions
52
53 typedef T value_type;
54 typedef T& reference;
55 typedef const T& const_reference;
56 typedef C value_copy;
57
58 //////////////////////////////////////////////////////////////////////////////
59 // constructors and destructors
60
61 // create a null pointer
62 smart_ptr_base(void);
63
64 // create a pointer containing a *copy* of the object using the template parameter C
65 // this copy is taken because the pointer class maintains a dynamically allocated object
66 // and the T& may not be (usually is not) dynamically allocated
67 explicit smart_ptr_base(const T& data) throw(illegal_copy);
68
69 // create a pointer containing a dynamically created object
70 // Note: the object must be allocated *by the user* with new
71 // constructor form - must be called in the form smart_ptr_base<type> x(new type(args))
72 explicit smart_ptr_base(T* data);
73
74 // copy constructor implements aliasing so no copy is made
75 // note that the copy constructor should NOT be explicit, as this breaks
76 // the returning of pointer objects from functions (at least within GCC 4.4)
77 smart_ptr_base(const smart_ptr_base<T,C>& r);
78
79 // assignment operator - required, else the output of GCC suffers segmentation faults
80 smart_ptr_base<T,C>& operator=(const smart_ptr_base<T,C>& r);
81
82 // destructor decrements the reference count and delete only when the last reference is destroyed
83 ~smart_ptr_base(void);
84
85 //////////////////////////////////////////////////////////////////////////////
86 // logical tests to see if there is anything contained in the pointer since it can be null
87
88 // there are two forms:explicit and implicit
89 // implicit: if(!r) or if(r)
90 // explicit: if(r.null()) or if(r.present())
91 operator bool(void) const;
92 bool operator!(void) const;
93 bool present(void) const;
94 bool null(void) const;
95
96 //////////////////////////////////////////////////////////////////////////////
97 // dereference operators and functions
98
99 // dereference the smart pointer to get the object - use in the form *p1
100 T& operator*(void) throw(null_dereference);
101 const T& operator*(void) const throw(null_dereference);
102
103 // used as a prefix to a member access to the contained object e.g. p1->print() calls T::print()
104 T* operator->(void) throw(null_dereference);
105 const T* operator->(void) const throw(null_dereference);
106
107 //////////////////////////////////////////////////////////////////////////////
108 // explicit function forms of the above assignment and dereference operators
109
110 // set the value - note that this does a copy using the C template parameter
111 void set_value(const T& data) throw(illegal_copy);
112 // get the value
113 T& value(void) throw(null_dereference);
114 const T& value(void) const throw(null_dereference);
115
116 // set the pointer
117 // deletes the previous pointer and adopts the passed pointer instead
118 // Note: the object must be allocated *by the user* with new
119 // Warning: it is very easy to break the memory management with this operation
120 void set(T* data = 0);
121 // get the pointer
122 T* pointer(void);
123 const T* pointer(void) const;
124
125 //////////////////////////////////////////////////////////////////////////////
126 // functions to manage aliases
127
128 // make this an alias of the passed object
129 void alias(const smart_ptr_base<T,C>&);
130
131 // test whether two pointers point to the same object(known as aliasing the object)
132 // used in the form if(a.aliases(b))
133 bool aliases(const smart_ptr_base<T,C>&) const;
134
135 // find the number of aliases - used when you need to know whether an
136 // object is still referred to from elsewhere (rare!)
137 unsigned alias_count(void) const;
138
139 // delete the object and make the pointer null - does not make it unique
140 // first, so all other pointers to this will be null too
141 void clear(void);
142
143 // make the pointer unique and null in one step - does not affect other
144 // pointers that were pointing to the same object
145 void clear_unique(void);
146
147 //////////////////////////////////////////////////////////////////////////////
148 // functions that involve copying
149
150 // these functions use the copy functor passed as the template parameter C
151 // to copy the object with the right copy semantics. If the copy functor
152 // is no_copy, an exception will be thrown.
153
154 // make this pointer unique with respect to any other references to the same object
155 // if this pointer is already unique, it does nothing - otherwise it copies the object
156 void make_unique(void) throw(illegal_copy);
157
158 // make this pointer a unique copy of the parameter
159 // useful for expressions like p1.copy(p2) which makes p1 a pointer to a unique copy of the contents of p2
160 void copy(const smart_ptr_base<T,C>&) throw(illegal_copy);
161
162 protected:
163 smart_ptr_holder<T>* m_holder;
164
165 public:
166 // internal use only - had to make them public because they need to be
167 // accessed by routines that could not be made friends
168 smart_ptr_holder<T>* _handle(void) const;
169 void _make_alias(smart_ptr_holder<T>* handle);
170 };
171
172 ////////////////////////////////////////////////////////////////////////////////
173 // smart_ptr for simple types and classes which have copy constructors
174
175 template <typename T>
176 class smart_ptr : public smart_ptr_base<T, constructor_copy<T> >
177 {
178 public:
179 smart_ptr(void) {}
180 explicit smart_ptr(const T& data) : smart_ptr_base<T, constructor_copy<T> >(data) {}
181 explicit smart_ptr(T* data) : smart_ptr_base<T, constructor_copy<T> >(data) {}
182 smart_ptr<T>& operator=(const T& data) {set_value(data); return *this;}
183 smart_ptr<T>& operator=(T* data) {set(data); return *this;}
184 ~smart_ptr(void) {}
185 };
186
187 ////////////////////////////////////////////////////////////////////////////////
188 // smart_ptr_clone for polymorphic class hierarchies which have a clone method
189
190 template <typename T>
191 class smart_ptr_clone : public smart_ptr_base<T, clone_copy<T> >
192 {
193 public:
194 smart_ptr_clone(void) {}
195 explicit smart_ptr_clone(const T& data) : smart_ptr_base<T, clone_copy<T> >(data) {}
196 explicit smart_ptr_clone(T* data) : smart_ptr_base<T, clone_copy<T> >(data) {}
197 smart_ptr_clone<T>& operator=(const T& data) {set_value(data); return *this;}
198 smart_ptr_clone<T>& operator=(T* data) {set(data); return *this;}
199 ~smart_ptr_clone(void) {}
200 };
201
202 ////////////////////////////////////////////////////////////////////////////////
203 // smart_ptr_nocopy for any class that cannot or should not be copied
204
205 template <typename T>
206 class smart_ptr_nocopy : public smart_ptr_base<T, no_copy<T> >
207 {
208 public:
209 smart_ptr_nocopy(void) {}
210 explicit smart_ptr_nocopy(const T& data) : smart_ptr_base<T, no_copy<T> >(data) {}
211 explicit smart_ptr_nocopy(T* data) : smart_ptr_base<T, no_copy<T> >(data) {}
212 smart_ptr_nocopy<T>& operator=(const T& data) {set_value(data); return *this;}
213 smart_ptr_nocopy<T>& operator=(T* data) {set(data); return *this;}
214 ~smart_ptr_nocopy(void) {}
215 };
216
217 ////////////////////////////////////////////////////////////////////////////////
218
219 } // end namespace stlplus
220
221 #include "smart_ptr.tpp"
222 #endif
This page took 0.04188 seconds and 4 git commands to generate.