CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/FWCore/Utilities/interface/value_ptr.h

Go to the documentation of this file.
00001 #ifndef FWCore_Utilities_value_ptr_h
00002 #define FWCore_Utilities_value_ptr_h
00003 
00004 // ----------------------------------------------------------------------
00005 //
00006 // value_ptr.h - Smart pointer permitting copying of pointed-to object.
00007 //
00008 // Purpose: value_ptr provides a smart pointer template that provides
00009 // sole ownership of the pointed-to object. When a value_ptr object is
00010 // copied, the new value_ptr object is given a copy of the object pointed
00011 // to by the original value_ptr object.
00012 //
00013 // The value_ptr_traits template is provided to allow specialization
00014 // of the copying behavior. See the notes below.
00015 //
00016 // Use value_ptr only when deep-copying of the pointed-to object is
00017 // desireable. Use boost::shared_ptr when sharing of the pointed-to
00018 // object is desireable. Use boost::scoped_ptr when no copying is
00019 // desireable.
00020 //
00021 // The design of value_ptr is taken from Herb Sutter's More
00022 // Exceptional C++, with modifications by Marc Paterno and further
00023 // modifications by Walter Brown. This version is based on the
00024 // ValuePtr found in the Fermilab ZOOM library.
00025 //
00026 //
00027 // Supports the following syntax
00028 //   value_ptr<T> ptr(...);
00029 //   if (ptr) { ...
00030 // Where the conditional will evaluate as true if and only if the
00031 // pointer the value_ptr contains is not null.
00032 //
00033 // ----------------------------------------------------------------------
00034 
00035 #include <algorithm> // for std::swap()
00036 #include <memory>
00037 
00038 namespace edm {
00039 
00040   // --------------------------------------------------------------------
00041   //
00042   //  Auxiliary traits class template providing default clone()
00043   //  Users should specialize this template for types that have their
00044   //  own self-copy operations; failure to do so may lead to slicing!
00045   //
00046   // --------------------------------------------------------------------
00047 
00048 
00049   template <typename T>
00050   struct value_ptr_traits {
00051     static T * clone(T const* p) { return new T(*p); }
00052   };
00053 
00054   // --------------------------------------------------------------------
00055   //
00056   // Copyable smart pointer class template
00057   //
00058   // --------------------------------------------------------------------
00059 
00060 
00061   template <typename T>
00062   class value_ptr {
00063 
00064   public:
00065 
00066     // --------------------------------------------------
00067     // Default constructor/destructor:
00068     // --------------------------------------------------
00069 
00070     value_ptr() : myP(0) { }
00071     explicit value_ptr(T* p) : myP(p) { }
00072     ~value_ptr() { delete myP; }
00073 
00074     // --------------------------------------------------
00075     // Copy constructor/copy assignment:
00076     // --------------------------------------------------
00077 
00078     value_ptr(value_ptr const& orig) :
00079       myP(createFrom(orig.myP)) {
00080     }
00081 
00082     value_ptr& operator= (value_ptr const& orig) {
00083       value_ptr<T> temp(orig);
00084       swap(temp);
00085       return *this;
00086     }
00087 
00088 #if defined( __GXX_EXPERIMENTAL_CXX0X__)
00089     value_ptr(value_ptr && orig) :
00090       myP(orig.myP) { orig.myP=0; }
00091 
00092     value_ptr& operator=(value_ptr && orig) {
00093       if (myP!=orig.myP) {
00094         delete myP;
00095         myP=orig.myP;
00096         orig.myP=0;
00097       } 
00098       return *this;
00099     }
00100 #endif
00101 
00102 
00103     // --------------------------------------------------
00104     // Access mechanisms:
00105     // --------------------------------------------------
00106 
00107     T& operator*() const { return *myP; }
00108     T* operator->() const { return myP; }
00109 
00110     // --------------------------------------------------
00111     // Manipulation:
00112     // --------------------------------------------------
00113 
00114     void swap(value_ptr& orig) { std::swap(myP, orig.myP); }
00115 
00116     // --------------------------------------------------
00117     // Copy-like construct/assign from compatible value_ptr<>:
00118     // --------------------------------------------------
00119 
00120     template <typename U>
00121     value_ptr(value_ptr<U> const& orig) :
00122       myP(createFrom(orig.operator->())) {
00123     }
00124 
00125     template <typename U>
00126     value_ptr& operator=(value_ptr<U> const& orig) {
00127       value_ptr<T> temp(orig);
00128       swap(temp);
00129       return *this;
00130     }
00131 
00132     // --------------------------------------------------
00133     // Copy-like construct/assign from auto_ptr<>:
00134     // --------------------------------------------------
00135 
00136     value_ptr(std::auto_ptr<T> orig) :
00137       myP(orig.release()) {
00138     }
00139 
00140     value_ptr& operator=(std::auto_ptr<T> orig) {
00141       value_ptr<T> temp(orig);
00142       swap(temp);
00143       return *this;
00144     }
00145 
00146   // The following typedef, function, and operator definition
00147   // support the following syntax:
00148   //   value_ptr<T> ptr(..);
00149   //   if (ptr) { ...
00150   // Where the conditional will evaluate as true if and only if the
00151   // pointer value_ptr contains is not null.
00152   private:
00153     typedef void (value_ptr::*bool_type)() const;
00154     void this_type_does_not_support_comparisons() const {}
00155 
00156   public:
00157     operator bool_type() const {
00158       return myP != 0 ?
00159         &value_ptr<T>::this_type_does_not_support_comparisons : 0;
00160     }
00161 
00162   private:
00163 
00164     // --------------------------------------------------
00165     // Implementation aid:
00166     // --------------------------------------------------
00167 
00168     template <typename U>
00169     static T*
00170     createFrom(U const* p) {
00171       return p
00172         ? value_ptr_traits<U>::clone(p)
00173         : 0;
00174     }
00175 
00176     // --------------------------------------------------
00177     // Member data:
00178     // --------------------------------------------------
00179 
00180     T * myP;
00181 
00182   }; // value_ptr
00183 
00184 
00185   // --------------------------------------------------------------------
00186   //
00187   // Free-standing swap()
00188   //
00189   // --------------------------------------------------------------------
00190 
00191   template <typename T>
00192   inline
00193   void
00194   swap(value_ptr<T>& vp1, value_ptr<T>& vp2) { vp1.swap(vp2); }
00195 
00196   // Do not allow nonsensical comparisons that the bool_type
00197   // conversion operator definition above would otherwise allow.
00198   // The function call inside the next 4 operator definitions is
00199   // private, so compilation will fail if there is an attempt to
00200   // instantiate these 4 operators.
00201   template <typename T, typename U>
00202   inline bool operator==(value_ptr<T> const& lhs, U const& rhs) {
00203     lhs.this_type_does_not_support_comparisons();       
00204     return false;       
00205   }
00206 
00207   template <typename T, typename U>
00208   inline bool operator!=(value_ptr<T> const& lhs, U const& rhs) {
00209     lhs.this_type_does_not_support_comparisons();       
00210     return false;       
00211   }
00212 
00213   template <typename T, typename U>
00214   inline bool operator==(U const& lhs, value_ptr<T> const& rhs) {
00215     rhs.this_type_does_not_support_comparisons();       
00216     return false;       
00217   }
00218 
00219   template <typename T, typename U>
00220   inline bool operator!=(U const& lhs, value_ptr<T> const& rhs) {
00221     rhs.this_type_does_not_support_comparisons();       
00222     return false;       
00223   }
00224 }
00225 
00226 
00227 #endif // FWCoreUtilities_value_ptr_h