Skip to content

Commit 2d441c4

Browse files
authored
Update variant_visit.hpp
1 parent 905ef28 commit 2d441c4

1 file changed

Lines changed: 16 additions & 20 deletions

File tree

variant_visit.hpp

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,27 @@
66

77
#include "invoke.hpp"
88

9-
template<class Visitor, class Variant, class IndexSeq>
10-
struct visit_return_type;
11-
12-
template<class Visitor, class Variant, std::size_t... I>
13-
struct visit_return_type<Visitor, Variant, std::index_sequence<I...>> {
14-
using type = std::common_type_t<std::invoke_result_t<
15-
Visitor, decltype(std::get<I>(std::declval<Variant>()))>...>;
16-
};
17-
189
template<class Visitor, class Variant>
1910
constexpr decltype(auto) variant_visit(Visitor&& vis, Variant&& var) {
2011
constexpr auto size = std::variant_size_v<std::decay_t<Variant>>;
21-
using R = typename visit_return_type<Visitor&&, Variant&&,
22-
std::make_index_sequence<size>>::type;
23-
auto f = [&vis, &var, index = var.index()](auto&& self, auto i) -> R {
24-
// [[assert: &self == &f]];
12+
using R = std::invoke_result_t<Visitor,
13+
decltype(std::get<0>(std::declval<Variant>()))>;
14+
auto f = [&vis, &var, index = var.index()](auto&& rec, auto i) -> R {
15+
// [[assert: &rec == &f]];
2516
static_assert(0 <= i && i <= size);
26-
if constexpr (decltype(i)::value == size)
17+
if constexpr (i == size)
2718
throw std::bad_variant_access();
28-
else if (i == index)
29-
return (invoke)(static_cast<Visitor&&>(vis),
30-
std::get<i>(static_cast<Variant&&>(var)));
31-
else
32-
return self(self, std::integral_constant<std::size_t, i + 1>{});
33-
};
19+
else {
20+
static_assert(std::is_same_v<R, std::invoke_result_t<Visitor,
21+
decltype(std::get<i>(std::declval<Variant>()))>>,
22+
"visitor must return the same type for all alternatives!");
23+
if (i == index)
24+
return (invoke)(static_cast<Visitor&&>(vis),
25+
std::get<i>(static_cast<Variant&&>(var)));
26+
else
27+
return rec(rec, std::integral_constant<std::size_t, i + 1>{});
28+
}
29+
};
3430
return f(f, std::integral_constant<std::size_t, 0>{});
3531
}
3632

0 commit comments

Comments
 (0)