Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-12-12 03:12:11

0001 #ifndef DataFormats_Common_Wrapper_h
0002 #define DataFormats_Common_Wrapper_h
0003 
0004 /*----------------------------------------------------------------------
0005 
0006 Wrapper: A template wrapper around EDProducts to hold the product ID.
0007 
0008 ----------------------------------------------------------------------*/
0009 
0010 #include "DataFormats/Common/interface/Uninitialized.h"
0011 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
0012 #include "DataFormats/Common/interface/WrapperBase.h"
0013 #include "DataFormats/Common/interface/WrapperDetail.h"
0014 #include "DataFormats/Provenance/interface/ProductID.h"
0015 #include "FWCore/Utilities/interface/Visibility.h"
0016 
0017 #include <algorithm>
0018 #include <cassert>
0019 #include <memory>
0020 #include <string>
0021 #include <typeinfo>
0022 
0023 namespace edm {
0024   template <typename T>
0025   class Wrapper : public WrapperBase {
0026   public:
0027     typedef T value_type;
0028     typedef T wrapped_type;  // used with the dictionary to identify Wrappers
0029     Wrapper() : WrapperBase(), obj{construct_()}, present(false) {}
0030     explicit Wrapper(std::unique_ptr<T> ptr);
0031     Wrapper(Wrapper<T> const& rh) = delete;             // disallow copy construction
0032     Wrapper<T>& operator=(Wrapper<T> const&) = delete;  // disallow assignment
0033 
0034     template <typename... Args>
0035     explicit Wrapper(Emplace, Args&&...);
0036     ~Wrapper() override {}
0037     T const* product() const { return (present ? &obj : nullptr); }
0038     T const* operator->() const { return product(); }
0039 
0040     T& bareProduct() { return obj; }
0041 
0042     //these are used by FWLite
0043     static std::type_info const& productTypeInfo() { return typeid(T); }
0044     static std::type_info const& typeInfo() { return typeid(Wrapper<T>); }
0045 
0046     // the constructor takes ownership of T*
0047     Wrapper(T*);
0048 
0049     //Used by ROOT storage
0050     CMS_CLASS_VERSION(4)
0051 
0052   private:
0053     constexpr T construct_() {
0054       if constexpr (requires { T(); }) {
0055         return T();
0056       } else {
0057         return T(edm::kUninitialized);
0058       }
0059     }
0060 
0061     bool isPresent_() const override { return present; }
0062     std::type_info const& dynamicTypeInfo_() const override { return typeid(T); }
0063     std::type_info const& wrappedTypeInfo_() const override { return typeid(Wrapper<T>); }
0064 
0065     std::type_info const& valueTypeInfo_() const override;
0066     std::type_info const& memberTypeInfo_() const override;
0067     bool isMergeable_() const override;
0068     bool mergeProduct_(WrapperBase const* newProduct) override;
0069     bool hasIsProductEqual_() const override;
0070     bool isProductEqual_(WrapperBase const* newProduct) const override;
0071     bool hasSwap_() const override;
0072     void swapProduct_(WrapperBase* newProduct) override;
0073 
0074     void do_fillView(ProductID const& id,
0075                      std::vector<void const*>& pointers,
0076                      FillViewHelperVector& helpers) const override;
0077     void do_setPtr(std::type_info const& iToType, unsigned long iIndex, void const*& oPtr) const override;
0078     void do_fillPtrVector(std::type_info const& iToType,
0079                           std::vector<unsigned long> const& iIndices,
0080                           std::vector<void const*>& oPtr) const override;
0081 
0082     std::shared_ptr<soa::TableExaminerBase> tableExaminer_() const override;
0083 
0084   private:
0085     T obj;
0086     bool present;
0087   };
0088 
0089   template <typename T>
0090   Wrapper<T>::Wrapper(std::unique_ptr<T> ptr) : WrapperBase(), obj{construct_()}, present(ptr.get() != nullptr) {
0091     if (present) {
0092       obj = std::move(*ptr);
0093     }
0094   }
0095 
0096   template <typename T>
0097   template <typename... Args>
0098   Wrapper<T>::Wrapper(Emplace, Args&&... args) : WrapperBase(), obj(std::forward<Args>(args)...), present(true) {}
0099 
0100   template <typename T>
0101   Wrapper<T>::Wrapper(T* ptr) : WrapperBase(), present(ptr != 0), obj{construct_()} {
0102     std::unique_ptr<T> temp(ptr);
0103     if (present) {
0104       obj = std::move(*ptr);
0105     }
0106   }
0107 
0108   template <typename T>
0109   inline std::type_info const& Wrapper<T>::valueTypeInfo_() const {
0110     return detail::getValueType<T>()();
0111   }
0112 
0113   template <typename T>
0114   inline std::type_info const& Wrapper<T>::memberTypeInfo_() const {
0115     return detail::getMemberType<T>()();
0116   }
0117 
0118   template <typename T>
0119   inline bool Wrapper<T>::isMergeable_() const {
0120     if constexpr (requires(T& a, T const& b) { a.mergeProduct(b); }) {
0121       return true;
0122     }
0123     return false;
0124   }
0125 
0126   template <typename T>
0127   inline bool Wrapper<T>::mergeProduct_(WrapperBase const* newProduct) {
0128     Wrapper<T> const* wrappedNewProduct = dynamic_cast<Wrapper<T> const*>(newProduct);
0129     assert(wrappedNewProduct != nullptr);
0130     if constexpr (requires(T& a, T const& b) { a.mergeProduct(b); }) {
0131       return obj.mergeProduct(wrappedNewProduct->obj);
0132     }
0133     return true;
0134   }
0135 
0136   template <typename T>
0137   inline bool Wrapper<T>::hasIsProductEqual_() const {
0138     if constexpr (requires(T& a, T const& b) { a.isProductEqual(b); }) {
0139       return true;
0140     }
0141     return false;
0142   }
0143 
0144   template <typename T>
0145   inline bool Wrapper<T>::isProductEqual_(WrapperBase const* newProduct) const {
0146     Wrapper<T> const* wrappedNewProduct = dynamic_cast<Wrapper<T> const*>(newProduct);
0147     assert(wrappedNewProduct != nullptr);
0148     if constexpr (requires(T& a, T const& b) { a.isProductEqual(b); }) {
0149       return obj.isProductEqual(wrappedNewProduct->obj);
0150     }
0151     return true;
0152   }
0153 
0154   template <typename T>
0155   inline bool Wrapper<T>::hasSwap_() const {
0156     if constexpr (requires(T& a, T& b) { a.swap(b); }) {
0157       return true;
0158     }
0159     return false;
0160   }
0161 
0162   template <typename T>
0163   inline void Wrapper<T>::swapProduct_(WrapperBase* newProduct) {
0164     Wrapper<T>* wrappedNewProduct = dynamic_cast<Wrapper<T>*>(newProduct);
0165     assert(wrappedNewProduct != nullptr);
0166     if constexpr (requires(T& a, T& b) { a.swap(b); }) {
0167       obj.swap(wrappedNewProduct->obj);
0168     }
0169   }
0170 
0171   namespace soa {
0172     template <class T>
0173     struct MakeTableExaminer {
0174       static std::shared_ptr<edm::soa::TableExaminerBase> make(void const*) {
0175         return std::shared_ptr<edm::soa::TableExaminerBase>{};
0176       }
0177     };
0178   }  // namespace soa
0179   template <typename T>
0180   inline std::shared_ptr<edm::soa::TableExaminerBase> Wrapper<T>::tableExaminer_() const {
0181     return soa::MakeTableExaminer<T>::make(&obj);
0182   }
0183 
0184 }  // namespace edm
0185 
0186 #include "DataFormats/Common/interface/WrapperView.icc"
0187 
0188 #endif