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 
51 namespace 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
79  smart_ptr_base(void);
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
95  ~smart_ptr_base(void);
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
112  T& operator*(void) throw(null_dereference);
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()
116  T* operator->(void) throw(null_dereference);
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
141  inline void alias(const smart_ptr_base<T,C,COUNTER>&);
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
172  void copy(const smart_ptr_base<T,C,COUNTER>&) throw(illegal_copy);
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>
214  class no_copy
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
void set(T *data=0)
bool present(void) const
smart_ptr_holder< T, COUNTER > * m_holder
Definition: smart_ptr.hpp:175
smart_ptr_clone< T > & operator=(const smart_ptr_clone< T > &r)
Definition: smart_ptr.hpp:250
smart_ptr(const T &data)
Definition: smart_ptr.hpp:232
void set_value(const T &data)
unsigned alias_count(void) const
void * handle(void) const
smart_ptr< T > & operator=(const T &data)
Definition: smart_ptr.hpp:234
T * operator()(const T &from)
Definition: smart_ptr.hpp:205
bool operator!(void) const
smart_ptr_nocopy< T > & operator=(const smart_ptr_nocopy< T > &r)
Definition: smart_ptr.hpp:265
void alias(const smart_ptr_base< T, C, COUNTER > &)
smart_ptr_clone(const T &data)
Definition: smart_ptr.hpp:247
smart_ptr< T > & operator=(const smart_ptr< T > &r)
Definition: smart_ptr.hpp:235
T * operator()(const T &from)
Definition: smart_ptr.hpp:193
smart_ptr_nocopy< T > & operator=(const T &data)
Definition: smart_ptr.hpp:264
T * operator()(const T &)
Definition: smart_ptr.hpp:217
bool aliases(const smart_ptr_base< T, C, COUNTER > &) const
void make_alias(void *handle)
smart_ptr_nocopy(const T &data)
Definition: smart_ptr.hpp:262
void copy(const smart_ptr_base< T, C, COUNTER > &)
smart_ptr_clone< T > & operator=(const T &data)
Definition: smart_ptr.hpp:249



Page generated by Doxygen 1.8.15 for MRPT 1.4.0 SVN: at Sat Aug 3 20:09:00 UTC 2019