Back to home page

EIC code displayed by LXR

 
 

    


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

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