@@ -96,11 +96,16 @@ _LIBCPP_HIDE_FROM_ABI constexpr __arg_t __get_packed_type(uint64_t __types, size
9696 return static_cast <__format::__arg_t >(__types & __packed_arg_t_mask);
9797}
9898
99+ enum class __directly_visit_i128 : bool { __no, __yes };
100+
99101} // namespace __format
100102
103+ template <class _Context >
104+ class __basic_format_arg_value ;
105+
101106// This function is not user observable, so it can directly use the non-standard
102107// types of the "variant". See __arg_t for more details.
103- template <class _Visitor , class _Context >
108+ template <__format::__directly_visit_i128 _DirectlyVisitingI128, class _Visitor , class _Context >
104109_LIBCPP_HIDE_FROM_ABI decltype (auto ) __visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
105110 switch (__arg.__type_ ) {
106111 case __format::__arg_t ::__none:
@@ -115,7 +120,12 @@ _LIBCPP_HIDE_FROM_ABI decltype(auto) __visit_format_arg(_Visitor&& __vis, basic_
115120 return std::invoke (std::forward<_Visitor>(__vis), __arg.__value_ .__long_long_ );
116121 case __format::__arg_t ::__i128:
117122# if _LIBCPP_HAS_INT128
118- return std::invoke (std::forward<_Visitor>(__vis), __arg.__value_ .__i128_ );
123+ if constexpr (_DirectlyVisitingI128 == __format::__directly_visit_i128::__yes)
124+ return std::invoke (std::forward<_Visitor>(__vis), __arg.__value_ .__i128_ );
125+ else {
126+ typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_ .__i128_ };
127+ return std::invoke (std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h});
128+ }
119129# else
120130 __libcpp_unreachable ();
121131# endif
@@ -125,7 +135,12 @@ _LIBCPP_HIDE_FROM_ABI decltype(auto) __visit_format_arg(_Visitor&& __vis, basic_
125135 return std::invoke (std::forward<_Visitor>(__vis), __arg.__value_ .__unsigned_long_long_ );
126136 case __format::__arg_t ::__u128:
127137# if _LIBCPP_HAS_INT128
128- return std::invoke (std::forward<_Visitor>(__vis), __arg.__value_ .__u128_ );
138+ if constexpr (_DirectlyVisitingI128 == __format::__directly_visit_i128::__yes)
139+ return std::invoke (std::forward<_Visitor>(__vis), __arg.__value_ .__u128_ );
140+ else {
141+ typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_ .__u128_ };
142+ return std::invoke (std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h});
143+ }
129144# else
130145 __libcpp_unreachable ();
131146# endif
@@ -166,7 +181,10 @@ _LIBCPP_HIDE_FROM_ABI _Rp __visit_format_arg(_Visitor&& __vis, basic_format_arg<
166181 return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_ .__long_long_ );
167182 case __format::__arg_t ::__i128:
168183# if _LIBCPP_HAS_INT128
169- return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_ .__i128_ );
184+ {
185+ typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_ .__u128_ };
186+ return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h});
187+ }
170188# else
171189 __libcpp_unreachable ();
172190# endif
@@ -176,7 +194,10 @@ _LIBCPP_HIDE_FROM_ABI _Rp __visit_format_arg(_Visitor&& __vis, basic_format_arg<
176194 return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_ .__unsigned_long_long_ );
177195 case __format::__arg_t ::__u128:
178196# if _LIBCPP_HAS_INT128
179- return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_ .__u128_ );
197+ {
198+ typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_ .__u128_ };
199+ return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h});
200+ }
180201# else
181202 __libcpp_unreachable ();
182203# endif
@@ -291,42 +312,14 @@ class _LIBCPP_NO_SPECIALIZATIONS basic_format_arg {
291312 // the "variant" in a handle to stay conforming. See __arg_t for more details.
292313 template <class _Visitor >
293314 _LIBCPP_HIDE_FROM_ABI decltype (auto ) visit(this basic_format_arg __arg, _Visitor&& __vis) {
294- switch (__arg.__type_ ) {
295- # if _LIBCPP_HAS_INT128
296- case __format::__arg_t ::__i128: {
297- typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_ .__i128_ };
298- return std::invoke (std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h});
299- }
300-
301- case __format::__arg_t ::__u128: {
302- typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_ .__u128_ };
303- return std::invoke (std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h});
304- }
305- # endif
306- default :
307- return std::__visit_format_arg (std::forward<_Visitor>(__vis), __arg);
308- }
315+ return std::__visit_format_arg<__format::__directly_visit_i128::__no>(std::forward<_Visitor>(__vis), __arg);
309316 }
310317
311318 // This function is user facing, so it must wrap the non-standard types of
312319 // the "variant" in a handle to stay conforming. See __arg_t for more details.
313320 template <class _Rp , class _Visitor >
314321 _LIBCPP_HIDE_FROM_ABI _Rp visit (this basic_format_arg __arg, _Visitor&& __vis) {
315- switch (__arg.__type_ ) {
316- # if _LIBCPP_HAS_INT128
317- case __format::__arg_t ::__i128: {
318- typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_ .__i128_ };
319- return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h});
320- }
321-
322- case __format::__arg_t ::__u128: {
323- typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_ .__u128_ };
324- return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h});
325- }
326- # endif
327- default :
328- return std::__visit_format_arg<_Rp>(std::forward<_Visitor>(__vis), __arg);
329- }
322+ return std::__visit_format_arg<_Rp>(std::forward<_Visitor>(__vis), __arg);
330323 }
331324
332325# endif // _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
@@ -376,21 +369,7 @@ _LIBCPP_DEPRECATED_IN_CXX26
376369# endif
377370 _LIBCPP_HIDE_FROM_ABI decltype (auto )
378371 visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
379- switch (__arg.__type_ ) {
380- # if _LIBCPP_HAS_INT128
381- case __format::__arg_t ::__i128: {
382- typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_ .__i128_ };
383- return std::invoke (std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h});
384- }
385-
386- case __format::__arg_t ::__u128: {
387- typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_ .__u128_ };
388- return std::invoke (std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h});
389- }
390- # endif // _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
391- default :
392- return std::__visit_format_arg (std::forward<_Visitor>(__vis), __arg);
393- }
372+ return std::__visit_format_arg<__format::__directly_visit_i128::__no>(std::forward<_Visitor>(__vis), __arg);
394373}
395374
396375#endif // _LIBCPP_STD_VER >= 20
0 commit comments