]>
Dogcows Code - chaz/yoink/blob - src/stlplus/containers/simple_ptr.hpp
08fff036eb91612865a8207b777e57deaa91e303
1 #ifndef STLPLUS_SIMPLE_PTR
2 #define STLPLUS_SIMPLE_PTR
3 ////////////////////////////////////////////////////////////////////////////////
5 // Author: Daniel Milton, Andy Rushton
6 // Copyright: (c) Southampton University 1999-2004
7 // (c) Daniel Milton, Andy Rushton 2004-2009
8 // License: BSD License, see ../docs/license.html
10 // A smart pointer is a memory-managing pointer to an object. If you like, it
11 // is a zero-dimensional container.
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.
17 // Aliases can be turned into copies if the pointed-to class supports copying.
19 // These simple_ptr classes from DJDM have slightly different semantics than
20 // the smart_ptr classes of AJR. There are no cross-pointer side effects
21 // that occur when the pointer is cleared. The clear() function is effectively
22 // equivalent to the clear_unique() function of the smart_ptr. The only way
23 // that a "referenced" object will be deleted is if all simple_ptr's that
24 // reference the object are cleared (by deletion, manual clearing or reassignment).
26 // Also, the simple pointer cannot contain a reference to a shared null pointer
27 // (which occurs as a side-effect of clearing a multiply referenced object in
28 // the smart_ptr classes). Which means that if you have a null simple_ptr, then
29 // the assignment of any other null simple_ptr will NOT reassign the reference of
30 // any other simple_ptr. Hence, the simple_ptr class acts a little more like a
31 // normal pointer (with fewer side effects), with the added bonus of containment.
33 // Due to the way that the simple_ptr contains the data, it also allows the
34 // addition of various casting functions, while still keeping the managed data
35 // containment functionality of the underlying object. This means that you can
36 // have two simple_ptr's of different template types, both pointing to the same
37 // data (if the differing template types are derivatives of each other).
39 // The base class is simple_ptr_base which defines the common interface. Then
40 // there are three subclasses which have the same interface but different copy
43 // - simple_ptr for simple types and classes which have copy constructors
44 // - simple_ptr_clone for polymorphic class hierarchies which are copied using a clone method
45 // - simple_ptr_nocopy for any class that cannot or should not be copied
47 ////////////////////////////////////////////////////////////////////////////////
48 #include "containers_fixes.hpp"
49 #include "exceptions.hpp"
50 #include "copy_functors.hpp"
57 ////////////////////////////////////////////////////////////////////////////////
59 ////////////////////////////////////////////////////////////////////////////////
61 template<typename T
, typename C
>
65 //////////////////////////////////////////////////////////////////////////////
66 // member type definitions
70 typedef const T
& const_reference
;
73 //////////////////////////////////////////////////////////////////////////////
74 // constructors and destructors
76 // create a null pointer
77 simple_ptr_base(void);
79 // create a pointer containing a *copy* of the object using the template parameter C
80 // this copy is taken because the pointer class maintains a dynamically allocated object
81 // and the T& may not be (usually is not) dynamically allocated
82 explicit simple_ptr_base(const T
& data
) throw(illegal_copy
);
84 // create a pointer containing a dynamically created object
85 // Note: the object must be allocated *by the user* with new
86 // constructor form - must be called in the form smart_ptr_base<type> x(new type(args))
87 explicit simple_ptr_base(T
* data
);
89 // copy constructor implements aliasing so no copy is made
90 // note that the copy constructor should NOT be explicit, as this breaks
91 // the returning of pointer objects from functions (at least within GCC 4.4)
92 simple_ptr_base(const simple_ptr_base
<T
,C
>& r
);
94 // assignment operator - required, else the output of GCC suffers segmentation faults
95 simple_ptr_base
<T
,C
>& operator=(const simple_ptr_base
<T
,C
>& r
);
97 // destructor decrements the reference count and delete only when the last reference is destroyed
98 ~simple_ptr_base(void);
100 //////////////////////////////////////////////////////////////////////////////
101 // logical tests to see if there is anything contained in the pointer since it can be null
103 // there are two forms:explicit and implicit
104 // implicit: if(!r) or if(r)
105 // explicit: if(r.null()) or if(r.present())
106 operator bool(void) const;
107 bool operator!(void) const;
108 bool present(void) const;
109 bool null(void) const;
111 //////////////////////////////////////////////////////////////////////////////
112 // dereference operators and functions
114 // dereference the smart pointer to get the object - use in the form *p1
115 T
& operator*(void) throw(null_dereference
);
116 const T
& operator*(void) const throw(null_dereference
);
118 // used as a prefix to a member access to the contained object e.g. p1->print() calls T::print()
119 T
* operator->(void) throw(null_dereference
);
120 const T
* operator->(void) const throw(null_dereference
);
122 //////////////////////////////////////////////////////////////////////////////
123 // explicit function forms of the above assignment and dereference operators
125 // set the value - note that this does a copy using the C template parameter
126 void set_value(const T
& data
) throw(illegal_copy
);
128 T
& value(void) throw(null_dereference
);
129 const T
& value(void) const throw(null_dereference
);
132 // deletes the previous pointer and adopts the passed pointer instead
133 // Note: the object must be allocated *by the user* with new
134 // Warning: it is very easy to break the memory management with this operation
135 void set(T
* data
= 0);
138 const T
* pointer(void) const;
140 //////////////////////////////////////////////////////////////////////////////
141 // functions to manage aliases
143 // make this an alias of the passed object
144 void alias(const simple_ptr_base
<T
,C
>&);
146 // test whether two pointers point to the same object(known as aliasing the object)
147 // used in the form if(a.aliases(b))
148 bool aliases(const simple_ptr_base
<T
,C
>&) const;
150 // find the number of aliases - used when you need to know whether an
151 // object is still referred to from elsewhere (rare!)
152 unsigned alias_count(void) const;
154 // clear the reference to the object, but only delete the object if there are no
155 // other references to that object. Hence, this does not affect other pointers
156 // that are pointing to the same object.
159 // This is just an alias of the clear() function, provided for completeness of
160 // the interface when acting as a replacement for the smart_ptr classes
161 void clear_unique(void);
163 //////////////////////////////////////////////////////////////////////////////
164 // functions that involve copying
166 // these functions use the copy functor passed as the template parameter C
167 // to copy the object with the right copy semantics. If the copy functor
168 // is no_copy, an exception will be thrown.
170 // make this pointer unique with respect to any other references to the same object
171 // if this pointer is already unique, it does nothing - otherwise it copies the object
172 void make_unique(void) throw(illegal_copy
);
174 // make this pointer a unique copy of the parameter
175 // useful for expressions like p1.copy(p2) which makes p1 a pointer to a unique copy of the contents of p2
176 void copy(const simple_ptr_base
<T
,C
>&) throw(illegal_copy
);
178 //////////////////////////////////////////////////////////////////////////////
179 // functions that involve casting
181 #ifdef STLPLUS_MEMBER_TEMPLATES
183 // dynamic cast of underlying pointer to a derived/parent
184 template<typename T2
> simple_ptr_base
<T2
,C
> dyn_cast(void) const;
186 // static cast of underlying pointer to a derived/parent
187 template<typename T2
> simple_ptr_base
<T2
,C
> stat_cast(void) const;
189 // cast of underlying pointer to a base - while keeping the same ref-counted object
190 template<typename T2
> simple_ptr_base
<T2
,C
> cast(void) const;
194 //////////////////////////////////////////////////////////////////////////////
201 // internal use only - had to make them public because they need to be
202 // accessed by routines that could not be made friends
203 // can't have a handle due to the way the simple pointer stores it's data
204 // in separate counter and pointer objects
205 unsigned* _count(void) const;
206 T
* _pointer(void) const;
207 void _make_alias(T
* pointer
, unsigned* count
);
210 void increment(void);
211 bool decrement(void);
214 ////////////////////////////////////////////////////////////////////////////////
215 // simple_ptr for simple types and classes which have copy constructors
217 template <typename T
>
218 class simple_ptr
: public simple_ptr_base
<T
, constructor_copy
<T
> >
222 explicit simple_ptr(const T
& data
) : simple_ptr_base
<T
, constructor_copy
<T
> >(data
) {}
223 explicit simple_ptr(T
* data
) : simple_ptr_base
<T
, constructor_copy
<T
> >(data
) {}
224 simple_ptr
<T
>& operator=(const T
& data
) {set_value(data
); return *this;}
225 simple_ptr
<T
>& operator=(T
* data
) {set(data
); return *this;}
229 ////////////////////////////////////////////////////////////////////////////////
230 // smart_ptr_clone for polymorphic class hierarchies which have a clone method
232 template <typename T
>
233 class simple_ptr_clone
: public simple_ptr_base
<T
, clone_copy
<T
> >
236 simple_ptr_clone(void) {}
237 explicit simple_ptr_clone(const T
& data
) : simple_ptr_base
<T
, clone_copy
<T
> >(data
) {}
238 explicit simple_ptr_clone(T
* data
) : simple_ptr_base
<T
, clone_copy
<T
> >(data
) {}
239 simple_ptr_clone
<T
>& operator=(const T
& data
) {set_value(data
); return *this;}
240 simple_ptr_clone
<T
>& operator=(T
* data
) {set(data
); return *this;}
241 ~simple_ptr_clone(void) {}
244 ////////////////////////////////////////////////////////////////////////////////
245 // smart_ptr_nocopy for any class that cannot or should not be copied
247 template <typename T
>
248 class simple_ptr_nocopy
: public simple_ptr_base
<T
, no_copy
<T
> >
251 simple_ptr_nocopy(void) {}
252 explicit simple_ptr_nocopy(const T
& data
) : simple_ptr_base
<T
, no_copy
<T
> >(data
) {}
253 explicit simple_ptr_nocopy(T
* data
) : simple_ptr_base
<T
, no_copy
<T
> >(data
) {}
254 simple_ptr_nocopy
<T
>& operator=(const T
& data
) {set_value(data
); return *this;}
255 simple_ptr_nocopy
<T
>& operator=(T
* data
) {set(data
); return *this;}
256 ~simple_ptr_nocopy(void) {}
259 ////////////////////////////////////////////////////////////////////////////////
261 } // end namespace stlplus
263 #include "simple_ptr.tpp"
This page took 0.048933 seconds and 4 git commands to generate.