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



Page generated by Doxygen 1.9.4 for MRPT 1.4.0 SVN: at Sun Aug 14 11:28:23 UTC 2022