1 #if !defined(SUM_F8718480_DC1C_4410_84C0_DDDA2C2FED94_H)
2 # define SUM_F8718480_DC1C_4410_84C0_DDDA2C2FED94_H
86 template <
class... Ts>
class sum_type;
96 struct index_of_impl<I, T, T, Ts...> {
97 static auto const value = I;
101 struct index_of_impl<I, T, recursive_wrapper<T>, Ts...> {
102 static auto const value = I;
105 template <
std::size_t I,
class X,
class T,
class... Ts>
106 struct index_of_impl<I, X, T, Ts...>{
107 static auto const value = index_of_impl<I + 1, X, Ts...>::value;
111 struct type_at_impl : type_at_impl<I - 1, Ts...>
114 template <
class T,
class... Ts>
115 struct type_at_impl<0, T, Ts...> {
116 using type = recursive_wrapper_unwrap_t<T>;
119 struct sum_type_accessor {
121 template <
class... Ts>
122 static constexpr
std::size_t active_index (sum_type<Ts...>
const& s)
127 template <
class... Ts>
128 static constexpr
bool compare_at (
129 std::size_t i, sum_type<Ts...>
const& u, sum_type<Ts...>
const& v)
131 return u.data.compare (i, v.data);
137 struct get_sum_type_element {
139 static auto get (sum_type<Ts...>& u)
140 -> decltype (recursive_union_indexer<I, Ts...>::ref (u.data)) {
143 message +=
"Indexing with ";
145 message +=
", but the active index is ";
148 throw invalid_sum_type_access{message};
153 static auto get (sum_type<Ts...>
const& u)
154 -> decltype (recursive_union_indexer<I, Ts...>::ref (u.data))
158 message +=
"Indexing with ";
160 message +=
", but the active index is ";
163 throw invalid_sum_type_access{message};
177 template <
class T,
class... Ts>
181 detail::index_of_impl<0u, T, Ts...>
::value;
186 using type_at =
typename detail::type_at_impl<I, Ts...>::type;
192 template <
class... Ts>
199 friend struct detail::sum_type_accessor;
201 friend struct detail::get_sum_type_element;
206 template <
class T,
class... Args>
209 sum_type () =
delete;
210 sum_type (sum_type
const& other);
211 sum_type (sum_type&& other);
216 sum_type&
operator= (sum_type
const& other);
222 template <
class R,
class... Fs> R
match(Fs&&... fs)
const;
224 template <
class R,
class... Fs> R
match(Fs&&... fs);
226 template <
class... Fs>
void match(Fs&&... fs)
const;
228 template <
class... Fs>
void match(Fs&&... fs);
232 constexpr
bool is ()
const noexcept;
235 template<std::
size_t I>
240 template <
class... Ts>
243 data.copy (cons, other.data);
246 template <
class... Ts>
247 sum_type<Ts...>::sum_type (sum_type&& other) : cons (other.cons) {
249 data.move (cons,
std::move (other.data));
252 template <
class... Ts>
253 template <
class T,
class... Args>
254 sum_type<Ts...>::sum_type (constructor<T> t, Args&&... args)
255 : data (t,
std::
forward<Args>(args)...), cons (index_of<T, Ts...>::value){
259 template <
class... Ts>
261 data.destruct (cons);
264 template <
class... Ts>
269 data.destruct (cons);
271 data.copy (cons, other.data);
276 template <
class... Ts>
281 data.destruct (cons);
283 data.move (cons,
std::move (other.data));
288 template<
class... Ts>
289 template <
class R,
class... Fs>
291 using indicies = range_t<0,
sizeof... (Ts) - 1>;
293 data, cons, std::forward<Fs>(fs)...);
296 template<
class... Ts>
297 template <
class R,
class... Fs>
299 using indicies = range_t<0,
sizeof... (Ts) - 1>;
302 data, cons, std::forward<Fs>(fs)...);
305 template<
class... Ts>
306 template <
class... Fs>
308 using indicies = range_t<0,
sizeof... (Ts) - 1>;
311 data, cons, std::forward<Fs>(fs)...);
314 template<
class... Ts>
315 template <
class... Fs>
317 using indicies = range_t<0,
sizeof... (Ts) - 1>;
320 data, cons, std::forward<Fs>(fs)...);
323 template <
class... Ts>
326 return cons == index_of<T, Ts...>::value;
329 template <
class... Ts>
330 template <std::
size_t I>
339 template<
class T,
class ... Ts>
340 constexpr T
const&
get (sum_type<Ts...>
const& s);
345 template<
class T,
class ... Ts>
346 constexpr T&
get (sum_type<Ts...>& s);
350 template<
class T,
class ... Ts>
351 constexpr T
const&
get (sum_type<Ts...>
const& s) {
352 return detail::get_sum_type_element<
353 index_of<T, Ts...>::value, Ts...>::get (s);
356 template<
class T,
class ... Ts>
357 constexpr T&
get (sum_type<Ts...>& s) {
358 return detail::get_sum_type_element<
359 index_of<T, Ts...>::value, Ts...>::get (s);
367 constexpr type_at<I, Ts...>&
get (sum_type<Ts...>& s);
372 constexpr type_at<I, Ts...>
const&
get (sum_type<Ts...>
const& s);
376 inline constexpr type_at<I, Ts...>&
get (sum_type<Ts...>& s) {
377 return detail::get_sum_type_element<I, Ts...>::get (s);
381 inline constexpr type_at<I, Ts...>
const&
get (sum_type<Ts...>
const& s) {
382 return detail::get_sum_type_element<I, Ts...>::get (s);
386 template <
class... Ts>
387 bool operator == (sum_type<Ts...>
const& u, sum_type<Ts...>
const& v) {
388 std::size_t m = detail::sum_type_accessor::active_index (u);
389 std::size_t n = detail::sum_type_accessor::active_index (v);
391 return m == n && detail::sum_type_accessor::compare_at (m, u, v);
394 template <
class... Ts>
395 bool operator != (sum_type<Ts...>
const& u, sum_type<Ts...>
const& v) {
A type modeling a "recursive union".
A type modeling "sums with constructors" as used in functional programming.
Definition: sum_type.hpp:193
R match(Fs &&...fs) const
match function, const overoad
constexpr bool is_type_at() const noexcept
The currently active v is at position I?
constexpr bool is() const noexcept
The currently active v is a T?
Definition: logical.hpp:13
A utility suitable for use as a wildcard in a pattern match.
Definition: sum_type.hpp:80
sum_type & operator=(sum_type const &other)
Copy-assign operator.
static result_type visit(overload_tag< O >, T const &t, F &&f, Fs &&...)
f is callable on t (of type T const&)
Definition: recursive_union.hpp:171
A metafunction to compute the index I of a type T in a sequence Ts
Definition: sum_type.hpp:178
static constexpr auto const value
The index of T in Ts...
Definition: sum_type.hpp:180
A type to model a sum constructor.
Definition: recursive_union.hpp:22
recursive union<> primary template
Definition: recursive_union.hpp:25
static constexpr auto ref(recursive_union< T, Ts... > &u) -> decltype(recursive_union_indexer< I-1, Ts... >::ref(u.r))
Decrement I, strip off T and recurse.
Definition: recursive_union.hpp:96