Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-03 08:13:49

0001 // -*- C++ -*-
0002 //===----------------------------------------------------------------------===//
0003 //
0004 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0005 // See https://llvm.org/LICENSE.txt for license information.
0006 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0007 //
0008 //===----------------------------------------------------------------------===//
0009 
0010 #ifndef _LIBCPP___FORMAT_FORMAT_FUNCTIONS
0011 #define _LIBCPP___FORMAT_FORMAT_FUNCTIONS
0012 
0013 #include <__algorithm/clamp.h>
0014 #include <__concepts/convertible_to.h>
0015 #include <__concepts/same_as.h>
0016 #include <__config>
0017 #include <__format/buffer.h>
0018 #include <__format/format_arg.h>
0019 #include <__format/format_arg_store.h>
0020 #include <__format/format_args.h>
0021 #include <__format/format_context.h>
0022 #include <__format/format_error.h>
0023 #include <__format/format_parse_context.h>
0024 #include <__format/format_string.h>
0025 #include <__format/format_to_n_result.h>
0026 #include <__format/formatter.h>
0027 #include <__format/formatter_bool.h>
0028 #include <__format/formatter_char.h>
0029 #include <__format/formatter_floating_point.h>
0030 #include <__format/formatter_integer.h>
0031 #include <__format/formatter_pointer.h>
0032 #include <__format/formatter_string.h>
0033 #include <__format/parser_std_format_spec.h>
0034 #include <__iterator/concepts.h>
0035 #include <__iterator/incrementable_traits.h>
0036 #include <__iterator/iterator_traits.h> // iter_value_t
0037 #include <__variant/monostate.h>
0038 #include <array>
0039 #include <string>
0040 #include <string_view>
0041 
0042 #if _LIBCPP_HAS_LOCALIZATION
0043 #  include <__locale>
0044 #endif
0045 
0046 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0047 #  pragma GCC system_header
0048 #endif
0049 
0050 _LIBCPP_PUSH_MACROS
0051 #include <__undef_macros>
0052 
0053 _LIBCPP_BEGIN_NAMESPACE_STD
0054 
0055 #if _LIBCPP_STD_VER >= 20
0056 
0057 // TODO FMT Evaluate which templates should be external templates. This
0058 // improves the efficiency of the header. However since the header is still
0059 // under heavy development and not all classes are stable it makes no sense
0060 // to do this optimization now.
0061 
0062 using format_args = basic_format_args<format_context>;
0063 #  if _LIBCPP_HAS_WIDE_CHARACTERS
0064 using wformat_args = basic_format_args<wformat_context>;
0065 #  endif
0066 
0067 template <class _Context = format_context, class... _Args>
0068 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> make_format_args(_Args&... __args) {
0069   return std::__format_arg_store<_Context, _Args...>(__args...);
0070 }
0071 
0072 #  if _LIBCPP_HAS_WIDE_CHARACTERS
0073 template <class... _Args>
0074 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __format_arg_store<wformat_context, _Args...> make_wformat_args(_Args&... __args) {
0075   return std::__format_arg_store<wformat_context, _Args...>(__args...);
0076 }
0077 #  endif
0078 
0079 namespace __format {
0080 
0081 /// Helper class parse and handle argument.
0082 ///
0083 /// When parsing a handle which is not enabled the code is ill-formed.
0084 /// This helper uses the parser of the appropriate formatter for the stored type.
0085 template <class _CharT>
0086 class _LIBCPP_TEMPLATE_VIS __compile_time_handle {
0087 public:
0088   template <class _ParseContext>
0089   _LIBCPP_HIDE_FROM_ABI constexpr void __parse(_ParseContext& __ctx) const {
0090     __parse_(__ctx);
0091   }
0092 
0093   template <class _Tp>
0094   _LIBCPP_HIDE_FROM_ABI constexpr void __enable() {
0095     __parse_ = [](basic_format_parse_context<_CharT>& __ctx) {
0096       formatter<_Tp, _CharT> __f;
0097       __ctx.advance_to(__f.parse(__ctx));
0098     };
0099   }
0100 
0101   // Before calling __parse the proper handler needs to be set with __enable.
0102   // The default handler isn't a core constant expression.
0103   _LIBCPP_HIDE_FROM_ABI constexpr __compile_time_handle()
0104       : __parse_([](basic_format_parse_context<_CharT>&) { std::__throw_format_error("Not a handle"); }) {}
0105 
0106 private:
0107   void (*__parse_)(basic_format_parse_context<_CharT>&);
0108 };
0109 
0110 // Dummy format_context only providing the parts used during constant
0111 // validation of the basic_format_string.
0112 template <class _CharT>
0113 struct _LIBCPP_TEMPLATE_VIS __compile_time_basic_format_context {
0114 public:
0115   using char_type = _CharT;
0116 
0117   _LIBCPP_HIDE_FROM_ABI constexpr explicit __compile_time_basic_format_context(
0118       const __arg_t* __args, const __compile_time_handle<_CharT>* __handles, size_t __size)
0119       : __args_(__args), __handles_(__handles), __size_(__size) {}
0120 
0121   // During the compile-time validation nothing needs to be written.
0122   // Therefore all operations of this iterator are a NOP.
0123   struct iterator {
0124     _LIBCPP_HIDE_FROM_ABI constexpr iterator& operator=(_CharT) { return *this; }
0125     _LIBCPP_HIDE_FROM_ABI constexpr iterator& operator*() { return *this; }
0126     _LIBCPP_HIDE_FROM_ABI constexpr iterator operator++(int) { return *this; }
0127   };
0128 
0129   _LIBCPP_HIDE_FROM_ABI constexpr __arg_t arg(size_t __id) const {
0130     if (__id >= __size_)
0131       std::__throw_format_error("The argument index value is too large for the number of arguments supplied");
0132     return __args_[__id];
0133   }
0134 
0135   _LIBCPP_HIDE_FROM_ABI constexpr const __compile_time_handle<_CharT>& __handle(size_t __id) const {
0136     if (__id >= __size_)
0137       std::__throw_format_error("The argument index value is too large for the number of arguments supplied");
0138     return __handles_[__id];
0139   }
0140 
0141   _LIBCPP_HIDE_FROM_ABI constexpr iterator out() { return {}; }
0142   _LIBCPP_HIDE_FROM_ABI constexpr void advance_to(iterator) {}
0143 
0144 private:
0145   const __arg_t* __args_;
0146   const __compile_time_handle<_CharT>* __handles_;
0147   size_t __size_;
0148 };
0149 
0150 // [format.string.std]/8
0151 // If { arg-idopt } is used in a width or precision, the value of the
0152 // corresponding formatting argument is used in its place. If the
0153 // corresponding formatting argument is not of standard signed or unsigned
0154 // integer type, or its value is negative for precision or non-positive for
0155 // width, an exception of type format_error is thrown.
0156 //
0157 // _HasPrecision does the formatter have a precision?
0158 template <class _CharT, class _Tp, bool _HasPrecision = false>
0159 _LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_validate_argument(
0160     basic_format_parse_context<_CharT>& __parse_ctx, __compile_time_basic_format_context<_CharT>& __ctx) {
0161   auto __validate_type = [](__arg_t __type) {
0162     // LWG3720 originally allowed "signed or unsigned integer types", however
0163     // the final version explicitly changed it to "*standard* signed or unsigned
0164     // integer types". It's trivial to use 128-bit integrals in libc++'s
0165     // implementation, but other implementations may not implement it.
0166     // (Using a width or precision, that does not fit in 64-bits, sounds very
0167     // unlikely in real world code.)
0168     switch (__type) {
0169     case __arg_t::__int:
0170     case __arg_t::__long_long:
0171     case __arg_t::__unsigned:
0172     case __arg_t::__unsigned_long_long:
0173       return;
0174 
0175     default:
0176       std::__throw_format_error("Replacement argument isn't a standard signed or unsigned integer type");
0177     }
0178   };
0179 
0180   formatter<_Tp, _CharT> __formatter;
0181   __parse_ctx.advance_to(__formatter.parse(__parse_ctx));
0182   if (__formatter.__parser_.__width_as_arg_)
0183     __validate_type(__ctx.arg(__formatter.__parser_.__width_));
0184 
0185   if constexpr (_HasPrecision)
0186     if (__formatter.__parser_.__precision_as_arg_)
0187       __validate_type(__ctx.arg(__formatter.__parser_.__precision_));
0188 }
0189 
0190 // This function is not user facing, so it can directly use the non-standard types of the "variant".
0191 template <class _CharT>
0192 _LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_visit_format_arg(
0193     basic_format_parse_context<_CharT>& __parse_ctx,
0194     __compile_time_basic_format_context<_CharT>& __ctx,
0195     __arg_t __type) {
0196   switch (__type) {
0197   case __arg_t::__none:
0198     std::__throw_format_error("Invalid argument");
0199   case __arg_t::__boolean:
0200     return __format::__compile_time_validate_argument<_CharT, bool>(__parse_ctx, __ctx);
0201   case __arg_t::__char_type:
0202     return __format::__compile_time_validate_argument<_CharT, _CharT>(__parse_ctx, __ctx);
0203   case __arg_t::__int:
0204     return __format::__compile_time_validate_argument<_CharT, int>(__parse_ctx, __ctx);
0205   case __arg_t::__long_long:
0206     return __format::__compile_time_validate_argument<_CharT, long long>(__parse_ctx, __ctx);
0207   case __arg_t::__i128:
0208 #  if _LIBCPP_HAS_INT128
0209     return __format::__compile_time_validate_argument<_CharT, __int128_t>(__parse_ctx, __ctx);
0210 #  else
0211     std::__throw_format_error("Invalid argument");
0212 #  endif
0213     return;
0214   case __arg_t::__unsigned:
0215     return __format::__compile_time_validate_argument<_CharT, unsigned>(__parse_ctx, __ctx);
0216   case __arg_t::__unsigned_long_long:
0217     return __format::__compile_time_validate_argument<_CharT, unsigned long long>(__parse_ctx, __ctx);
0218   case __arg_t::__u128:
0219 #  if _LIBCPP_HAS_INT128
0220     return __format::__compile_time_validate_argument<_CharT, __uint128_t>(__parse_ctx, __ctx);
0221 #  else
0222     std::__throw_format_error("Invalid argument");
0223 #  endif
0224     return;
0225   case __arg_t::__float:
0226     return __format::__compile_time_validate_argument<_CharT, float, true>(__parse_ctx, __ctx);
0227   case __arg_t::__double:
0228     return __format::__compile_time_validate_argument<_CharT, double, true>(__parse_ctx, __ctx);
0229   case __arg_t::__long_double:
0230     return __format::__compile_time_validate_argument<_CharT, long double, true>(__parse_ctx, __ctx);
0231   case __arg_t::__const_char_type_ptr:
0232     return __format::__compile_time_validate_argument<_CharT, const _CharT*, true>(__parse_ctx, __ctx);
0233   case __arg_t::__string_view:
0234     return __format::__compile_time_validate_argument<_CharT, basic_string_view<_CharT>, true>(__parse_ctx, __ctx);
0235   case __arg_t::__ptr:
0236     return __format::__compile_time_validate_argument<_CharT, const void*>(__parse_ctx, __ctx);
0237   case __arg_t::__handle:
0238     std::__throw_format_error("Handle should use __compile_time_validate_handle_argument");
0239   }
0240   std::__throw_format_error("Invalid argument");
0241 }
0242 
0243 template <contiguous_iterator _Iterator, class _ParseCtx, class _Ctx>
0244 _LIBCPP_HIDE_FROM_ABI constexpr _Iterator
0245 __handle_replacement_field(_Iterator __begin, _Iterator __end, _ParseCtx& __parse_ctx, _Ctx& __ctx) {
0246   using _CharT                        = iter_value_t<_Iterator>;
0247   __format::__parse_number_result __r = __format::__parse_arg_id(__begin, __end, __parse_ctx);
0248 
0249   if (__r.__last == __end)
0250     std::__throw_format_error("The argument index should end with a ':' or a '}'");
0251 
0252   bool __parse = *__r.__last == _CharT(':');
0253   switch (*__r.__last) {
0254   case _CharT(':'):
0255     // The arg-id has a format-specifier, advance the input to the format-spec.
0256     __parse_ctx.advance_to(__r.__last + 1);
0257     break;
0258   case _CharT('}'):
0259     // The arg-id has no format-specifier.
0260     __parse_ctx.advance_to(__r.__last);
0261     break;
0262   default:
0263     std::__throw_format_error("The argument index should end with a ':' or a '}'");
0264   }
0265 
0266   if constexpr (same_as<_Ctx, __compile_time_basic_format_context<_CharT>>) {
0267     __arg_t __type = __ctx.arg(__r.__value);
0268     if (__type == __arg_t::__none)
0269       std::__throw_format_error("The argument index value is too large for the number of arguments supplied");
0270     else if (__type == __arg_t::__handle)
0271       __ctx.__handle(__r.__value).__parse(__parse_ctx);
0272     else if (__parse)
0273       __format::__compile_time_visit_format_arg(__parse_ctx, __ctx, __type);
0274   } else
0275     std::__visit_format_arg(
0276         [&](auto __arg) {
0277           if constexpr (same_as<decltype(__arg), monostate>)
0278             std::__throw_format_error("The argument index value is too large for the number of arguments supplied");
0279           else if constexpr (same_as<decltype(__arg), typename basic_format_arg<_Ctx>::handle>)
0280             __arg.format(__parse_ctx, __ctx);
0281           else {
0282             formatter<decltype(__arg), _CharT> __formatter;
0283             if (__parse)
0284               __parse_ctx.advance_to(__formatter.parse(__parse_ctx));
0285             __ctx.advance_to(__formatter.format(__arg, __ctx));
0286           }
0287         },
0288         __ctx.arg(__r.__value));
0289 
0290   __begin = __parse_ctx.begin();
0291   if (__begin == __end || *__begin != _CharT('}'))
0292     std::__throw_format_error("The replacement field misses a terminating '}'");
0293 
0294   return ++__begin;
0295 }
0296 
0297 template <class _ParseCtx, class _Ctx>
0298 _LIBCPP_HIDE_FROM_ABI constexpr typename _Ctx::iterator __vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) {
0299   using _CharT = typename _ParseCtx::char_type;
0300   static_assert(same_as<typename _Ctx::char_type, _CharT>);
0301 
0302   auto __begin                     = __parse_ctx.begin();
0303   auto __end                       = __parse_ctx.end();
0304   typename _Ctx::iterator __out_it = __ctx.out();
0305   while (__begin != __end) {
0306     switch (*__begin) {
0307     case _CharT('{'):
0308       ++__begin;
0309       if (__begin == __end)
0310         std::__throw_format_error("The format string terminates at a '{'");
0311 
0312       if (*__begin != _CharT('{')) [[likely]] {
0313         __ctx.advance_to(std::move(__out_it));
0314         __begin  = __format::__handle_replacement_field(__begin, __end, __parse_ctx, __ctx);
0315         __out_it = __ctx.out();
0316 
0317         // The output is written and __begin points to the next character. So
0318         // start the next iteration.
0319         continue;
0320       }
0321       // The string is an escape character.
0322       break;
0323 
0324     case _CharT('}'):
0325       ++__begin;
0326       if (__begin == __end || *__begin != _CharT('}'))
0327         std::__throw_format_error("The format string contains an invalid escape sequence");
0328 
0329       break;
0330     }
0331 
0332     // Copy the character to the output verbatim.
0333     *__out_it++ = *__begin++;
0334   }
0335   return __out_it;
0336 }
0337 
0338 } // namespace __format
0339 
0340 #  if _LIBCPP_STD_VER >= 26
0341 template <class _CharT>
0342 struct _LIBCPP_TEMPLATE_VIS __runtime_format_string {
0343 private:
0344   basic_string_view<_CharT> __str_;
0345 
0346   template <class _Cp, class... _Args>
0347   friend struct _LIBCPP_TEMPLATE_VIS basic_format_string;
0348 
0349 public:
0350   _LIBCPP_HIDE_FROM_ABI __runtime_format_string(basic_string_view<_CharT> __s) noexcept : __str_(__s) {}
0351 
0352   __runtime_format_string(const __runtime_format_string&)            = delete;
0353   __runtime_format_string& operator=(const __runtime_format_string&) = delete;
0354 };
0355 
0356 _LIBCPP_HIDE_FROM_ABI inline __runtime_format_string<char> runtime_format(string_view __fmt) noexcept { return __fmt; }
0357 #    if _LIBCPP_HAS_WIDE_CHARACTERS
0358 _LIBCPP_HIDE_FROM_ABI inline __runtime_format_string<wchar_t> runtime_format(wstring_view __fmt) noexcept {
0359   return __fmt;
0360 }
0361 #    endif
0362 #  endif // _LIBCPP_STD_VER >= 26
0363 
0364 template <class _CharT, class... _Args>
0365 struct _LIBCPP_TEMPLATE_VIS basic_format_string {
0366   template <class _Tp>
0367     requires convertible_to<const _Tp&, basic_string_view<_CharT>>
0368   consteval basic_format_string(const _Tp& __str) : __str_{__str} {
0369     __format::__vformat_to(basic_format_parse_context<_CharT>{__str_, sizeof...(_Args)},
0370                            _Context{__types_.data(), __handles_.data(), sizeof...(_Args)});
0371   }
0372 
0373   _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<_CharT> get() const noexcept { return __str_; }
0374 #  if _LIBCPP_STD_VER >= 26
0375   _LIBCPP_HIDE_FROM_ABI basic_format_string(__runtime_format_string<_CharT> __s) noexcept : __str_(__s.__str_) {}
0376 #  endif
0377 
0378 private:
0379   basic_string_view<_CharT> __str_;
0380 
0381   using _Context _LIBCPP_NODEBUG = __format::__compile_time_basic_format_context<_CharT>;
0382 
0383   static constexpr array<__format::__arg_t, sizeof...(_Args)> __types_{
0384       __format::__determine_arg_t<_Context, remove_cvref_t<_Args>>()...};
0385 
0386   static constexpr array<__format::__compile_time_handle<_CharT>, sizeof...(_Args)> __handles_{[] {
0387     using _Tp = remove_cvref_t<_Args>;
0388     __format::__compile_time_handle<_CharT> __handle;
0389     if (__format::__determine_arg_t<_Context, _Tp>() == __format::__arg_t::__handle)
0390       __handle.template __enable<_Tp>();
0391 
0392     return __handle;
0393   }()...};
0394 };
0395 
0396 template <class... _Args>
0397 using format_string = basic_format_string<char, type_identity_t<_Args>...>;
0398 
0399 #  if _LIBCPP_HAS_WIDE_CHARACTERS
0400 template <class... _Args>
0401 using wformat_string = basic_format_string<wchar_t, type_identity_t<_Args>...>;
0402 #  endif
0403 
0404 template <class _OutIt, class _CharT, class _FormatOutIt>
0405   requires(output_iterator<_OutIt, const _CharT&>)
0406 _LIBCPP_HIDE_FROM_ABI _OutIt __vformat_to(_OutIt __out_it,
0407                                           basic_string_view<_CharT> __fmt,
0408                                           basic_format_args<basic_format_context<_FormatOutIt, _CharT>> __args) {
0409   if constexpr (same_as<_OutIt, _FormatOutIt>)
0410     return std::__format::__vformat_to(
0411         basic_format_parse_context{__fmt, __args.__size()}, std::__format_context_create(std::move(__out_it), __args));
0412   else {
0413     typename __format::__buffer_selector<_OutIt, _CharT>::type __buffer{std::move(__out_it)};
0414     std::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()},
0415                                 std::__format_context_create(__buffer.__make_output_iterator(), __args));
0416     return std::move(__buffer).__out_it();
0417   }
0418 }
0419 
0420 // The function is _LIBCPP_ALWAYS_INLINE since the compiler is bad at inlining
0421 // https://reviews.llvm.org/D110499#inline-1180704
0422 // TODO FMT Evaluate whether we want to file a Clang bug report regarding this.
0423 template <output_iterator<const char&> _OutIt>
0424 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt vformat_to(_OutIt __out_it, string_view __fmt, format_args __args) {
0425   return std::__vformat_to(std::move(__out_it), __fmt, __args);
0426 }
0427 
0428 #  if _LIBCPP_HAS_WIDE_CHARACTERS
0429 template <output_iterator<const wchar_t&> _OutIt>
0430 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
0431 vformat_to(_OutIt __out_it, wstring_view __fmt, wformat_args __args) {
0432   return std::__vformat_to(std::move(__out_it), __fmt, __args);
0433 }
0434 #  endif
0435 
0436 template <output_iterator<const char&> _OutIt, class... _Args>
0437 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
0438 format_to(_OutIt __out_it, format_string<_Args...> __fmt, _Args&&... __args) {
0439   return std::vformat_to(std::move(__out_it), __fmt.get(), std::make_format_args(__args...));
0440 }
0441 
0442 #  if _LIBCPP_HAS_WIDE_CHARACTERS
0443 template <output_iterator<const wchar_t&> _OutIt, class... _Args>
0444 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
0445 format_to(_OutIt __out_it, wformat_string<_Args...> __fmt, _Args&&... __args) {
0446   return std::vformat_to(std::move(__out_it), __fmt.get(), std::make_wformat_args(__args...));
0447 }
0448 #  endif
0449 
0450 // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup
0451 // fires too eagerly, see http://llvm.org/PR61563.
0452 template <class = void>
0453 [[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string vformat(string_view __fmt, format_args __args) {
0454   __format::__allocating_buffer<char> __buffer;
0455   std::vformat_to(__buffer.__make_output_iterator(), __fmt, __args);
0456   return string{__buffer.__view()};
0457 }
0458 
0459 #  if _LIBCPP_HAS_WIDE_CHARACTERS
0460 // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup
0461 // fires too eagerly, see http://llvm.org/PR61563.
0462 template <class = void>
0463 [[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring
0464 vformat(wstring_view __fmt, wformat_args __args) {
0465   __format::__allocating_buffer<wchar_t> __buffer;
0466   std::vformat_to(__buffer.__make_output_iterator(), __fmt, __args);
0467   return wstring{__buffer.__view()};
0468 }
0469 #  endif
0470 
0471 template <class... _Args>
0472 [[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string
0473 format(format_string<_Args...> __fmt, _Args&&... __args) {
0474   return std::vformat(__fmt.get(), std::make_format_args(__args...));
0475 }
0476 
0477 #  if _LIBCPP_HAS_WIDE_CHARACTERS
0478 template <class... _Args>
0479 [[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring
0480 format(wformat_string<_Args...> __fmt, _Args&&... __args) {
0481   return std::vformat(__fmt.get(), std::make_wformat_args(__args...));
0482 }
0483 #  endif
0484 
0485 template <class _Context, class _OutIt, class _CharT>
0486 _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt>
0487 __vformat_to_n(_OutIt __out_it,
0488                iter_difference_t<_OutIt> __n,
0489                basic_string_view<_CharT> __fmt,
0490                basic_format_args<_Context> __args) {
0491   __format::__format_to_n_buffer<_OutIt, _CharT> __buffer{std::move(__out_it), __n};
0492   std::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()},
0493                               std::__format_context_create(__buffer.__make_output_iterator(), __args));
0494   return std::move(__buffer).__result();
0495 }
0496 
0497 template <output_iterator<const char&> _OutIt, class... _Args>
0498 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt>
0499 format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, format_string<_Args...> __fmt, _Args&&... __args) {
0500   return std::__vformat_to_n<format_context>(std::move(__out_it), __n, __fmt.get(), std::make_format_args(__args...));
0501 }
0502 
0503 #  if _LIBCPP_HAS_WIDE_CHARACTERS
0504 template <output_iterator<const wchar_t&> _OutIt, class... _Args>
0505 _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt>
0506 format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, wformat_string<_Args...> __fmt, _Args&&... __args) {
0507   return std::__vformat_to_n<wformat_context>(std::move(__out_it), __n, __fmt.get(), std::make_wformat_args(__args...));
0508 }
0509 #  endif
0510 
0511 template <class _CharT>
0512 _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(basic_string_view<_CharT> __fmt, auto __args) {
0513   __format::__formatted_size_buffer<_CharT> __buffer;
0514   std::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()},
0515                               std::__format_context_create(__buffer.__make_output_iterator(), __args));
0516   return std::move(__buffer).__result();
0517 }
0518 
0519 template <class... _Args>
0520 [[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
0521 formatted_size(format_string<_Args...> __fmt, _Args&&... __args) {
0522   return std::__vformatted_size(__fmt.get(), basic_format_args{std::make_format_args(__args...)});
0523 }
0524 
0525 #  if _LIBCPP_HAS_WIDE_CHARACTERS
0526 template <class... _Args>
0527 [[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
0528 formatted_size(wformat_string<_Args...> __fmt, _Args&&... __args) {
0529   return std::__vformatted_size(__fmt.get(), basic_format_args{std::make_wformat_args(__args...)});
0530 }
0531 #  endif
0532 
0533 #  if _LIBCPP_HAS_LOCALIZATION
0534 
0535 template <class _OutIt, class _CharT, class _FormatOutIt>
0536   requires(output_iterator<_OutIt, const _CharT&>)
0537 _LIBCPP_HIDE_FROM_ABI _OutIt __vformat_to(
0538     _OutIt __out_it,
0539     locale __loc,
0540     basic_string_view<_CharT> __fmt,
0541     basic_format_args<basic_format_context<_FormatOutIt, _CharT>> __args) {
0542   if constexpr (same_as<_OutIt, _FormatOutIt>)
0543     return std::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()},
0544                                        std::__format_context_create(std::move(__out_it), __args, std::move(__loc)));
0545   else {
0546     typename __format::__buffer_selector<_OutIt, _CharT>::type __buffer{std::move(__out_it)};
0547     std::__format::__vformat_to(
0548         basic_format_parse_context{__fmt, __args.__size()},
0549         std::__format_context_create(__buffer.__make_output_iterator(), __args, std::move(__loc)));
0550     return std::move(__buffer).__out_it();
0551   }
0552 }
0553 
0554 template <output_iterator<const char&> _OutIt>
0555 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
0556 vformat_to(_OutIt __out_it, locale __loc, string_view __fmt, format_args __args) {
0557   return std::__vformat_to(std::move(__out_it), std::move(__loc), __fmt, __args);
0558 }
0559 
0560 #    if _LIBCPP_HAS_WIDE_CHARACTERS
0561 template <output_iterator<const wchar_t&> _OutIt>
0562 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
0563 vformat_to(_OutIt __out_it, locale __loc, wstring_view __fmt, wformat_args __args) {
0564   return std::__vformat_to(std::move(__out_it), std::move(__loc), __fmt, __args);
0565 }
0566 #    endif
0567 
0568 template <output_iterator<const char&> _OutIt, class... _Args>
0569 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
0570 format_to(_OutIt __out_it, locale __loc, format_string<_Args...> __fmt, _Args&&... __args) {
0571   return std::vformat_to(std::move(__out_it), std::move(__loc), __fmt.get(), std::make_format_args(__args...));
0572 }
0573 
0574 #    if _LIBCPP_HAS_WIDE_CHARACTERS
0575 template <output_iterator<const wchar_t&> _OutIt, class... _Args>
0576 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
0577 format_to(_OutIt __out_it, locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) {
0578   return std::vformat_to(std::move(__out_it), std::move(__loc), __fmt.get(), std::make_wformat_args(__args...));
0579 }
0580 #    endif
0581 
0582 // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup
0583 // fires too eagerly, see http://llvm.org/PR61563.
0584 template <class = void>
0585 [[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string
0586 vformat(locale __loc, string_view __fmt, format_args __args) {
0587   __format::__allocating_buffer<char> __buffer;
0588   std::vformat_to(__buffer.__make_output_iterator(), std::move(__loc), __fmt, __args);
0589   return string{__buffer.__view()};
0590 }
0591 
0592 #    if _LIBCPP_HAS_WIDE_CHARACTERS
0593 // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup
0594 // fires too eagerly, see http://llvm.org/PR61563.
0595 template <class = void>
0596 [[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring
0597 vformat(locale __loc, wstring_view __fmt, wformat_args __args) {
0598   __format::__allocating_buffer<wchar_t> __buffer;
0599   std::vformat_to(__buffer.__make_output_iterator(), std::move(__loc), __fmt, __args);
0600   return wstring{__buffer.__view()};
0601 }
0602 #    endif
0603 
0604 template <class... _Args>
0605 [[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string
0606 format(locale __loc, format_string<_Args...> __fmt, _Args&&... __args) {
0607   return std::vformat(std::move(__loc), __fmt.get(), std::make_format_args(__args...));
0608 }
0609 
0610 #    if _LIBCPP_HAS_WIDE_CHARACTERS
0611 template <class... _Args>
0612 [[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring
0613 format(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) {
0614   return std::vformat(std::move(__loc), __fmt.get(), std::make_wformat_args(__args...));
0615 }
0616 #    endif
0617 
0618 template <class _Context, class _OutIt, class _CharT>
0619 _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(
0620     _OutIt __out_it,
0621     iter_difference_t<_OutIt> __n,
0622     locale __loc,
0623     basic_string_view<_CharT> __fmt,
0624     basic_format_args<_Context> __args) {
0625   __format::__format_to_n_buffer<_OutIt, _CharT> __buffer{std::move(__out_it), __n};
0626   std::__format::__vformat_to(
0627       basic_format_parse_context{__fmt, __args.__size()},
0628       std::__format_context_create(__buffer.__make_output_iterator(), __args, std::move(__loc)));
0629   return std::move(__buffer).__result();
0630 }
0631 
0632 template <output_iterator<const char&> _OutIt, class... _Args>
0633 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> format_to_n(
0634     _OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, format_string<_Args...> __fmt, _Args&&... __args) {
0635   return std::__vformat_to_n<format_context>(
0636       std::move(__out_it), __n, std::move(__loc), __fmt.get(), std::make_format_args(__args...));
0637 }
0638 
0639 #    if _LIBCPP_HAS_WIDE_CHARACTERS
0640 template <output_iterator<const wchar_t&> _OutIt, class... _Args>
0641 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> format_to_n(
0642     _OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) {
0643   return std::__vformat_to_n<wformat_context>(
0644       std::move(__out_it), __n, std::move(__loc), __fmt.get(), std::make_wformat_args(__args...));
0645 }
0646 #    endif
0647 
0648 template <class _CharT>
0649 _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(locale __loc, basic_string_view<_CharT> __fmt, auto __args) {
0650   __format::__formatted_size_buffer<_CharT> __buffer;
0651   std::__format::__vformat_to(
0652       basic_format_parse_context{__fmt, __args.__size()},
0653       std::__format_context_create(__buffer.__make_output_iterator(), __args, std::move(__loc)));
0654   return std::move(__buffer).__result();
0655 }
0656 
0657 template <class... _Args>
0658 [[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
0659 formatted_size(locale __loc, format_string<_Args...> __fmt, _Args&&... __args) {
0660   return std::__vformatted_size(std::move(__loc), __fmt.get(), basic_format_args{std::make_format_args(__args...)});
0661 }
0662 
0663 #    if _LIBCPP_HAS_WIDE_CHARACTERS
0664 template <class... _Args>
0665 [[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
0666 formatted_size(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) {
0667   return std::__vformatted_size(std::move(__loc), __fmt.get(), basic_format_args{std::make_wformat_args(__args...)});
0668 }
0669 #    endif
0670 
0671 #  endif // _LIBCPP_HAS_LOCALIZATION
0672 
0673 #endif // _LIBCPP_STD_VER >= 20
0674 
0675 _LIBCPP_END_NAMESPACE_STD
0676 
0677 _LIBCPP_POP_MACROS
0678 
0679 #endif // _LIBCPP___FORMAT_FORMAT_FUNCTIONS