@@ -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,42 @@ _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 &&
1596+ conditional_t <is_same_v<variant_size<void >, __variant_size>,
1597+ std::integral_constant<size_t , variant_npos>,
1598+ __variant_size>::value < _XDispatchCount) {
1599+ using __variant_detail::__access::__variant;
1600+ const size_t __indexes[] = {
1601+ __vs.decltype (std::__upcast_to_variant (std::declval<remove_reference_t <_Vs>*>()))::index ()...};
1602+ switch (__indexes[0 ]) {
1603+ _XDispatchIndex (_XDispatchCount - 8 );
1604+ _XDispatchIndex (_XDispatchCount - 7 );
1605+ _XDispatchIndex (_XDispatchCount - 6 );
1606+ _XDispatchIndex (_XDispatchCount - 5 );
1607+ _XDispatchIndex (_XDispatchCount - 4 );
1608+ _XDispatchIndex (_XDispatchCount - 3 );
1609+ _XDispatchIndex (_XDispatchCount - 2 );
1610+ _XDispatchIndex (_XDispatchCount - 1 );
1611+ default :
1612+ __throw_bad_variant_access ();
1613+ }
1614+ } else {
1615+ using __variant_detail::__visitation::__variant;
1616+ std::__throw_if_valueless (std::forward<_Vs>(__vs)...);
1617+ return __variant::__visit_value (std::forward<_Visitor>(__visitor), std::forward<_Vs>(__vs)...);
1618+ }
1619+ # undef _XDispatchCount
1620+ # undef _XDispatchIndex
15861621}
15871622
15881623# if _LIBCPP_STD_VER >= 20
0 commit comments