4#ifndef TETL_VARIANT_VISIT_HPP
5#define TETL_VARIANT_VISIT_HPP
7#include <etl/_cstddef/size_t.hpp>
8#include <etl/_tuple/tuple.hpp>
9#include <etl/_type_traits/add_rvalue_reference.hpp>
10#include <etl/_type_traits/bool_constant.hpp>
11#include <etl/_type_traits/conditional.hpp>
12#include <etl/_type_traits/decay.hpp>
13#include <etl/_type_traits/is_lvalue_reference.hpp>
14#include <etl/_type_traits/is_reference.hpp>
15#include <etl/_type_traits/is_rvalue_reference.hpp>
16#include <etl/_type_traits/remove_reference.hpp>
17#include <etl/_type_traits/void_t.hpp>
18#include <etl/_utility/forward.hpp>
19#include <etl/_utility/index_sequence.hpp>
20#include <etl/_variant/variant_fwd.hpp>
26template <
typename... Ts>
30using variant_access_t =
decltype(variant_access(
static_cast<decay_t<T>*>(
nullptr)));
32template <
template <
typename...>
typename,
typename =
void,
typename...>
33struct is_detected_impl : false_type { };
35template <
template <
typename...>
typename D,
typename... Ts>
36struct is_detected_impl<D, void_t<D<Ts...>>, Ts...> : true_type { };
38template <
template <
typename...>
typename D,
typename... Ts>
39using is_detected =
typename is_detected_impl<D,
void, Ts...>::type;
41template <
template <
typename...>
typename D,
typename... Ts>
42constexpr bool is_detected_v = is_detected<D, Ts...>::value;
45constexpr bool is_variant_v = is_detected_v<variant_access_t, T>;
48[[nodiscard]]
consteval auto sum(index_sequence<I...> ) -> size_t
53template <size_t I, size_t... Is>
54[[nodiscard]]
consteval auto prepend(index_sequence<Is...> ) -> index_sequence<I, Is...>
59[[nodiscard]]
consteval auto next_seq(index_sequence<> , index_sequence<> ) -> index_sequence<>
64template <size_t I, size_t... Is, size_t J, size_t... Js>
65consteval auto next_seq(index_sequence<I, Is...> , index_sequence<J, Js...> )
67 if constexpr (I + 1 == J) {
68 return prepend<0>(next_seq(index_sequence<Is...>{}, index_sequence<Js...>{}));
70 return index_sequence<I + 1, Is...>{};
75consteval auto variant_size() -> size_t
77 if constexpr (is_variant_v<V>) {
78 return variant_size_v<variant_access_t<V>>;
84template <size_t I,
typename T>
85constexpr auto get(T&& t) ->
decltype(
auto)
87 if constexpr (is_variant_v<T>) {
88 return etl::unchecked_get<I>(
etl::forward<T>(t));
90 static_assert(I == 0);
91 return etl::forward<T>(t);
96constexpr auto index(V
const& v) -> size_t
98 if constexpr (is_variant_v<V>) {
105template <
typename T, size_t I>
106struct indexed_value {
107 static constexpr auto index = index_v<I>;
109 constexpr explicit indexed_value(T value)
110 : _value(
etl::forward<T>(value))
114 [[nodiscard]]
constexpr auto value()
const& ->
auto&
119 [[nodiscard]]
constexpr auto value() && ->
auto&&
121 return etl::forward<T>(_value);
128template <size_t... Is, size_t... Ms,
typename F,
typename... Vs>
129constexpr auto visit_with_index(index_sequence<Is...> i, index_sequence<Ms...> m, F&& f, Vs&&... vs)
131 constexpr auto n = next_seq(i, m);
132 if constexpr (sum(n) == 0) {
133 return f(indexed_value<
decltype(get<Is>(
etl::forward<Vs>(vs))), Is>{get<Is>(
etl::forward<Vs>(vs))}...);
136 return f(indexed_value<
decltype(get<Is>(
etl::forward<Vs>(vs))), Is>{get<Is>(
etl::forward<Vs>(vs))}...);
138 return visit_with_index(n, m,
etl::forward<F>(f),
etl::forward<Vs>(vs)...);
143inline constexpr size_t zero = 0;
158template <
typename F,
typename... Vs>
161 if constexpr (((detail::variant_size<Vs>() == 1)
and ...)) {
163 detail::indexed_value<
decltype(detail::get<0>(
etl::forward<Vs>(vs))), 0>(
164 detail::get<0>(
etl::forward<Vs>(vs))
168 return detail::visit_with_index(
169 index_sequence<detail::zero<Vs>...>{},
170 index_sequence<detail::variant_size<Vs>()...>{},
172 etl::forward<Vs>(vs)...
188template <
typename F,
typename... Vs>
189constexpr auto visit(F&& f, Vs&&... vs)
191 return etl::visit_with_index([&](
auto... parameter) {
192 return etl::forward<F>(f)(
etl::move(parameter).value()...);
193 },
etl::forward<Vs>(vs)...);
constexpr auto visit(F &&f, Vs &&... vs)
Applies the visitor vis (Callable that can be called with any combination of types from variants) to ...
Definition visit.hpp:189
constexpr auto visit_with_index(F &&f, Vs &&... vs)
Applies the visitor vis (Callable that can be called with any combination of types from variants) to ...
Definition visit.hpp:159
Definition adjacent_find.hpp:9
Definition variant.hpp:99