CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/DataFormats/Common/interface/RefProd.h

Go to the documentation of this file.
00001 #ifndef DataFormats_Common_RefProd_h
00002 #define DataFormats_Common_RefProd_h
00003 
00004 /*----------------------------------------------------------------------
00005   
00006 Ref: A template for an interproduct reference to a product.
00007 
00008 $Id: RefProd.h,v 1.20 2009/11/04 15:30:20 wmtan Exp $
00009 
00010 ----------------------------------------------------------------------*/
00011 
00012 /*----------------------------------------------------------------------
00013 //  This defines the public interface to the class RefProd<T>.
00014 //
00015 //  ProductID productID         is the product ID of the collection. (0 is invalid)
00016 //  RefProd<T> const& ref       is another RefProd<T>
00017 
00018 //  Constructors
00019     RefProd(); // Default constructor
00020     RefProd(RefProd<T> const& ref);     // Copy constructor  (default, not explicitly specified)
00021 
00022     RefProd(Handle<T> const& handle);
00023     RefProd(ProductID pid, EDProductGetter const* prodGetter);
00024 
00025 //  Destructor
00026     virtual ~RefProd() {}
00027 
00028 // Operators and methods
00029     RefProd<T>& operator=(RefProd<T> const&);   // assignment (default, not explicitly specified)
00030     T const& operator*() const;                 // dereference
00031     T const* operator->() const;                // member dereference
00032     bool operator==(RefProd<T> const& ref) const;       // equality
00033     bool operator!=(RefProd<T> const& ref) const;       // inequality
00034     bool operator<(RefProd<T> const& ref) const;        // ordering
00035     bool isNonnull() const;                     // true if an object is referenced
00036     bool isNull() const;                        // equivalent to !isNonnull()
00037     bool operator!() const;                     // equivalent to !isNonnull()
00038 ----------------------------------------------------------------------*/ 
00039 
00040 #include "DataFormats/Common/interface/EDProductfwd.h"
00041 #include "DataFormats/Common/interface/EDProductGetter.h"
00042 #include "DataFormats/Common/interface/RefCore.h"
00043 #include "DataFormats/Provenance/interface/ProductID.h"
00044 #include "DataFormats/Common/interface/Handle.h"
00045 #include "DataFormats/Common/interface/OrphanHandle.h"
00046 #include "DataFormats/Common/interface/TestHandle.h"
00047 
00048 namespace edm {
00049 
00050   template <typename C>
00051   class RefProd {
00052   public:
00053     typedef C product_type;
00054     typedef C value_type;
00055 
00057     RefProd() : product_() {}
00058 
00060     explicit RefProd(Handle<C> const& handle) :
00061     product_(handle.id(), handle.product(), 0, false) {
00062       checkTypeAtCompileTime(handle.product());
00063     }
00064 
00066     explicit RefProd(OrphanHandle<C> const& handle) :
00067     product_(handle.id(), handle.product(), 0, false) {
00068       checkTypeAtCompileTime(handle.product());
00069     }
00070 
00072     //  An exception will be thrown if an attempt is made to persistify
00073     //  any object containing this RefProd.  Also, in the future work will
00074     //  be done to throw an exception if an attempt is made to put any object
00075     //  containing this RefProd into an event(or run or lumi).
00076     RefProd(C const* product) :
00077       product_(ProductID(), product, 0, true) {
00078       checkTypeAtCompileTime(product);
00079     }
00080 
00082     //  An exception will be thrown if an attempt is made to persistify
00083     //  any object containing this RefProd.  Also, in the future work will
00084     //  be done to throw an exception if an attempt is made to put any object
00085     //  containing this RefProd into an event(or run or lumi).
00086     explicit RefProd(TestHandle<C> const& handle) :
00087     product_(handle.id(), handle.product(), 0, true) {
00088       checkTypeAtCompileTime(handle.product());
00089     }
00090 
00092     template <typename T, typename F>
00093     explicit RefProd(Ref<C, T, F> const& ref);
00094 
00096     template <typename T, typename F>
00097     explicit RefProd(RefVector<C, T, F> const& ref);
00098 
00099     // Constructor for those users who do not have a product handle,
00100     // but have a pointer to a product getter (such as the EventPrincipal).
00101     // prodGetter will ususally be a pointer to the event principal.
00102     RefProd(ProductID const& productID, EDProductGetter const* prodGetter) :
00103       product_(productID, 0, mustBeNonZero(prodGetter, "RefProd", productID), false) {
00104     }
00105 
00107     ~RefProd() {}
00108 
00110     product_type const& operator*() const;
00111 
00113     product_type const* operator->() const;
00114 
00117     product_type const* get() const {
00118       return isNull() ? 0 : this->operator->();
00119     }
00120 
00123     product_type const* product() const {
00124       return isNull() ? 0 : this->operator->();
00125     }
00126 
00127     RefCore const& refCore() const {
00128       return product_;
00129     }
00130 
00132     bool isNull() const {return !isNonnull();}
00133 
00135     bool isNonnull() const {return product_.isNonnull();}
00136 
00138     bool operator!() const {return isNull();}
00139 
00141     ProductID id() const {return product_.id();}
00142 
00144     EDProductGetter const* productGetter() const {return product_.productGetter();}
00145 
00147     bool hasCache() const {return product_.productPtr() != 0;}
00148 
00150     bool hasProductCache() const {return hasCache();}
00151 
00154     bool isAvailable() const {return product_.isAvailable();}
00155 
00157     bool isTransient() const {return product_.isTransient();}
00158 
00159     void swap(RefProd<C> &);
00160 
00161   private:
00162     // Compile time check that the argument is a C* or C const*
00163     // or derived from it.
00164     void checkTypeAtCompileTime(C const* ptr) {}
00165 
00166     RefCore product_;
00167   };
00168 }
00169 
00170 #include "DataFormats/Common/interface/Ref.h"
00171 #include "DataFormats/Common/interface/RefCoreGet.h"
00172 
00173 namespace edm {
00174   template<typename C, typename T, typename F>
00175   class RefVector;
00176 
00178   template <typename C>
00179   template <typename T, typename F>
00180   inline
00181   RefProd<C>::RefProd(Ref<C, T, F> const& ref) :
00182       product_(ref.id(), ref.hasProductCache() ?  ref.product() : 0, ref.productGetter(), ref.isTransient()) 
00183   {  }
00184 
00186   template <typename C>
00187   template <typename T, typename F>
00188   inline
00189   RefProd<C>::RefProd(RefVector<C, T, F> const& ref) :
00190       product_(ref.id(), ref.hasProductCache() ?  ref.product() : 0, ref.productGetter(), ref.isTransient()) 
00191   {  }
00192 
00194   template <typename C>
00195   inline
00196   C const& RefProd<C>::operator*() const {
00197     return *(edm::template getProduct<C>(product_));
00198   }
00199 
00201   template <typename C>
00202   inline
00203   C const* RefProd<C>::operator->() const {
00204     return edm::template getProduct<C>(product_);
00205   } 
00206 
00207 
00208   template<typename C>
00209   inline
00210   void RefProd<C>::swap(RefProd<C> & other) {
00211     std::swap(product_, other.product_);
00212   }
00213 
00214   template <typename C>
00215   inline
00216   bool
00217   operator== (RefProd<C> const& lhs, RefProd<C> const& rhs) {
00218     return lhs.refCore() == rhs.refCore();
00219   }
00220 
00221   template <typename C>
00222   inline
00223   bool
00224   operator!= (RefProd<C> const& lhs, RefProd<C> const& rhs) {
00225     return !(lhs == rhs);
00226   }
00227 
00228   template <typename C>
00229   inline
00230   bool
00231   operator< (RefProd<C> const& lhs, RefProd<C> const& rhs) {
00232     return (lhs.refCore() < rhs.refCore());
00233   }
00234 
00235   template<typename C>
00236   inline
00237   void swap(edm::RefProd<C> const& lhs, edm::RefProd<C> const& rhs ) {
00238     lhs.swap(rhs);
00239   }
00240 }
00241 
00242 #include "DataFormats/Common/interface/HolderToVectorTrait.h"
00243 
00244 namespace edm {
00245   namespace reftobase {
00246 
00247     template <typename T>
00248     struct RefProdHolderToVector {
00249       static  std::auto_ptr<BaseVectorHolder<T> > makeVectorHolder() {
00250         Exception::throwThis(errors::InvalidReference, "attempting to make a BaseVectorHolder<T> from a RefProd<C>.\n");
00251         return std::auto_ptr<BaseVectorHolder<T> >();
00252       }
00253       static std::auto_ptr<RefVectorHolderBase> makeVectorBaseHolder() {
00254         Exception::throwThis(errors::InvalidReference, "attempting to make a RefVectorHolderBase from a RefProd<C>.\n");
00255         return std::auto_ptr<RefVectorHolderBase>();
00256       }
00257     };
00258 
00259     template<typename C, typename T>
00260     struct HolderToVectorTrait<T, RefProd<C> > {
00261       typedef RefProdHolderToVector<T> type;
00262     };
00263 
00264     struct RefProdRefHolderToRefVector {
00265       static  std::auto_ptr<RefVectorHolderBase> makeVectorHolder() {
00266         Exception::throwThis(errors::InvalidReference, "attempting to make a BaseVectorHolder<T> from a RefProd<C>.\n");
00267         return std::auto_ptr<RefVectorHolderBase>();
00268       }
00269       static  std::auto_ptr<RefVectorHolderBase> makeVectorBaseHolder() {
00270         Exception::throwThis(errors::InvalidReference, "attempting to make a RefVectorHolderBase from a RefProd<C>.\n");
00271         return std::auto_ptr<RefVectorHolderBase>();
00272       }
00273     };
00274 
00275     template<typename C>
00276     struct RefHolderToRefVectorTrait<RefProd<C> > {
00277       typedef RefProdRefHolderToRefVector type;
00278     };
00279 
00280   }
00281 }
00282 
00283 #endif