CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/DataFormats/Common/interface/Ptr.h

Go to the documentation of this file.
00001 #ifndef DataFormats_Common_Ptr_h
00002 #define DataFormats_Common_Ptr_h
00003 // -*- C++ -*-
00004 //
00005 // Package:     Common
00006 // Class  :     Ptr
00007 //
00016 //
00017 // Original Author:  Chris Jones
00018 //         Created:  Thu Oct 18 14:41:33 CEST 2007
00019 //
00020 
00021 // system include files
00022 #include "boost/type_traits/is_base_of.hpp"
00023 #include "boost/utility/enable_if.hpp"
00024 
00025 // user include files
00026 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
00027 #include "DataFormats/Common/interface/RefCore.h"
00028 #include "DataFormats/Common/interface/traits.h"
00029 #include "DataFormats/Common/interface/GetProduct.h"
00030 #include "DataFormats/Common/interface/EDProduct.h"
00031 #include "DataFormats/Common/interface/EDProductGetter.h"
00032 #include "DataFormats/Common/interface/Handle.h"
00033 #include "DataFormats/Common/interface/OrphanHandle.h"
00034 #include "DataFormats/Common/interface/TestHandle.h"
00035 
00036 // forward declarations
00037 namespace edm {
00038   template <typename T>
00039   class Ptr {
00040      friend class PtrVectorBase;
00041   public:
00042 
00043     typedef unsigned long key_type;
00044     typedef T   value_type;
00045 
00046     // General purpose constructor from handle.
00047     template <typename C>
00048     Ptr(Handle<C> const& handle, key_type itemKey, bool setNow=true):
00049     core_(handle.id(), getItem_(handle.product(), itemKey), 0, false), key_(itemKey) {}
00050 
00051     // General purpose constructor from orphan handle.
00052     template <typename C>
00053     Ptr(OrphanHandle<C> const& handle, key_type itemKey, bool setNow=true):
00054     core_(handle.id(), getItem_(handle.product(), itemKey), 0, false), key_(itemKey) {}
00055 
00056     // General purpose "constructor" from a Ref.
00057     // Use the conversion function template:
00058     // ptr = refToPtr(ref)
00059     // defined in DataFormats/Common/interface/RefToPtr.h
00060     // to construct a Ptr<T> from a Ref<C>, where T is C::value_type.
00061 
00062     // Constructor for ref to object that is not in an event.
00063     // An exception will be thrown if an attempt is made to persistify
00064     // any object containing this Ptr.  Also, in the future work will
00065     // be done to throw an exception if an attempt is made to put any object
00066     // containing this Ptr into an event(or run or lumi).
00067     template <typename C>
00068     Ptr(C const* product, key_type itemKey, bool setNow=true):
00069     core_(ProductID(), product != 0 ? getItem_(product,itemKey) : 0, 0, true),
00070          key_(product != 0 ? itemKey : key_traits<key_type>::value) {}
00071 
00072     // Constructor from test handle.
00073     // An exception will be thrown if an attempt is made to persistify
00074     // any object containing this Ptr.
00075     template <typename C>
00076     Ptr(TestHandle<C> const& handle, key_type itemKey, bool setNow=true):
00077     core_(handle.id(), getItem_(handle.product(), itemKey), 0, true), key_(itemKey) {}
00078 
00082     Ptr(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter) :
00083     core_(productID, 0, mustBeNonZero(prodGetter, "Ptr", productID), false), key_(itemKey) {
00084     }
00085 
00093     Ptr(ProductID const& productID, T const* item, key_type item_key) :
00094     core_(productID, item, 0, false),
00095     key_(item_key) {
00096     }
00097 
00102     explicit Ptr(ProductID const& id) :
00103     core_(id, 0, 0, false),
00104     key_(key_traits<key_type>::value)
00105     { }
00106 
00107     Ptr():
00108     core_(),
00109     key_(key_traits<key_type>::value)
00110     {}
00111 
00112     Ptr(Ptr<T> const& iOther):
00113     core_(iOther.core_),
00114     key_(iOther.key_)
00115     {}
00116 
00117     template<typename U>
00118     Ptr(Ptr<U> const& iOther, typename boost::enable_if_c<boost::is_base_of<T, U>::value>::type * = 0):
00119     core_(iOther.id(),
00120           (iOther.hasProductCache() ? static_cast<T const*>(iOther.get()): static_cast<T const*>(0)),
00121           iOther.productGetter(),
00122           iOther.isTransient()),
00123     key_(iOther.key()) {
00124     }
00125 
00126     template<typename U>
00127     explicit
00128     Ptr(Ptr<U> const& iOther, typename boost::enable_if_c<boost::is_base_of<U, T>::value>::type * = 0):
00129     core_(iOther.id(),
00130           dynamic_cast<T const*>(iOther.get()),
00131           0,
00132           iOther.isTransient()),
00133     key_(iOther.key()) {
00134     }
00135 
00137     ~Ptr() {}
00138 
00140     T const&
00141     operator*() const;
00142 
00144     T const*
00145     operator->() const;
00146 
00148     T const* get() const {
00149       return isNull() ? 0 : this->operator->();
00150     }
00151 
00153     bool isNull() const {return !isNonnull(); }
00154 
00156     //bool isNonnull() const {return id().isValid(); }
00157     bool isNonnull() const {return key_traits<key_type>::value != key_;}
00159     bool operator!() const {return isNull();}
00160 
00163     bool isAvailable() const {return core_.isAvailable();}
00164 
00166     bool isTransient() const {return core_.isTransient();}
00167 
00169     ProductID id() const {return core_.id();}
00170 
00172     EDProductGetter const* productGetter() const {return core_.productGetter();}
00173 
00174     key_type key() const {return key_;}
00175 
00176     bool hasProductCache() const { return 0 != core_.productPtr(); }
00177 
00178     RefCore const& refCore() const {return core_;}
00179     // ---------- member functions ---------------------------
00180 
00181     void const* product() const {return 0;}
00182     
00183     //Used by ROOT storage
00184     CMS_CLASS_VERSION(10)
00185 
00186   private:
00187     //Ptr(Ptr const&); // stop default
00188 
00190     Ptr(T const* item, key_type item_key) :
00191     core_(ProductID(), item, 0, true),
00192     key_(item_key) {
00193     }
00194 
00195     //Ptr const& operator=(Ptr const&); // stop default
00196     template<typename C>
00197     T const* getItem_(C const* product, key_type iKey);
00198 
00199     void getData_() const {
00200       if(!hasProductCache() && 0 != productGetter()) {
00201         void const* ad = 0;
00202         EDProduct const* prod = productGetter()->getIt(core_.id());
00203         if(prod == 0) {
00204           core_.productNotFoundException(typeid(T));
00205         }
00206         prod->setPtr(typeid(T), key_, ad);
00207         core_.setProductPtr(ad);
00208       }
00209     }
00210     // ---------- member data --------------------------------
00211     RefCore core_;
00212     key_type key_;
00213   };
00214 
00215   template<typename T>
00216   template<typename C>
00217   T const* Ptr<T>::getItem_(C const* product, key_type iKey) {
00218     assert (product != 0);
00219     typename C::const_iterator it = product->begin();
00220     std::advance(it,iKey);
00221     T const* address = detail::GetProduct<C>::address(it);
00222     return address;
00223   }
00224 
00226   template <typename T>
00227   inline
00228   T const&
00229   Ptr<T>::operator*() const {
00230     getData_();
00231     return *reinterpret_cast<T const*>(core_.productPtr());
00232   }
00233 
00235   template <typename T>
00236   inline
00237   T const*
00238   Ptr<T>::operator->() const {
00239     getData_();
00240     return reinterpret_cast<T const*>(core_.productPtr());
00241   }
00242 
00243   template <typename T>
00244   inline
00245   bool
00246   operator==(Ptr<T> const& lhs, Ptr<T> const& rhs) {
00247     return lhs.refCore() == rhs.refCore() && lhs.key() == rhs.key();
00248   }
00249 
00250   template <typename T>
00251   inline
00252   bool
00253   operator!=(Ptr<T> const& lhs, Ptr<T> const& rhs) {
00254     return !(lhs == rhs);
00255   }
00256 
00257   template <typename T>
00258   inline
00259   bool
00260   operator<(Ptr<T> const& lhs, Ptr<T> const& rhs) {
00263     return (lhs.refCore() == rhs.refCore() ? lhs.key() < rhs.key() : lhs.refCore() < rhs.refCore());
00264   }
00265 
00266 }
00267 
00268 #endif