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