CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/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     explicit value_ptr(T* p = 0) : myP(p) { }
00071     ~value_ptr() { delete myP; }
00072 
00073     // --------------------------------------------------
00074     // Copy constructor/copy assignment:
00075     // --------------------------------------------------
00076 
00077     value_ptr(value_ptr const& orig) :
00078       myP(createFrom(orig.myP)) {
00079     }
00080 
00081     value_ptr& operator= (value_ptr const& orig) {
00082       value_ptr<T> temp(orig);
00083       swap(temp);
00084       return *this;
00085     }
00086 
00087     // --------------------------------------------------
00088     // Access mechanisms:
00089     // --------------------------------------------------
00090 
00091     T& operator*() const { return *myP; }
00092     T* operator->() const { return myP; }
00093 
00094     // --------------------------------------------------
00095     // Manipulation:
00096     // --------------------------------------------------
00097 
00098     void swap(value_ptr& orig) { std::swap(myP, orig.myP); }
00099 
00100     // --------------------------------------------------
00101     // Copy-like construct/assign from compatible value_ptr<>:
00102     // --------------------------------------------------
00103 
00104     template <typename U>
00105     value_ptr(value_ptr<U> const& orig) :
00106       myP(createFrom(orig.operator->())) {
00107     }
00108 
00109     template <typename U>
00110     value_ptr& operator=(value_ptr<U> const& orig) {
00111       value_ptr<T> temp(orig);
00112       swap(temp);
00113       return *this;
00114     }
00115 
00116     // --------------------------------------------------
00117     // Copy-like construct/assign from auto_ptr<>:
00118     // --------------------------------------------------
00119 
00120     value_ptr(std::auto_ptr<T> orig) :
00121       myP(orig.release()) {
00122     }
00123 
00124     value_ptr& operator=(std::auto_ptr<T> orig) {
00125       value_ptr<T> temp(orig);
00126       swap(temp);
00127       return *this;
00128     }
00129 
00130   // The following typedef, function, and operator definition
00131   // support the following syntax:
00132   //   value_ptr<T> ptr(..);
00133   //   if (ptr) { ...
00134   // Where the conditional will evaluate as true if and only if the
00135   // pointer value_ptr contains is not null.
00136   private:
00137     typedef void (value_ptr::*bool_type)() const;
00138     void this_type_does_not_support_comparisons() const {}
00139 
00140   public:
00141     operator bool_type() const {
00142       return myP != 0 ?
00143         &value_ptr<T>::this_type_does_not_support_comparisons : 0;
00144     }
00145 
00146   private:
00147 
00148     // --------------------------------------------------
00149     // Implementation aid:
00150     // --------------------------------------------------
00151 
00152     template <typename U>
00153     T*
00154     createFrom(U const* p) const {
00155       return p
00156         ? value_ptr_traits<U>::clone(p)
00157         : 0;
00158     }
00159 
00160     // --------------------------------------------------
00161     // Member data:
00162     // --------------------------------------------------
00163 
00164     T * myP;
00165 
00166   }; // value_ptr
00167 
00168 
00169   // --------------------------------------------------------------------
00170   //
00171   // Free-standing swap()
00172   //
00173   // --------------------------------------------------------------------
00174 
00175   template <typename T>
00176   inline
00177   void
00178   swap(value_ptr<T>& vp1, value_ptr<T>& vp2) { vp1.swap(vp2); }
00179 
00180   // Do not allow nonsensical comparisons that the bool_type
00181   // conversion operator definition above would otherwise allow.
00182   // The function call inside the next 4 operator definitions is
00183   // private, so compilation will fail if there is an attempt to
00184   // instantiate these 4 operators.
00185   template <typename T, typename U>
00186   bool operator==(value_ptr<T> const& lhs, U const& rhs) {
00187     lhs.this_type_does_not_support_comparisons();       
00188     return false;       
00189   }
00190 
00191   template <typename T, typename U>
00192   bool operator!=(value_ptr<T> const& lhs, U const& rhs) {
00193     lhs.this_type_does_not_support_comparisons();       
00194     return false;       
00195   }
00196 
00197   template <typename T, typename U>
00198   bool operator==(U const& lhs, value_ptr<T> const& rhs) {
00199     rhs.this_type_does_not_support_comparisons();       
00200     return false;       
00201   }
00202 
00203   template <typename T, typename U>
00204   bool operator!=(U const& lhs, value_ptr<T> const& rhs) {
00205     rhs.this_type_does_not_support_comparisons();       
00206     return false;       
00207   }
00208 }
00209 
00210 
00211 #endif // FWCoreUtilities_value_ptr_h