Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef DataFormats_Common_RefCoreGet_h
0002 #define DataFormats_Common_RefCoreGet_h
0003 
0004 /*----------------------------------------------------------------------
0005 
0006 RefCoreGet: Free function to get the pointer to a referenced product.
0007 
0008 ----------------------------------------------------------------------*/
0009 
0010 #include "DataFormats/Common/interface/RefCore.h"
0011 #include "DataFormats/Common/interface/WrapperBase.h"
0012 #include "DataFormats/Common/interface/Wrapper.h"
0013 
0014 #include <cassert>
0015 #include <typeinfo>
0016 
0017 namespace edm {
0018 
0019   namespace refcore {
0020     template <typename T>
0021     inline T const* getProduct_(RefCore const& ref, const EDProductGetter* prodGetter) {
0022       assert(!ref.isTransient());
0023       WrapperBase const* product = ref.getProductPtr(typeid(T), prodGetter);
0024       Wrapper<T> const* wrapper = static_cast<Wrapper<T> const*>(product);
0025       if (wrapper == nullptr) {
0026         ref.wrongTypeException(typeid(T), typeid(*product));
0027       }
0028       ref.setProductPtr(wrapper->product());
0029       return wrapper->product();
0030     }
0031   }  // namespace refcore
0032 
0033   // Get the product using a RefCore from a RefProd.
0034   // In this case the pointer cache in the RefCore
0035   // is designed to hold a pointer to the container product.
0036   template <typename T>
0037   inline T const* getProduct(RefCore const& ref) {
0038     T const* p = static_cast<T const*>(ref.productPtr());
0039     if (p != nullptr)
0040       return p;
0041     if (ref.isTransient()) {
0042       ref.nullPointerForTransientException(typeid(T));
0043     }
0044     auto productGetter = ref.productGetter();
0045     if (nullptr == productGetter) {
0046       p = static_cast<T const*>(ref.productPtr());
0047       if (p != nullptr) {
0048         //another thread updated the value since we checked
0049         return p;
0050       }
0051     }
0052     return refcore::getProduct_<T>(ref, productGetter);
0053   }
0054 
0055   namespace refcore {
0056     template <typename T>
0057     inline T const* getProductWithCoreFromRef_(RefCore const& ref, EDProductGetter const* prodGetter) {
0058       WrapperBase const* product = ref.getProductPtr(typeid(T), prodGetter);
0059       Wrapper<T> const* wrapper = static_cast<Wrapper<T> const*>(product);
0060       if (wrapper == nullptr) {
0061         ref.wrongTypeException(typeid(T), typeid(*product));
0062       }
0063       return wrapper->product();
0064     }
0065   }  // namespace refcore
0066 
0067   // Get the product using a RefCore from a Ref.
0068   // In this case the pointer cache in the RefCore
0069   // is designed to hold a pointer to an element in the container product.
0070   template <typename T>
0071   inline T const* getProductWithCoreFromRef(RefCore const& ref, EDProductGetter const* prodGetter) {
0072     if (ref.isTransient()) {
0073       ref.nullPointerForTransientException(typeid(T));
0074     }
0075     return refcore::getProductWithCoreFromRef_<T>(ref, prodGetter);
0076   }
0077 
0078   namespace refcore {
0079     template <typename T>
0080     inline T const* tryToGetProductWithCoreFromRef_(RefCore const& ref, EDProductGetter const* prodGetter) {
0081       WrapperBase const* product = ref.tryToGetProductPtr(typeid(T), prodGetter);
0082       if (product == nullptr) {
0083         return nullptr;
0084       }
0085       Wrapper<T> const* wrapper = static_cast<Wrapper<T> const*>(product);
0086       return wrapper->product();
0087     }
0088   }  // namespace refcore
0089 
0090   // get the product using a RefCore from a Ref
0091   // In this case the pointer cache in the RefCore
0092   // is for a pointer to an element in the container product.
0093   // In this case we try only, which means we do not throw
0094   // if we fail. This gives the calling function the
0095   // chance to look in thinned containers.
0096   template <typename T>
0097   inline T const* tryToGetProductWithCoreFromRef(RefCore const& ref, EDProductGetter const* prodGetter) {
0098     if (ref.isTransient()) {
0099       ref.nullPointerForTransientException(typeid(T));
0100     }
0101     return refcore::tryToGetProductWithCoreFromRef_<T>(ref, prodGetter);
0102   }
0103 
0104   namespace refcore {
0105     template <typename T>
0106     inline std::tuple<T const*, unsigned int> getThinnedProduct_(RefCore const& ref,
0107                                                                  unsigned int key,
0108                                                                  EDProductGetter const* prodGetter) {
0109       auto [product, thinnedKey] = ref.getThinnedProductPtr(typeid(T), key, prodGetter);
0110       Wrapper<T> const* wrapper = static_cast<Wrapper<T> const*>(product);
0111       return std::tuple(wrapper->product(), thinnedKey);
0112     }
0113   }  // namespace refcore
0114 
0115   template <typename T>
0116   inline std::tuple<T const*, unsigned int> getThinnedProduct(RefCore const& ref,
0117                                                               unsigned int key,
0118                                                               EDProductGetter const* prodGetter) {
0119     // The pointer to a thinned collection will never be cached
0120     // T const* p = static_cast<T const*>(ref.productPtr());
0121     // if (p != 0) return p;
0122 
0123     if (ref.isTransient()) {
0124       ref.nullPointerForTransientException(typeid(T));
0125     }
0126     return refcore::getThinnedProduct_<T>(ref, key, prodGetter);
0127   }
0128 }  // namespace edm
0129 #endif