]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/libcxx/include/format
Merge llvm-project main llvmorg-15-init-17485-ga3e38b4a206b
[FreeBSD/FreeBSD.git] / contrib / llvm-project / libcxx / include / format
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
15 namespace 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.fmt.string], class template basic-format-string
27   template<class charT, class... Args>
28     struct basic-format-string;                       // exposition only
29
30   template<class... Args>
31     using format-string =                             // exposition only
32       basic-format-string<char, type_identity_t<Args>...>;
33   template<class... Args>
34     using wformat-string =                            // exposition only
35       basic-format-string<wchar_t, type_identity_t<Args>...>;
36
37   // [format.functions], formatting functions
38   template<class... Args>
39     string format(format-string<Args...> fmt, Args&&... args);
40   template<class... Args>
41     wstring format(wformat-string<Args...> fmt, Args&&... args);
42   template<class... Args>
43     string format(const locale& loc, format-string<Args...> fmt, Args&&... args);
44   template<class... Args>
45     wstring format(const locale& loc, wformat-string<Args...> fmt, Args&&... args);
46
47   string vformat(string_view fmt, format_args args);
48   wstring vformat(wstring_view fmt, wformat_args args);
49   string vformat(const locale& loc, string_view fmt, format_args args);
50   wstring vformat(const locale& loc, wstring_view fmt, wformat_args args);
51
52   template<class Out, class... Args>
53     Out format_to(Out out, format-string<Args...> fmt, Args&&... args);
54   template<class Out, class... Args>
55     Out format_to(Out out, wformat-string<Args...> fmt, Args&&... args);
56   template<class Out, class... Args>
57     Out format_to(Out out, const locale& loc, format-string<Args...> fmt, Args&&... args);
58   template<class Out, class... Args>
59     Out format_to(Out out, const locale& loc, wformat-string<Args...> fmt, Args&&... args);
60
61   template<class Out>
62     Out vformat_to(Out out, string_view fmt, format_args args);
63   template<class Out>
64     Out vformat_to(Out out, wstring_view fmt, wformat_args args);
65   template<class Out>
66     Out vformat_to(Out out, const locale& loc, string_view fmt,
67                    format_args char> args);
68   template<class Out>
69     Out vformat_to(Out out, const locale& loc, wstring_view fmt,
70                    wformat_args args);
71
72   template<class Out> struct format_to_n_result {
73     Out out;
74     iter_difference_t<Out> size;
75   };
76   template<class Out, class... Args>
77     format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
78                                         format-string<Args...> fmt, Args&&... args);
79   template<class Out, class... Args>
80     format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
81                                         wformat-string<Args...> fmt, Args&&... args);
82   template<class Out, class... Args>
83     format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
84                                         const locale& loc, format-string<Args...> fmt,
85                                         Args&&... args);
86   template<class Out, class... Args>
87     format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
88                                         const locale& loc, wformat-string<Args...> fmt,
89                                         Args&&... args);
90
91   template<class... Args>
92     size_t formatted_size(format-string<Args...> fmt, Args&&... args);
93   template<class... Args>
94     size_t formatted_size(wformat-string<Args...> fmt, Args&&... args);
95   template<class... Args>
96     size_t formatted_size(const locale& loc, format-string<Args...> fmt, Args&&... args);
97   template<class... Args>
98     size_t formatted_size(const locale& loc, wformat-string<Args...> fmt, Args&&... args);
99
100   // [format.formatter], formatter
101   template<class T, class charT = char> struct formatter;
102
103   // [format.parse.ctx], class template basic_format_parse_context
104   template<class charT> class basic_format_parse_context;
105   using format_parse_context = basic_format_parse_context<char>;
106   using wformat_parse_context = basic_format_parse_context<wchar_t>;
107
108   // [format.arguments], arguments
109   // [format.arg], class template basic_format_arg
110   template<class Context> class basic_format_arg;
111
112   template<class Visitor, class Context>
113     see below visit_format_arg(Visitor&& vis, basic_format_arg<Context> arg);
114
115   // [format.arg.store], class template format-arg-store
116   template<class Context, class... Args> struct format-arg-store;      // exposition only
117
118   template<class Context = format_context, class... Args>
119     format-arg-store<Context, Args...>
120       make_format_args(Args&&... args);
121   template<class... Args>
122     format-arg-store<wformat_context, Args...>
123       make_wformat_args(Args&&... args);
124
125   // [format.error], class format_error
126   class format_error;
127 }
128
129 */
130
131 #include <__assert> // all public C++ headers provide the assertion handler
132 // Make sure all feature-test macros are available.
133 #include <version>
134 // Enable the contents of the header only when libc++ was built with experimental features enabled.
135 #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
136
137 #include <__algorithm/clamp.h>
138 #include <__config>
139 #include <__debug>
140 #include <__format/buffer.h>
141 #include <__format/concepts.h>
142 #include <__format/enable_insertable.h>
143 #include <__format/format_arg.h>
144 #include <__format/format_arg_store.h>
145 #include <__format/format_args.h>
146 #include <__format/format_context.h>
147 #include <__format/format_error.h>
148 #include <__format/format_fwd.h>
149 #include <__format/format_parse_context.h>
150 #include <__format/format_string.h>
151 #include <__format/format_to_n_result.h>
152 #include <__format/formatter.h>
153 #include <__format/formatter_bool.h>
154 #include <__format/formatter_char.h>
155 #include <__format/formatter_floating_point.h>
156 #include <__format/formatter_integer.h>
157 #include <__format/formatter_pointer.h>
158 #include <__format/formatter_string.h>
159 #include <__format/parser_std_format_spec.h>
160 #include <__format/unicode.h>
161 #include <__iterator/back_insert_iterator.h>
162 #include <__iterator/incrementable_traits.h>
163 #include <__variant/monostate.h>
164 #include <array>
165 #include <concepts>
166 #include <string>
167 #include <string_view>
168 #include <type_traits>
169
170 #ifndef _LIBCPP_HAS_NO_LOCALIZATION
171 #include <locale>
172 #endif
173
174 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
175 #  pragma GCC system_header
176 #endif
177
178 _LIBCPP_BEGIN_NAMESPACE_STD
179
180 #if _LIBCPP_STD_VER > 17
181
182 // TODO FMT Move the implementation in this file to its own granular headers.
183
184 // TODO FMT Evaluate which templates should be external templates. This
185 // improves the efficiency of the header. However since the header is still
186 // under heavy development and not all classes are stable it makes no sense
187 // to do this optimization now.
188
189 using format_args = basic_format_args<format_context>;
190 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
191 using wformat_args = basic_format_args<wformat_context>;
192 #endif
193
194 template <class _Context = format_context, class... _Args>
195 _LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> make_format_args(_Args&&... __args) {
196   return _VSTD::__format_arg_store<_Context, _Args...>(__args...);
197 }
198
199 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
200 template <class... _Args>
201 _LIBCPP_HIDE_FROM_ABI __format_arg_store<wformat_context, _Args...> make_wformat_args(_Args&&... __args) {
202   return _VSTD::__format_arg_store<wformat_context, _Args...>(__args...);
203 }
204 #endif
205
206 namespace __format {
207
208 /// Helper class parse and handle argument.
209 ///
210 /// When parsing a handle which is not enabled the code is ill-formed.
211 /// This helper uses the parser of the appropriate formatter for the stored type.
212 template <class _CharT>
213 class _LIBCPP_TEMPLATE_VIS __compile_time_handle {
214 public:
215   _LIBCPP_HIDE_FROM_ABI
216   constexpr void __parse(basic_format_parse_context<_CharT>& __parse_ctx) const { __parse_(__parse_ctx); }
217
218   template <class _Tp>
219   _LIBCPP_HIDE_FROM_ABI constexpr void __enable() {
220     __parse_ = [](basic_format_parse_context<_CharT>& __parse_ctx) {
221       formatter<_Tp, _CharT> __f;
222       __parse_ctx.advance_to(__f.parse(__parse_ctx));
223     };
224   }
225
226   // Before calling __parse the proper handler needs to be set with __enable.
227   // The default handler isn't a core constant expression.
228   _LIBCPP_HIDE_FROM_ABI constexpr __compile_time_handle()
229       : __parse_([](basic_format_parse_context<_CharT>&) { __throw_format_error("Not a handle"); }) {}
230
231 private:
232   void (*__parse_)(basic_format_parse_context<_CharT>&);
233 };
234
235 // Dummy format_context only providing the parts used during constant
236 // validation of the basic-format-string.
237 template <class _CharT>
238 struct _LIBCPP_TEMPLATE_VIS __compile_time_basic_format_context {
239 public:
240   using char_type = _CharT;
241
242   _LIBCPP_HIDE_FROM_ABI constexpr explicit __compile_time_basic_format_context(
243       const __arg_t* __args, const __compile_time_handle<_CharT>* __handles, size_t __size)
244       : __args_(__args), __handles_(__handles), __size_(__size) {}
245
246   // During the compile-time validation nothing needs to be written.
247   // Therefore all operations of this iterator are a NOP.
248   struct iterator {
249     _LIBCPP_HIDE_FROM_ABI constexpr iterator& operator=(_CharT) { return *this; }
250     _LIBCPP_HIDE_FROM_ABI constexpr iterator& operator*() { return *this; }
251     _LIBCPP_HIDE_FROM_ABI constexpr iterator operator++(int) { return *this; }
252   };
253
254   _LIBCPP_HIDE_FROM_ABI constexpr __arg_t arg(size_t __id) const {
255     if (__id >= __size_)
256       __throw_format_error("Argument index out of bounds");
257     return __args_[__id];
258   }
259
260   _LIBCPP_HIDE_FROM_ABI constexpr const __compile_time_handle<_CharT>& __handle(size_t __id) const {
261     if (__id >= __size_)
262       __throw_format_error("Argument index out of bounds");
263     return __handles_[__id];
264   }
265
266   _LIBCPP_HIDE_FROM_ABI constexpr iterator out() { return {}; }
267   _LIBCPP_HIDE_FROM_ABI constexpr void advance_to(iterator) {}
268
269 private:
270   const __arg_t* __args_;
271   const __compile_time_handle<_CharT>* __handles_;
272   size_t __size_;
273 };
274
275 _LIBCPP_HIDE_FROM_ABI
276 constexpr void __compile_time_validate_integral(__arg_t __type) {
277   switch (__type) {
278   case __arg_t::__int:
279   case __arg_t::__long_long:
280   case __arg_t::__i128:
281   case __arg_t::__unsigned:
282   case __arg_t::__unsigned_long_long:
283   case __arg_t::__u128:
284     return;
285
286   default:
287     __throw_format_error("Argument isn't an integral type");
288   }
289 }
290
291 // _HasPrecision does the formatter have a precision?
292 template <class _CharT, class _Tp, bool _HasPrecision = false>
293 _LIBCPP_HIDE_FROM_ABI constexpr void
294 __compile_time_validate_argument(basic_format_parse_context<_CharT>& __parse_ctx,
295                                  __compile_time_basic_format_context<_CharT>& __ctx) {
296   formatter<_Tp, _CharT> __formatter;
297   __parse_ctx.advance_to(__formatter.parse(__parse_ctx));
298   // [format.string.std]/7
299   // ... If the corresponding formatting argument is not of integral type, or
300   // its value is negative for precision or non-positive for width, an
301   // exception of type format_error is thrown.
302   //
303   // Validate whether the arguments are integrals.
304   if constexpr (requires(formatter<_Tp, _CharT> __f) { __f.__width_needs_substitution(); }) {
305     // TODO FMT Remove this when parser v1 has been phased out.
306     if (__formatter.__width_needs_substitution())
307       __format::__compile_time_validate_integral(__ctx.arg(__formatter.__width));
308
309     if constexpr (_HasPrecision)
310       if (__formatter.__precision_needs_substitution())
311         __format::__compile_time_validate_integral(__ctx.arg(__formatter.__precision));
312   } else {
313     if (__formatter.__parser_.__width_as_arg_)
314       __format::__compile_time_validate_integral(__ctx.arg(__formatter.__parser_.__width_));
315
316     if constexpr (_HasPrecision)
317       if (__formatter.__parser_.__precision_as_arg_)
318         __format::__compile_time_validate_integral(__ctx.arg(__formatter.__parser_.__precision_));
319   }
320 }
321
322 template <class _CharT>
323 _LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_visit_format_arg(basic_format_parse_context<_CharT>& __parse_ctx,
324                                                                      __compile_time_basic_format_context<_CharT>& __ctx,
325                                                                      __arg_t __type) {
326   switch (__type) {
327   case __arg_t::__none:
328     __throw_format_error("Invalid argument");
329   case __arg_t::__boolean:
330     return __format::__compile_time_validate_argument<_CharT, bool>(__parse_ctx, __ctx);
331   case __arg_t::__char_type:
332     return __format::__compile_time_validate_argument<_CharT, _CharT>(__parse_ctx, __ctx);
333   case __arg_t::__int:
334     return __format::__compile_time_validate_argument<_CharT, int>(__parse_ctx, __ctx);
335   case __arg_t::__long_long:
336     return __format::__compile_time_validate_argument<_CharT, long long>(__parse_ctx, __ctx);
337   case __arg_t::__i128:
338 #      ifndef _LIBCPP_HAS_NO_INT128
339     return __format::__compile_time_validate_argument<_CharT, __int128_t>(__parse_ctx, __ctx);
340 #      else
341     __throw_format_error("Invalid argument");
342 #      endif
343     return;
344   case __arg_t::__unsigned:
345     return __format::__compile_time_validate_argument<_CharT, unsigned>(__parse_ctx, __ctx);
346   case __arg_t::__unsigned_long_long:
347     return __format::__compile_time_validate_argument<_CharT, unsigned long long>(__parse_ctx, __ctx);
348   case __arg_t::__u128:
349 #      ifndef _LIBCPP_HAS_NO_INT128
350     return __format::__compile_time_validate_argument<_CharT, __uint128_t>(__parse_ctx, __ctx);
351 #      else
352     __throw_format_error("Invalid argument");
353 #      endif
354     return;
355   case __arg_t::__float:
356     return __format::__compile_time_validate_argument<_CharT, float, true>(__parse_ctx, __ctx);
357   case __arg_t::__double:
358     return __format::__compile_time_validate_argument<_CharT, double, true>(__parse_ctx, __ctx);
359   case __arg_t::__long_double:
360     return __format::__compile_time_validate_argument<_CharT, long double, true>(__parse_ctx, __ctx);
361   case __arg_t::__const_char_type_ptr:
362     return __format::__compile_time_validate_argument<_CharT, const _CharT*, true>(__parse_ctx, __ctx);
363   case __arg_t::__string_view:
364     return __format::__compile_time_validate_argument<_CharT, basic_string_view<_CharT>, true>(__parse_ctx, __ctx);
365   case __arg_t::__ptr:
366     return __format::__compile_time_validate_argument<_CharT, const void*>(__parse_ctx, __ctx);
367   case __arg_t::__handle:
368     __throw_format_error("Handle should use __compile_time_validate_handle_argument");
369   }
370   __throw_format_error("Invalid argument");
371 }
372
373 template <class _CharT, class _ParseCtx, class _Ctx>
374 _LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
375 __handle_replacement_field(const _CharT* __begin, const _CharT* __end,
376                            _ParseCtx& __parse_ctx, _Ctx& __ctx) {
377   __format::__parse_number_result __r =
378       __format::__parse_arg_id(__begin, __end, __parse_ctx);
379
380   bool __parse = *__r.__ptr == _CharT(':');
381   switch (*__r.__ptr) {
382   case _CharT(':'):
383     // The arg-id has a format-specifier, advance the input to the format-spec.
384     __parse_ctx.advance_to(__r.__ptr + 1);
385     break;
386   case _CharT('}'):
387     // The arg-id has no format-specifier.
388     __parse_ctx.advance_to(__r.__ptr);
389     break;
390   default:
391     __throw_format_error(
392         "The replacement field arg-id should terminate at a ':' or '}'");
393   }
394
395   if constexpr (same_as<_Ctx, __compile_time_basic_format_context<_CharT>>) {
396     __arg_t __type = __ctx.arg(__r.__value);
397     if (__type == __arg_t::__handle)
398       __ctx.__handle(__r.__value).__parse(__parse_ctx);
399     else
400         __format::__compile_time_visit_format_arg(__parse_ctx, __ctx, __type);
401   } else
402     _VSTD::visit_format_arg(
403         [&](auto __arg) {
404           if constexpr (same_as<decltype(__arg), monostate>)
405             __throw_format_error("Argument index out of bounds");
406           else if constexpr (same_as<decltype(__arg), typename basic_format_arg<_Ctx>::handle>)
407             __arg.format(__parse_ctx, __ctx);
408           else {
409             formatter<decltype(__arg), _CharT> __formatter;
410             if (__parse)
411               __parse_ctx.advance_to(__formatter.parse(__parse_ctx));
412             __ctx.advance_to(__formatter.format(__arg, __ctx));
413           }
414         },
415         __ctx.arg(__r.__value));
416
417   __begin = __parse_ctx.begin();
418   if (__begin == __end || *__begin != _CharT('}'))
419     __throw_format_error("The replacement field misses a terminating '}'");
420
421   return ++__begin;
422 }
423
424 template <class _ParseCtx, class _Ctx>
425 _LIBCPP_HIDE_FROM_ABI constexpr typename _Ctx::iterator
426 __vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) {
427   using _CharT = typename _ParseCtx::char_type;
428   static_assert(same_as<typename _Ctx::char_type, _CharT>);
429
430   const _CharT* __begin = __parse_ctx.begin();
431   const _CharT* __end = __parse_ctx.end();
432   typename _Ctx::iterator __out_it = __ctx.out();
433   while (__begin != __end) {
434     switch (*__begin) {
435     case _CharT('{'):
436       ++__begin;
437       if (__begin == __end)
438         __throw_format_error("The format string terminates at a '{'");
439
440       if (*__begin != _CharT('{')) [[likely]] {
441         __ctx.advance_to(_VSTD::move(__out_it));
442         __begin =
443             __handle_replacement_field(__begin, __end, __parse_ctx, __ctx);
444         __out_it = __ctx.out();
445
446         // The output is written and __begin points to the next character. So
447         // start the next iteration.
448         continue;
449       }
450       // The string is an escape character.
451       break;
452
453     case _CharT('}'):
454       ++__begin;
455       if (__begin == __end || *__begin != _CharT('}'))
456         __throw_format_error(
457             "The format string contains an invalid escape sequence");
458
459       break;
460     }
461
462     // Copy the character to the output verbatim.
463     *__out_it++ = *__begin++;
464   }
465   return __out_it;
466 }
467
468 } // namespace __format
469
470 template <class _CharT, class... _Args>
471 struct _LIBCPP_TEMPLATE_VIS __basic_format_string {
472   basic_string_view<_CharT> __str_;
473
474   template <class _Tp>
475     requires convertible_to<const _Tp&, basic_string_view<_CharT>>
476   consteval __basic_format_string(const _Tp& __str) : __str_{__str} {
477     __format::__vformat_to(basic_format_parse_context<_CharT>{__str_, sizeof...(_Args)},
478                            _Context{__types_.data(), __handles_.data(), sizeof...(_Args)});
479   }
480
481 private:
482   using _Context = __format::__compile_time_basic_format_context<_CharT>;
483
484   static constexpr array<__format::__arg_t, sizeof...(_Args)> __types_{
485       __format::__determine_arg_t<_Context, remove_cvref_t<_Args>>()...};
486
487   // TODO FMT remove this work-around when the AIX ICE has been resolved.
488 #    if defined(_AIX) && defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 1400
489   template <class _Tp>
490   static constexpr __format::__compile_time_handle<_CharT> __get_handle() {
491     __format::__compile_time_handle<_CharT> __handle;
492     if (__format::__determine_arg_t<_Context, _Tp>() == __format::__arg_t::__handle)
493       __handle.template __enable<_Tp>();
494
495     return __handle;
496   }
497
498   static constexpr array<__format::__compile_time_handle<_CharT>, sizeof...(_Args)> __handles_{
499       __get_handle<_Args>()...};
500 #    else
501   static constexpr array<__format::__compile_time_handle<_CharT>, sizeof...(_Args)> __handles_{[] {
502     using _Tp = remove_cvref_t<_Args>;
503     __format::__compile_time_handle<_CharT> __handle;
504     if (__format::__determine_arg_t<_Context, _Tp>() == __format::__arg_t::__handle)
505       __handle.template __enable<_Tp>();
506
507     return __handle;
508   }()...};
509 #    endif
510 };
511
512 template <class... _Args>
513 using __format_string_t = __basic_format_string<char, type_identity_t<_Args>...>;
514
515 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
516 template <class... _Args>
517 using __wformat_string_t = __basic_format_string<wchar_t, type_identity_t<_Args>...>;
518 #endif
519
520 template <class _OutIt, class _CharT, class _FormatOutIt>
521 requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt
522     __vformat_to(
523         _OutIt __out_it, basic_string_view<_CharT> __fmt,
524         basic_format_args<basic_format_context<_FormatOutIt, _CharT>> __args) {
525   if constexpr (same_as<_OutIt, _FormatOutIt>)
526     return _VSTD::__format::__vformat_to(
527         basic_format_parse_context{__fmt, __args.__size()},
528         _VSTD::__format_context_create(_VSTD::move(__out_it), __args));
529   else {
530     __format::__format_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it)};
531     _VSTD::__format::__vformat_to(
532         basic_format_parse_context{__fmt, __args.__size()},
533         _VSTD::__format_context_create(__buffer.make_output_iterator(),
534                                        __args));
535     return _VSTD::move(__buffer).out();
536   }
537 }
538
539 // The function is _LIBCPP_ALWAYS_INLINE since the compiler is bad at inlining
540 // https://reviews.llvm.org/D110499#inline-1180704
541 // TODO FMT Evaluate whether we want to file a Clang bug report regarding this.
542 template <output_iterator<const char&> _OutIt>
543 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
544 vformat_to(_OutIt __out_it, string_view __fmt, format_args __args) {
545   return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args);
546 }
547
548 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
549 template <output_iterator<const wchar_t&> _OutIt>
550 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
551 vformat_to(_OutIt __out_it, wstring_view __fmt, wformat_args __args) {
552   return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args);
553 }
554 #endif
555
556 template <output_iterator<const char&> _OutIt, class... _Args>
557 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
558 format_to(_OutIt __out_it, __format_string_t<_Args...> __fmt, _Args&&... __args) {
559   return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt.__str_,
560                            _VSTD::make_format_args(__args...));
561 }
562
563 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
564 template <output_iterator<const wchar_t&> _OutIt, class... _Args>
565 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
566 format_to(_OutIt __out_it, __wformat_string_t<_Args...> __fmt, _Args&&... __args) {
567   return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt.__str_,
568                            _VSTD::make_wformat_args(__args...));
569 }
570 #endif
571
572 _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string
573 vformat(string_view __fmt, format_args __args) {
574   string __res;
575   _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args);
576   return __res;
577 }
578
579 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
580 _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
581 vformat(wstring_view __fmt, wformat_args __args) {
582   wstring __res;
583   _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args);
584   return __res;
585 }
586 #endif
587
588 template <class... _Args>
589 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string format(__format_string_t<_Args...> __fmt,
590                                                                                       _Args&&... __args) {
591   return _VSTD::vformat(__fmt.__str_, _VSTD::make_format_args(__args...));
592 }
593
594 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
595 template <class... _Args>
596 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
597 format(__wformat_string_t<_Args...> __fmt, _Args&&... __args) {
598   return _VSTD::vformat(__fmt.__str_, _VSTD::make_wformat_args(__args...));
599 }
600 #endif
601
602 template <class _Context, class _OutIt, class _CharT>
603 _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n,
604                                                                 basic_string_view<_CharT> __fmt,
605                                                                 basic_format_args<_Context> __args) {
606   __format::__format_to_n_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it), __n};
607   _VSTD::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()},
608                                 _VSTD::__format_context_create(__buffer.make_output_iterator(), __args));
609   return _VSTD::move(__buffer).result();
610 }
611
612 template <output_iterator<const char&> _OutIt, class... _Args>
613 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
614 format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, __format_string_t<_Args...> __fmt, _Args&&... __args) {
615   return _VSTD::__vformat_to_n<format_context>(_VSTD::move(__out_it), __n, __fmt.__str_, _VSTD::make_format_args(__args...));
616 }
617
618 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
619 template <output_iterator<const wchar_t&> _OutIt, class... _Args>
620 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
621 format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, __wformat_string_t<_Args...> __fmt,
622             _Args&&... __args) {
623   return _VSTD::__vformat_to_n<wformat_context>(_VSTD::move(__out_it), __n, __fmt.__str_, _VSTD::make_wformat_args(__args...));
624 }
625 #endif
626
627 template <class _CharT>
628 _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(basic_string_view<_CharT> __fmt, auto __args) {
629   __format::__formatted_size_buffer<_CharT> __buffer;
630   _VSTD::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()},
631                                 _VSTD::__format_context_create(__buffer.make_output_iterator(), __args));
632   return _VSTD::move(__buffer).result();
633 }
634
635 template <class... _Args>
636 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
637 formatted_size(__format_string_t<_Args...> __fmt, _Args&&... __args) {
638   return _VSTD::__vformatted_size(__fmt.__str_, basic_format_args{_VSTD::make_format_args(__args...)});
639 }
640
641 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
642 template <class... _Args>
643 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
644 formatted_size(__wformat_string_t<_Args...> __fmt, _Args&&... __args) {
645   return _VSTD::__vformatted_size(__fmt.__str_, basic_format_args{_VSTD::make_wformat_args(__args...)});
646 }
647 #endif
648
649 #ifndef _LIBCPP_HAS_NO_LOCALIZATION
650
651 template <class _OutIt, class _CharT, class _FormatOutIt>
652 requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt
653     __vformat_to(
654         _OutIt __out_it, locale __loc, basic_string_view<_CharT> __fmt,
655         basic_format_args<basic_format_context<_FormatOutIt, _CharT>> __args) {
656   if constexpr (same_as<_OutIt, _FormatOutIt>)
657     return _VSTD::__format::__vformat_to(
658         basic_format_parse_context{__fmt, __args.__size()},
659         _VSTD::__format_context_create(_VSTD::move(__out_it), __args,
660                                        _VSTD::move(__loc)));
661   else {
662     __format::__format_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it)};
663     _VSTD::__format::__vformat_to(
664         basic_format_parse_context{__fmt, __args.__size()},
665         _VSTD::__format_context_create(__buffer.make_output_iterator(),
666                                        __args, _VSTD::move(__loc)));
667     return _VSTD::move(__buffer).out();
668   }
669 }
670
671 template <output_iterator<const char&> _OutIt>
672 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt vformat_to(
673     _OutIt __out_it, locale __loc, string_view __fmt, format_args __args) {
674   return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt,
675                              __args);
676 }
677
678 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
679 template <output_iterator<const wchar_t&> _OutIt>
680 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt vformat_to(
681     _OutIt __out_it, locale __loc, wstring_view __fmt, wformat_args __args) {
682   return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt,
683                              __args);
684 }
685 #endif
686
687 template <output_iterator<const char&> _OutIt, class... _Args>
688 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
689 format_to(_OutIt __out_it, locale __loc, __format_string_t<_Args...> __fmt, _Args&&... __args) {
690   return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt.__str_,
691                            _VSTD::make_format_args(__args...));
692 }
693
694 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
695 template <output_iterator<const wchar_t&> _OutIt, class... _Args>
696 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
697 format_to(_OutIt __out_it, locale __loc, __wformat_string_t<_Args...> __fmt, _Args&&... __args) {
698   return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt.__str_,
699                            _VSTD::make_wformat_args(__args...));
700 }
701 #endif
702
703 _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string
704 vformat(locale __loc, string_view __fmt, format_args __args) {
705   string __res;
706   _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt,
707                     __args);
708   return __res;
709 }
710
711 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
712 _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
713 vformat(locale __loc, wstring_view __fmt, wformat_args __args) {
714   wstring __res;
715   _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt,
716                     __args);
717   return __res;
718 }
719 #endif
720
721 template <class... _Args>
722 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string format(locale __loc,
723                                                                                       __format_string_t<_Args...> __fmt,
724                                                                                       _Args&&... __args) {
725   return _VSTD::vformat(_VSTD::move(__loc), __fmt.__str_,
726                         _VSTD::make_format_args(__args...));
727 }
728
729 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
730 template <class... _Args>
731 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
732 format(locale __loc, __wformat_string_t<_Args...> __fmt, _Args&&... __args) {
733   return _VSTD::vformat(_VSTD::move(__loc), __fmt.__str_,
734                         _VSTD::make_wformat_args(__args...));
735 }
736 #endif
737
738 template <class _Context, class _OutIt, class _CharT>
739 _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n,
740                                                                 locale __loc, basic_string_view<_CharT> __fmt,
741                                                                 basic_format_args<_Context> __args) {
742   __format::__format_to_n_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it), __n};
743   _VSTD::__format::__vformat_to(
744       basic_format_parse_context{__fmt, __args.__size()},
745       _VSTD::__format_context_create(__buffer.make_output_iterator(), __args, _VSTD::move(__loc)));
746   return _VSTD::move(__buffer).result();
747 }
748
749 template <output_iterator<const char&> _OutIt, class... _Args>
750 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
751 format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, __format_string_t<_Args...> __fmt,
752             _Args&&... __args) {
753   return _VSTD::__vformat_to_n<format_context>(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt.__str_,
754                                                _VSTD::make_format_args(__args...));
755 }
756
757 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
758 template <output_iterator<const wchar_t&> _OutIt, class... _Args>
759 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
760 format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, __wformat_string_t<_Args...> __fmt,
761             _Args&&... __args) {
762   return _VSTD::__vformat_to_n<wformat_context>(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt.__str_,
763                                                 _VSTD::make_wformat_args(__args...));
764 }
765 #endif
766
767 template <class _CharT>
768 _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(locale __loc, basic_string_view<_CharT> __fmt, auto __args) {
769   __format::__formatted_size_buffer<_CharT> __buffer;
770   _VSTD::__format::__vformat_to(
771       basic_format_parse_context{__fmt, __args.__size()},
772       _VSTD::__format_context_create(__buffer.make_output_iterator(), __args, _VSTD::move(__loc)));
773   return _VSTD::move(__buffer).result();
774 }
775
776 template <class... _Args>
777 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
778 formatted_size(locale __loc, __format_string_t<_Args...> __fmt, _Args&&... __args) {
779   return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt.__str_, basic_format_args{_VSTD::make_format_args(__args...)});
780 }
781
782 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
783 template <class... _Args>
784 _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
785 formatted_size(locale __loc, __wformat_string_t<_Args...> __fmt, _Args&&... __args) {
786   return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt.__str_, basic_format_args{_VSTD::make_wformat_args(__args...)});
787 }
788 #endif
789
790 #endif // _LIBCPP_HAS_NO_LOCALIZATION
791
792 #endif //_LIBCPP_STD_VER > 17
793
794 _LIBCPP_END_NAMESPACE_STD
795
796 #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
797
798 #endif // _LIBCPP_FORMAT