Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:27:48

0001 #ifndef Framework_produce_helpers_h
0002 #define Framework_produce_helpers_h
0003 // -*- C++ -*-
0004 //
0005 // Package:     Framework
0006 // Class  :     produce_helpers
0007 //
0008 /**\class produce_helpers produce_helpers.h FWCore/Framework/interface/produce_helpers.h
0009 
0010    Description: <one line class summary>
0011 
0012    Usage:
0013    <usage>
0014 
0015 */
0016 //
0017 // Author:      Chris Jones
0018 // Created:     Fri Apr 15 10:25:20 EDT 2005
0019 //
0020 
0021 // system include files
0022 #include <memory>
0023 #include <optional>
0024 // user include files
0025 
0026 namespace edm::eventsetup {
0027 
0028   namespace produce {
0029     struct Null;
0030   }
0031 
0032   template <typename FromT, typename ToT>
0033   void moveFromTo(FromT& iFrom, ToT& iTo) {
0034     iTo = std::move(iFrom);
0035   }
0036 
0037   template <typename FromT, typename ToT>
0038   void moveFromTo(std::unique_ptr<FromT>& iFrom, ToT& iTo) {
0039     iTo = std::move(iFrom);
0040   }
0041   template <typename FromT, typename ToT>
0042   void moveFromTo(std::optional<FromT>& iFrom, ToT& iTo) {
0043     iTo = std::move(iFrom.value());
0044   }
0045 
0046   namespace produce {
0047     struct Null {};
0048     template <typename T>
0049     struct EndList {
0050       static_assert(
0051           (not std::is_pointer_v<T>),
0052           "use std::shared_ptr or std::unique_ptr to hold EventSetup data products, do not use bare pointers");
0053       using tail_type = T;
0054       using head_type = Null;
0055     };
0056     template <typename T>
0057     struct product_traits {
0058       using type = T;
0059     };
0060     template <typename T>
0061     struct product_traits<T*> {
0062       using type = EndList<T*>;
0063     };
0064     template <typename T>
0065     struct product_traits<std::unique_ptr<T>> {
0066       using type = EndList<std::unique_ptr<T>>;
0067     };
0068     template <typename T>
0069     struct product_traits<std::shared_ptr<T>> {
0070       using type = EndList<std::shared_ptr<T>>;
0071     };
0072     template <typename T>
0073     struct product_traits<std::optional<T>> {
0074       using type = EndList<std::optional<T>>;
0075     };
0076 
0077     template <typename T>
0078     struct size {
0079       using type = typename product_traits<T>::type;
0080       constexpr static int value = size<typename type::head_type>::value + 1;
0081     };
0082     template <>
0083     struct size<Null> {
0084       constexpr static int value = 0;
0085     };
0086 
0087     template <typename T>
0088     struct smart_pointer_traits {
0089       using type = typename T::element_type;
0090       static auto getPointer(T const& iPtr) -> decltype(&*iPtr) { return &*iPtr; }
0091     };
0092 
0093     template <typename T>
0094     struct smart_pointer_traits<std::unique_ptr<const T>> {
0095       using type = T;
0096       static auto getPointer(std::unique_ptr<const T> const& iPtr) -> decltype(&*iPtr) { return &*iPtr; }
0097     };
0098 
0099     template <typename T>
0100     struct smart_pointer_traits<std::shared_ptr<const T>> {
0101       using type = T;
0102       static auto getPointer(std::shared_ptr<const T> const& iPtr) -> decltype(&*iPtr) { return &*iPtr; }
0103     };
0104 
0105     template <typename T>
0106     struct smart_pointer_traits<std::optional<T>> {
0107       using type = T;
0108       static T const* getPointer(std::optional<T> const& iPtr) {
0109         if (iPtr.has_value()) {
0110           return &*iPtr;
0111         }
0112         return nullptr;
0113       }
0114     };
0115 
0116     template <typename T, typename FindT>
0117     struct find_index {
0118       using container_type = typename product_traits<T>::type;
0119       template <typename HeadT, typename TailT>
0120       constexpr static int findIndexOf() {
0121         if constexpr (not std::is_same_v<TailT, FindT>) {
0122           using container_type = typename product_traits<HeadT>::type;
0123           return findIndexOf<typename container_type::head_type, typename container_type::tail_type>() + 1;
0124         } else {
0125           return 0;
0126         }
0127       }
0128       constexpr static int value =
0129           findIndexOf<typename container_type::head_type, typename container_type::tail_type>();
0130     };
0131     namespace test {
0132       template <typename T>
0133       const char* name(const T*);
0134     }
0135 
0136   }  // namespace produce
0137 }  // namespace edm::eventsetup
0138 
0139 #endif