00001 /* 00002 The STL+ C++ Library Collection 00003 00004 Website <http://stlplus.sourceforge.net/> Collection <index.html> 00005 00006 00007 License Agreement 00008 00009 <http://www.opensource.org/> 00010 00011 * License for using the STLplus Library Collection <#license> 00012 * The Intent of this License <#intent> 00013 * How to Comply with this License <#compliance> 00014 * Historical Note <#history> 00015 00016 00017 License for using the STLplus Library Collection 00018 00019 *© 1999-2008 Andy Rushton. All rights reserved.* 00020 00021 Redistribution and use in source and binary forms, with or without 00022 modification, are permitted provided that the following conditions are met: 00023 00024 * Redistributions of source code must retain the above Copyright 00025 notice, this list of conditions and the following disclaimer. 00026 * Redistributions in binary form must reproduce the above Copyright 00027 notice, this list of conditions and the following disclaimer in 00028 the documentation and/or other materials provided with the 00029 distribution. 00030 * Neither the name of the STLplus library nor the names of its 00031 contributors may be used to endorse or promote products derived 00032 from this software without specific prior written permission. 00033 00034 This software is provided by the Copyright holders and contributors "as 00035 is" and any express or implied warranties, including, but not limited 00036 to, the implied warranties of merchantability and fitness for a 00037 particular purpose are disclaimed. In no event shall the Copyright owner 00038 or contributors be liable for any direct, indirect, incidental, special, 00039 exemplary, or consequential damages (including, but not limited to, 00040 procurement of substitute goods or services; loss of use, data, or 00041 profits; or business interruption) however caused and on any theory of 00042 liability, whether in contract, strict liability, or tort (including 00043 negligence or otherwise) arising in any way out of the use of this 00044 software, even if advised of the possibility of such damage. 00045 */ 00046 00047 /* 00048 Modified version of STL+ sources shipped with the Mobile Robot 00049 Programming Toolkit (MRPT). 00050 00051 Sources have been modified to support thred-safe smart pointers 00052 through Boost atomic operations. 00053 00054 2009, Jose Luis Blanco. University of Malaga. 00055 */ 00056 00057 00058 #ifndef STLPLUS_SMART_PTR 00059 #define STLPLUS_SMART_PTR 00060 //////////////////////////////////////////////////////////////////////////////// 00061 00062 // Author: Andy Rushton 00063 // Copyright: (c) Andy Rushton, 2007 00064 // License: BSD License, see ../docs/license.html 00065 00066 // A smart pointer is a memory-managing pointer to an object. If you like, it 00067 // is a zero-dimensional container. 00068 00069 // Assignment of smart pointers result in multiple aliases of the same object. 00070 // The term alias is used to differentiate from conventional pointers because 00071 // the semantics are different. 00072 00073 // Aliases can be turned into copies if the pointed-to class supports copying. 00074 00075 // The base class is smart_ptr_base which defines the common interface. Then 00076 // there are three subclasses which have the same interface but different copy 00077 // semantics: 00078 00079 // - smart_ptr for simple types and classes which have copy constructors 00080 // - smart_ptr_clone for polymorphic class hierarchies which are copied using a clone method 00081 // - smart_ptr_nocopy for any class that cannot or should not be copied 00082 00083 //////////////////////////////////////////////////////////////////////////////// 00084 #include "containers_fixes.hpp" 00085 #include "exceptions.hpp" 00086 #include <map> 00087 #include <string> 00088 00089 #include <mrpt/synch/atomic_incr.h> // JLB: For atomic_count. See smart_ptr.tpp 00090 00091 namespace stlplus 00092 { 00093 00094 //////////////////////////////////////////////////////////////////////////////// 00095 // internals 00096 00097 template<typename T> class smart_ptr_holder; 00098 00099 //////////////////////////////////////////////////////////////////////////////// 00100 // Base class 00101 //////////////////////////////////////////////////////////////////////////////// 00102 00103 template<typename T, typename C> 00104 class smart_ptr_base 00105 { 00106 public: 00107 ////////////////////////////////////////////////////////////////////////////// 00108 // member type definitions 00109 00110 typedef T value_type; 00111 typedef T& reference; 00112 typedef const T& const_reference; 00113 typedef C value_copy; 00114 00115 ////////////////////////////////////////////////////////////////////////////// 00116 // constructors and destructors 00117 00118 // create a null pointer 00119 smart_ptr_base(void); 00120 00121 // create a pointer containing a *copy* of the object using the template parameter C 00122 // this copy is taken because the pointer class maintains a dynamically allocated object 00123 // and the T& may not be (usually is not) dynamically allocated 00124 explicit smart_ptr_base(const T& data) throw(illegal_copy); 00125 00126 // create a pointer containing a dynamically created object 00127 // Note: the object must be allocated *by the user* with new 00128 // constructor form - must be called in the form smart_ptr_base<type> x(new type(args)) 00129 explicit smart_ptr_base(T* data); 00130 00131 // copy constructor implements aliasing so no copy is made 00132 explicit smart_ptr_base(const smart_ptr_base<T,C>& r); 00133 00134 // destructor decrements the reference count and delete only when the last reference is destroyed 00135 ~smart_ptr_base(void); 00136 00137 ////////////////////////////////////////////////////////////////////////////// 00138 // logical tests to see if there is anything contained in the pointer since it can be null 00139 00140 // there are two forms:explicit and implicit 00141 // implicit: if(!r) or if(r) 00142 // explicit: if(r.null()) or if(r.present()) 00143 operator bool(void) const; 00144 bool operator!(void) const; 00145 bool present(void) const; 00146 bool null(void) const; 00147 00148 ////////////////////////////////////////////////////////////////////////////// 00149 // dereference operators and functions 00150 00151 // dereference the smart pointer to get the object - use in the form *p1 00152 T& operator*(void) throw(null_dereference); 00153 const T& operator*(void) const throw(null_dereference); 00154 00155 // used as a prefix to a member access to the contained object e.g. p1->print() calls T::print() 00156 T* operator->(void) throw(null_dereference); 00157 const T* operator->(void) const throw(null_dereference); 00158 00159 ////////////////////////////////////////////////////////////////////////////// 00160 // explicit function forms of the above assignment and dereference operators 00161 00162 // set the value - note that this does a copy using the C template parameter 00163 void set_value(const T& data) throw(illegal_copy); 00164 // get the value 00165 T& value(void) throw(null_dereference); 00166 const T& value(void) const throw(null_dereference); 00167 00168 // set the pointer 00169 // deletes the previous pointer and adopts the passed pointer instead 00170 // Note: the object must be allocated *by the user* with new 00171 // Warning: it is very easy to break the memory management with this operation 00172 void set(T* data = 0); 00173 // get the pointer 00174 T* pointer(void); 00175 const T* pointer(void) const; 00176 00177 ////////////////////////////////////////////////////////////////////////////// 00178 // functions to manage aliases 00179 00180 // make this an alias of the passed object 00181 void alias(const smart_ptr_base<T,C>&); 00182 00183 // test whether two pointers point to the same object(known as aliasing the object) 00184 // used in the form if(a.aliases(b)) 00185 bool aliases(const smart_ptr_base<T,C>&) const; 00186 00187 // find the number of aliases - used when you need to know whether an 00188 // object is still referred to from elsewhere (rare!) 00189 unsigned alias_count(void) const; 00190 00191 // delete the object and make the pointer null - does not make it unique 00192 // first, so all other pointers to this will be null too 00193 void clear(void); 00194 00195 // make the pointer unique and null in one step - does not affect other 00196 // pointers that were pointing to the same object 00197 void clear_unique(void); 00198 00199 ////////////////////////////////////////////////////////////////////////////// 00200 // functions that involve copying 00201 00202 // these functions use the copy functor passed as the template parameter C 00203 // to copy the object with the right copy semantics. If the copy functor 00204 // is no_copy, an exception will be thrown. 00205 00206 // make this pointer unique with respect to any other references to the same object 00207 // if this pointer is already unique, it does nothing - otherwise it copies the object 00208 void make_unique(void) throw(illegal_copy); 00209 00210 // make this pointer a unique copy of the parameter 00211 // useful for expressions like p1.copy(p2) which makes p1 a pointer to a unique copy of the contents of p2 00212 void copy(const smart_ptr_base<T,C>&) throw(illegal_copy); 00213 00214 protected: 00215 smart_ptr_holder<T>* m_holder; 00216 00217 public: 00218 // internal use only - had to make them public because they need to be 00219 // accessed by routines that could not be made friends 00220 void* handle(void) const; 00221 void make_alias(void* handle); 00222 }; 00223 00224 //////////////////////////////////////////////////////////////////////////////// 00225 // copy functors implementing the three possible copy semantics 00226 00227 // constructor_copy uses the copy constructor of the object - used for simple types 00228 00229 template <typename T> 00230 class constructor_copy 00231 { 00232 public: 00233 T* operator() (const T& from) throw() 00234 { 00235 return new T(from); 00236 } 00237 }; 00238 00239 // clone_copy uses the clone method of the object - used for polymorphic types 00240 00241 template <typename T> 00242 class clone_copy 00243 { 00244 public: 00245 T* operator() (const T& from) throw() 00246 { 00247 return from.clone(); 00248 } 00249 }; 00250 00251 // no_copy throws an exception - used for types that cannot be copied 00252 00253 template <typename T> 00254 class no_copy 00255 { 00256 public: 00257 T* operator() (const T& from) throw(illegal_copy) 00258 { 00259 throw illegal_copy("no_copy functor called"); 00260 return 0; 00261 } 00262 }; 00263 00264 //////////////////////////////////////////////////////////////////////////////// 00265 // smart_ptr for simple types and classes which have copy constructors 00266 00267 template <typename T> 00268 class smart_ptr : public smart_ptr_base<T, constructor_copy<T> > 00269 { 00270 public: 00271 smart_ptr(void) {} 00272 explicit smart_ptr(const T& data) : smart_ptr_base<T, constructor_copy<T> >(data) {} 00273 explicit smart_ptr(T* data) : smart_ptr_base<T, constructor_copy<T> >(data) {} 00274 smart_ptr<T>& operator=(const T& data) {set_value(data); return *this;} 00275 smart_ptr<T>& operator=(const smart_ptr<T>& r) {alias(r); return *this;} 00276 ~smart_ptr(void) {} 00277 }; 00278 00279 //////////////////////////////////////////////////////////////////////////////// 00280 // smart_ptr_clone for polymorphic class hierarchies which have a clone method 00281 00282 template <typename T> 00283 class smart_ptr_clone : public smart_ptr_base<T, clone_copy<T> > 00284 { 00285 public: 00286 smart_ptr_clone(void) {} 00287 explicit smart_ptr_clone(const T& data) : smart_ptr_base<T, clone_copy<T> >(data) {} 00288 explicit smart_ptr_clone(T* data) : smart_ptr_base<T, clone_copy<T> >(data) {} 00289 smart_ptr_clone<T>& operator=(const T& data) {set_value(data); return *this;} 00290 smart_ptr_clone<T>& operator=(const smart_ptr_clone<T>& r) {alias(r); return *this;} 00291 ~smart_ptr_clone(void) {} 00292 }; 00293 00294 //////////////////////////////////////////////////////////////////////////////// 00295 // smart_ptr_nocopy for any class that cannot or should not be copied 00296 00297 template <typename T> 00298 class smart_ptr_nocopy : public smart_ptr_base<T, no_copy<T> > 00299 { 00300 public: 00301 smart_ptr_nocopy(void) {} 00302 explicit smart_ptr_nocopy(const T& data) : smart_ptr_base<T, no_copy<T> >(data) {} 00303 explicit smart_ptr_nocopy(T* data) : smart_ptr_base<T, no_copy<T> >(data) {} 00304 smart_ptr_nocopy<T>& operator=(const T& data) {set_value(data); return *this;} 00305 smart_ptr_nocopy<T>& operator=(const smart_ptr_nocopy<T>& r) {alias(r); return *this;} 00306 ~smart_ptr_nocopy(void) {} 00307 }; 00308 00309 //////////////////////////////////////////////////////////////////////////////// 00310 00311 } // end namespace stlplus 00312 00313 #include "smart_ptr.tpp" 00314 #endif
Page generated by Doxygen 1.5.7.1 for MRPT 0.7.1 SVN: at Mon Aug 17 23:10:56 EDT 2009 |