Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef DataFormats_Portable_interface_PortableCollectionCommon_h
0002 #define DataFormats_Portable_interface_PortableCollectionCommon_h
0003 
0004 #include <cstddef>
0005 #include <type_traits>
0006 #include <array>
0007 
0008 namespace portablecollection {
0009 
0010   // Note: if there are other uses for this, it could be moved to a central place
0011   template <std::size_t Start, std::size_t End, std::size_t Inc = 1, typename F>
0012   constexpr void constexpr_for(F&& f) {
0013     if constexpr (Start < End) {
0014       f(std::integral_constant<std::size_t, Start>());
0015       constexpr_for<Start + Inc, End, Inc>(std::forward<F>(f));
0016     }
0017   }
0018 
0019   template <std::size_t Idx, typename T>
0020   struct CollectionLeaf {
0021     CollectionLeaf() = default;
0022     CollectionLeaf(std::byte* buffer, int32_t elements) : layout_(buffer, elements), view_(layout_) {}
0023     template <std::size_t N>
0024     CollectionLeaf(std::byte* buffer, std::array<int32_t, N> const& sizes)
0025         : layout_(buffer, sizes[Idx]), view_(layout_) {
0026       static_assert(N >= Idx);
0027     }
0028     using Layout = T;
0029     using View = typename Layout::View;
0030     using ConstView = typename Layout::ConstView;
0031     Layout layout_;  //
0032     View view_;      //!
0033     // Make sure types are not void.
0034     static_assert(not std::is_same<T, void>::value);
0035   };
0036 
0037   template <std::size_t Idx, typename T, typename... Args>
0038   struct CollectionImpl : public CollectionLeaf<Idx, T>, public CollectionImpl<Idx + 1, Args...> {
0039     CollectionImpl() = default;
0040     CollectionImpl(std::byte* buffer, int32_t elements) : CollectionLeaf<Idx, T>(buffer, elements) {}
0041 
0042     template <std::size_t N>
0043     CollectionImpl(std::byte* buffer, std::array<int32_t, N> const& sizes)
0044         : CollectionLeaf<Idx, T>(buffer, sizes),
0045           CollectionImpl<Idx + 1, Args...>(CollectionLeaf<Idx, T>::layout_.metadata().nextByte(), sizes) {}
0046   };
0047 
0048   template <std::size_t Idx, typename T>
0049   struct CollectionImpl<Idx, T> : public CollectionLeaf<Idx, T> {
0050     CollectionImpl() = default;
0051     CollectionImpl(std::byte* buffer, int32_t elements) : CollectionLeaf<Idx, T>(buffer, elements) {}
0052 
0053     template <std::size_t N>
0054     CollectionImpl(std::byte* buffer, std::array<int32_t, N> const& sizes) : CollectionLeaf<Idx, T>(buffer, sizes) {
0055       static_assert(N == Idx + 1);
0056     }
0057   };
0058 
0059   template <typename... Args>
0060   struct Collections : public CollectionImpl<0, Args...> {};
0061 
0062   // return the type at the Idx position in Args...
0063   template <std::size_t Idx, typename... Args>
0064   using TypeResolver = typename std::tuple_element<Idx, std::tuple<Args...>>::type;
0065 
0066   // count how many times the type T occurs in Args...
0067   template <typename T, typename... Args>
0068   inline constexpr std::size_t typeCount = ((std::is_same<T, Args>::value ? 1 : 0) + ... + 0);
0069 
0070   // count the non-void elements of Args...
0071   template <typename... Args>
0072   inline constexpr std::size_t membersCount = sizeof...(Args);
0073 
0074   // if the type T occurs in Tuple, TupleTypeIndex has a static member value with the corresponding index;
0075   // otherwise there is no such data  member.
0076   template <typename T, typename Tuple>
0077   struct TupleTypeIndex {};
0078 
0079   template <typename T, typename... Args>
0080   struct TupleTypeIndex<T, std::tuple<T, Args...>> {
0081     static_assert(typeCount<T, Args...> == 0, "the requested type appears more than once among the arguments");
0082     static constexpr std::size_t value = 0;
0083   };
0084 
0085   template <typename T, typename U, typename... Args>
0086   struct TupleTypeIndex<T, std::tuple<U, Args...>> {
0087     static_assert(not std::is_same_v<T, U>);
0088     static_assert(typeCount<T, Args...> == 1, "the requested type does not appear among the arguments");
0089     static constexpr std::size_t value = 1 + TupleTypeIndex<T, std::tuple<Args...>>::value;
0090   };
0091 
0092   // if the type T occurs in Args..., TypeIndex has a static member value with the corresponding index;
0093   // otherwise there is no such data  member.
0094   template <typename T, typename... Args>
0095   using TypeIndex = TupleTypeIndex<T, std::tuple<Args...>>;
0096 
0097   // return the index where the type T occurs in Args...
0098   template <typename T, typename... Args>
0099   inline constexpr std::size_t typeIndex = TypeIndex<T, Args...>::value;
0100 
0101 }  // namespace portablecollection
0102 
0103 #endif  // DataFormats_Portable_interface_PortableCollectionCommon_h