File indexing completed on 2026-05-03 08:13:28
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LIBCPP___CXX03___FORMAT_FORMAT_ARG_H
0011 #define _LIBCPP___CXX03___FORMAT_FORMAT_ARG_H
0012
0013 #include <__cxx03/__assert>
0014 #include <__cxx03/__concepts/arithmetic.h>
0015 #include <__cxx03/__config>
0016 #include <__cxx03/__format/concepts.h>
0017 #include <__cxx03/__format/format_parse_context.h>
0018 #include <__cxx03/__functional/invoke.h>
0019 #include <__cxx03/__fwd/format.h>
0020 #include <__cxx03/__memory/addressof.h>
0021 #include <__cxx03/__type_traits/conditional.h>
0022 #include <__cxx03/__type_traits/remove_const.h>
0023 #include <__cxx03/__utility/forward.h>
0024 #include <__cxx03/__utility/move.h>
0025 #include <__cxx03/__utility/unreachable.h>
0026 #include <__cxx03/__variant/monostate.h>
0027 #include <__cxx03/cstdint>
0028 #include <__cxx03/string_view>
0029
0030 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0031 # pragma GCC system_header
0032 #endif
0033
0034 _LIBCPP_PUSH_MACROS
0035 #include <__cxx03/__undef_macros>
0036
0037 _LIBCPP_BEGIN_NAMESPACE_STD
0038
0039 #if _LIBCPP_STD_VER >= 20
0040
0041 namespace __format {
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060 enum class __arg_t : uint8_t {
0061 __none,
0062 __boolean,
0063 __char_type,
0064 __int,
0065 __long_long,
0066 __i128,
0067 __unsigned,
0068 __unsigned_long_long,
0069 __u128,
0070 __float,
0071 __double,
0072 __long_double,
0073 __const_char_type_ptr,
0074 __string_view,
0075 __ptr,
0076 __handle
0077 };
0078
0079 inline constexpr unsigned __packed_arg_t_bits = 5;
0080 inline constexpr uint8_t __packed_arg_t_mask = 0x1f;
0081
0082 inline constexpr unsigned __packed_types_storage_bits = 64;
0083 inline constexpr unsigned __packed_types_max = __packed_types_storage_bits / __packed_arg_t_bits;
0084
0085 _LIBCPP_HIDE_FROM_ABI constexpr bool __use_packed_format_arg_store(size_t __size) {
0086 return __size <= __packed_types_max;
0087 }
0088
0089 _LIBCPP_HIDE_FROM_ABI constexpr __arg_t __get_packed_type(uint64_t __types, size_t __id) {
0090 _LIBCPP_ASSERT_INTERNAL(__id <= __packed_types_max, "");
0091
0092 if (__id > 0)
0093 __types >>= __id * __packed_arg_t_bits;
0094
0095 return static_cast<__format::__arg_t>(__types & __packed_arg_t_mask);
0096 }
0097
0098 }
0099
0100
0101
0102 template <class _Visitor, class _Context>
0103 _LIBCPP_HIDE_FROM_ABI decltype(auto) __visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
0104 switch (__arg.__type_) {
0105 case __format::__arg_t::__none:
0106 return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__monostate_);
0107 case __format::__arg_t::__boolean:
0108 return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__boolean_);
0109 case __format::__arg_t::__char_type:
0110 return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__char_type_);
0111 case __format::__arg_t::__int:
0112 return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__int_);
0113 case __format::__arg_t::__long_long:
0114 return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__long_long_);
0115 case __format::__arg_t::__i128:
0116 # ifndef _LIBCPP_HAS_NO_INT128
0117 return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__i128_);
0118 # else
0119 __libcpp_unreachable();
0120 # endif
0121 case __format::__arg_t::__unsigned:
0122 return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__unsigned_);
0123 case __format::__arg_t::__unsigned_long_long:
0124 return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__unsigned_long_long_);
0125 case __format::__arg_t::__u128:
0126 # ifndef _LIBCPP_HAS_NO_INT128
0127 return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__u128_);
0128 # else
0129 __libcpp_unreachable();
0130 # endif
0131 case __format::__arg_t::__float:
0132 return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__float_);
0133 case __format::__arg_t::__double:
0134 return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__double_);
0135 case __format::__arg_t::__long_double:
0136 return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__long_double_);
0137 case __format::__arg_t::__const_char_type_ptr:
0138 return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__const_char_type_ptr_);
0139 case __format::__arg_t::__string_view:
0140 return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__string_view_);
0141 case __format::__arg_t::__ptr:
0142 return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__ptr_);
0143 case __format::__arg_t::__handle:
0144 return std::invoke(
0145 std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__arg.__value_.__handle_});
0146 }
0147
0148 __libcpp_unreachable();
0149 }
0150
0151 # if _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_HAS_EXPLICIT_THIS_PARAMETER)
0152
0153 template <class _Rp, class _Visitor, class _Context>
0154 _LIBCPP_HIDE_FROM_ABI _Rp __visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
0155 switch (__arg.__type_) {
0156 case __format::__arg_t::__none:
0157 return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__monostate_);
0158 case __format::__arg_t::__boolean:
0159 return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__boolean_);
0160 case __format::__arg_t::__char_type:
0161 return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__char_type_);
0162 case __format::__arg_t::__int:
0163 return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__int_);
0164 case __format::__arg_t::__long_long:
0165 return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__long_long_);
0166 case __format::__arg_t::__i128:
0167 # ifndef _LIBCPP_HAS_NO_INT128
0168 return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__i128_);
0169 # else
0170 __libcpp_unreachable();
0171 # endif
0172 case __format::__arg_t::__unsigned:
0173 return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__unsigned_);
0174 case __format::__arg_t::__unsigned_long_long:
0175 return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__unsigned_long_long_);
0176 case __format::__arg_t::__u128:
0177 # ifndef _LIBCPP_HAS_NO_INT128
0178 return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__u128_);
0179 # else
0180 __libcpp_unreachable();
0181 # endif
0182 case __format::__arg_t::__float:
0183 return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__float_);
0184 case __format::__arg_t::__double:
0185 return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__double_);
0186 case __format::__arg_t::__long_double:
0187 return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__long_double_);
0188 case __format::__arg_t::__const_char_type_ptr:
0189 return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__const_char_type_ptr_);
0190 case __format::__arg_t::__string_view:
0191 return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__string_view_);
0192 case __format::__arg_t::__ptr:
0193 return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__ptr_);
0194 case __format::__arg_t::__handle:
0195 return std::invoke_r<_Rp>(
0196 std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__arg.__value_.__handle_});
0197 }
0198
0199 __libcpp_unreachable();
0200 }
0201
0202 # endif
0203
0204
0205
0206
0207
0208 template <class _Context>
0209 class __basic_format_arg_value {
0210 using _CharT = typename _Context::char_type;
0211
0212 public:
0213
0214 struct __handle {
0215 template <class _Tp>
0216 _LIBCPP_HIDE_FROM_ABI explicit __handle(_Tp& __v) noexcept
0217 : __ptr_(std::addressof(__v)),
0218 __format_([](basic_format_parse_context<_CharT>& __parse_ctx, _Context& __ctx, const void* __ptr) {
0219 using _Dp = remove_const_t<_Tp>;
0220 using _Qp = conditional_t<__formattable_with<const _Dp, _Context>, const _Dp, _Dp>;
0221 static_assert(__formattable_with<_Qp, _Context>, "Mandated by [format.arg]/10");
0222
0223 typename _Context::template formatter_type<_Dp> __f;
0224 __parse_ctx.advance_to(__f.parse(__parse_ctx));
0225 __ctx.advance_to(__f.format(*const_cast<_Qp*>(static_cast<const _Dp*>(__ptr)), __ctx));
0226 }) {}
0227
0228 const void* __ptr_;
0229 void (*__format_)(basic_format_parse_context<_CharT>&, _Context&, const void*);
0230 };
0231
0232 union {
0233 monostate __monostate_;
0234 bool __boolean_;
0235 _CharT __char_type_;
0236 int __int_;
0237 unsigned __unsigned_;
0238 long long __long_long_;
0239 unsigned long long __unsigned_long_long_;
0240 # ifndef _LIBCPP_HAS_NO_INT128
0241 __int128_t __i128_;
0242 __uint128_t __u128_;
0243 # endif
0244 float __float_;
0245 double __double_;
0246 long double __long_double_;
0247 const _CharT* __const_char_type_ptr_;
0248 basic_string_view<_CharT> __string_view_;
0249 const void* __ptr_;
0250 __handle __handle_;
0251 };
0252
0253
0254
0255
0256 _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value() noexcept : __monostate_() {}
0257 _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(bool __value) noexcept : __boolean_(__value) {}
0258 _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(_CharT __value) noexcept : __char_type_(__value) {}
0259 _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(int __value) noexcept : __int_(__value) {}
0260 _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(unsigned __value) noexcept : __unsigned_(__value) {}
0261 _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(long long __value) noexcept : __long_long_(__value) {}
0262 _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(unsigned long long __value) noexcept
0263 : __unsigned_long_long_(__value) {}
0264 # ifndef _LIBCPP_HAS_NO_INT128
0265 _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__int128_t __value) noexcept : __i128_(__value) {}
0266 _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__uint128_t __value) noexcept : __u128_(__value) {}
0267 # endif
0268 _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(float __value) noexcept : __float_(__value) {}
0269 _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(double __value) noexcept : __double_(__value) {}
0270 _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(long double __value) noexcept : __long_double_(__value) {}
0271 _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(const _CharT* __value) noexcept : __const_char_type_ptr_(__value) {}
0272 _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(basic_string_view<_CharT> __value) noexcept
0273 : __string_view_(__value) {}
0274 _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(const void* __value) noexcept : __ptr_(__value) {}
0275 _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__handle&& __value) noexcept : __handle_(std::move(__value)) {}
0276 };
0277
0278 template <class _Context>
0279 class _LIBCPP_TEMPLATE_VIS basic_format_arg {
0280 public:
0281 class _LIBCPP_TEMPLATE_VIS handle;
0282
0283 _LIBCPP_HIDE_FROM_ABI basic_format_arg() noexcept : __type_{__format::__arg_t::__none} {}
0284
0285 _LIBCPP_HIDE_FROM_ABI explicit operator bool() const noexcept { return __type_ != __format::__arg_t::__none; }
0286
0287 # if _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_HAS_EXPLICIT_THIS_PARAMETER)
0288
0289
0290
0291 template <class _Visitor>
0292 _LIBCPP_HIDE_FROM_ABI decltype(auto) visit(this basic_format_arg __arg, _Visitor&& __vis) {
0293 switch (__arg.__type_) {
0294 # ifndef _LIBCPP_HAS_NO_INT128
0295 case __format::__arg_t::__i128: {
0296 typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_.__i128_};
0297 return std::invoke(std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h});
0298 }
0299
0300 case __format::__arg_t::__u128: {
0301 typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_.__u128_};
0302 return std::invoke(std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h});
0303 }
0304 # endif
0305 default:
0306 return std::__visit_format_arg(std::forward<_Visitor>(__vis), __arg);
0307 }
0308 }
0309
0310
0311
0312 template <class _Rp, class _Visitor>
0313 _LIBCPP_HIDE_FROM_ABI _Rp visit(this basic_format_arg __arg, _Visitor&& __vis) {
0314 switch (__arg.__type_) {
0315 # ifndef _LIBCPP_HAS_NO_INT128
0316 case __format::__arg_t::__i128: {
0317 typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_.__i128_};
0318 return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h});
0319 }
0320
0321 case __format::__arg_t::__u128: {
0322 typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_.__u128_};
0323 return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h});
0324 }
0325 # endif
0326 default:
0327 return std::__visit_format_arg<_Rp>(std::forward<_Visitor>(__vis), __arg);
0328 }
0329 }
0330
0331 # endif
0332
0333 private:
0334 using char_type = typename _Context::char_type;
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347 public:
0348 __basic_format_arg_value<_Context> __value_;
0349 __format::__arg_t __type_;
0350
0351 _LIBCPP_HIDE_FROM_ABI explicit basic_format_arg(__format::__arg_t __type,
0352 __basic_format_arg_value<_Context> __value) noexcept
0353 : __value_(__value), __type_(__type) {}
0354 };
0355
0356 template <class _Context>
0357 class _LIBCPP_TEMPLATE_VIS basic_format_arg<_Context>::handle {
0358 public:
0359 _LIBCPP_HIDE_FROM_ABI void format(basic_format_parse_context<char_type>& __parse_ctx, _Context& __ctx) const {
0360 __handle_.__format_(__parse_ctx, __ctx, __handle_.__ptr_);
0361 }
0362
0363 _LIBCPP_HIDE_FROM_ABI explicit handle(typename __basic_format_arg_value<_Context>::__handle& __handle) noexcept
0364 : __handle_(__handle) {}
0365
0366 private:
0367 typename __basic_format_arg_value<_Context>::__handle& __handle_;
0368 };
0369
0370
0371
0372 template <class _Visitor, class _Context>
0373 # if _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_HAS_EXPLICIT_THIS_PARAMETER)
0374 _LIBCPP_DEPRECATED_IN_CXX26
0375 # endif
0376 _LIBCPP_HIDE_FROM_ABI decltype(auto)
0377 visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
0378 switch (__arg.__type_) {
0379 # ifndef _LIBCPP_HAS_NO_INT128
0380 case __format::__arg_t::__i128: {
0381 typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_.__i128_};
0382 return std::invoke(std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h});
0383 }
0384
0385 case __format::__arg_t::__u128: {
0386 typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_.__u128_};
0387 return std::invoke(std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h});
0388 }
0389 # endif
0390 default:
0391 return std::__visit_format_arg(std::forward<_Visitor>(__vis), __arg);
0392 }
0393 }
0394
0395 #endif
0396
0397 _LIBCPP_END_NAMESPACE_STD
0398
0399 _LIBCPP_POP_MACROS
0400
0401 #endif