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