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
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
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
0063 template <std::size_t Idx, typename... Args>
0064 using TypeResolver = typename std::tuple_element<Idx, std::tuple<Args...>>::type;
0065
0066
0067 template <typename T, typename... Args>
0068 inline constexpr std::size_t typeCount = ((std::is_same<T, Args>::value ? 1 : 0) + ... + 0);
0069
0070
0071 template <typename... Args>
0072 inline constexpr std::size_t membersCount = sizeof...(Args);
0073
0074
0075
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
0093
0094 template <typename T, typename... Args>
0095 using TypeIndex = TupleTypeIndex<T, std::tuple<Args...>>;
0096
0097
0098 template <typename T, typename... Args>
0099 inline constexpr std::size_t typeIndex = TypeIndex<T, Args...>::value;
0100
0101 }
0102
0103 #endif