@@ -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; };
3939template <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>
6267constexpr 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