Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:53:02

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 for null
0070     bool operator!() const { return isNull(); }
0071 
0072     /// Accessor for product ID.
0073     ProductID id() const { return product_.id(); }
0074 
0075     /// Accessor for product getter.
0076     EDProductGetter const* productGetter() const { return product_.productGetter(); }
0077 
0078     /// Checks if product is in memory.
0079     bool hasCache() const { return product_.productPtr() != nullptr; }
0080 
0081     RefToBaseProd<T>& operator=(const RefToBaseProd<T>& other);
0082 
0083     void swap(RefToBaseProd<T>&);
0084 
0085     //Needed for ROOT storage
0086     CMS_CLASS_VERSION(10)
0087   private:
0088     //NOTE: Access to RefCore should be private since we modify the use of productPtr
0089     RefCore const& refCore() const { return product_; }
0090 
0091     View<T> const* viewPtr() const { return reinterpret_cast<const View<T>*>(product_.productPtr()); }
0092 
0093     RefCore product_;
0094   };
0095 
0096   template <typename T>
0097   inline RefToBaseProd<T>::RefToBaseProd(Handle<View<T>> const& handle)
0098       : product_(handle.id(), nullptr, nullptr, false) {
0099     product_.setProductPtr(new View<T>(*handle));
0100   }
0101 
0102   template <typename T>
0103   inline RefToBaseProd<T>::RefToBaseProd(const RefToBaseProd<T>& ref) : product_(ref.product_) {
0104     if (product_.productPtr()) {
0105       product_.setProductPtr(ref.viewPtr() ? (new View<T>(*ref)) : nullptr);
0106     }
0107   }
0108 
0109   template <typename T>
0110   inline RefToBaseProd<T>& RefToBaseProd<T>::operator=(const RefToBaseProd<T>& other) {
0111     RefToBaseProd<T> temp(other);
0112     this->swap(temp);
0113     return *this;
0114   }
0115 
0116   /// Dereference operator
0117   template <typename T>
0118   inline View<T> const& RefToBaseProd<T>::operator*() const {
0119     return *operator->();
0120   }
0121 
0122   /// Member dereference operator
0123   template <typename T>
0124   inline View<T> const* RefToBaseProd<T>::operator->() const {
0125     //Another thread might change the value returned so just get it once
0126     auto getter = product_.productGetter();
0127     if (getter != nullptr) {
0128       if (product_.isNull()) {
0129         Exception::throwThis(errors::InvalidReference, "attempting get view from a null RefToBaseProd.\n");
0130       }
0131       ProductID tId = product_.id();
0132       std::vector<void const*> pointers;
0133       FillViewHelperVector helpers;
0134       WrapperBase const* prod = getter->getIt(tId);
0135       if (prod == nullptr) {
0136         Exception::throwThis(errors::InvalidReference, "attempting to get view from an unavailable RefToBaseProd.");
0137       }
0138       prod->fillView(tId, pointers, helpers);
0139       std::unique_ptr<View<T>> tmp{new View<T>(pointers, helpers, getter)};
0140       if (product_.tryToSetProductPtrForFirstTime(tmp.get())) {
0141         tmp.release();
0142       }
0143     }
0144     return viewPtr();
0145   }
0146 
0147   template <typename T>
0148   inline void RefToBaseProd<T>::swap(RefToBaseProd<T>& other) {
0149     edm::swap(product_, other.product_);
0150   }
0151 
0152   template <typename T>
0153   inline bool operator==(RefToBaseProd<T> const& lhs, RefToBaseProd<T> const& rhs) {
0154     return lhs.refCore() == rhs.refCore();
0155   }
0156 
0157   template <typename T>
0158   inline bool operator!=(RefToBaseProd<T> const& lhs, RefToBaseProd<T> const& rhs) {
0159     return !(lhs == rhs);
0160   }
0161 
0162   template <typename T>
0163   inline bool operator<(RefToBaseProd<T> const& lhs, RefToBaseProd<T> const& rhs) {
0164     return (lhs.refCore() < rhs.refCore());
0165   }
0166 
0167   template <typename T>
0168   inline void swap(edm::RefToBaseProd<T> const& lhs, edm::RefToBaseProd<T> const& rhs) {
0169     lhs.swap(rhs);
0170   }
0171 }  // namespace edm
0172 
0173 #include "DataFormats/Common/interface/FillView.h"
0174 
0175 namespace edm {
0176   template <typename T>
0177   template <typename C>
0178   inline RefToBaseProd<T>::RefToBaseProd(const RefProd<C>& ref) : product_(ref.refCore()) {
0179     std::vector<void const*> pointers;
0180     FillViewHelperVector helpers;
0181     fillView(*ref.product(), ref.id(), pointers, helpers);
0182     product_.setProductPtr(new View<T>(pointers, helpers, ref.refCore().productGetter()));
0183   }
0184 
0185   template <typename T>
0186   template <typename C>
0187   inline RefToBaseProd<T>::RefToBaseProd(Handle<C> const& handle)
0188       : product_(handle.id(), handle.product(), nullptr, false) {
0189     std::vector<void const*> pointers;
0190     FillViewHelperVector helpers;
0191     fillView(*handle, handle.id(), pointers, helpers);
0192     product_.setProductPtr(new View<T>(pointers, helpers, nullptr));
0193   }
0194 
0195   template <typename T>
0196   template <typename C>
0197   inline RefToBaseProd<T>::RefToBaseProd(OrphanHandle<C> const& handle)
0198       : product_(handle.id(), handle.product(), nullptr, false) {
0199     std::vector<void const*> pointers;
0200     FillViewHelperVector helpers;
0201     fillView(*handle, handle.id(), pointers, helpers);
0202     product_.setProductPtr(new View<T>(pointers, helpers, nullptr));
0203   }
0204 
0205   template <typename T>
0206   inline RefToBaseProd<T>::RefToBaseProd(ProductID const& id, EDProductGetter const* getter)
0207       : product_(id, nullptr, getter, false) {}
0208 }  // namespace edm
0209 
0210 #endif