CMS 3D CMS Logo

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