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 #ifndef STLPLUS_SMART_PTR 00048 #define STLPLUS_SMART_PTR 00050 00051 // Author: Andy Rushton 00052 // Copyright: (c) Andy Rushton, 2007 00053 // License: BSD License, see ../docs/license.html 00054 00055 // A smart pointer is a memory-managing pointer to an object. If you like, it 00056 // is a zero-dimensional container. 00057 00058 // Assignment of smart pointers result in multiple aliases of the same object. 00059 // The term alias is used to differentiate from conventional pointers because 00060 // the semantics are different. 00061 00062 // Aliases can be turned into copies if the pointed-to class supports copying. 00063 00064 // The base class is smart_ptr_base which defines the common interface. Then 00065 // there are three subclasses which have the same interface but different copy 00066 // semantics: 00067 00068 // - smart_ptr for simple types and classes which have copy constructors 00069 // - smart_ptr_clone for polymorphic class hierarchies which are copied using a clone method 00070 // - smart_ptr_nocopy for any class that cannot or should not be copied 00071 00073 #include "containers_fixes.hpp" 00074 #include "exceptions.hpp" 00075 #include <map> 00076 #include <string> 00077 00078 namespace stlplus 00079 { 00080 00082 // internals 00083 00084 template<typename T> class smart_ptr_holder; 00085 00087 // Base class 00089 00090 template<typename T, typename C> 00091 class smart_ptr_base 00092 { 00093 public: 00095 // member type definitions 00096 00097 typedef T value_type; 00098 typedef T& reference; 00099 typedef const T& const_reference; 00100 typedef C value_copy; 00101 00103 // constructors and destructors 00104 00105 // create a null pointer 00106 smart_ptr_base(void); 00107 00108 // create a pointer containing a *copy* of the object using the template parameter C 00109 // this copy is taken because the pointer class maintains a dynamically allocated object 00110 // and the T& may not be (usually is not) dynamically allocated 00111 explicit smart_ptr_base(const T& data) throw(illegal_copy); 00112 00113 // create a pointer containing a dynamically created object 00114 // Note: the object must be allocated *by the user* with new 00115 // constructor form - must be called in the form smart_ptr_base<type> x(new type(args)) 00116 explicit smart_ptr_base(T* data); 00117 00118 // copy constructor implements aliasing so no copy is made 00119 explicit smart_ptr_base(const smart_ptr_base<T,C>& r); 00120 00121 // destructor decrements the reference count and delete only when the last reference is destroyed 00122 ~smart_ptr_base(void); 00123 00125 // logical tests to see if there is anything contained in the pointer since it can be null 00126 00127 // there are two forms:explicit and implicit 00128 // implicit: if(!r) or if(r) 00129 // explicit: if(r.null()) or if(r.present()) 00130 operator bool(void) const; 00131 bool operator!(void) const; 00132 bool present(void) const; 00133 bool null(void) const; 00134 00136 // dereference operators and functions 00137 00138 // dereference the smart pointer to get the object - use in the form *p1 00139 T& operator*(void) throw(null_dereference); 00140 const T& operator*(void) const throw(null_dereference); 00141 00142 // used as a prefix to a member access to the contained object e.g. p1->print() calls T::print() 00143 T* operator->(void) throw(null_dereference); 00144 const T* operator->(void) const throw(null_dereference); 00145 00147 // explicit function forms of the above assignment and dereference operators 00148 00149 // set the value - note that this does a copy using the C template parameter 00150 void set_value(const T& data) throw(illegal_copy); 00151 // get the value 00152 T& value(void) throw(null_dereference); 00153 const T& value(void) const throw(null_dereference); 00154 00155 // set the pointer 00156 // deletes the previous pointer and adopts the passed pointer instead 00157 // Note: the object must be allocated *by the user* with new 00158 // Warning: it is very easy to break the memory management with this operation 00159 void set(T* data = 0); 00160 // get the pointer 00161 T* pointer(void); 00162 const T* pointer(void) const; 00163 00165 // functions to manage aliases 00166 00167 // make this an alias of the passed object 00168 void alias(const smart_ptr_base<T,C>&); 00169 00170 // test whether two pointers point to the same object(known as aliasing the object) 00171 // used in the form if(a.aliases(b)) 00172 bool aliases(const smart_ptr_base<T,C>&) const; 00173 00174 // find the number of aliases - used when you need to know whether an 00175 // object is still referred to from elsewhere (rare!) 00176 unsigned alias_count(void) const; 00177 00178 // delete the object and make the pointer null - does not make it unique 00179 // first, so all other pointers to this will be null too 00180 void clear(void); 00181 00182 // make the pointer unique and null in one step - does not affect other 00183 // pointers that were pointing to the same object 00184 void clear_unique(void); 00185 00187 // functions that involve copying 00188 00189 // these functions use the copy functor passed as the template parameter C 00190 // to copy the object with the right copy semantics. If the copy functor 00191 // is no_copy, an exception will be thrown. 00192 00193 // make this pointer unique with respect to any other references to the same object 00194 // if this pointer is already unique, it does nothing - otherwise it copies the object 00195 void make_unique(void) throw(illegal_copy); 00196 00197 // make this pointer a unique copy of the parameter 00198 // useful for expressions like p1.copy(p2) which makes p1 a pointer to a unique copy of the contents of p2 00199 void copy(const smart_ptr_base<T,C>&) throw(illegal_copy); 00200 00201 protected: 00202 smart_ptr_holder<T>* m_holder; 00203 00204 public: 00205 // internal use only - had to make them public because they need to be 00206 // accessed by routines that could not be made friends 00207 void* handle(void) const; 00208 void make_alias(void* handle); 00209 }; 00210 00212 // copy functors implementing the three possible copy semantics 00213 00214 // constructor_copy uses the copy constructor of the object - used for simple types 00215 00216 template <typename T> 00217 class constructor_copy 00218 { 00219 public: 00220 T* operator() (const T& from) throw() 00221 { 00222 return new T(from); 00223 } 00224 }; 00225 00226 // clone_copy uses the clone method of the object - used for polymorphic types 00227 00228 template <typename T> 00229 class clone_copy 00230 { 00231 public: 00232 T* operator() (const T& from) throw() 00233 { 00234 return from.clone(); 00235 } 00236 }; 00237 00238 // no_copy throws an exception - used for types that cannot be copied 00239 00240 template <typename T> 00241 class no_copy 00242 { 00243 public: 00244 T* operator() (const T& from) throw(illegal_copy) 00245 { 00246 throw illegal_copy("no_copy functor called"); 00247 return 0; 00248 } 00249 }; 00250 00252 // smart_ptr for simple types and classes which have copy constructors 00253 00254 template <typename T> 00255 class smart_ptr : public smart_ptr_base<T, constructor_copy<T> > 00256 { 00257 public: 00258 smart_ptr(void) {} 00259 explicit smart_ptr(const T& data) : smart_ptr_base<T, constructor_copy<T> >(data) {} 00260 explicit smart_ptr(T* data) : smart_ptr_base<T, constructor_copy<T> >(data) {} 00261 smart_ptr<T>& operator=(const T& data) {set_value(data); return *this;} 00262 smart_ptr<T>& operator=(const smart_ptr<T>& r) {alias(r); return *this;} 00263 ~smart_ptr(void) {} 00264 }; 00265 00267 // smart_ptr_clone for polymorphic class hierarchies which have a clone method 00268 00269 template <typename T> 00270 class smart_ptr_clone : public smart_ptr_base<T, clone_copy<T> > 00271 { 00272 public: 00273 smart_ptr_clone(void) {} 00274 explicit smart_ptr_clone(const T& data) : smart_ptr_base<T, clone_copy<T> >(data) {} 00275 explicit smart_ptr_clone(T* data) : smart_ptr_base<T, clone_copy<T> >(data) {} 00276 smart_ptr_clone<T>& operator=(const T& data) {set_value(data); return *this;} 00277 smart_ptr_clone<T>& operator=(const smart_ptr_clone<T>& r) {alias(r); return *this;} 00278 ~smart_ptr_clone(void) {} 00279 }; 00280 00282 // smart_ptr_nocopy for any class that cannot or should not be copied 00283 00284 template <typename T> 00285 class smart_ptr_nocopy : public smart_ptr_base<T, no_copy<T> > 00286 { 00287 public: 00288 smart_ptr_nocopy(void) {} 00289 explicit smart_ptr_nocopy(const T& data) : smart_ptr_base<T, no_copy<T> >(data) {} 00290 explicit smart_ptr_nocopy(T* data) : smart_ptr_base<T, no_copy<T> >(data) {} 00291 smart_ptr_nocopy<T>& operator=(const T& data) {set_value(data); return *this;} 00292 smart_ptr_nocopy<T>& operator=(const smart_ptr_nocopy<T>& r) {alias(r); return *this;} 00293 ~smart_ptr_nocopy(void) {} 00294 }; 00295 00297 00298 } // end namespace stlplus 00299 00300 #include "smart_ptr.tpp" 00301 #endif
Page generated by Doxygen 1.5.8 for MRPT 0.6.5 SVN: at Thu Feb 26 02:14:51 EST 2009 |