xref: /freebsd/contrib/llvm-project/libcxx/include/format (revision 349cc55c9796c4596a5b9904cd3281af295f878f)
1fe6060f1SDimitry Andric// -*- C++ -*-
2*349cc55cSDimitry 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 {
16*349cc55cSDimitry Andric  // [format.context], class template basic_format_context
17*349cc55cSDimitry Andric  template<class Out, class charT>
18*349cc55cSDimitry Andric  class basic_format_context {
19*349cc55cSDimitry Andric    basic_format_args<basic_format_context> args_;      // exposition only
20*349cc55cSDimitry Andric    Out out_;                                           // exposition only
21*349cc55cSDimitry Andric
22*349cc55cSDimitry Andric  public:
23*349cc55cSDimitry Andric    using iterator = Out;
24*349cc55cSDimitry Andric    using char_type = charT;
25*349cc55cSDimitry Andric    template<class T> using formatter_type = formatter<T, charT>;
26*349cc55cSDimitry Andric
27*349cc55cSDimitry Andric    basic_format_arg<basic_format_context> arg(size_t id) const;
28*349cc55cSDimitry Andric    std::locale locale();
29*349cc55cSDimitry Andric
30*349cc55cSDimitry Andric    iterator out();
31*349cc55cSDimitry Andric    void advance_to(iterator it);
32*349cc55cSDimitry Andric  };
33*349cc55cSDimitry Andric  using format_context = basic_format_context<unspecified, char>;
34*349cc55cSDimitry Andric  using wformat_context = basic_format_context<unspecified, wchar_t>;
35*349cc55cSDimitry Andric
36*349cc55cSDimitry Andric  // [format.args], class template basic_format_args
37*349cc55cSDimitry Andric  template<class Context>
38*349cc55cSDimitry Andric  class basic_format_args {
39*349cc55cSDimitry Andric    size_t size_;                               // exposition only
40*349cc55cSDimitry Andric    const basic_format_arg<Context>* data_;     // exposition only
41*349cc55cSDimitry Andric
42*349cc55cSDimitry Andric  public:
43*349cc55cSDimitry Andric    basic_format_args() noexcept;
44*349cc55cSDimitry Andric
45*349cc55cSDimitry Andric    template<class... Args>
46*349cc55cSDimitry Andric      basic_format_args(const format-arg-store<Context, Args...>& store) noexcept;
47*349cc55cSDimitry Andric
48*349cc55cSDimitry Andric    basic_format_arg<Context> get(size_t i) const noexcept;
49*349cc55cSDimitry Andric  };
50*349cc55cSDimitry Andric  using format_args = basic_format_args<format_context>;
51*349cc55cSDimitry Andric  using wformat_args = basic_format_args<wformat_context>;
52*349cc55cSDimitry Andric
53*349cc55cSDimitry Andric
54*349cc55cSDimitry Andric  template<class Out, class charT>
55*349cc55cSDimitry Andric    using format_args_t = basic_format_args<basic_format_context<Out, charT>>;
56*349cc55cSDimitry Andric
57*349cc55cSDimitry Andric  // [format.functions], formatting functions
58*349cc55cSDimitry Andric  template<class... Args>
59*349cc55cSDimitry Andric    string format(string_view fmt, const Args&... args);
60*349cc55cSDimitry Andric  template<class... Args>
61*349cc55cSDimitry Andric    wstring format(wstring_view fmt, const Args&... args);
62*349cc55cSDimitry Andric  template<class... Args>
63*349cc55cSDimitry Andric    string format(const locale& loc, string_view fmt, const Args&... args);
64*349cc55cSDimitry Andric  template<class... Args>
65*349cc55cSDimitry Andric    wstring format(const locale& loc, wstring_view fmt, const Args&... args);
66*349cc55cSDimitry Andric
67*349cc55cSDimitry Andric  string vformat(string_view fmt, format_args args);
68*349cc55cSDimitry Andric  wstring vformat(wstring_view fmt, wformat_args args);
69*349cc55cSDimitry Andric  string vformat(const locale& loc, string_view fmt, format_args args);
70*349cc55cSDimitry Andric  wstring vformat(const locale& loc, wstring_view fmt, wformat_args args);
71*349cc55cSDimitry Andric
72*349cc55cSDimitry Andric  template<class Out, class... Args>
73*349cc55cSDimitry Andric    Out format_to(Out out, string_view fmt, const Args&... args);
74*349cc55cSDimitry Andric  template<class Out, class... Args>
75*349cc55cSDimitry Andric    Out format_to(Out out, wstring_view fmt, const Args&... args);
76*349cc55cSDimitry Andric  template<class Out, class... Args>
77*349cc55cSDimitry Andric    Out format_to(Out out, const locale& loc, string_view fmt, const Args&... args);
78*349cc55cSDimitry Andric  template<class Out, class... Args>
79*349cc55cSDimitry Andric    Out format_to(Out out, const locale& loc, wstring_view fmt, const Args&... args);
80*349cc55cSDimitry Andric
81*349cc55cSDimitry Andric  template<class Out>
82*349cc55cSDimitry Andric    Out vformat_to(Out out, string_view fmt,
83*349cc55cSDimitry Andric                   format_args_t<type_identity_t<Out>, char> args);
84*349cc55cSDimitry Andric  template<class Out>
85*349cc55cSDimitry Andric    Out vformat_to(Out out, wstring_view fmt,
86*349cc55cSDimitry Andric                   format_args_t<type_identity_t<Out>, wchar_t> args);
87*349cc55cSDimitry Andric  template<class Out>
88*349cc55cSDimitry Andric    Out vformat_to(Out out, const locale& loc, string_view fmt,
89*349cc55cSDimitry Andric                   format_args_t<type_identity_t<Out>, char> args);
90*349cc55cSDimitry Andric  template<class Out>
91*349cc55cSDimitry Andric    Out vformat_to(Out out, const locale& loc, wstring_view fmt,
92*349cc55cSDimitry Andric                   format_args_t<type_identity_t<Out>, wchar_t> args);
93*349cc55cSDimitry Andric
94*349cc55cSDimitry Andric  template<class Out> struct format_to_n_result {
95*349cc55cSDimitry Andric    Out out;
96*349cc55cSDimitry Andric    iter_difference_t<Out> size;
97*349cc55cSDimitry Andric  };
98*349cc55cSDimitry Andric
99*349cc55cSDimitry Andric template<class Out, class... Args>
100*349cc55cSDimitry Andric    format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
101*349cc55cSDimitry Andric                                        string_view fmt, const Args&... args);
102*349cc55cSDimitry Andric  template<class Out, class... Args>
103*349cc55cSDimitry Andric    format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
104*349cc55cSDimitry Andric                                        wstring_view fmt, const Args&... args);
105*349cc55cSDimitry Andric  template<class Out, class... Args>
106*349cc55cSDimitry Andric    format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
107*349cc55cSDimitry Andric                                        const locale& loc, string_view fmt,
108*349cc55cSDimitry Andric                                        const Args&... args);
109*349cc55cSDimitry Andric  template<class Out, class... Args>
110*349cc55cSDimitry Andric    format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
111*349cc55cSDimitry Andric                                        const locale& loc, wstring_view fmt,
112*349cc55cSDimitry Andric                                        const Args&... args);
113*349cc55cSDimitry Andric
114*349cc55cSDimitry Andric  template<class... Args>
115*349cc55cSDimitry Andric    size_t formatted_size(string_view fmt, const Args&... args);
116*349cc55cSDimitry Andric  template<class... Args>
117*349cc55cSDimitry Andric    size_t formatted_size(wstring_view fmt, const Args&... args);
118*349cc55cSDimitry Andric  template<class... Args>
119*349cc55cSDimitry Andric    size_t formatted_size(const locale& loc, string_view fmt, const Args&... args);
120*349cc55cSDimitry Andric  template<class... Args>
121*349cc55cSDimitry Andric    size_t formatted_size(const locale& loc, wstring_view fmt, const Args&... args);
122*349cc55cSDimitry Andric
123*349cc55cSDimitry Andric  // [format.formatter], formatter
124*349cc55cSDimitry Andric  template<> struct formatter<char, char>;
125*349cc55cSDimitry Andric  template<> struct formatter<char, wchar_t>;
126*349cc55cSDimitry Andric  template<> struct formatter<wchar_t, wchar_t>;
127*349cc55cSDimitry Andric
128*349cc55cSDimitry Andric  template<> struct formatter<charT*, charT>;
129*349cc55cSDimitry Andric  template<> struct formatter<const charT*, charT>;
130*349cc55cSDimitry Andric  template<size_t N> struct formatter<const charT[N], charT>;
131*349cc55cSDimitry Andric  template<class traits, class Allocator>
132*349cc55cSDimitry Andric    struct formatter<basic_string<charT, traits, Allocator>, charT>;
133*349cc55cSDimitry Andric  template<class traits>
134*349cc55cSDimitry Andric    struct formatter<basic_string_view<charT, traits>, charT>;
135*349cc55cSDimitry Andric
136*349cc55cSDimitry Andric  // [format.parse.ctx], class template basic_format_parse_context
137*349cc55cSDimitry Andric  template<class charT>
138*349cc55cSDimitry Andric  class basic_format_parse_context {
139*349cc55cSDimitry Andric  public:
140*349cc55cSDimitry Andric    using char_type = charT;
141*349cc55cSDimitry Andric    using const_iterator = typename basic_string_view<charT>::const_iterator;
142*349cc55cSDimitry Andric    using iterator = const_iterator;
143*349cc55cSDimitry Andric
144*349cc55cSDimitry Andric  private:
145*349cc55cSDimitry Andric    iterator begin_;                                    // exposition only
146*349cc55cSDimitry Andric    iterator end_;                                      // exposition only
147*349cc55cSDimitry Andric    enum indexing { unknown, manual, automatic };       // exposition only
148*349cc55cSDimitry Andric    indexing indexing_;                                 // exposition only
149*349cc55cSDimitry Andric    size_t next_arg_id_;                                // exposition only
150*349cc55cSDimitry Andric    size_t num_args_;                                   // exposition only
151*349cc55cSDimitry Andric
152*349cc55cSDimitry Andric  public:
153*349cc55cSDimitry Andric    constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt,
154*349cc55cSDimitry Andric                                                  size_t num_args = 0) noexcept;
155*349cc55cSDimitry Andric    basic_format_parse_context(const basic_format_parse_context&) = delete;
156*349cc55cSDimitry Andric    basic_format_parse_context& operator=(const basic_format_parse_context&) = delete;
157*349cc55cSDimitry Andric
158*349cc55cSDimitry Andric    constexpr const_iterator begin() const noexcept;
159*349cc55cSDimitry Andric    constexpr const_iterator end() const noexcept;
160*349cc55cSDimitry Andric    constexpr void advance_to(const_iterator it);
161*349cc55cSDimitry Andric
162*349cc55cSDimitry Andric    constexpr size_t next_arg_id();
163*349cc55cSDimitry Andric    constexpr void check_arg_id(size_t id);
164*349cc55cSDimitry Andric  };
165*349cc55cSDimitry Andric  using format_parse_context = basic_format_parse_context<char>;
166*349cc55cSDimitry Andric  using wformat_parse_context = basic_format_parse_context<wchar_t>;
167*349cc55cSDimitry Andric
168*349cc55cSDimitry Andric  // [format.arguments], arguments
169*349cc55cSDimitry Andric  // [format.arg], class template basic_format_arg
170*349cc55cSDimitry Andric  template<class Context>
171*349cc55cSDimitry Andric  class basic_format_arg {
172*349cc55cSDimitry Andric  public:
173*349cc55cSDimitry Andric    class handle;
174*349cc55cSDimitry Andric
175*349cc55cSDimitry Andric  private:
176*349cc55cSDimitry Andric    using char_type = typename Context::char_type;                              // exposition only
177*349cc55cSDimitry Andric
178*349cc55cSDimitry Andric    variant<monostate, bool, char_type,
179*349cc55cSDimitry Andric            int, unsigned int, long long int, unsigned long long int,
180*349cc55cSDimitry Andric            float, double, long double,
181*349cc55cSDimitry Andric            const char_type*, basic_string_view<char_type>,
182*349cc55cSDimitry Andric            const void*, handle> value;                                         // exposition only
183*349cc55cSDimitry Andric
184*349cc55cSDimitry Andric    template<class T> explicit basic_format_arg(const T& v) noexcept;           // exposition only
185*349cc55cSDimitry Andric    explicit basic_format_arg(float n) noexcept;                                // exposition only
186*349cc55cSDimitry Andric    explicit basic_format_arg(double n) noexcept;                               // exposition only
187*349cc55cSDimitry Andric    explicit basic_format_arg(long double n) noexcept;                          // exposition only
188*349cc55cSDimitry Andric    explicit basic_format_arg(const char_type* s);                              // exposition only
189*349cc55cSDimitry Andric
190*349cc55cSDimitry Andric    template<class traits>
191*349cc55cSDimitry Andric      explicit basic_format_arg(
192*349cc55cSDimitry Andric        basic_string_view<char_type, traits> s) noexcept;                       // exposition only
193*349cc55cSDimitry Andric
194*349cc55cSDimitry Andric    template<class traits, class Allocator>
195*349cc55cSDimitry Andric      explicit basic_format_arg(
196*349cc55cSDimitry Andric        const basic_string<char_type, traits, Allocator>& s) noexcept;          // exposition only
197*349cc55cSDimitry Andric
198*349cc55cSDimitry Andric    explicit basic_format_arg(nullptr_t) noexcept;                              // exposition only
199*349cc55cSDimitry Andric
200*349cc55cSDimitry Andric    template<class T>
201*349cc55cSDimitry Andric      explicit basic_format_arg(const T* p) noexcept;                           // exposition only
202*349cc55cSDimitry Andric
203*349cc55cSDimitry Andric  public:
204*349cc55cSDimitry Andric    basic_format_arg() noexcept;
205*349cc55cSDimitry Andric
206*349cc55cSDimitry Andric    explicit operator bool() const noexcept;
207*349cc55cSDimitry Andric  };
208*349cc55cSDimitry Andric
209*349cc55cSDimitry Andric  template<class Visitor, class Context>
210*349cc55cSDimitry Andric    see below visit_format_arg(Visitor&& vis, basic_format_arg<Context> arg);
211*349cc55cSDimitry Andric
212*349cc55cSDimitry Andric  // [format.arg.store], class template format-arg-store
213*349cc55cSDimitry Andric  template<class Context, class... Args>
214*349cc55cSDimitry Andric  struct format-arg-store {      // exposition only
215*349cc55cSDimitry Andric    array<basic_format_arg<Context>, sizeof...(Args)> args;
216*349cc55cSDimitry Andric  };
217*349cc55cSDimitry Andric
218*349cc55cSDimitry Andric  template<class Context = format_context, class... Args>
219*349cc55cSDimitry Andric    format-arg-store<Context, Args...>
220*349cc55cSDimitry Andric      make_format_args(const Args&... args);
221*349cc55cSDimitry Andric  template<class... Args>
222*349cc55cSDimitry Andric    format-arg-store<wformat_context, Args...>
223*349cc55cSDimitry Andric      make_wformat_args(const Args&... args);
224*349cc55cSDimitry Andric
225fe6060f1SDimitry Andric  // [format.error], class format_error
226fe6060f1SDimitry Andric  class format_error : public runtime_error {
227fe6060f1SDimitry Andric  public:
228fe6060f1SDimitry Andric    explicit format_error(const string& what_arg);
229fe6060f1SDimitry Andric    explicit format_error(const char* what_arg);
230fe6060f1SDimitry Andric  };
231fe6060f1SDimitry Andric
232fe6060f1SDimitry Andric  // [format.parse.ctx], class template basic_format_parse_context
233fe6060f1SDimitry Andric  template<class charT>
234fe6060f1SDimitry Andric  class basic_format_parse_context {
235fe6060f1SDimitry Andric  public:
236fe6060f1SDimitry Andric    using char_type = charT;
237fe6060f1SDimitry Andric    using const_iterator = typename basic_string_view<charT>::const_iterator;
238fe6060f1SDimitry Andric    using iterator = const_iterator;
239fe6060f1SDimitry Andric
240fe6060f1SDimitry Andric  private:
241fe6060f1SDimitry Andric    iterator begin_;                                    // exposition only
242fe6060f1SDimitry Andric    iterator end_;                                      // exposition only
243fe6060f1SDimitry Andric    enum indexing { unknown, manual, automatic };       // exposition only
244fe6060f1SDimitry Andric    indexing indexing_;                                 // exposition only
245fe6060f1SDimitry Andric    size_t next_arg_id_;                                // exposition only
246fe6060f1SDimitry Andric    size_t num_args_;                                   // exposition only
247fe6060f1SDimitry Andric
248fe6060f1SDimitry Andric  public:
249fe6060f1SDimitry Andric    constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt,
250fe6060f1SDimitry Andric                                                  size_t num_args = 0) noexcept;
251fe6060f1SDimitry Andric    basic_format_parse_context(const basic_format_parse_context&) = delete;
252fe6060f1SDimitry Andric    basic_format_parse_context& operator=(const basic_format_parse_context&) = delete;
253fe6060f1SDimitry Andric
254fe6060f1SDimitry Andric    constexpr const_iterator begin() const noexcept;
255fe6060f1SDimitry Andric    constexpr const_iterator end() const noexcept;
256fe6060f1SDimitry Andric    constexpr void advance_to(const_iterator it);
257fe6060f1SDimitry Andric
258fe6060f1SDimitry Andric    constexpr size_t next_arg_id();
259fe6060f1SDimitry Andric    constexpr void check_arg_id(size_t id);
260fe6060f1SDimitry Andric  };
261fe6060f1SDimitry Andric  using format_parse_context = basic_format_parse_context<char>;
262fe6060f1SDimitry Andric  using wformat_parse_context = basic_format_parse_context<wchar_t>;
263fe6060f1SDimitry Andric}
264fe6060f1SDimitry Andric
265fe6060f1SDimitry Andric*/
266fe6060f1SDimitry Andric
267*349cc55cSDimitry Andric// Make sure all feature-test macros are available.
2686e75b2fbSDimitry Andric#include <version>
269*349cc55cSDimitry Andric// Enable the contents of the header only when libc++ was built with LIBCXX_ENABLE_INCOMPLETE_FEATURES.
2706e75b2fbSDimitry Andric#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
2716e75b2fbSDimitry Andric
272fe6060f1SDimitry Andric#include <__config>
273*349cc55cSDimitry Andric#include <__debug>
274*349cc55cSDimitry Andric#include <__format/format_arg.h>
275*349cc55cSDimitry Andric#include <__format/format_args.h>
276*349cc55cSDimitry Andric#include <__format/format_context.h>
277fe6060f1SDimitry Andric#include <__format/format_error.h>
278*349cc55cSDimitry Andric#include <__format/format_fwd.h>
279fe6060f1SDimitry Andric#include <__format/format_parse_context.h>
280*349cc55cSDimitry Andric#include <__format/format_string.h>
281*349cc55cSDimitry Andric#include <__format/format_to_n_result.h>
282*349cc55cSDimitry Andric#include <__format/formatter.h>
283*349cc55cSDimitry Andric#include <__format/formatter_bool.h>
284*349cc55cSDimitry Andric#include <__format/formatter_char.h>
285*349cc55cSDimitry Andric#include <__format/formatter_integer.h>
286*349cc55cSDimitry Andric#include <__format/formatter_string.h>
287*349cc55cSDimitry Andric#include <__format/parser_std_format_spec.h>
288*349cc55cSDimitry Andric#include <__variant/monostate.h>
289*349cc55cSDimitry Andric#include <array>
290*349cc55cSDimitry Andric#include <concepts>
291*349cc55cSDimitry Andric#include <string>
292*349cc55cSDimitry Andric#include <string_view>
293*349cc55cSDimitry Andric#include <type_traits>
294*349cc55cSDimitry Andric
295*349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_LOCALIZATION
296*349cc55cSDimitry Andric#include <locale>
297*349cc55cSDimitry Andric#endif
298fe6060f1SDimitry Andric
299fe6060f1SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
300fe6060f1SDimitry Andric#pragma GCC system_header
301fe6060f1SDimitry Andric#endif
302fe6060f1SDimitry Andric
303fe6060f1SDimitry Andric_LIBCPP_PUSH_MACROS
304fe6060f1SDimitry Andric#include <__undef_macros>
305fe6060f1SDimitry Andric
306fe6060f1SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
307fe6060f1SDimitry Andric
308fe6060f1SDimitry Andric#if _LIBCPP_STD_VER > 17
309fe6060f1SDimitry Andric
310*349cc55cSDimitry Andric// TODO FMT Remove this once we require compilers with proper C++20 support.
311*349cc55cSDimitry Andric// If the compiler has no concepts support, the format header will be disabled.
312*349cc55cSDimitry Andric// Without concepts support enable_if needs to be used and that too much effort
313*349cc55cSDimitry Andric// to support compilers with partial C++20 support.
314*349cc55cSDimitry Andric#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
315*349cc55cSDimitry Andric
316*349cc55cSDimitry Andric// TODO FMT Move the implementation in this file to its own granular headers.
317*349cc55cSDimitry Andric
318*349cc55cSDimitry Andric// TODO FMT Evaluate which templates should be external templates. This
319*349cc55cSDimitry Andric// improves the efficiency of the header. However since the header is still
320*349cc55cSDimitry Andric// under heavy development and not all classes are stable it makes no sense
321*349cc55cSDimitry Andric// to do this optimization now.
322*349cc55cSDimitry Andric
323*349cc55cSDimitry Andricusing format_args = basic_format_args<format_context>;
324*349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
325*349cc55cSDimitry Andricusing wformat_args = basic_format_args<wformat_context>;
326*349cc55cSDimitry Andric#endif
327*349cc55cSDimitry Andric
328*349cc55cSDimitry Andrictemplate <class _OutIt, class _CharT>
329*349cc55cSDimitry Andricusing format_args_t = basic_format_args<basic_format_context<_OutIt, _CharT>>;
330*349cc55cSDimitry Andric
331*349cc55cSDimitry Andrictemplate <class _Context, class... _Args>
332*349cc55cSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS __format_arg_store {
333*349cc55cSDimitry Andric  // TODO FMT Use a built-in array.
334*349cc55cSDimitry Andric  array<basic_format_arg<_Context>, sizeof...(_Args)> __args;
335*349cc55cSDimitry Andric};
336*349cc55cSDimitry Andric
337*349cc55cSDimitry Andrictemplate <class _Context = format_context, class... _Args>
338*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...>
339*349cc55cSDimitry Andricmake_format_args(const _Args&... __args) {
340*349cc55cSDimitry Andric  return {basic_format_arg<_Context>(__args)...};
341*349cc55cSDimitry Andric}
342*349cc55cSDimitry Andric
343*349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
344*349cc55cSDimitry Andrictemplate <class... _Args>
345*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI __format_arg_store<wformat_context, _Args...>
346*349cc55cSDimitry Andricmake_wformat_args(const _Args&... __args) {
347*349cc55cSDimitry Andric  return _VSTD::make_format_args<wformat_context>(__args...);
348*349cc55cSDimitry Andric}
349*349cc55cSDimitry Andric#endif
350*349cc55cSDimitry Andric
351*349cc55cSDimitry Andricnamespace __format {
352*349cc55cSDimitry Andric
353*349cc55cSDimitry Andrictemplate <class _CharT, class _ParseCtx, class _Ctx>
354*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI const _CharT*
355*349cc55cSDimitry Andric__handle_replacement_field(const _CharT* __begin, const _CharT* __end,
356*349cc55cSDimitry Andric                           _ParseCtx& __parse_ctx, _Ctx& __ctx) {
357*349cc55cSDimitry Andric  __format::__parse_number_result __r =
358*349cc55cSDimitry Andric      __format::__parse_arg_id(__begin, __end, __parse_ctx);
359*349cc55cSDimitry Andric
360*349cc55cSDimitry Andric  switch (*__r.__ptr) {
361*349cc55cSDimitry Andric  case _CharT(':'):
362*349cc55cSDimitry Andric    // The arg-id has a format-specifier, advance the input to the format-spec.
363*349cc55cSDimitry Andric    __parse_ctx.advance_to(__r.__ptr + 1);
364*349cc55cSDimitry Andric    break;
365*349cc55cSDimitry Andric  case _CharT('}'):
366*349cc55cSDimitry Andric    // The arg-id has no format-specifier.
367*349cc55cSDimitry Andric    __parse_ctx.advance_to(__r.__ptr);
368*349cc55cSDimitry Andric    break;
369*349cc55cSDimitry Andric  default:
370*349cc55cSDimitry Andric    __throw_format_error(
371*349cc55cSDimitry Andric        "The replacement field arg-id should terminate at a ':' or '}'");
372*349cc55cSDimitry Andric  }
373*349cc55cSDimitry Andric
374*349cc55cSDimitry Andric  _VSTD::visit_format_arg(
375*349cc55cSDimitry Andric      [&](auto __arg) {
376*349cc55cSDimitry Andric        if constexpr (same_as<decltype(__arg), monostate>)
377*349cc55cSDimitry Andric          __throw_format_error("Argument index out of bounds");
378*349cc55cSDimitry Andric        else {
379*349cc55cSDimitry Andric          formatter<decltype(__arg), _CharT> __formatter;
380*349cc55cSDimitry Andric          __parse_ctx.advance_to(__formatter.parse(__parse_ctx));
381*349cc55cSDimitry Andric          __ctx.advance_to(__formatter.format(__arg, __ctx));
382*349cc55cSDimitry Andric        }
383*349cc55cSDimitry Andric      },
384*349cc55cSDimitry Andric      __ctx.arg(__r.__value));
385*349cc55cSDimitry Andric
386*349cc55cSDimitry Andric  __begin = __parse_ctx.begin();
387*349cc55cSDimitry Andric  if (__begin == __end || *__begin != _CharT('}'))
388*349cc55cSDimitry Andric    __throw_format_error("The replacement field misses a terminating '}'");
389*349cc55cSDimitry Andric
390*349cc55cSDimitry Andric  return ++__begin;
391*349cc55cSDimitry Andric}
392*349cc55cSDimitry Andric
393*349cc55cSDimitry Andrictemplate <class _ParseCtx, class _Ctx>
394*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI typename _Ctx::iterator
395*349cc55cSDimitry Andric__vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) {
396*349cc55cSDimitry Andric  using _CharT = typename _ParseCtx::char_type;
397*349cc55cSDimitry Andric  static_assert(same_as<typename _Ctx::char_type, _CharT>);
398*349cc55cSDimitry Andric
399*349cc55cSDimitry Andric  const _CharT* __begin = __parse_ctx.begin();
400*349cc55cSDimitry Andric  const _CharT* __end = __parse_ctx.end();
401*349cc55cSDimitry Andric  typename _Ctx::iterator __out_it = __ctx.out();
402*349cc55cSDimitry Andric  while (__begin != __end) {
403*349cc55cSDimitry Andric    switch (*__begin) {
404*349cc55cSDimitry Andric    case _CharT('{'):
405*349cc55cSDimitry Andric      ++__begin;
406*349cc55cSDimitry Andric      if (__begin == __end)
407*349cc55cSDimitry Andric        __throw_format_error("The format string terminates at a '{'");
408*349cc55cSDimitry Andric
409*349cc55cSDimitry Andric      if (*__begin != _CharT('{')) [[likely]] {
410*349cc55cSDimitry Andric        __ctx.advance_to(_VSTD::move(__out_it));
411*349cc55cSDimitry Andric        __begin =
412*349cc55cSDimitry Andric            __handle_replacement_field(__begin, __end, __parse_ctx, __ctx);
413*349cc55cSDimitry Andric        __out_it = __ctx.out();
414*349cc55cSDimitry Andric
415*349cc55cSDimitry Andric        // The output is written and __begin points to the next character. So
416*349cc55cSDimitry Andric        // start the next iteration.
417*349cc55cSDimitry Andric        continue;
418*349cc55cSDimitry Andric      }
419*349cc55cSDimitry Andric      // The string is an escape character.
420*349cc55cSDimitry Andric      break;
421*349cc55cSDimitry Andric
422*349cc55cSDimitry Andric    case _CharT('}'):
423*349cc55cSDimitry Andric      ++__begin;
424*349cc55cSDimitry Andric      if (__begin == __end || *__begin != _CharT('}'))
425*349cc55cSDimitry Andric        __throw_format_error(
426*349cc55cSDimitry Andric            "The format string contains an invalid escape sequence");
427*349cc55cSDimitry Andric
428*349cc55cSDimitry Andric      break;
429*349cc55cSDimitry Andric    }
430*349cc55cSDimitry Andric
431*349cc55cSDimitry Andric    // Copy the character to the output verbatim.
432*349cc55cSDimitry Andric    *__out_it++ = *__begin++;
433*349cc55cSDimitry Andric  }
434*349cc55cSDimitry Andric  return __out_it;
435*349cc55cSDimitry Andric}
436*349cc55cSDimitry Andric
437*349cc55cSDimitry Andric} // namespace __format
438*349cc55cSDimitry Andric
439*349cc55cSDimitry Andrictemplate <class _OutIt, class _CharT>
440*349cc55cSDimitry Andricrequires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt
441*349cc55cSDimitry Andric    __vformat_to(_OutIt __out_it, basic_string_view<_CharT> __fmt,
442*349cc55cSDimitry Andric                 format_args_t<type_identity_t<_OutIt>, _CharT> __args) {
443*349cc55cSDimitry Andric  return __format::__vformat_to(
444*349cc55cSDimitry Andric      basic_format_parse_context{__fmt, __args.__size()},
445*349cc55cSDimitry Andric      _VSTD::__format_context_create(_VSTD::move(__out_it), __args));
446*349cc55cSDimitry Andric}
447*349cc55cSDimitry Andric
448*349cc55cSDimitry Andrictemplate <output_iterator<const char&> _OutIt>
449*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
450*349cc55cSDimitry Andricvformat_to(_OutIt __out_it, string_view __fmt,
451*349cc55cSDimitry Andric           format_args_t<type_identity_t<_OutIt>, char> __args) {
452*349cc55cSDimitry Andric  return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args);
453*349cc55cSDimitry Andric}
454*349cc55cSDimitry Andric
455*349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
456*349cc55cSDimitry Andrictemplate <output_iterator<const wchar_t&> _OutIt>
457*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
458*349cc55cSDimitry Andricvformat_to(_OutIt __out_it, wstring_view __fmt,
459*349cc55cSDimitry Andric           format_args_t<type_identity_t<_OutIt>, wchar_t> __args) {
460*349cc55cSDimitry Andric  return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args);
461*349cc55cSDimitry Andric}
462*349cc55cSDimitry Andric#endif
463*349cc55cSDimitry Andric
464*349cc55cSDimitry Andrictemplate <output_iterator<const char&> _OutIt, class... _Args>
465*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
466*349cc55cSDimitry Andricformat_to(_OutIt __out_it, string_view __fmt, const _Args&... __args) {
467*349cc55cSDimitry Andric  return _VSTD::vformat_to(
468*349cc55cSDimitry Andric      _VSTD::move(__out_it), __fmt,
469*349cc55cSDimitry Andric      _VSTD::make_format_args<basic_format_context<_OutIt, char>>(__args...));
470*349cc55cSDimitry Andric}
471*349cc55cSDimitry Andric
472*349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
473*349cc55cSDimitry Andrictemplate <output_iterator<const wchar_t&> _OutIt, class... _Args>
474*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
475*349cc55cSDimitry Andricformat_to(_OutIt __out_it, wstring_view __fmt, const _Args&... __args) {
476*349cc55cSDimitry Andric  return _VSTD::vformat_to(
477*349cc55cSDimitry Andric      _VSTD::move(__out_it), __fmt,
478*349cc55cSDimitry Andric      _VSTD::make_format_args<basic_format_context<_OutIt, wchar_t>>(
479*349cc55cSDimitry Andric          __args...));
480*349cc55cSDimitry Andric}
481*349cc55cSDimitry Andric#endif
482*349cc55cSDimitry Andric
483*349cc55cSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string
484*349cc55cSDimitry Andricvformat(string_view __fmt, format_args __args) {
485*349cc55cSDimitry Andric  string __res;
486*349cc55cSDimitry Andric  _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args);
487*349cc55cSDimitry Andric  return __res;
488*349cc55cSDimitry Andric}
489*349cc55cSDimitry Andric
490*349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
491*349cc55cSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
492*349cc55cSDimitry Andricvformat(wstring_view __fmt, wformat_args __args) {
493*349cc55cSDimitry Andric  wstring __res;
494*349cc55cSDimitry Andric  _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args);
495*349cc55cSDimitry Andric  return __res;
496*349cc55cSDimitry Andric}
497*349cc55cSDimitry Andric#endif
498*349cc55cSDimitry Andric
499*349cc55cSDimitry Andrictemplate <class... _Args>
500*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string
501*349cc55cSDimitry Andricformat(string_view __fmt, const _Args&... __args) {
502*349cc55cSDimitry Andric  return _VSTD::vformat(__fmt, _VSTD::make_format_args(__args...));
503*349cc55cSDimitry Andric}
504*349cc55cSDimitry Andric
505*349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
506*349cc55cSDimitry Andrictemplate <class... _Args>
507*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
508*349cc55cSDimitry Andricformat(wstring_view __fmt, const _Args&... __args) {
509*349cc55cSDimitry Andric  return _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...));
510*349cc55cSDimitry Andric}
511*349cc55cSDimitry Andric#endif
512*349cc55cSDimitry Andric
513*349cc55cSDimitry Andrictemplate <output_iterator<const char&> _OutIt, class... _Args>
514*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
515*349cc55cSDimitry Andricformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, string_view __fmt,
516*349cc55cSDimitry Andric            const _Args&... __args) {
517*349cc55cSDimitry Andric  // TODO FMT Improve PoC: using std::string is inefficient.
518*349cc55cSDimitry Andric  string __str = _VSTD::vformat(__fmt, _VSTD::make_format_args(__args...));
519*349cc55cSDimitry Andric  iter_difference_t<_OutIt> __s = __str.size();
520*349cc55cSDimitry Andric  iter_difference_t<_OutIt> __m =
521*349cc55cSDimitry Andric      _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s);
522*349cc55cSDimitry Andric  __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it));
523*349cc55cSDimitry Andric  return {_VSTD::move(__out_it), __s};
524*349cc55cSDimitry Andric}
525*349cc55cSDimitry Andric
526*349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
527*349cc55cSDimitry Andrictemplate <output_iterator<const wchar_t&> _OutIt, class... _Args>
528*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
529*349cc55cSDimitry Andricformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, wstring_view __fmt,
530*349cc55cSDimitry Andric            const _Args&... __args) {
531*349cc55cSDimitry Andric  // TODO FMT Improve PoC: using std::string is inefficient.
532*349cc55cSDimitry Andric  wstring __str = _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...));
533*349cc55cSDimitry Andric  iter_difference_t<_OutIt> __s = __str.size();
534*349cc55cSDimitry Andric  iter_difference_t<_OutIt> __m =
535*349cc55cSDimitry Andric      _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s);
536*349cc55cSDimitry Andric  __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it));
537*349cc55cSDimitry Andric  return {_VSTD::move(__out_it), __s};
538*349cc55cSDimitry Andric}
539*349cc55cSDimitry Andric#endif
540*349cc55cSDimitry Andric
541*349cc55cSDimitry Andrictemplate <class... _Args>
542*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
543*349cc55cSDimitry Andricformatted_size(string_view __fmt, const _Args&... __args) {
544*349cc55cSDimitry Andric  // TODO FMT Improve PoC: using std::string is inefficient.
545*349cc55cSDimitry Andric  return _VSTD::vformat(__fmt, _VSTD::make_format_args(__args...)).size();
546*349cc55cSDimitry Andric}
547*349cc55cSDimitry Andric
548*349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
549*349cc55cSDimitry Andrictemplate <class... _Args>
550*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
551*349cc55cSDimitry Andricformatted_size(wstring_view __fmt, const _Args&... __args) {
552*349cc55cSDimitry Andric  // TODO FMT Improve PoC: using std::string is inefficient.
553*349cc55cSDimitry Andric  return _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...)).size();
554*349cc55cSDimitry Andric}
555*349cc55cSDimitry Andric#endif
556*349cc55cSDimitry Andric
557*349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_LOCALIZATION
558*349cc55cSDimitry Andric
559*349cc55cSDimitry Andrictemplate <class _OutIt, class _CharT>
560*349cc55cSDimitry Andricrequires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt
561*349cc55cSDimitry Andric    __vformat_to(_OutIt __out_it, locale __loc, basic_string_view<_CharT> __fmt,
562*349cc55cSDimitry Andric                 format_args_t<type_identity_t<_OutIt>, _CharT> __args) {
563*349cc55cSDimitry Andric  return __format::__vformat_to(
564*349cc55cSDimitry Andric      basic_format_parse_context{__fmt, __args.__size()},
565*349cc55cSDimitry Andric      _VSTD::__format_context_create(_VSTD::move(__out_it), __args,
566*349cc55cSDimitry Andric                                     _VSTD::move(__loc)));
567*349cc55cSDimitry Andric}
568*349cc55cSDimitry Andric
569*349cc55cSDimitry Andrictemplate <output_iterator<const char&> _OutIt>
570*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
571*349cc55cSDimitry Andricvformat_to(_OutIt __out_it, locale __loc, string_view __fmt,
572*349cc55cSDimitry Andric           format_args_t<type_identity_t<_OutIt>, char> __args) {
573*349cc55cSDimitry Andric  return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt,
574*349cc55cSDimitry Andric                             __args);
575*349cc55cSDimitry Andric}
576*349cc55cSDimitry Andric
577*349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
578*349cc55cSDimitry Andrictemplate <output_iterator<const wchar_t&> _OutIt>
579*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
580*349cc55cSDimitry Andricvformat_to(_OutIt __out_it, locale __loc, wstring_view __fmt,
581*349cc55cSDimitry Andric           format_args_t<type_identity_t<_OutIt>, wchar_t> __args) {
582*349cc55cSDimitry Andric  return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt,
583*349cc55cSDimitry Andric                             __args);
584*349cc55cSDimitry Andric}
585*349cc55cSDimitry Andric#endif
586*349cc55cSDimitry Andric
587*349cc55cSDimitry Andrictemplate <output_iterator<const char&> _OutIt, class... _Args>
588*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to(
589*349cc55cSDimitry Andric    _OutIt __out_it, locale __loc, string_view __fmt, const _Args&... __args) {
590*349cc55cSDimitry Andric  return _VSTD::vformat_to(
591*349cc55cSDimitry Andric      _VSTD::move(__out_it), _VSTD::move(__loc), __fmt,
592*349cc55cSDimitry Andric      _VSTD::make_format_args<basic_format_context<_OutIt, char>>(__args...));
593*349cc55cSDimitry Andric}
594*349cc55cSDimitry Andric
595*349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
596*349cc55cSDimitry Andrictemplate <output_iterator<const wchar_t&> _OutIt, class... _Args>
597*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to(
598*349cc55cSDimitry Andric    _OutIt __out_it, locale __loc, wstring_view __fmt, const _Args&... __args) {
599*349cc55cSDimitry Andric  return _VSTD::vformat_to(
600*349cc55cSDimitry Andric      _VSTD::move(__out_it), _VSTD::move(__loc), __fmt,
601*349cc55cSDimitry Andric      _VSTD::make_format_args<basic_format_context<_OutIt, wchar_t>>(
602*349cc55cSDimitry Andric          __args...));
603*349cc55cSDimitry Andric}
604*349cc55cSDimitry Andric#endif
605*349cc55cSDimitry Andric
606*349cc55cSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string
607*349cc55cSDimitry Andricvformat(locale __loc, string_view __fmt, format_args __args) {
608*349cc55cSDimitry Andric  string __res;
609*349cc55cSDimitry Andric  _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt,
610*349cc55cSDimitry Andric                    __args);
611*349cc55cSDimitry Andric  return __res;
612*349cc55cSDimitry Andric}
613*349cc55cSDimitry Andric
614*349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
615*349cc55cSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
616*349cc55cSDimitry Andricvformat(locale __loc, wstring_view __fmt, wformat_args __args) {
617*349cc55cSDimitry Andric  wstring __res;
618*349cc55cSDimitry Andric  _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt,
619*349cc55cSDimitry Andric                    __args);
620*349cc55cSDimitry Andric  return __res;
621*349cc55cSDimitry Andric}
622*349cc55cSDimitry Andric#endif
623*349cc55cSDimitry Andric
624*349cc55cSDimitry Andrictemplate <class... _Args>
625*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string
626*349cc55cSDimitry Andricformat(locale __loc, string_view __fmt, const _Args&... __args) {
627*349cc55cSDimitry Andric  return _VSTD::vformat(_VSTD::move(__loc), __fmt,
628*349cc55cSDimitry Andric                        _VSTD::make_format_args(__args...));
629*349cc55cSDimitry Andric}
630*349cc55cSDimitry Andric
631*349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
632*349cc55cSDimitry Andrictemplate <class... _Args>
633*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
634*349cc55cSDimitry Andricformat(locale __loc, wstring_view __fmt, const _Args&... __args) {
635*349cc55cSDimitry Andric  return _VSTD::vformat(_VSTD::move(__loc), __fmt,
636*349cc55cSDimitry Andric                        _VSTD::make_wformat_args(__args...));
637*349cc55cSDimitry Andric}
638*349cc55cSDimitry Andric#endif
639*349cc55cSDimitry Andric
640*349cc55cSDimitry Andrictemplate <output_iterator<const char&> _OutIt, class... _Args>
641*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
642*349cc55cSDimitry Andricformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc,
643*349cc55cSDimitry Andric            string_view __fmt, const _Args&... __args) {
644*349cc55cSDimitry Andric  // TODO FMT Improve PoC: using std::string is inefficient.
645*349cc55cSDimitry Andric  string __str = _VSTD::vformat(_VSTD::move(__loc), __fmt,
646*349cc55cSDimitry Andric                                _VSTD::make_format_args(__args...));
647*349cc55cSDimitry Andric  iter_difference_t<_OutIt> __s = __str.size();
648*349cc55cSDimitry Andric  iter_difference_t<_OutIt> __m =
649*349cc55cSDimitry Andric      _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s);
650*349cc55cSDimitry Andric  __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it));
651*349cc55cSDimitry Andric  return {_VSTD::move(__out_it), __s};
652*349cc55cSDimitry Andric}
653*349cc55cSDimitry Andric
654*349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
655*349cc55cSDimitry Andrictemplate <output_iterator<const wchar_t&> _OutIt, class... _Args>
656*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
657*349cc55cSDimitry Andricformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc,
658*349cc55cSDimitry Andric            wstring_view __fmt, const _Args&... __args) {
659*349cc55cSDimitry Andric  // TODO FMT Improve PoC: using std::string is inefficient.
660*349cc55cSDimitry Andric  wstring __str = _VSTD::vformat(_VSTD::move(__loc), __fmt,
661*349cc55cSDimitry Andric                                 _VSTD::make_wformat_args(__args...));
662*349cc55cSDimitry Andric  iter_difference_t<_OutIt> __s = __str.size();
663*349cc55cSDimitry Andric  iter_difference_t<_OutIt> __m =
664*349cc55cSDimitry Andric      _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s);
665*349cc55cSDimitry Andric  __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it));
666*349cc55cSDimitry Andric  return {_VSTD::move(__out_it), __s};
667*349cc55cSDimitry Andric}
668*349cc55cSDimitry Andric#endif
669*349cc55cSDimitry Andric
670*349cc55cSDimitry Andrictemplate <class... _Args>
671*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
672*349cc55cSDimitry Andricformatted_size(locale __loc, string_view __fmt, const _Args&... __args) {
673*349cc55cSDimitry Andric  // TODO FMT Improve PoC: using std::string is inefficient.
674*349cc55cSDimitry Andric  return _VSTD::vformat(_VSTD::move(__loc), __fmt,
675*349cc55cSDimitry Andric                        _VSTD::make_format_args(__args...))
676*349cc55cSDimitry Andric      .size();
677*349cc55cSDimitry Andric}
678*349cc55cSDimitry Andric
679*349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
680*349cc55cSDimitry Andrictemplate <class... _Args>
681*349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
682*349cc55cSDimitry Andricformatted_size(locale __loc, wstring_view __fmt, const _Args&... __args) {
683*349cc55cSDimitry Andric  // TODO FMT Improve PoC: using std::string is inefficient.
684*349cc55cSDimitry Andric  return _VSTD::vformat(_VSTD::move(__loc), __fmt,
685*349cc55cSDimitry Andric                        _VSTD::make_wformat_args(__args...))
686*349cc55cSDimitry Andric      .size();
687*349cc55cSDimitry Andric}
688*349cc55cSDimitry Andric#endif
689*349cc55cSDimitry Andric
690*349cc55cSDimitry Andric#endif // _LIBCPP_HAS_NO_LOCALIZATION
691*349cc55cSDimitry Andric
692*349cc55cSDimitry Andric#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
693fe6060f1SDimitry Andric#endif //_LIBCPP_STD_VER > 17
694fe6060f1SDimitry Andric
695fe6060f1SDimitry Andric_LIBCPP_END_NAMESPACE_STD
696fe6060f1SDimitry Andric
697fe6060f1SDimitry Andric_LIBCPP_POP_MACROS
698fe6060f1SDimitry Andric
6996e75b2fbSDimitry Andric#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
7006e75b2fbSDimitry Andric
701fe6060f1SDimitry Andric#endif // _LIBCPP_FORMAT
702