@@ -1325,6 +1325,10 @@ private:
13251325 friend struct __variant_detail ::__visitation::__variant;
13261326};
13271327
1328+ template <class ... _Types>
1329+ variant<_Types...> __upcast_to_variant (const volatile variant<_Types...>*);
1330+ void __upcast_to_variant (...);
1331+
13281332template <size_t _Ip, class ... _Types>
13291333_LIBCPP_HIDE_FROM_ABI constexpr bool __holds_alternative (const variant<_Types...>& __v) noexcept {
13301334 return __v.index () == _Ip;
@@ -1578,11 +1582,38 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __throw_if_valueless(_Vs&&... __vs) {
15781582 }
15791583}
15801584
1581- template < class _Visitor , class ... _Vs, typename >
1585+ template <class _Visitor , class ... _Vs, typename >
15821586_LIBCPP_HIDE_FROM_ABI constexpr decltype (auto ) visit(_Visitor&& __visitor, _Vs&&... __vs) {
1583- using __variant_detail::__visitation::__variant;
1584- std::__throw_if_valueless (std::forward<_Vs>(__vs)...);
1585- return __variant::__visit_value (std::forward<_Visitor>(__visitor), std::forward<_Vs>(__vs)...);
1587+ # define _XDispatchIndex (_I ) \
1588+ case _I: \
1589+ if constexpr (__variant_size::value > _I) { \
1590+ return std::forward<_Visitor>(__visitor)(__variant::__get_alt<_I>(std::forward<_Vs>(__vs)...).__value ); \
1591+ } \
1592+ [[__fallthrough__]]
1593+ # define _XDispatchCount 8 // Speed up compilation for the common cases
1594+ using __variant_size = variant_size<decltype (std::__upcast_to_variant (std::declval<remove_reference_t <_Vs>*>()...))>;
1595+ if constexpr (sizeof ...(_Vs) == 1 && conditional_t <is_same_v<variant_size<void >, __variant_size>, std::integral_constant<size_t , variant_npos>, __variant_size>::value < _XDispatchCount) {
1596+ using __variant_detail::__access::__variant;
1597+ const size_t __indexes[] = {__vs.index ()...};
1598+ switch (__indexes[0 ]) {
1599+ _XDispatchIndex (_XDispatchCount - 8 );
1600+ _XDispatchIndex (_XDispatchCount - 7 );
1601+ _XDispatchIndex (_XDispatchCount - 6 );
1602+ _XDispatchIndex (_XDispatchCount - 5 );
1603+ _XDispatchIndex (_XDispatchCount - 4 );
1604+ _XDispatchIndex (_XDispatchCount - 3 );
1605+ _XDispatchIndex (_XDispatchCount - 2 );
1606+ _XDispatchIndex (_XDispatchCount - 1 );
1607+ default :
1608+ __throw_bad_variant_access ();
1609+ }
1610+ } else {
1611+ using __variant_detail::__visitation::__variant;
1612+ std::__throw_if_valueless (std::forward<_Vs>(__vs)...);
1613+ return __variant::__visit_value (std::forward<_Visitor>(__visitor), std::forward<_Vs>(__vs)...);
1614+ }
1615+ # undef _XDispatchCount
1616+ # undef _XDispatchIndex
15861617}
15871618
15881619# if _LIBCPP_STD_VER >= 20
0 commit comments