xref: /freebsd/contrib/llvm-project/libcxx/include/format (revision 04eeddc0aa8e0a417a16eaf9d7d095207f4a8623)
1fe6060f1SDimitry Andric// -*- C++ -*-
2349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
3fe6060f1SDimitry Andric//
4fe6060f1SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5fe6060f1SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
6fe6060f1SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7fe6060f1SDimitry Andric//
8fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
9fe6060f1SDimitry Andric
10fe6060f1SDimitry Andric#ifndef _LIBCPP_FORMAT
11fe6060f1SDimitry Andric#define _LIBCPP_FORMAT
12fe6060f1SDimitry Andric
13fe6060f1SDimitry Andric/*
14fe6060f1SDimitry Andric
15fe6060f1SDimitry Andricnamespace std {
16349cc55cSDimitry Andric  // [format.context], class template basic_format_context
17*04eeddc0SDimitry Andric  template<class Out, class charT> class basic_format_context;
18349cc55cSDimitry Andric  using format_context = basic_format_context<unspecified, char>;
19349cc55cSDimitry Andric  using wformat_context = basic_format_context<unspecified, wchar_t>;
20349cc55cSDimitry Andric
21349cc55cSDimitry Andric  // [format.args], class template basic_format_args
22*04eeddc0SDimitry Andric  template<class Context> class basic_format_args;
23349cc55cSDimitry Andric  using format_args = basic_format_args<format_context>;
24349cc55cSDimitry Andric  using wformat_args = basic_format_args<wformat_context>;
25349cc55cSDimitry Andric
26349cc55cSDimitry Andric  // [format.functions], formatting functions
27349cc55cSDimitry Andric  template<class... Args>
28349cc55cSDimitry Andric    string format(string_view fmt, const Args&... args);
29349cc55cSDimitry Andric  template<class... Args>
30349cc55cSDimitry Andric    wstring format(wstring_view fmt, const Args&... args);
31349cc55cSDimitry Andric  template<class... Args>
32349cc55cSDimitry Andric    string format(const locale& loc, string_view fmt, const Args&... args);
33349cc55cSDimitry Andric  template<class... Args>
34349cc55cSDimitry Andric    wstring format(const locale& loc, wstring_view fmt, const Args&... args);
35349cc55cSDimitry Andric
36349cc55cSDimitry Andric  string vformat(string_view fmt, format_args args);
37349cc55cSDimitry Andric  wstring vformat(wstring_view fmt, wformat_args args);
38349cc55cSDimitry Andric  string vformat(const locale& loc, string_view fmt, format_args args);
39349cc55cSDimitry Andric  wstring vformat(const locale& loc, wstring_view fmt, wformat_args args);
40349cc55cSDimitry Andric
41349cc55cSDimitry Andric  template<class Out, class... Args>
42349cc55cSDimitry Andric    Out format_to(Out out, string_view fmt, const Args&... args);
43349cc55cSDimitry Andric  template<class Out, class... Args>
44349cc55cSDimitry Andric    Out format_to(Out out, wstring_view fmt, const Args&... args);
45349cc55cSDimitry Andric  template<class Out, class... Args>
46349cc55cSDimitry Andric    Out format_to(Out out, const locale& loc, string_view fmt, const Args&... args);
47349cc55cSDimitry Andric  template<class Out, class... Args>
48349cc55cSDimitry Andric    Out format_to(Out out, const locale& loc, wstring_view fmt, const Args&... args);
49349cc55cSDimitry Andric
50349cc55cSDimitry Andric  template<class Out>
514824e7fdSDimitry Andric    Out vformat_to(Out out, string_view fmt, format_args args);
52349cc55cSDimitry Andric  template<class Out>
534824e7fdSDimitry Andric    Out vformat_to(Out out, wstring_view fmt, wformat_args args);
54349cc55cSDimitry Andric  template<class Out>
55349cc55cSDimitry Andric    Out vformat_to(Out out, const locale& loc, string_view fmt,
564824e7fdSDimitry Andric                   format_args char> args);
57349cc55cSDimitry Andric  template<class Out>
58349cc55cSDimitry Andric    Out vformat_to(Out out, const locale& loc, wstring_view fmt,
594824e7fdSDimitry Andric                   wformat_args args);
60349cc55cSDimitry Andric
61349cc55cSDimitry Andric  template<class Out> struct format_to_n_result {
62349cc55cSDimitry Andric    Out out;
63349cc55cSDimitry Andric    iter_difference_t<Out> size;
64349cc55cSDimitry Andric  };
65349cc55cSDimitry Andric  template<class Out, class... Args>
66349cc55cSDimitry Andric    format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
67349cc55cSDimitry Andric                                        string_view fmt, const Args&... args);
68349cc55cSDimitry Andric  template<class Out, class... Args>
69349cc55cSDimitry Andric    format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
70349cc55cSDimitry Andric                                        wstring_view fmt, const Args&... args);
71349cc55cSDimitry Andric  template<class Out, class... Args>
72349cc55cSDimitry Andric    format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
73349cc55cSDimitry Andric                                        const locale& loc, string_view fmt,
74349cc55cSDimitry Andric                                        const Args&... args);
75349cc55cSDimitry Andric  template<class Out, class... Args>
76349cc55cSDimitry Andric    format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
77349cc55cSDimitry Andric                                        const locale& loc, wstring_view fmt,
78349cc55cSDimitry Andric                                        const Args&... args);
79349cc55cSDimitry Andric
80349cc55cSDimitry Andric  template<class... Args>
81349cc55cSDimitry Andric    size_t formatted_size(string_view fmt, const Args&... args);
82349cc55cSDimitry Andric  template<class... Args>
83349cc55cSDimitry Andric    size_t formatted_size(wstring_view fmt, const Args&... args);
84349cc55cSDimitry Andric  template<class... Args>
85349cc55cSDimitry Andric    size_t formatted_size(const locale& loc, string_view fmt, const Args&... args);
86349cc55cSDimitry Andric  template<class... Args>
87349cc55cSDimitry Andric    size_t formatted_size(const locale& loc, wstring_view fmt, const Args&... args);
88349cc55cSDimitry Andric
89349cc55cSDimitry Andric  // [format.formatter], formatter
90*04eeddc0SDimitry Andric  template<class T, class charT = char> struct formatter;
91349cc55cSDimitry Andric
92349cc55cSDimitry Andric  // [format.parse.ctx], class template basic_format_parse_context
93*04eeddc0SDimitry Andric  template<class charT> class basic_format_parse_context;
94349cc55cSDimitry Andric  using format_parse_context = basic_format_parse_context<char>;
95349cc55cSDimitry Andric  using wformat_parse_context = basic_format_parse_context<wchar_t>;
96349cc55cSDimitry Andric
97349cc55cSDimitry Andric  // [format.arguments], arguments
98349cc55cSDimitry Andric  // [format.arg], class template basic_format_arg
99*04eeddc0SDimitry Andric  template<class Context> class basic_format_arg;
100349cc55cSDimitry Andric
101349cc55cSDimitry Andric  template<class Visitor, class Context>
102349cc55cSDimitry Andric    see below visit_format_arg(Visitor&& vis, basic_format_arg<Context> arg);
103349cc55cSDimitry Andric
104349cc55cSDimitry Andric  // [format.arg.store], class template format-arg-store
105*04eeddc0SDimitry Andric  template<class Context, class... Args> struct format-arg-store;      // exposition only
106349cc55cSDimitry Andric
107349cc55cSDimitry Andric  template<class Context = format_context, class... Args>
108349cc55cSDimitry Andric    format-arg-store<Context, Args...>
109349cc55cSDimitry Andric      make_format_args(const Args&... args);
110349cc55cSDimitry Andric  template<class... Args>
111349cc55cSDimitry Andric    format-arg-store<wformat_context, Args...>
112349cc55cSDimitry Andric      make_wformat_args(const Args&... args);
113349cc55cSDimitry Andric
114fe6060f1SDimitry Andric  // [format.error], class format_error
115*04eeddc0SDimitry Andric  class format_error;
116fe6060f1SDimitry Andric}
117fe6060f1SDimitry Andric
118fe6060f1SDimitry Andric*/
119fe6060f1SDimitry Andric
120349cc55cSDimitry Andric// Make sure all feature-test macros are available.
1216e75b2fbSDimitry Andric#include <version>
122349cc55cSDimitry Andric// Enable the contents of the header only when libc++ was built with LIBCXX_ENABLE_INCOMPLETE_FEATURES.
1236e75b2fbSDimitry Andric#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
1246e75b2fbSDimitry Andric
125fe6060f1SDimitry Andric#include <__config>
126349cc55cSDimitry Andric#include <__debug>
127349cc55cSDimitry Andric#include <__format/format_arg.h>
128349cc55cSDimitry Andric#include <__format/format_args.h>
129349cc55cSDimitry Andric#include <__format/format_context.h>
130fe6060f1SDimitry Andric#include <__format/format_error.h>
131349cc55cSDimitry Andric#include <__format/format_fwd.h>
132fe6060f1SDimitry Andric#include <__format/format_parse_context.h>
133349cc55cSDimitry Andric#include <__format/format_string.h>
134349cc55cSDimitry Andric#include <__format/format_to_n_result.h>
135349cc55cSDimitry Andric#include <__format/formatter.h>
136349cc55cSDimitry Andric#include <__format/formatter_bool.h>
137349cc55cSDimitry Andric#include <__format/formatter_char.h>
138*04eeddc0SDimitry Andric#include <__format/formatter_floating_point.h>
139349cc55cSDimitry Andric#include <__format/formatter_integer.h>
140*04eeddc0SDimitry Andric#include <__format/formatter_pointer.h>
141349cc55cSDimitry Andric#include <__format/formatter_string.h>
142349cc55cSDimitry Andric#include <__format/parser_std_format_spec.h>
143349cc55cSDimitry Andric#include <__variant/monostate.h>
144349cc55cSDimitry Andric#include <array>
145349cc55cSDimitry Andric#include <concepts>
146349cc55cSDimitry Andric#include <string>
147349cc55cSDimitry Andric#include <string_view>
148349cc55cSDimitry Andric#include <type_traits>
149349cc55cSDimitry Andric
150349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_LOCALIZATION
151349cc55cSDimitry Andric#include <locale>
152349cc55cSDimitry Andric#endif
153fe6060f1SDimitry Andric
154fe6060f1SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
155fe6060f1SDimitry Andric#pragma GCC system_header
156fe6060f1SDimitry Andric#endif
157fe6060f1SDimitry Andric
158fe6060f1SDimitry Andric_LIBCPP_PUSH_MACROS
159fe6060f1SDimitry Andric#include <__undef_macros>
160fe6060f1SDimitry Andric
161fe6060f1SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
162fe6060f1SDimitry Andric
163fe6060f1SDimitry Andric#if _LIBCPP_STD_VER > 17
164fe6060f1SDimitry Andric
165349cc55cSDimitry Andric// TODO FMT Remove this once we require compilers with proper C++20 support.
166349cc55cSDimitry Andric// If the compiler has no concepts support, the format header will be disabled.
167349cc55cSDimitry Andric// Without concepts support enable_if needs to be used and that too much effort
168349cc55cSDimitry Andric// to support compilers with partial C++20 support.
169349cc55cSDimitry Andric#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
170349cc55cSDimitry Andric
171349cc55cSDimitry Andric// TODO FMT Move the implementation in this file to its own granular headers.
172349cc55cSDimitry Andric
173349cc55cSDimitry Andric// TODO FMT Evaluate which templates should be external templates. This
174349cc55cSDimitry Andric// improves the efficiency of the header. However since the header is still
175349cc55cSDimitry Andric// under heavy development and not all classes are stable it makes no sense
176349cc55cSDimitry Andric// to do this optimization now.
177349cc55cSDimitry Andric
178349cc55cSDimitry Andricusing format_args = basic_format_args<format_context>;
179349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
180349cc55cSDimitry Andricusing wformat_args = basic_format_args<wformat_context>;
181349cc55cSDimitry Andric#endif
182349cc55cSDimitry Andric
183349cc55cSDimitry Andrictemplate <class _Context, class... _Args>
184349cc55cSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS __format_arg_store {
185349cc55cSDimitry Andric  // TODO FMT Use a built-in array.
186349cc55cSDimitry Andric  array<basic_format_arg<_Context>, sizeof...(_Args)> __args;
187349cc55cSDimitry Andric};
188349cc55cSDimitry Andric
189349cc55cSDimitry Andrictemplate <class _Context = format_context, class... _Args>
190349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...>
191349cc55cSDimitry Andricmake_format_args(const _Args&... __args) {
192349cc55cSDimitry Andric  return {basic_format_arg<_Context>(__args)...};
193349cc55cSDimitry Andric}
194349cc55cSDimitry Andric
195349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
196349cc55cSDimitry Andrictemplate <class... _Args>
197349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI __format_arg_store<wformat_context, _Args...>
198349cc55cSDimitry Andricmake_wformat_args(const _Args&... __args) {
199349cc55cSDimitry Andric  return _VSTD::make_format_args<wformat_context>(__args...);
200349cc55cSDimitry Andric}
201349cc55cSDimitry Andric#endif
202349cc55cSDimitry Andric
203349cc55cSDimitry Andricnamespace __format {
204349cc55cSDimitry Andric
205349cc55cSDimitry Andrictemplate <class _CharT, class _ParseCtx, class _Ctx>
206349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI const _CharT*
207349cc55cSDimitry Andric__handle_replacement_field(const _CharT* __begin, const _CharT* __end,
208349cc55cSDimitry Andric                           _ParseCtx& __parse_ctx, _Ctx& __ctx) {
209349cc55cSDimitry Andric  __format::__parse_number_result __r =
210349cc55cSDimitry Andric      __format::__parse_arg_id(__begin, __end, __parse_ctx);
211349cc55cSDimitry Andric
212349cc55cSDimitry Andric  switch (*__r.__ptr) {
213349cc55cSDimitry Andric  case _CharT(':'):
214349cc55cSDimitry Andric    // The arg-id has a format-specifier, advance the input to the format-spec.
215349cc55cSDimitry Andric    __parse_ctx.advance_to(__r.__ptr + 1);
216349cc55cSDimitry Andric    break;
217349cc55cSDimitry Andric  case _CharT('}'):
218349cc55cSDimitry Andric    // The arg-id has no format-specifier.
219349cc55cSDimitry Andric    __parse_ctx.advance_to(__r.__ptr);
220349cc55cSDimitry Andric    break;
221349cc55cSDimitry Andric  default:
222349cc55cSDimitry Andric    __throw_format_error(
223349cc55cSDimitry Andric        "The replacement field arg-id should terminate at a ':' or '}'");
224349cc55cSDimitry Andric  }
225349cc55cSDimitry Andric
226349cc55cSDimitry Andric  _VSTD::visit_format_arg(
227349cc55cSDimitry Andric      [&](auto __arg) {
228349cc55cSDimitry Andric        if constexpr (same_as<decltype(__arg), monostate>)
229349cc55cSDimitry Andric          __throw_format_error("Argument index out of bounds");
230*04eeddc0SDimitry Andric        else if constexpr (same_as<decltype(__arg), typename basic_format_arg<_Ctx>::handle>)
231*04eeddc0SDimitry Andric          __arg.format(__parse_ctx, __ctx);
232349cc55cSDimitry Andric        else {
233349cc55cSDimitry Andric          formatter<decltype(__arg), _CharT> __formatter;
234349cc55cSDimitry Andric          __parse_ctx.advance_to(__formatter.parse(__parse_ctx));
235349cc55cSDimitry Andric          __ctx.advance_to(__formatter.format(__arg, __ctx));
236349cc55cSDimitry Andric        }
237349cc55cSDimitry Andric      },
238349cc55cSDimitry Andric      __ctx.arg(__r.__value));
239349cc55cSDimitry Andric
240349cc55cSDimitry Andric  __begin = __parse_ctx.begin();
241349cc55cSDimitry Andric  if (__begin == __end || *__begin != _CharT('}'))
242349cc55cSDimitry Andric    __throw_format_error("The replacement field misses a terminating '}'");
243349cc55cSDimitry Andric
244349cc55cSDimitry Andric  return ++__begin;
245349cc55cSDimitry Andric}
246349cc55cSDimitry Andric
247349cc55cSDimitry Andrictemplate <class _ParseCtx, class _Ctx>
248349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI typename _Ctx::iterator
249349cc55cSDimitry Andric__vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) {
250349cc55cSDimitry Andric  using _CharT = typename _ParseCtx::char_type;
251349cc55cSDimitry Andric  static_assert(same_as<typename _Ctx::char_type, _CharT>);
252349cc55cSDimitry Andric
253349cc55cSDimitry Andric  const _CharT* __begin = __parse_ctx.begin();
254349cc55cSDimitry Andric  const _CharT* __end = __parse_ctx.end();
255349cc55cSDimitry Andric  typename _Ctx::iterator __out_it = __ctx.out();
256349cc55cSDimitry Andric  while (__begin != __end) {
257349cc55cSDimitry Andric    switch (*__begin) {
258349cc55cSDimitry Andric    case _CharT('{'):
259349cc55cSDimitry Andric      ++__begin;
260349cc55cSDimitry Andric      if (__begin == __end)
261349cc55cSDimitry Andric        __throw_format_error("The format string terminates at a '{'");
262349cc55cSDimitry Andric
263349cc55cSDimitry Andric      if (*__begin != _CharT('{')) [[likely]] {
264349cc55cSDimitry Andric        __ctx.advance_to(_VSTD::move(__out_it));
265349cc55cSDimitry Andric        __begin =
266349cc55cSDimitry Andric            __handle_replacement_field(__begin, __end, __parse_ctx, __ctx);
267349cc55cSDimitry Andric        __out_it = __ctx.out();
268349cc55cSDimitry Andric
269349cc55cSDimitry Andric        // The output is written and __begin points to the next character. So
270349cc55cSDimitry Andric        // start the next iteration.
271349cc55cSDimitry Andric        continue;
272349cc55cSDimitry Andric      }
273349cc55cSDimitry Andric      // The string is an escape character.
274349cc55cSDimitry Andric      break;
275349cc55cSDimitry Andric
276349cc55cSDimitry Andric    case _CharT('}'):
277349cc55cSDimitry Andric      ++__begin;
278349cc55cSDimitry Andric      if (__begin == __end || *__begin != _CharT('}'))
279349cc55cSDimitry Andric        __throw_format_error(
280349cc55cSDimitry Andric            "The format string contains an invalid escape sequence");
281349cc55cSDimitry Andric
282349cc55cSDimitry Andric      break;
283349cc55cSDimitry Andric    }
284349cc55cSDimitry Andric
285349cc55cSDimitry Andric    // Copy the character to the output verbatim.
286349cc55cSDimitry Andric    *__out_it++ = *__begin++;
287349cc55cSDimitry Andric  }
288349cc55cSDimitry Andric  return __out_it;
289349cc55cSDimitry Andric}
290349cc55cSDimitry Andric
291349cc55cSDimitry Andric} // namespace __format
292349cc55cSDimitry Andric
2934824e7fdSDimitry Andrictemplate <class _OutIt, class _CharT, class _FormatOutIt>
294349cc55cSDimitry Andricrequires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt
2954824e7fdSDimitry Andric    __vformat_to(
2964824e7fdSDimitry Andric        _OutIt __out_it, basic_string_view<_CharT> __fmt,
2974824e7fdSDimitry Andric        basic_format_args<basic_format_context<_FormatOutIt, _CharT>> __args) {
2984824e7fdSDimitry Andric  if constexpr (same_as<_OutIt, _FormatOutIt>)
2994824e7fdSDimitry Andric    return _VSTD::__format::__vformat_to(
300349cc55cSDimitry Andric        basic_format_parse_context{__fmt, __args.__size()},
301349cc55cSDimitry Andric        _VSTD::__format_context_create(_VSTD::move(__out_it), __args));
3024824e7fdSDimitry Andric  else {
3034824e7fdSDimitry Andric    basic_string<_CharT> __str;
3044824e7fdSDimitry Andric    _VSTD::__format::__vformat_to(
3054824e7fdSDimitry Andric        basic_format_parse_context{__fmt, __args.__size()},
3064824e7fdSDimitry Andric        _VSTD::__format_context_create(_VSTD::back_inserter(__str), __args));
3074824e7fdSDimitry Andric    return _VSTD::copy_n(__str.begin(), __str.size(), _VSTD::move(__out_it));
3084824e7fdSDimitry Andric  }
309349cc55cSDimitry Andric}
310349cc55cSDimitry Andric
311349cc55cSDimitry Andrictemplate <output_iterator<const char&> _OutIt>
3124824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
3134824e7fdSDimitry Andricvformat_to(_OutIt __out_it, string_view __fmt, format_args __args) {
314349cc55cSDimitry Andric  return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args);
315349cc55cSDimitry Andric}
316349cc55cSDimitry Andric
317349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
318349cc55cSDimitry Andrictemplate <output_iterator<const wchar_t&> _OutIt>
3194824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
3204824e7fdSDimitry Andricvformat_to(_OutIt __out_it, wstring_view __fmt, wformat_args __args) {
321349cc55cSDimitry Andric  return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args);
322349cc55cSDimitry Andric}
323349cc55cSDimitry Andric#endif
324349cc55cSDimitry Andric
325349cc55cSDimitry Andrictemplate <output_iterator<const char&> _OutIt, class... _Args>
3264824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
327349cc55cSDimitry Andricformat_to(_OutIt __out_it, string_view __fmt, const _Args&... __args) {
3284824e7fdSDimitry Andric  return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt,
3294824e7fdSDimitry Andric                           _VSTD::make_format_args(__args...));
330349cc55cSDimitry Andric}
331349cc55cSDimitry Andric
332349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
333349cc55cSDimitry Andrictemplate <output_iterator<const wchar_t&> _OutIt, class... _Args>
3344824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
335349cc55cSDimitry Andricformat_to(_OutIt __out_it, wstring_view __fmt, const _Args&... __args) {
3364824e7fdSDimitry Andric  return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt,
3374824e7fdSDimitry Andric                           _VSTD::make_wformat_args(__args...));
338349cc55cSDimitry Andric}
339349cc55cSDimitry Andric#endif
340349cc55cSDimitry Andric
3414824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string
342349cc55cSDimitry Andricvformat(string_view __fmt, format_args __args) {
343349cc55cSDimitry Andric  string __res;
344349cc55cSDimitry Andric  _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args);
345349cc55cSDimitry Andric  return __res;
346349cc55cSDimitry Andric}
347349cc55cSDimitry Andric
348349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
3494824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
350349cc55cSDimitry Andricvformat(wstring_view __fmt, wformat_args __args) {
351349cc55cSDimitry Andric  wstring __res;
352349cc55cSDimitry Andric  _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args);
353349cc55cSDimitry Andric  return __res;
354349cc55cSDimitry Andric}
355349cc55cSDimitry Andric#endif
356349cc55cSDimitry Andric
357349cc55cSDimitry Andrictemplate <class... _Args>
3584824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string
359349cc55cSDimitry Andricformat(string_view __fmt, const _Args&... __args) {
360349cc55cSDimitry Andric  return _VSTD::vformat(__fmt, _VSTD::make_format_args(__args...));
361349cc55cSDimitry Andric}
362349cc55cSDimitry Andric
363349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
364349cc55cSDimitry Andrictemplate <class... _Args>
3654824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
366349cc55cSDimitry Andricformat(wstring_view __fmt, const _Args&... __args) {
367349cc55cSDimitry Andric  return _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...));
368349cc55cSDimitry Andric}
369349cc55cSDimitry Andric#endif
370349cc55cSDimitry Andric
371349cc55cSDimitry Andrictemplate <output_iterator<const char&> _OutIt, class... _Args>
372349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
373349cc55cSDimitry Andricformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, string_view __fmt,
374349cc55cSDimitry Andric            const _Args&... __args) {
375349cc55cSDimitry Andric  // TODO FMT Improve PoC: using std::string is inefficient.
376349cc55cSDimitry Andric  string __str = _VSTD::vformat(__fmt, _VSTD::make_format_args(__args...));
377349cc55cSDimitry Andric  iter_difference_t<_OutIt> __s = __str.size();
378349cc55cSDimitry Andric  iter_difference_t<_OutIt> __m =
379349cc55cSDimitry Andric      _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s);
380349cc55cSDimitry Andric  __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it));
381349cc55cSDimitry Andric  return {_VSTD::move(__out_it), __s};
382349cc55cSDimitry Andric}
383349cc55cSDimitry Andric
384349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
385349cc55cSDimitry Andrictemplate <output_iterator<const wchar_t&> _OutIt, class... _Args>
386349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
387349cc55cSDimitry Andricformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, wstring_view __fmt,
388349cc55cSDimitry Andric            const _Args&... __args) {
389349cc55cSDimitry Andric  // TODO FMT Improve PoC: using std::string is inefficient.
390349cc55cSDimitry Andric  wstring __str = _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...));
391349cc55cSDimitry Andric  iter_difference_t<_OutIt> __s = __str.size();
392349cc55cSDimitry Andric  iter_difference_t<_OutIt> __m =
393349cc55cSDimitry Andric      _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s);
394349cc55cSDimitry Andric  __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it));
395349cc55cSDimitry Andric  return {_VSTD::move(__out_it), __s};
396349cc55cSDimitry Andric}
397349cc55cSDimitry Andric#endif
398349cc55cSDimitry Andric
399349cc55cSDimitry Andrictemplate <class... _Args>
400349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
401349cc55cSDimitry Andricformatted_size(string_view __fmt, const _Args&... __args) {
402349cc55cSDimitry Andric  // TODO FMT Improve PoC: using std::string is inefficient.
403349cc55cSDimitry Andric  return _VSTD::vformat(__fmt, _VSTD::make_format_args(__args...)).size();
404349cc55cSDimitry Andric}
405349cc55cSDimitry Andric
406349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
407349cc55cSDimitry Andrictemplate <class... _Args>
408349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
409349cc55cSDimitry Andricformatted_size(wstring_view __fmt, const _Args&... __args) {
410349cc55cSDimitry Andric  // TODO FMT Improve PoC: using std::string is inefficient.
411349cc55cSDimitry Andric  return _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...)).size();
412349cc55cSDimitry Andric}
413349cc55cSDimitry Andric#endif
414349cc55cSDimitry Andric
415349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_LOCALIZATION
416349cc55cSDimitry Andric
4174824e7fdSDimitry Andrictemplate <class _OutIt, class _CharT, class _FormatOutIt>
418349cc55cSDimitry Andricrequires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt
4194824e7fdSDimitry Andric    __vformat_to(
4204824e7fdSDimitry Andric        _OutIt __out_it, locale __loc, basic_string_view<_CharT> __fmt,
4214824e7fdSDimitry Andric        basic_format_args<basic_format_context<_FormatOutIt, _CharT>> __args) {
4224824e7fdSDimitry Andric  if constexpr (same_as<_OutIt, _FormatOutIt>)
4234824e7fdSDimitry Andric    return _VSTD::__format::__vformat_to(
424349cc55cSDimitry Andric        basic_format_parse_context{__fmt, __args.__size()},
425349cc55cSDimitry Andric        _VSTD::__format_context_create(_VSTD::move(__out_it), __args,
426349cc55cSDimitry Andric                                       _VSTD::move(__loc)));
4274824e7fdSDimitry Andric  else {
4284824e7fdSDimitry Andric    basic_string<_CharT> __str;
4294824e7fdSDimitry Andric    _VSTD::__format::__vformat_to(
4304824e7fdSDimitry Andric        basic_format_parse_context{__fmt, __args.__size()},
4314824e7fdSDimitry Andric        _VSTD::__format_context_create(_VSTD::back_inserter(__str), __args,
4324824e7fdSDimitry Andric                                       _VSTD::move(__loc)));
4334824e7fdSDimitry Andric    return _VSTD::copy_n(__str.begin(), __str.size(), _VSTD::move(__out_it));
4344824e7fdSDimitry Andric  }
435349cc55cSDimitry Andric}
436349cc55cSDimitry Andric
437349cc55cSDimitry Andrictemplate <output_iterator<const char&> _OutIt>
4384824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt vformat_to(
4394824e7fdSDimitry Andric    _OutIt __out_it, locale __loc, string_view __fmt, format_args __args) {
440349cc55cSDimitry Andric  return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt,
441349cc55cSDimitry Andric                             __args);
442349cc55cSDimitry Andric}
443349cc55cSDimitry Andric
444349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
445349cc55cSDimitry Andrictemplate <output_iterator<const wchar_t&> _OutIt>
4464824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt vformat_to(
4474824e7fdSDimitry Andric    _OutIt __out_it, locale __loc, wstring_view __fmt, wformat_args __args) {
448349cc55cSDimitry Andric  return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt,
449349cc55cSDimitry Andric                             __args);
450349cc55cSDimitry Andric}
451349cc55cSDimitry Andric#endif
452349cc55cSDimitry Andric
453349cc55cSDimitry Andrictemplate <output_iterator<const char&> _OutIt, class... _Args>
4544824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to(
455349cc55cSDimitry Andric    _OutIt __out_it, locale __loc, string_view __fmt, const _Args&... __args) {
4564824e7fdSDimitry Andric  return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt,
4574824e7fdSDimitry Andric                           _VSTD::make_format_args(__args...));
458349cc55cSDimitry Andric}
459349cc55cSDimitry Andric
460349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
461349cc55cSDimitry Andrictemplate <output_iterator<const wchar_t&> _OutIt, class... _Args>
4624824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to(
463349cc55cSDimitry Andric    _OutIt __out_it, locale __loc, wstring_view __fmt, const _Args&... __args) {
4644824e7fdSDimitry Andric  return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt,
4654824e7fdSDimitry Andric                           _VSTD::make_wformat_args(__args...));
466349cc55cSDimitry Andric}
467349cc55cSDimitry Andric#endif
468349cc55cSDimitry Andric
4694824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string
470349cc55cSDimitry Andricvformat(locale __loc, string_view __fmt, format_args __args) {
471349cc55cSDimitry Andric  string __res;
472349cc55cSDimitry Andric  _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt,
473349cc55cSDimitry Andric                    __args);
474349cc55cSDimitry Andric  return __res;
475349cc55cSDimitry Andric}
476349cc55cSDimitry Andric
477349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4784824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
479349cc55cSDimitry Andricvformat(locale __loc, wstring_view __fmt, wformat_args __args) {
480349cc55cSDimitry Andric  wstring __res;
481349cc55cSDimitry Andric  _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt,
482349cc55cSDimitry Andric                    __args);
483349cc55cSDimitry Andric  return __res;
484349cc55cSDimitry Andric}
485349cc55cSDimitry Andric#endif
486349cc55cSDimitry Andric
487349cc55cSDimitry Andrictemplate <class... _Args>
4884824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string
489349cc55cSDimitry Andricformat(locale __loc, string_view __fmt, const _Args&... __args) {
490349cc55cSDimitry Andric  return _VSTD::vformat(_VSTD::move(__loc), __fmt,
491349cc55cSDimitry Andric                        _VSTD::make_format_args(__args...));
492349cc55cSDimitry Andric}
493349cc55cSDimitry Andric
494349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
495349cc55cSDimitry Andrictemplate <class... _Args>
4964824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
497349cc55cSDimitry Andricformat(locale __loc, wstring_view __fmt, const _Args&... __args) {
498349cc55cSDimitry Andric  return _VSTD::vformat(_VSTD::move(__loc), __fmt,
499349cc55cSDimitry Andric                        _VSTD::make_wformat_args(__args...));
500349cc55cSDimitry Andric}
501349cc55cSDimitry Andric#endif
502349cc55cSDimitry Andric
503349cc55cSDimitry Andrictemplate <output_iterator<const char&> _OutIt, class... _Args>
504349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
505349cc55cSDimitry Andricformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc,
506349cc55cSDimitry Andric            string_view __fmt, const _Args&... __args) {
507349cc55cSDimitry Andric  // TODO FMT Improve PoC: using std::string is inefficient.
508349cc55cSDimitry Andric  string __str = _VSTD::vformat(_VSTD::move(__loc), __fmt,
509349cc55cSDimitry Andric                                _VSTD::make_format_args(__args...));
510349cc55cSDimitry Andric  iter_difference_t<_OutIt> __s = __str.size();
511349cc55cSDimitry Andric  iter_difference_t<_OutIt> __m =
512349cc55cSDimitry Andric      _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s);
513349cc55cSDimitry Andric  __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it));
514349cc55cSDimitry Andric  return {_VSTD::move(__out_it), __s};
515349cc55cSDimitry Andric}
516349cc55cSDimitry Andric
517349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
518349cc55cSDimitry Andrictemplate <output_iterator<const wchar_t&> _OutIt, class... _Args>
519349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
520349cc55cSDimitry Andricformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc,
521349cc55cSDimitry Andric            wstring_view __fmt, const _Args&... __args) {
522349cc55cSDimitry Andric  // TODO FMT Improve PoC: using std::string is inefficient.
523349cc55cSDimitry Andric  wstring __str = _VSTD::vformat(_VSTD::move(__loc), __fmt,
524349cc55cSDimitry Andric                                 _VSTD::make_wformat_args(__args...));
525349cc55cSDimitry Andric  iter_difference_t<_OutIt> __s = __str.size();
526349cc55cSDimitry Andric  iter_difference_t<_OutIt> __m =
527349cc55cSDimitry Andric      _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s);
528349cc55cSDimitry Andric  __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it));
529349cc55cSDimitry Andric  return {_VSTD::move(__out_it), __s};
530349cc55cSDimitry Andric}
531349cc55cSDimitry Andric#endif
532349cc55cSDimitry Andric
533349cc55cSDimitry Andrictemplate <class... _Args>
534349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
535349cc55cSDimitry Andricformatted_size(locale __loc, string_view __fmt, const _Args&... __args) {
536349cc55cSDimitry Andric  // TODO FMT Improve PoC: using std::string is inefficient.
537349cc55cSDimitry Andric  return _VSTD::vformat(_VSTD::move(__loc), __fmt,
538349cc55cSDimitry Andric                        _VSTD::make_format_args(__args...))
539349cc55cSDimitry Andric      .size();
540349cc55cSDimitry Andric}
541349cc55cSDimitry Andric
542349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
543349cc55cSDimitry Andrictemplate <class... _Args>
544349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
545349cc55cSDimitry Andricformatted_size(locale __loc, wstring_view __fmt, const _Args&... __args) {
546349cc55cSDimitry Andric  // TODO FMT Improve PoC: using std::string is inefficient.
547349cc55cSDimitry Andric  return _VSTD::vformat(_VSTD::move(__loc), __fmt,
548349cc55cSDimitry Andric                        _VSTD::make_wformat_args(__args...))
549349cc55cSDimitry Andric      .size();
550349cc55cSDimitry Andric}
551349cc55cSDimitry Andric#endif
552349cc55cSDimitry Andric
553349cc55cSDimitry Andric#endif // _LIBCPP_HAS_NO_LOCALIZATION
554349cc55cSDimitry Andric
555349cc55cSDimitry Andric#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
556fe6060f1SDimitry Andric#endif //_LIBCPP_STD_VER > 17
557fe6060f1SDimitry Andric
558fe6060f1SDimitry Andric_LIBCPP_END_NAMESPACE_STD
559fe6060f1SDimitry Andric
560fe6060f1SDimitry Andric_LIBCPP_POP_MACROS
561fe6060f1SDimitry Andric
5626e75b2fbSDimitry Andric#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
5636e75b2fbSDimitry Andric
564fe6060f1SDimitry Andric#endif // _LIBCPP_FORMAT
565