File indexing completed on 2023-03-17 11:02:05
0001 #ifndef Framework_produce_helpers_h
0002 #define Framework_produce_helpers_h
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include <memory>
0023 #include <optional>
0024
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 }
0137 }
0138
0139 #endif