Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:03:53

0001 #ifndef DataFormats_Common_RefToBaseProd_h
0002 #define DataFormats_Common_RefToBaseProd_h
0003 
0004 /* \class edm::RefToBaseProd<T>
0005  *
0006  * \author Luca Lista, INFN
0007  *
0008  */
0009 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
0010 
0011 #include "DataFormats/Common/interface/EDProductfwd.h"
0012 #include "DataFormats/Common/interface/FillView.h"
0013 #include "DataFormats/Common/interface/FillViewHelperVector.h"
0014 #include "DataFormats/Common/interface/Handle.h"
0015 #include "DataFormats/Common/interface/OrphanHandle.h"
0016 #include "DataFormats/Common/interface/RefCore.h"
0017 #include "DataFormats/Common/interface/RefProd.h"
0018 #include "DataFormats/Common/interface/View.h"
0019 #include "DataFormats/Common/interface/WrapperBase.h"
0020 #include "DataFormats/Provenance/interface/ProductID.h"
0021 #include "FWCore/Utilities/interface/EDMException.h"
0022 
0023 #include <utility>
0024 #include <vector>
0025 
0026 namespace edm {
0027 
0028   template <typename T>
0029   class RefToBaseProd {
0030   public:
0031     typedef View<T> product_type;
0032 
0033     /// Default constructor needed for reading from persistent store. Not for direct use.
0034     RefToBaseProd() : product_() {}
0035 
0036     template <typename C>
0037     explicit RefToBaseProd(Handle<C> const& handle);
0038     explicit RefToBaseProd(Handle<View<T>> const& handle);
0039     template <typename C>
0040     explicit RefToBaseProd(OrphanHandle<C> const& handle);
0041     RefToBaseProd(const RefToBaseProd<T>&);
0042     template <typename C>
0043     explicit RefToBaseProd(const RefProd<C>&);
0044     RefToBaseProd(ProductID const&, EDProductGetter const*);
0045 
0046     /// Destructor
0047     ~RefToBaseProd() { delete viewPtr(); }
0048 
0049     /// Dereference operator
0050     product_type const& operator*() const;
0051 
0052     /// Member dereference operator
0053     product_type const* operator->() const;
0054 
0055     /// Returns C++ pointer to the product
0056     /// Will attempt to retrieve product
0057     product_type const* get() const { return isNull() ? nullptr : this->operator->(); }
0058 
0059     /// Returns C++ pointer to the product
0060     /// Will attempt to retrieve product
0061     product_type const* product() const { return isNull() ? 0 : this->operator->(); }
0062 
0063     /// Checks for null
0064     bool isNull() const { return !isNonnull(); }
0065 
0066     /// Checks for non-null
0067     bool isNonnull() const { return product_.isNonnull(); }
0068 
0069     /// Checks if collection is in memory or available
0070     /// in the Event. No type checking is done.
0071     /// This function is potentially costly as it might cause a disk
0072     /// read (note that it does not cause the data to be cached locally)
0073     bool isAvailable() const { return product_.isAvailable(); }
0074 
0075     /// Checks for null
0076     bool operator!() const { return isNull(); }
0077 
0078     /// Accessor for product ID.
0079     ProductID id() const { return product_.id(); }
0080 
0081     /// Accessor for product getter.
0082     EDProductGetter const* productGetter() const { return product_.productGetter(); }
0083 
0084     /// Checks if product is in memory.
0085     bool hasCache() const { return product_.productPtr() != nullptr; }
0086 
0087     RefToBaseProd<T>& operator=(const RefToBaseProd<T>& other);
0088 
0089     void swap(RefToBaseProd<T>&);
0090 
0091     //Needed for ROOT storage
0092     CMS_CLASS_VERSION(10)
0093   private:
0094     //NOTE: Access to RefCore should be private since we modify the use of productPtr
0095     RefCore const& refCore() const { return product_; }
0096 
0097     View<T> const* viewPtr() const { return reinterpret_cast<const View<T>*>(product_.productPtr()); }
0098 
0099     RefCore product_;
0100   };
0101 
0102   template <typename T>
0103   inline RefToBaseProd<T>::RefToBaseProd(Handle<View<T>> const& handle)
0104       : product_(handle.id(), nullptr, nullptr, false) {
0105     product_.setProductPtr(new View<T>(*handle));
0106   }
0107 
0108   template <typename T>
0109   inline RefToBaseProd<T>::RefToBaseProd(const RefToBaseProd<T>& ref) : product_(ref.product_) {
0110     if (product_.productPtr()) {
0111       product_.setProductPtr(ref.viewPtr() ? (new View<T>(*ref)) : nullptr);
0112     }
0113   }
0114 
0115   template <typename T>
0116   inline RefToBaseProd<T>& RefToBaseProd<T>::operator=(const RefToBaseProd<T>& other) {
0117     RefToBaseProd<T> temp(other);
0118     this->swap(temp);
0119     return *this;
0120   }
0121 
0122   /// Dereference operator
0123   template <typename T>
0124   inline View<T> const& RefToBaseProd<T>::operator*() const {
0125     return *operator->();
0126   }
0127 
0128   /// Member dereference operator
0129   template <typename T>
0130   inline View<T> const* RefToBaseProd<T>::operator->() const {
0131     //Another thread might change the value returned so just get it once
0132     auto getter = product_.productGetter();
0133     if (getter != nullptr) {
0134       if (product_.isNull()) {
0135         Exception::throwThis(errors::InvalidReference, "attempting get view from a null RefToBaseProd.\n");
0136       }
0137       ProductID tId = product_.id();
0138       std::vector<void const*> pointers;
0139       FillViewHelperVector helpers;
0140       WrapperBase const* prod = getter->getIt(tId);
0141       if (prod == nullptr) {
0142         Exception::throwThis(errors::InvalidReference, "attempting to get view from an unavailable RefToBaseProd.");
0143       }
0144       prod->fillView(tId, pointers, helpers);
0145       std::unique_ptr<View<T>> tmp{new View<T>(pointers, helpers, getter)};
0146       if (product_.tryToSetProductPtrForFirstTime(tmp.get())) {
0147         tmp.release();
0148       }
0149     }
0150     return viewPtr();
0151   }
0152 
0153   template <typename T>
0154   inline void RefToBaseProd<T>::swap(RefToBaseProd<T>& other) {
0155     edm::swap(product_, other.product_);
0156   }
0157 
0158   template <typename T>
0159   inline bool operator==(RefToBaseProd<T> const& lhs, RefToBaseProd<T> const& rhs) {
0160     return lhs.refCore() == rhs.refCore();
0161   }
0162 
0163   template <typename T>
0164   inline bool operator!=(RefToBaseProd<T> const& lhs, RefToBaseProd<T> const& rhs) {
0165     return !(lhs == rhs);
0166   }
0167 
0168   template <typename T>
0169   inline bool operator<(RefToBaseProd<T> const& lhs, RefToBaseProd<T> const& rhs) {
0170     return (lhs.refCore() < rhs.refCore());
0171   }
0172 
0173   template <typename T>
0174   inline void swap(edm::RefToBaseProd<T> const& lhs, edm::RefToBaseProd<T> const& rhs) {
0175     lhs.swap(rhs);
0176   }
0177 }  // namespace edm
0178 
0179 #include "DataFormats/Common/interface/FillView.h"
0180 
0181 namespace edm {
0182   template <typename T>
0183   template <typename C>
0184   inline RefToBaseProd<T>::RefToBaseProd(const RefProd<C>& ref) : product_(ref.refCore()) {
0185     std::vector<void const*> pointers;
0186     FillViewHelperVector helpers;
0187     fillView(*ref.product(), ref.id(), pointers, helpers);
0188     product_.setProductPtr(new View<T>(pointers, helpers, ref.refCore().productGetter()));
0189   }
0190 
0191   template <typename T>
0192   template <typename C>
0193   inline RefToBaseProd<T>::RefToBaseProd(Handle<C> const& handle)
0194       : product_(handle.id(), handle.product(), nullptr, false) {
0195     std::vector<void const*> pointers;
0196     FillViewHelperVector helpers;
0197     fillView(*handle, handle.id(), pointers, helpers);
0198     product_.setProductPtr(new View<T>(pointers, helpers, nullptr));
0199   }
0200 
0201   template <typename T>
0202   template <typename C>
0203   inline RefToBaseProd<T>::RefToBaseProd(OrphanHandle<C> const& handle)
0204       : product_(handle.id(), handle.product(), nullptr, false) {
0205     std::vector<void const*> pointers;
0206     FillViewHelperVector helpers;
0207     fillView(*handle, handle.id(), pointers, helpers);
0208     product_.setProductPtr(new View<T>(pointers, helpers, nullptr));
0209   }
0210 
0211   template <typename T>
0212   inline RefToBaseProd<T>::RefToBaseProd(ProductID const& id, EDProductGetter const* getter)
0213       : product_(id, nullptr, getter, false) {}
0214 }  // namespace edm
0215 
0216 #endif