1// -*- C++ -*- 2//===----------------------------------------------------------------------===// 3// 4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5// See https://llvm.org/LICENSE.txt for license information. 6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef _LIBCPP_FORMAT 11#define _LIBCPP_FORMAT 12 13/* 14 15namespace std { 16 // [format.context], class template basic_format_context 17 template<class Out, class charT> class basic_format_context; 18 using format_context = basic_format_context<unspecified, char>; 19 using wformat_context = basic_format_context<unspecified, wchar_t>; 20 21 // [format.args], class template basic_format_args 22 template<class Context> class basic_format_args; 23 using format_args = basic_format_args<format_context>; 24 using wformat_args = basic_format_args<wformat_context>; 25 26 // [format.functions], formatting functions 27 template<class... Args> 28 string format(string_view fmt, const Args&... args); 29 template<class... Args> 30 wstring format(wstring_view fmt, const Args&... args); 31 template<class... Args> 32 string format(const locale& loc, string_view fmt, const Args&... args); 33 template<class... Args> 34 wstring format(const locale& loc, wstring_view fmt, const Args&... args); 35 36 string vformat(string_view fmt, format_args args); 37 wstring vformat(wstring_view fmt, wformat_args args); 38 string vformat(const locale& loc, string_view fmt, format_args args); 39 wstring vformat(const locale& loc, wstring_view fmt, wformat_args args); 40 41 template<class Out, class... Args> 42 Out format_to(Out out, string_view fmt, const Args&... args); 43 template<class Out, class... Args> 44 Out format_to(Out out, wstring_view fmt, const Args&... args); 45 template<class Out, class... Args> 46 Out format_to(Out out, const locale& loc, string_view fmt, const Args&... args); 47 template<class Out, class... Args> 48 Out format_to(Out out, const locale& loc, wstring_view fmt, const Args&... args); 49 50 template<class Out> 51 Out vformat_to(Out out, string_view fmt, format_args args); 52 template<class Out> 53 Out vformat_to(Out out, wstring_view fmt, wformat_args args); 54 template<class Out> 55 Out vformat_to(Out out, const locale& loc, string_view fmt, 56 format_args char> args); 57 template<class Out> 58 Out vformat_to(Out out, const locale& loc, wstring_view fmt, 59 wformat_args args); 60 61 template<class Out> struct format_to_n_result { 62 Out out; 63 iter_difference_t<Out> size; 64 }; 65 template<class Out, class... Args> 66 format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, 67 string_view fmt, const Args&... args); 68 template<class Out, class... Args> 69 format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, 70 wstring_view fmt, const Args&... args); 71 template<class Out, class... Args> 72 format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, 73 const locale& loc, string_view fmt, 74 const Args&... args); 75 template<class Out, class... Args> 76 format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, 77 const locale& loc, wstring_view fmt, 78 const Args&... args); 79 80 template<class... Args> 81 size_t formatted_size(string_view fmt, const Args&... args); 82 template<class... Args> 83 size_t formatted_size(wstring_view fmt, const Args&... args); 84 template<class... Args> 85 size_t formatted_size(const locale& loc, string_view fmt, const Args&... args); 86 template<class... Args> 87 size_t formatted_size(const locale& loc, wstring_view fmt, const Args&... args); 88 89 // [format.formatter], formatter 90 template<class T, class charT = char> struct formatter; 91 92 // [format.parse.ctx], class template basic_format_parse_context 93 template<class charT> class basic_format_parse_context; 94 using format_parse_context = basic_format_parse_context<char>; 95 using wformat_parse_context = basic_format_parse_context<wchar_t>; 96 97 // [format.arguments], arguments 98 // [format.arg], class template basic_format_arg 99 template<class Context> class basic_format_arg; 100 101 template<class Visitor, class Context> 102 see below visit_format_arg(Visitor&& vis, basic_format_arg<Context> arg); 103 104 // [format.arg.store], class template format-arg-store 105 template<class Context, class... Args> struct format-arg-store; // exposition only 106 107 template<class Context = format_context, class... Args> 108 format-arg-store<Context, Args...> 109 make_format_args(const Args&... args); 110 template<class... Args> 111 format-arg-store<wformat_context, Args...> 112 make_wformat_args(const Args&... args); 113 114 // [format.error], class format_error 115 class format_error; 116} 117 118*/ 119 120#include <__assert> // all public C++ headers provide the assertion handler 121// Make sure all feature-test macros are available. 122#include <version> 123// Enable the contents of the header only when libc++ was built with LIBCXX_ENABLE_INCOMPLETE_FEATURES. 124#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) 125 126#include <__algorithm/clamp.h> 127#include <__config> 128#include <__debug> 129#include <__format/buffer.h> 130#include <__format/concepts.h> 131#include <__format/enable_insertable.h> 132#include <__format/format_arg.h> 133#include <__format/format_arg_store.h> 134#include <__format/format_args.h> 135#include <__format/format_context.h> 136#include <__format/format_error.h> 137#include <__format/format_fwd.h> 138#include <__format/format_parse_context.h> 139#include <__format/format_string.h> 140#include <__format/format_to_n_result.h> 141#include <__format/formatter.h> 142#include <__format/formatter_bool.h> 143#include <__format/formatter_char.h> 144#include <__format/formatter_floating_point.h> 145#include <__format/formatter_integer.h> 146#include <__format/formatter_pointer.h> 147#include <__format/formatter_string.h> 148#include <__format/parser_std_format_spec.h> 149#include <__iterator/incrementable_traits.h> 150#include <__variant/monostate.h> 151#include <array> 152#include <concepts> 153#include <string> 154#include <string_view> 155#include <type_traits> 156 157#ifndef _LIBCPP_HAS_NO_LOCALIZATION 158#include <locale> 159#endif 160 161#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 162# pragma GCC system_header 163#endif 164 165_LIBCPP_BEGIN_NAMESPACE_STD 166 167#if _LIBCPP_STD_VER > 17 168 169// TODO FMT Move the implementation in this file to its own granular headers. 170 171// TODO FMT Evaluate which templates should be external templates. This 172// improves the efficiency of the header. However since the header is still 173// under heavy development and not all classes are stable it makes no sense 174// to do this optimization now. 175 176using format_args = basic_format_args<format_context>; 177#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 178using wformat_args = basic_format_args<wformat_context>; 179#endif 180 181// TODO FMT This helper wrapper can probably be removed after P2418 has been 182// implemented. 183template <class _Context, class... _Args> 184_LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> 185__make_format_args(_Args&&... __args) { 186 return _VSTD::__format_arg_store<_Context, _Args...>( 187 _VSTD::forward<_Args>(__args)...); 188} 189 190// TODO FMT After P2418 specify the return type instead of using auto. 191template <class _Context = format_context, class... _Args> 192_LIBCPP_HIDE_FROM_ABI auto make_format_args(const _Args&... __args) { 193 return _VSTD::__make_format_args<_Context>(__args...); 194} 195 196#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 197// TODO FMT After P2418 specify the return type instead of using auto. 198template <class... _Args> 199_LIBCPP_HIDE_FROM_ABI auto make_wformat_args(const _Args&... __args) { 200 return _VSTD::make_format_args<wformat_context>(__args...); 201} 202#endif 203 204namespace __format { 205 206template <class _CharT, class _ParseCtx, class _Ctx> 207_LIBCPP_HIDE_FROM_ABI const _CharT* 208__handle_replacement_field(const _CharT* __begin, const _CharT* __end, 209 _ParseCtx& __parse_ctx, _Ctx& __ctx) { 210 __format::__parse_number_result __r = 211 __format::__parse_arg_id(__begin, __end, __parse_ctx); 212 213 switch (*__r.__ptr) { 214 case _CharT(':'): 215 // The arg-id has a format-specifier, advance the input to the format-spec. 216 __parse_ctx.advance_to(__r.__ptr + 1); 217 break; 218 case _CharT('}'): 219 // The arg-id has no format-specifier. 220 __parse_ctx.advance_to(__r.__ptr); 221 break; 222 default: 223 __throw_format_error( 224 "The replacement field arg-id should terminate at a ':' or '}'"); 225 } 226 227 _VSTD::visit_format_arg( 228 [&](auto __arg) { 229 if constexpr (same_as<decltype(__arg), monostate>) 230 __throw_format_error("Argument index out of bounds"); 231 else if constexpr (same_as<decltype(__arg), typename basic_format_arg<_Ctx>::handle>) 232 __arg.format(__parse_ctx, __ctx); 233 else { 234 formatter<decltype(__arg), _CharT> __formatter; 235 __parse_ctx.advance_to(__formatter.parse(__parse_ctx)); 236 __ctx.advance_to(__formatter.format(__arg, __ctx)); 237 } 238 }, 239 __ctx.arg(__r.__value)); 240 241 __begin = __parse_ctx.begin(); 242 if (__begin == __end || *__begin != _CharT('}')) 243 __throw_format_error("The replacement field misses a terminating '}'"); 244 245 return ++__begin; 246} 247 248template <class _ParseCtx, class _Ctx> 249_LIBCPP_HIDE_FROM_ABI typename _Ctx::iterator 250__vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) { 251 using _CharT = typename _ParseCtx::char_type; 252 static_assert(same_as<typename _Ctx::char_type, _CharT>); 253 254 const _CharT* __begin = __parse_ctx.begin(); 255 const _CharT* __end = __parse_ctx.end(); 256 typename _Ctx::iterator __out_it = __ctx.out(); 257 while (__begin != __end) { 258 switch (*__begin) { 259 case _CharT('{'): 260 ++__begin; 261 if (__begin == __end) 262 __throw_format_error("The format string terminates at a '{'"); 263 264 if (*__begin != _CharT('{')) [[likely]] { 265 __ctx.advance_to(_VSTD::move(__out_it)); 266 __begin = 267 __handle_replacement_field(__begin, __end, __parse_ctx, __ctx); 268 __out_it = __ctx.out(); 269 270 // The output is written and __begin points to the next character. So 271 // start the next iteration. 272 continue; 273 } 274 // The string is an escape character. 275 break; 276 277 case _CharT('}'): 278 ++__begin; 279 if (__begin == __end || *__begin != _CharT('}')) 280 __throw_format_error( 281 "The format string contains an invalid escape sequence"); 282 283 break; 284 } 285 286 // Copy the character to the output verbatim. 287 *__out_it++ = *__begin++; 288 } 289 return __out_it; 290} 291 292} // namespace __format 293 294template <class _OutIt, class _CharT, class _FormatOutIt> 295requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt 296 __vformat_to( 297 _OutIt __out_it, basic_string_view<_CharT> __fmt, 298 basic_format_args<basic_format_context<_FormatOutIt, _CharT>> __args) { 299 if constexpr (same_as<_OutIt, _FormatOutIt>) 300 return _VSTD::__format::__vformat_to( 301 basic_format_parse_context{__fmt, __args.__size()}, 302 _VSTD::__format_context_create(_VSTD::move(__out_it), __args)); 303 else { 304 __format::__format_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it)}; 305 _VSTD::__format::__vformat_to( 306 basic_format_parse_context{__fmt, __args.__size()}, 307 _VSTD::__format_context_create(__buffer.make_output_iterator(), 308 __args)); 309 return _VSTD::move(__buffer).out(); 310 } 311} 312 313// The function is _LIBCPP_ALWAYS_INLINE since the compiler is bad at inlining 314// https://reviews.llvm.org/D110499#inline-1180704 315// TODO FMT Evaluate whether we want to file a Clang bug report regarding this. 316template <output_iterator<const char&> _OutIt> 317_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt 318vformat_to(_OutIt __out_it, string_view __fmt, format_args __args) { 319 return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args); 320} 321 322#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 323template <output_iterator<const wchar_t&> _OutIt> 324_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt 325vformat_to(_OutIt __out_it, wstring_view __fmt, wformat_args __args) { 326 return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args); 327} 328#endif 329 330template <output_iterator<const char&> _OutIt, class... _Args> 331_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt 332format_to(_OutIt __out_it, string_view __fmt, const _Args&... __args) { 333 return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt, 334 _VSTD::make_format_args(__args...)); 335} 336 337#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 338template <output_iterator<const wchar_t&> _OutIt, class... _Args> 339_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt 340format_to(_OutIt __out_it, wstring_view __fmt, const _Args&... __args) { 341 return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt, 342 _VSTD::make_wformat_args(__args...)); 343} 344#endif 345 346_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string 347vformat(string_view __fmt, format_args __args) { 348 string __res; 349 _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args); 350 return __res; 351} 352 353#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 354_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring 355vformat(wstring_view __fmt, wformat_args __args) { 356 wstring __res; 357 _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args); 358 return __res; 359} 360#endif 361 362template <class... _Args> 363_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string 364format(string_view __fmt, const _Args&... __args) { 365 return _VSTD::vformat(__fmt, _VSTD::make_format_args(__args...)); 366} 367 368#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 369template <class... _Args> 370_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring 371format(wstring_view __fmt, const _Args&... __args) { 372 return _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...)); 373} 374#endif 375 376template <class _Context, class _OutIt, class _CharT> 377_LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, 378 basic_string_view<_CharT> __fmt, 379 basic_format_args<_Context> __args) { 380 __format::__format_to_n_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it), __n}; 381 _VSTD::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, 382 _VSTD::__format_context_create(__buffer.make_output_iterator(), __args)); 383 return _VSTD::move(__buffer).result(); 384} 385 386template <output_iterator<const char&> _OutIt, class... _Args> 387_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> 388format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, string_view __fmt, const _Args&... __args) { 389 return _VSTD::__vformat_to_n<format_context>(_VSTD::move(__out_it), __n, __fmt, _VSTD::make_format_args(__args...)); 390} 391 392#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 393template <output_iterator<const wchar_t&> _OutIt, class... _Args> 394_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> 395format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, wstring_view __fmt, const _Args&... __args) { 396 return _VSTD::__vformat_to_n<wformat_context>(_VSTD::move(__out_it), __n, __fmt, _VSTD::make_wformat_args(__args...)); 397} 398#endif 399 400template <class _CharT> 401_LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(basic_string_view<_CharT> __fmt, auto __args) { 402 __format::__formatted_size_buffer<_CharT> __buffer; 403 _VSTD::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, 404 _VSTD::__format_context_create(__buffer.make_output_iterator(), __args)); 405 return _VSTD::move(__buffer).result(); 406} 407 408template <class... _Args> 409_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t formatted_size(string_view __fmt, 410 const _Args&... __args) { 411 return _VSTD::__vformatted_size(__fmt, basic_format_args{_VSTD::make_format_args(__args...)}); 412} 413 414#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 415template <class... _Args> 416_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t formatted_size(wstring_view __fmt, 417 const _Args&... __args) { 418 return _VSTD::__vformatted_size(__fmt, basic_format_args{_VSTD::make_wformat_args(__args...)}); 419} 420#endif 421 422#ifndef _LIBCPP_HAS_NO_LOCALIZATION 423 424template <class _OutIt, class _CharT, class _FormatOutIt> 425requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt 426 __vformat_to( 427 _OutIt __out_it, locale __loc, basic_string_view<_CharT> __fmt, 428 basic_format_args<basic_format_context<_FormatOutIt, _CharT>> __args) { 429 if constexpr (same_as<_OutIt, _FormatOutIt>) 430 return _VSTD::__format::__vformat_to( 431 basic_format_parse_context{__fmt, __args.__size()}, 432 _VSTD::__format_context_create(_VSTD::move(__out_it), __args, 433 _VSTD::move(__loc))); 434 else { 435 __format::__format_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it)}; 436 _VSTD::__format::__vformat_to( 437 basic_format_parse_context{__fmt, __args.__size()}, 438 _VSTD::__format_context_create(__buffer.make_output_iterator(), 439 __args, _VSTD::move(__loc))); 440 return _VSTD::move(__buffer).out(); 441 } 442} 443 444template <output_iterator<const char&> _OutIt> 445_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt vformat_to( 446 _OutIt __out_it, locale __loc, string_view __fmt, format_args __args) { 447 return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, 448 __args); 449} 450 451#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 452template <output_iterator<const wchar_t&> _OutIt> 453_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt vformat_to( 454 _OutIt __out_it, locale __loc, wstring_view __fmt, wformat_args __args) { 455 return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, 456 __args); 457} 458#endif 459 460template <output_iterator<const char&> _OutIt, class... _Args> 461_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to( 462 _OutIt __out_it, locale __loc, string_view __fmt, const _Args&... __args) { 463 return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, 464 _VSTD::make_format_args(__args...)); 465} 466 467#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 468template <output_iterator<const wchar_t&> _OutIt, class... _Args> 469_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to( 470 _OutIt __out_it, locale __loc, wstring_view __fmt, const _Args&... __args) { 471 return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, 472 _VSTD::make_wformat_args(__args...)); 473} 474#endif 475 476_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string 477vformat(locale __loc, string_view __fmt, format_args __args) { 478 string __res; 479 _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt, 480 __args); 481 return __res; 482} 483 484#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 485_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring 486vformat(locale __loc, wstring_view __fmt, wformat_args __args) { 487 wstring __res; 488 _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt, 489 __args); 490 return __res; 491} 492#endif 493 494template <class... _Args> 495_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string 496format(locale __loc, string_view __fmt, const _Args&... __args) { 497 return _VSTD::vformat(_VSTD::move(__loc), __fmt, 498 _VSTD::make_format_args(__args...)); 499} 500 501#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 502template <class... _Args> 503_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring 504format(locale __loc, wstring_view __fmt, const _Args&... __args) { 505 return _VSTD::vformat(_VSTD::move(__loc), __fmt, 506 _VSTD::make_wformat_args(__args...)); 507} 508#endif 509 510template <class _Context, class _OutIt, class _CharT> 511_LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, 512 locale __loc, basic_string_view<_CharT> __fmt, 513 basic_format_args<_Context> __args) { 514 __format::__format_to_n_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it), __n}; 515 _VSTD::__format::__vformat_to( 516 basic_format_parse_context{__fmt, __args.__size()}, 517 _VSTD::__format_context_create(__buffer.make_output_iterator(), __args, _VSTD::move(__loc))); 518 return _VSTD::move(__buffer).result(); 519} 520 521template <output_iterator<const char&> _OutIt, class... _Args> 522_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> 523format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, string_view __fmt, const _Args&... __args) { 524 return _VSTD::__vformat_to_n<format_context>(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt, 525 _VSTD::make_format_args(__args...)); 526} 527 528#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 529template <output_iterator<const wchar_t&> _OutIt, class... _Args> 530_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> 531format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, wstring_view __fmt, const _Args&... __args) { 532 return _VSTD::__vformat_to_n<wformat_context>(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt, 533 _VSTD::make_wformat_args(__args...)); 534} 535#endif 536 537template <class _CharT> 538_LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(locale __loc, basic_string_view<_CharT> __fmt, auto __args) { 539 __format::__formatted_size_buffer<_CharT> __buffer; 540 _VSTD::__format::__vformat_to( 541 basic_format_parse_context{__fmt, __args.__size()}, 542 _VSTD::__format_context_create(__buffer.make_output_iterator(), __args, _VSTD::move(__loc))); 543 return _VSTD::move(__buffer).result(); 544} 545 546template <class... _Args> 547_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t formatted_size(locale __loc, 548 string_view __fmt, 549 const _Args&... __args) { 550 return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt, basic_format_args{_VSTD::make_format_args(__args...)}); 551} 552 553#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 554template <class... _Args> 555_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t formatted_size(locale __loc, 556 wstring_view __fmt, 557 const _Args&... __args) { 558 return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt, basic_format_args{_VSTD::make_wformat_args(__args...)}); 559} 560#endif 561 562#endif // _LIBCPP_HAS_NO_LOCALIZATION 563 564#endif //_LIBCPP_STD_VER > 17 565 566_LIBCPP_END_NAMESPACE_STD 567 568#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) 569 570#endif // _LIBCPP_FORMAT 571