5
5
6
6
#include " ../compilation_config_in.h"
7
7
8
- namespace stdsharp ::details
8
+ namespace stdsharp
9
9
{
10
- template <typename >
11
- struct type_seq_converter ;
12
-
13
- template <template <auto ...> typename Seq, auto ... V>
14
- struct type_seq_converter <Seq<V...>>
10
+ template <typename ... T>
11
+ struct type_sequence
15
12
{
16
- using type = regular_type_sequence<typename decltype (V)::type...>;
17
- };
13
+ using value_seq_t = value_sequence<basic_type_constant<T>{}...>;
18
14
19
- template <typename Seq>
20
- using type_seq_converter_t = type_seq_converter<Seq>::type;
15
+ using regular_type_seq = regular_type_sequence<T...>;
21
16
22
- template <typename ... Types>
23
- struct type_sequence
24
- {
25
17
private:
26
- using value_sequence = value_sequence<basic_type_constant<Types>{}...>;
18
+ template <auto ... Func>
19
+ struct transform
20
+ {
21
+ using type = regular_type_sequence<
22
+ typename decltype (stdsharp::invoke(Func, basic_type_constant<T>{}))::type...>;
23
+ };
24
+
25
+ template <auto Func>
26
+ struct transform <Func>
27
+ {
28
+ using type = regular_type_sequence<
29
+ typename decltype (stdsharp::invoke(Func, basic_type_constant<T>{}))::type...>;
30
+ };
27
31
28
32
public:
29
- static constexpr std::size_t size () noexcept { return sizeof ...(Types ); }
33
+ static constexpr std::size_t size () noexcept { return sizeof ...(T ); }
30
34
31
35
template <std::size_t I>
32
- using type = type_at<I, Types...>;
33
-
34
- template <template <typename ...> typename T>
35
- using apply_t = T<Types...>;
36
+ using type = type_at<I, T...>;
36
37
37
- template <typename ... Others >
38
- using append_t = regular_type_sequence<Types..., Others ...>;
38
+ template <template < typename ...> typename U >
39
+ using apply_t = U<T ...>;
39
40
40
41
template <auto ... Func>
41
- using transform_fn = value_sequence:: template transform_fn <Func...>;
42
+ using transform_t = transform <Func...>::type ;
42
43
43
- template <auto ... Func>
44
- static constexpr transform_fn<Func...> transform{};
45
-
46
- template <auto ... Func>
47
- requires std::invocable<transform_fn<Func...>>
48
- using transform_t = decltype (transform<Func...>());
49
-
50
- template <typename T = void >
51
- using invoke_fn = value_sequence::template invoke_fn<T>;
44
+ template <typename U = void >
45
+ using invoke_fn = value_seq_t ::template invoke_fn<U>;
52
46
53
- template <typename T = void >
54
- static constexpr invoke_fn<T > invoke{};
47
+ template <typename U = void >
48
+ static constexpr invoke_fn<U > invoke{};
55
49
56
- using for_each_fn = value_sequence ::for_each_fn;
50
+ using for_each_fn = value_seq_t ::for_each_fn;
57
51
58
52
static constexpr for_each_fn for_each{};
59
53
60
- template <std::size_t From, std::size_t Size>
61
- using select_range_t =
62
- type_seq_converter_t <typename value_sequence::template select_range_t <From, Size>>;
54
+ template <typename ... Others>
55
+ using append_t = regular_type_sequence<T..., Others...>;
63
56
64
57
template <typename ... Others>
65
- using append_front_t = regular_type_sequence<Others..., Types...>;
58
+ using append_front_t = regular_type_sequence<Others..., T...>;
59
+
60
+ private:
61
+ template <std::size_t Index>
62
+ struct insert
63
+ {
64
+ template <typename ... Others, auto ... I, auto ... J>
65
+ static consteval regular_type_sequence<type<I>..., Others..., type<J + Index>...>
66
+ impl (std::index_sequence<I...>, std::index_sequence<J...>);
67
+
68
+ template <typename ... Others>
69
+ using type = decltype ( //
70
+ impl<Others...>(
71
+ std::make_index_sequence<Index>{},
72
+ std::make_index_sequence<size() - Index>{}
73
+ )
74
+ );
75
+ };
76
+
77
+ template <std::size_t Index>
78
+ struct remove_at
79
+ {
80
+ template <auto ... I, auto ... J>
81
+ static consteval regular_type_sequence<type<I>..., type<J + Index + 1 >...>
82
+ impl (std::index_sequence<I...>, std::index_sequence<J...>);
83
+
84
+ using type = decltype ( //
85
+ impl (
86
+ std::make_index_sequence<Index>{},
87
+ std::make_index_sequence<size() - Index - 1 >{}
88
+ )
89
+ );
90
+ };
91
+
92
+ template <std::size_t Index>
93
+ struct replace_at
94
+ {
95
+ template <typename Other, auto ... I, auto ... J>
96
+ static consteval regular_type_sequence<type<I>..., Other, type<J + Index + 1 >...>
97
+ impl (std::index_sequence<I...>, std::index_sequence<J...>);
98
+
99
+ template <typename Other>
100
+ using type = decltype ( //
101
+ impl<Other>(
102
+ std::make_index_sequence<Index>{},
103
+ std::make_index_sequence<size() - Index - 1 >{}
104
+ )
105
+ );
106
+ };
66
107
108
+ public:
67
109
template <std::size_t Index, typename ... Other>
68
- using insert_t = type_seq_converter_t <
69
- typename Base::template insert_t <Index, basic_type_constant<Other>{}...>>;
110
+ using insert_t = insert<Index>::template type<Other...>;
70
111
71
112
template <std::size_t ... Index>
72
- using remove_at_t = type_seq_converter_t < typename Base:: template remove_at_t < Index...>> ;
113
+ using remove_at_t = remove_at< Index...>::type ;
73
114
74
115
template <std::size_t Index, typename Other>
75
- using replace_t = type_seq_converter_t <
76
- typename Base::template replace_t <Index, basic_type_constant<Other>{}>>;
77
-
116
+ using replace_t = replace_at<Index>::template type<Other>;
78
117
};
79
118
}
80
119
81
120
namespace stdsharp
82
121
{
83
- template <typename ... Types>
84
- using type_sequence = adl_proof_t <
85
- details::type_sequence,
86
- value_sequence<basic_type_constant<Types>{}...>,
87
- Types...>;
88
-
89
122
template <typename T>
90
123
using to_type_sequence = decltype ( //
91
124
[]<template <typename ...> typename Inner, typename ... U>(const Inner<U...>&)
@@ -95,17 +128,87 @@ namespace stdsharp
95
128
);
96
129
}
97
130
131
+ namespace stdsharp ::details
132
+ {
133
+ template <typename >
134
+ struct reverse_type_sequence ;
135
+
136
+ template <typename ... T>
137
+ struct reverse_type_sequence <type_sequence<T...>>
138
+ {
139
+ using seq = type_sequence<T...>;
140
+
141
+ template <std::size_t ... I>
142
+ static consteval regular_type_sequence<typename seq::template type<seq::size() - I - 1 >...>
143
+ impl (std::index_sequence<I...>);
144
+
145
+ using type = decltype (impl(std::make_index_sequence<seq::size()>{}));
146
+ };
147
+
148
+ template <typename , typename >
149
+ struct unique_type_sequence ;
150
+
151
+ template <typename ... T, std::constructible_from Comp>
152
+ struct unique_type_sequence <type_sequence<T...>, Comp>
153
+ {
154
+ using seq = type_sequence<T...>;
155
+
156
+ static consteval auto size () noexcept { return seq::size (); }
157
+
158
+ template <std::size_t I>
159
+ static consteval auto fill_indices (auto & indices, std::size_t & i, Comp& comp)
160
+ {
161
+ using value_seq = seq::value_seq_t ;
162
+
163
+ const auto found =
164
+ stdsharp::value_sequence_algo::find<value_seq>(value_seq::template get<I>(), comp);
165
+ if (found < i) return ;
166
+ indices[i++] = I;
167
+ }
168
+
169
+ template <auto ... I>
170
+ static consteval auto get_indices (const std::index_sequence<I...> /* unused*/ )
171
+ {
172
+ std::array<std::size_t , size ()> indices{};
173
+ std::size_t i = 0 ;
174
+ Comp comp{};
175
+ (fill_indices<I>(indices, i, comp), ...);
176
+ return std::pair{indices, i};
177
+ }
178
+
179
+ static constexpr auto indices_pair = get_indices(std::make_index_sequence<size()>{});
180
+
181
+ static constexpr auto indices_size = indices_pair.second;
182
+
183
+ template <auto ... I>
184
+ static consteval regular_type_sequence<typename seq::template type<indices_pair.first[I]>...>
185
+ apply_indices (std::index_sequence<I...>);
186
+
187
+ using type = decltype (apply_indices(std::make_index_sequence<indices_size>{}));
188
+ };
189
+ }
190
+
191
+ namespace stdsharp ::type_sequence_algo
192
+ {
193
+ template <typename Seq>
194
+ using reverse_t = details::reverse_type_sequence<Seq>::type;
195
+
196
+ template <typename Seq, typename Comp = std::ranges::equal_to>
197
+ using unique_t = details::unique_type_sequence<Seq, Comp>::type;
198
+ }
199
+
98
200
namespace std
99
201
{
100
- template <::stdsharp::adl_proofed_for<stdsharp::details::type_sequence> Seq>
101
- struct tuple_size <Seq> : stdsharp::index_constant<Seq::size()>
202
+ template <typename ... T>
203
+ struct tuple_size <::stdsharp::type_sequence<T...>> :
204
+ stdsharp::index_constant<::stdsharp::type_sequence<T...>::size()>
102
205
{
103
206
};
104
207
105
- template <std::size_t I, ::stdsharp::adl_proofed_for<stdsharp::details::type_sequence> Seq >
106
- struct tuple_element <I, Seq >
208
+ template <std::size_t I, typename ... T >
209
+ struct tuple_element <I, ::stdsharp::type_sequence<T...> >
107
210
{
108
- using type = Seq ::template type<I>;
211
+ using type = ::stdsharp::type_sequence<T...> ::template type<I>;
109
212
};
110
213
}
111
214
0 commit comments