Blender V5.0
BLI_parameter_pack_utils.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
13
14#include <cstddef>
15#include <tuple>
16#include <type_traits>
17
18namespace blender {
19
23template<typename T, T Element> struct TypeForValue {
24 static constexpr T value = Element;
25};
26
30template<typename T> struct TypeTag {
31 using type = T;
32};
33
39template<typename T, T... Elements> struct ValueSequence {
43 static constexpr size_t size() noexcept
44 {
45 return sizeof...(Elements);
46 }
47
51 template<size_t I> static constexpr T at_index()
52 {
53 static_assert(I < sizeof...(Elements));
54 return std::tuple_element_t<I, std::tuple<TypeForValue<T, Elements>...>>::value;
55 }
56
60 template<T Element> static constexpr bool contains()
61 {
62 return ((Element == Elements) || ...);
63 }
64};
65
70template<typename... T> struct TypeSequence {
74 static constexpr size_t size() noexcept
75 {
76 return sizeof...(T);
77 }
78
82 template<size_t I> using at_index = std::tuple_element_t<I, std::tuple<T...>>;
83};
84
85namespace detail {
86
87template<typename T, T Value, size_t... I>
88inline ValueSequence<T, ((I == 0) ? Value : Value)...> make_value_sequence_impl(
89 std::index_sequence<I...> /*indices*/)
90{
91 return {};
92}
93
94template<typename T, T Value1, T Value2, size_t... Value1Indices, size_t... I>
95inline ValueSequence<T,
96 (ValueSequence<size_t, Value1Indices...>::template contains<I>() ? Value1 :
97 Value2)...>
99 std::index_sequence<I...> /*indices*/)
100{
101 return {};
102};
103
104} // namespace detail
105
109template<typename T, T Value, size_t Size>
111 std::make_index_sequence<Size>()));
112
117template<typename T, T Value1, T Value2, size_t Size, size_t... Value1Indices>
119 ValueSequence<size_t, Value1Indices...>(), std::make_index_sequence<Size>()));
120
122enum class MyEnum { A, B };
123static_assert(std::is_same_v<make_value_sequence<MyEnum, MyEnum::A, 3>,
125static_assert(
126 std::is_same_v<make_two_value_sequence<MyEnum, MyEnum::A, MyEnum::B, 5, 1, 2>,
128} // namespace parameter_pack_utils_static_tests
129
130} // namespace blender
#define A
#define T
#define B
ValueSequence< T,(ValueSequence< size_t, Value1Indices... >::template contains< I >() ? Value1 :Value2)... > make_two_value_sequence_impl(ValueSequence< size_t, Value1Indices... >, std::index_sequence< I... >)
ValueSequence< T,((I==0) ? Value :Value)... > make_value_sequence_impl(std::index_sequence< I... >)
decltype(detail::make_two_value_sequence_impl< T, Value1, Value2 >( ValueSequence< size_t, Value1Indices... >(), std::make_index_sequence< Size >())) make_two_value_sequence
decltype(detail::make_value_sequence_impl< T, Value >( std::make_index_sequence< Size >())) make_value_sequence
#define I
std::tuple_element_t< I, std::tuple< T... > > at_index
static constexpr size_t size() noexcept
static constexpr size_t size() noexcept
static constexpr bool contains()