Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:12:05

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   namespace produce {
0038     struct Null {};
0039     template <typename T>
0040     struct EndList {
0041       static_assert(
0042           (not std::is_pointer_v<T>),
0043           "use std::shared_ptr or std::unique_ptr to hold EventSetup data products, do not use bare pointers");
0044       using tail_type = T;
0045       using head_type = Null;
0046     };
0047     template <typename T>
0048     struct product_traits {
0049       using type = T;
0050     };
0051     template <typename T>
0052     struct product_traits<T*> {
0053       using type = EndList<T*>;
0054     };
0055     template <typename T>
0056     struct product_traits<std::unique_ptr<T>> {
0057       using type = EndList<std::unique_ptr<T>>;
0058     };
0059     template <typename T>
0060     struct product_traits<std::shared_ptr<T>> {
0061       using type = EndList<std::shared_ptr<T>>;
0062     };
0063     template <typename T>
0064     struct product_traits<std::optional<T>> {
0065       using type = EndList<std::optional<T>>;
0066     };
0067 
0068     template <typename T>
0069     struct size {
0070       using type = typename product_traits<T>::type;
0071       constexpr static int value = size<typename type::head_type>::value + 1;
0072     };
0073     template <>
0074     struct size<Null> {
0075       constexpr static int value = 0;
0076     };
0077 
0078     template <typename T>
0079     struct smart_pointer_traits {
0080       using type = typename T::element_type;
0081       static auto getPointer(T const& iPtr) -> decltype(&*iPtr) { return &*iPtr; }
0082     };
0083 
0084     template <typename T>
0085     struct smart_pointer_traits<std::unique_ptr<const T>> {
0086       using type = T;
0087       static auto getPointer(std::unique_ptr<const T> const& iPtr) -> decltype(&*iPtr) { return &*iPtr; }
0088     };
0089 
0090     template <typename T>
0091     struct smart_pointer_traits<std::shared_ptr<const T>> {
0092       using type = T;
0093       static auto getPointer(std::shared_ptr<const T> const& iPtr) -> decltype(&*iPtr) { return &*iPtr; }
0094     };
0095 
0096     template <typename T>
0097     struct smart_pointer_traits<std::optional<T>> {
0098       using type = T;
0099       static T const* getPointer(std::optional<T> const& iPtr) {
0100         if (iPtr.has_value()) {
0101           return &*iPtr;
0102         }
0103         return nullptr;
0104       }
0105     };
0106 
0107     template <typename T, typename FindT>
0108     struct find_index {
0109       using container_type = typename product_traits<T>::type;
0110       template <typename HeadT, typename TailT>
0111       constexpr static int findIndexOf() {
0112         if constexpr (not std::is_same_v<TailT, FindT>) {
0113           using container_type = typename product_traits<HeadT>::type;
0114           return findIndexOf<typename container_type::head_type, typename container_type::tail_type>() + 1;
0115         } else {
0116           return 0;
0117         }
0118       }
0119       constexpr static int value =
0120           findIndexOf<typename container_type::head_type, typename container_type::tail_type>();
0121     };
0122     namespace test {
0123       template <typename T>
0124       const char* name(const T*);
0125     }
0126 
0127   }  // namespace produce
0128 }  // namespace edm::eventsetup
0129 
0130 #endif