Skip to content

Commit fc52548

Browse files
authored
Update variant_visit.hpp
1 parent e5dfb0d commit fc52548

File tree

1 file changed

+19
-13
lines changed

1 file changed

+19
-13
lines changed

β€Žvariant_visit.hpp

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ constexpr decltype(auto) variant_visit(Visitor&& vis, Variant&& var) {
2121
using R = typename visit_return_type<Visitor&&, Variant&&,
2222
std::make_index_sequence<size>>::type;
2323
auto f = [&vis, &var, index = var.index()](auto&& self, auto i) -> R {
24-
// [[assert: &self == &f]]
25-
// [[assert: 0 <= i && i <= size]]
24+
// [[assert: &self == &f]];
25+
static_assert(0 <= i && i <= size);
2626
if constexpr (i == size)
2727
throw std::bad_variant_access();
2828
else if (i == index)
@@ -35,23 +35,28 @@ constexpr decltype(auto) variant_visit(Visitor&& vis, Variant&& var) {
3535
#undef size
3636
}
3737

38-
template<class T> struct wrapper { T elem; };
38+
template<class T, std::size_t> struct wrapper { T elem; };
3939
template<class... Args> struct tuple : Args... {};
4040

41-
template<class Visitor, class... Ts>
42-
constexpr decltype(auto) visit_impl(Visitor&& vis, tuple<wrapper<Ts>...> tpl) {
43-
return static_cast<Visitor&&>(vis)(static_cast<wrapper<Ts>&>(tpl).elem...);
41+
template<class I, class Visitor, class... Ts, std::size_t... Is>
42+
constexpr decltype(auto) visit_impl(I, Visitor&& vis,
43+
tuple<wrapper<Ts, Is>...> tpl)
44+
{
45+
return static_cast<Visitor&&>(vis)(
46+
static_cast<wrapper<Ts, Is>&>(tpl).elem...);
4447
}
4548

46-
template<class Visitor, class... Ts, class Variant, class... Variants>
47-
constexpr decltype(auto) visit_impl(Visitor&& vis, tuple<wrapper<Ts>...> tpl,
48-
Variant&& var, Variants&&... vars)
49+
template<class I, class Visitor, class... Ts, std::size_t... Is,
50+
class Variant, class... Variants>
51+
constexpr decltype(auto) visit_impl(I i, Visitor&& vis,
52+
tuple<wrapper<Ts, Is>...> tpl, Variant&& var, Variants&&... vars)
4953
{
5054
auto f = [&vis, &tpl, &vars...](auto&& cur) -> decltype(auto) {
5155
using T = decltype(cur);
52-
return (visit_impl)(static_cast<Visitor&&>(vis),
53-
tuple<wrapper<Ts>..., wrapper<T>>{
54-
static_cast<wrapper<Ts>&>(tpl)..., { static_cast<T>(cur) }
56+
return (visit_impl)(std::integral_constant<std::size_t, i + 1>{},
57+
static_cast<Visitor&&>(vis),
58+
tuple<wrapper<Ts, Is>..., wrapper<T, i>>{
59+
static_cast<wrapper<Ts, Is>>(tpl)..., { static_cast<T>(cur) }
5560
},
5661
static_cast<Variants&&>(vars)...);
5762
};
@@ -62,6 +67,7 @@ template<class Visitor, class Variant, class... Variants>
6267
constexpr decltype(auto) variant_visit(Visitor&& vis, Variant&& var,
6368
Variants&&... vars)
6469
{
65-
return (visit_impl)(static_cast<Visitor&&>(vis), tuple<>{},
70+
return (visit_impl)(std::integral_constant<std::size_t, 0>{},
71+
static_cast<Visitor&&>(vis), tuple<>{},
6672
static_cast<Variant&&>(var), static_cast<Variants&&>(vars)...);
6773
}

0 commit comments

Comments
 (0)