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 17349cc55cSDimitry Andric template<class Out, class charT> 18349cc55cSDimitry Andric class basic_format_context { 19349cc55cSDimitry Andric basic_format_args<basic_format_context> args_; // exposition only 20349cc55cSDimitry Andric Out out_; // exposition only 21349cc55cSDimitry Andric 22349cc55cSDimitry Andric public: 23349cc55cSDimitry Andric using iterator = Out; 24349cc55cSDimitry Andric using char_type = charT; 25349cc55cSDimitry Andric template<class T> using formatter_type = formatter<T, charT>; 26349cc55cSDimitry Andric 27349cc55cSDimitry Andric basic_format_arg<basic_format_context> arg(size_t id) const; 28349cc55cSDimitry Andric std::locale locale(); 29349cc55cSDimitry Andric 30349cc55cSDimitry Andric iterator out(); 31349cc55cSDimitry Andric void advance_to(iterator it); 32349cc55cSDimitry Andric }; 33349cc55cSDimitry Andric using format_context = basic_format_context<unspecified, char>; 34349cc55cSDimitry Andric using wformat_context = basic_format_context<unspecified, wchar_t>; 35349cc55cSDimitry Andric 36349cc55cSDimitry Andric // [format.args], class template basic_format_args 37349cc55cSDimitry Andric template<class Context> 38349cc55cSDimitry Andric class basic_format_args { 39349cc55cSDimitry Andric size_t size_; // exposition only 40349cc55cSDimitry Andric const basic_format_arg<Context>* data_; // exposition only 41349cc55cSDimitry Andric 42349cc55cSDimitry Andric public: 43349cc55cSDimitry Andric basic_format_args() noexcept; 44349cc55cSDimitry Andric 45349cc55cSDimitry Andric template<class... Args> 46349cc55cSDimitry Andric basic_format_args(const format-arg-store<Context, Args...>& store) noexcept; 47349cc55cSDimitry Andric 48349cc55cSDimitry Andric basic_format_arg<Context> get(size_t i) const noexcept; 49349cc55cSDimitry Andric }; 50349cc55cSDimitry Andric using format_args = basic_format_args<format_context>; 51349cc55cSDimitry Andric using wformat_args = basic_format_args<wformat_context>; 52349cc55cSDimitry Andric 53349cc55cSDimitry Andric 54349cc55cSDimitry Andric // [format.functions], formatting functions 55349cc55cSDimitry Andric template<class... Args> 56349cc55cSDimitry Andric string format(string_view fmt, const Args&... args); 57349cc55cSDimitry Andric template<class... Args> 58349cc55cSDimitry Andric wstring format(wstring_view fmt, const Args&... args); 59349cc55cSDimitry Andric template<class... Args> 60349cc55cSDimitry Andric string format(const locale& loc, string_view fmt, const Args&... args); 61349cc55cSDimitry Andric template<class... Args> 62349cc55cSDimitry Andric wstring format(const locale& loc, wstring_view fmt, const Args&... args); 63349cc55cSDimitry Andric 64349cc55cSDimitry Andric string vformat(string_view fmt, format_args args); 65349cc55cSDimitry Andric wstring vformat(wstring_view fmt, wformat_args args); 66349cc55cSDimitry Andric string vformat(const locale& loc, string_view fmt, format_args args); 67349cc55cSDimitry Andric wstring vformat(const locale& loc, wstring_view fmt, wformat_args args); 68349cc55cSDimitry Andric 69349cc55cSDimitry Andric template<class Out, class... Args> 70349cc55cSDimitry Andric Out format_to(Out out, string_view fmt, const Args&... args); 71349cc55cSDimitry Andric template<class Out, class... Args> 72349cc55cSDimitry Andric Out format_to(Out out, wstring_view fmt, const Args&... args); 73349cc55cSDimitry Andric template<class Out, class... Args> 74349cc55cSDimitry Andric Out format_to(Out out, const locale& loc, string_view fmt, const Args&... args); 75349cc55cSDimitry Andric template<class Out, class... Args> 76349cc55cSDimitry Andric Out format_to(Out out, const locale& loc, wstring_view fmt, const Args&... args); 77349cc55cSDimitry Andric 78349cc55cSDimitry Andric template<class Out> 79*4824e7fdSDimitry Andric Out vformat_to(Out out, string_view fmt, format_args args); 80349cc55cSDimitry Andric template<class Out> 81*4824e7fdSDimitry Andric Out vformat_to(Out out, wstring_view fmt, wformat_args args); 82349cc55cSDimitry Andric template<class Out> 83349cc55cSDimitry Andric Out vformat_to(Out out, const locale& loc, string_view fmt, 84*4824e7fdSDimitry Andric format_args char> args); 85349cc55cSDimitry Andric template<class Out> 86349cc55cSDimitry Andric Out vformat_to(Out out, const locale& loc, wstring_view fmt, 87*4824e7fdSDimitry Andric wformat_args args); 88349cc55cSDimitry Andric 89349cc55cSDimitry Andric template<class Out> struct format_to_n_result { 90349cc55cSDimitry Andric Out out; 91349cc55cSDimitry Andric iter_difference_t<Out> size; 92349cc55cSDimitry Andric }; 93349cc55cSDimitry Andric 94349cc55cSDimitry Andric template<class Out, class... Args> 95349cc55cSDimitry Andric format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, 96349cc55cSDimitry Andric string_view fmt, const Args&... args); 97349cc55cSDimitry Andric template<class Out, class... Args> 98349cc55cSDimitry Andric format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, 99349cc55cSDimitry Andric wstring_view fmt, const Args&... args); 100349cc55cSDimitry Andric template<class Out, class... Args> 101349cc55cSDimitry Andric format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, 102349cc55cSDimitry Andric const locale& loc, string_view fmt, 103349cc55cSDimitry Andric const Args&... args); 104349cc55cSDimitry Andric template<class Out, class... Args> 105349cc55cSDimitry Andric format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, 106349cc55cSDimitry Andric const locale& loc, wstring_view fmt, 107349cc55cSDimitry Andric const Args&... args); 108349cc55cSDimitry Andric 109349cc55cSDimitry Andric template<class... Args> 110349cc55cSDimitry Andric size_t formatted_size(string_view fmt, const Args&... args); 111349cc55cSDimitry Andric template<class... Args> 112349cc55cSDimitry Andric size_t formatted_size(wstring_view fmt, const Args&... args); 113349cc55cSDimitry Andric template<class... Args> 114349cc55cSDimitry Andric size_t formatted_size(const locale& loc, string_view fmt, const Args&... args); 115349cc55cSDimitry Andric template<class... Args> 116349cc55cSDimitry Andric size_t formatted_size(const locale& loc, wstring_view fmt, const Args&... args); 117349cc55cSDimitry Andric 118349cc55cSDimitry Andric // [format.formatter], formatter 119349cc55cSDimitry Andric template<> struct formatter<char, char>; 120349cc55cSDimitry Andric template<> struct formatter<char, wchar_t>; 121349cc55cSDimitry Andric template<> struct formatter<wchar_t, wchar_t>; 122349cc55cSDimitry Andric 123349cc55cSDimitry Andric template<> struct formatter<charT*, charT>; 124349cc55cSDimitry Andric template<> struct formatter<const charT*, charT>; 125349cc55cSDimitry Andric template<size_t N> struct formatter<const charT[N], charT>; 126349cc55cSDimitry Andric template<class traits, class Allocator> 127349cc55cSDimitry Andric struct formatter<basic_string<charT, traits, Allocator>, charT>; 128349cc55cSDimitry Andric template<class traits> 129349cc55cSDimitry Andric struct formatter<basic_string_view<charT, traits>, charT>; 130349cc55cSDimitry Andric 131349cc55cSDimitry Andric // [format.parse.ctx], class template basic_format_parse_context 132349cc55cSDimitry Andric template<class charT> 133349cc55cSDimitry Andric class basic_format_parse_context { 134349cc55cSDimitry Andric public: 135349cc55cSDimitry Andric using char_type = charT; 136349cc55cSDimitry Andric using const_iterator = typename basic_string_view<charT>::const_iterator; 137349cc55cSDimitry Andric using iterator = const_iterator; 138349cc55cSDimitry Andric 139349cc55cSDimitry Andric private: 140349cc55cSDimitry Andric iterator begin_; // exposition only 141349cc55cSDimitry Andric iterator end_; // exposition only 142349cc55cSDimitry Andric enum indexing { unknown, manual, automatic }; // exposition only 143349cc55cSDimitry Andric indexing indexing_; // exposition only 144349cc55cSDimitry Andric size_t next_arg_id_; // exposition only 145349cc55cSDimitry Andric size_t num_args_; // exposition only 146349cc55cSDimitry Andric 147349cc55cSDimitry Andric public: 148349cc55cSDimitry Andric constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt, 149349cc55cSDimitry Andric size_t num_args = 0) noexcept; 150349cc55cSDimitry Andric basic_format_parse_context(const basic_format_parse_context&) = delete; 151349cc55cSDimitry Andric basic_format_parse_context& operator=(const basic_format_parse_context&) = delete; 152349cc55cSDimitry Andric 153349cc55cSDimitry Andric constexpr const_iterator begin() const noexcept; 154349cc55cSDimitry Andric constexpr const_iterator end() const noexcept; 155349cc55cSDimitry Andric constexpr void advance_to(const_iterator it); 156349cc55cSDimitry Andric 157349cc55cSDimitry Andric constexpr size_t next_arg_id(); 158349cc55cSDimitry Andric constexpr void check_arg_id(size_t id); 159349cc55cSDimitry Andric }; 160349cc55cSDimitry Andric using format_parse_context = basic_format_parse_context<char>; 161349cc55cSDimitry Andric using wformat_parse_context = basic_format_parse_context<wchar_t>; 162349cc55cSDimitry Andric 163349cc55cSDimitry Andric // [format.arguments], arguments 164349cc55cSDimitry Andric // [format.arg], class template basic_format_arg 165349cc55cSDimitry Andric template<class Context> 166349cc55cSDimitry Andric class basic_format_arg { 167349cc55cSDimitry Andric public: 168349cc55cSDimitry Andric class handle; 169349cc55cSDimitry Andric 170349cc55cSDimitry Andric private: 171349cc55cSDimitry Andric using char_type = typename Context::char_type; // exposition only 172349cc55cSDimitry Andric 173349cc55cSDimitry Andric variant<monostate, bool, char_type, 174349cc55cSDimitry Andric int, unsigned int, long long int, unsigned long long int, 175349cc55cSDimitry Andric float, double, long double, 176349cc55cSDimitry Andric const char_type*, basic_string_view<char_type>, 177349cc55cSDimitry Andric const void*, handle> value; // exposition only 178349cc55cSDimitry Andric 179349cc55cSDimitry Andric template<class T> explicit basic_format_arg(const T& v) noexcept; // exposition only 180349cc55cSDimitry Andric explicit basic_format_arg(float n) noexcept; // exposition only 181349cc55cSDimitry Andric explicit basic_format_arg(double n) noexcept; // exposition only 182349cc55cSDimitry Andric explicit basic_format_arg(long double n) noexcept; // exposition only 183349cc55cSDimitry Andric explicit basic_format_arg(const char_type* s); // exposition only 184349cc55cSDimitry Andric 185349cc55cSDimitry Andric template<class traits> 186349cc55cSDimitry Andric explicit basic_format_arg( 187349cc55cSDimitry Andric basic_string_view<char_type, traits> s) noexcept; // exposition only 188349cc55cSDimitry Andric 189349cc55cSDimitry Andric template<class traits, class Allocator> 190349cc55cSDimitry Andric explicit basic_format_arg( 191349cc55cSDimitry Andric const basic_string<char_type, traits, Allocator>& s) noexcept; // exposition only 192349cc55cSDimitry Andric 193349cc55cSDimitry Andric explicit basic_format_arg(nullptr_t) noexcept; // exposition only 194349cc55cSDimitry Andric 195349cc55cSDimitry Andric template<class T> 196349cc55cSDimitry Andric explicit basic_format_arg(const T* p) noexcept; // exposition only 197349cc55cSDimitry Andric 198349cc55cSDimitry Andric public: 199349cc55cSDimitry Andric basic_format_arg() noexcept; 200349cc55cSDimitry Andric 201349cc55cSDimitry Andric explicit operator bool() const noexcept; 202349cc55cSDimitry Andric }; 203349cc55cSDimitry Andric 204349cc55cSDimitry Andric template<class Visitor, class Context> 205349cc55cSDimitry Andric see below visit_format_arg(Visitor&& vis, basic_format_arg<Context> arg); 206349cc55cSDimitry Andric 207349cc55cSDimitry Andric // [format.arg.store], class template format-arg-store 208349cc55cSDimitry Andric template<class Context, class... Args> 209349cc55cSDimitry Andric struct format-arg-store { // exposition only 210349cc55cSDimitry Andric array<basic_format_arg<Context>, sizeof...(Args)> args; 211349cc55cSDimitry Andric }; 212349cc55cSDimitry Andric 213349cc55cSDimitry Andric template<class Context = format_context, class... Args> 214349cc55cSDimitry Andric format-arg-store<Context, Args...> 215349cc55cSDimitry Andric make_format_args(const Args&... args); 216349cc55cSDimitry Andric template<class... Args> 217349cc55cSDimitry Andric format-arg-store<wformat_context, Args...> 218349cc55cSDimitry Andric make_wformat_args(const Args&... args); 219349cc55cSDimitry Andric 220fe6060f1SDimitry Andric // [format.error], class format_error 221fe6060f1SDimitry Andric class format_error : public runtime_error { 222fe6060f1SDimitry Andric public: 223fe6060f1SDimitry Andric explicit format_error(const string& what_arg); 224fe6060f1SDimitry Andric explicit format_error(const char* what_arg); 225fe6060f1SDimitry Andric }; 226fe6060f1SDimitry Andric 227fe6060f1SDimitry Andric // [format.parse.ctx], class template basic_format_parse_context 228fe6060f1SDimitry Andric template<class charT> 229fe6060f1SDimitry Andric class basic_format_parse_context { 230fe6060f1SDimitry Andric public: 231fe6060f1SDimitry Andric using char_type = charT; 232fe6060f1SDimitry Andric using const_iterator = typename basic_string_view<charT>::const_iterator; 233fe6060f1SDimitry Andric using iterator = const_iterator; 234fe6060f1SDimitry Andric 235fe6060f1SDimitry Andric private: 236fe6060f1SDimitry Andric iterator begin_; // exposition only 237fe6060f1SDimitry Andric iterator end_; // exposition only 238fe6060f1SDimitry Andric enum indexing { unknown, manual, automatic }; // exposition only 239fe6060f1SDimitry Andric indexing indexing_; // exposition only 240fe6060f1SDimitry Andric size_t next_arg_id_; // exposition only 241fe6060f1SDimitry Andric size_t num_args_; // exposition only 242fe6060f1SDimitry Andric 243fe6060f1SDimitry Andric public: 244fe6060f1SDimitry Andric constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt, 245fe6060f1SDimitry Andric size_t num_args = 0) noexcept; 246fe6060f1SDimitry Andric basic_format_parse_context(const basic_format_parse_context&) = delete; 247fe6060f1SDimitry Andric basic_format_parse_context& operator=(const basic_format_parse_context&) = delete; 248fe6060f1SDimitry Andric 249fe6060f1SDimitry Andric constexpr const_iterator begin() const noexcept; 250fe6060f1SDimitry Andric constexpr const_iterator end() const noexcept; 251fe6060f1SDimitry Andric constexpr void advance_to(const_iterator it); 252fe6060f1SDimitry Andric 253fe6060f1SDimitry Andric constexpr size_t next_arg_id(); 254fe6060f1SDimitry Andric constexpr void check_arg_id(size_t id); 255fe6060f1SDimitry Andric }; 256fe6060f1SDimitry Andric using format_parse_context = basic_format_parse_context<char>; 257fe6060f1SDimitry Andric using wformat_parse_context = basic_format_parse_context<wchar_t>; 258fe6060f1SDimitry Andric} 259fe6060f1SDimitry Andric 260fe6060f1SDimitry Andric*/ 261fe6060f1SDimitry Andric 262349cc55cSDimitry Andric// Make sure all feature-test macros are available. 2636e75b2fbSDimitry Andric#include <version> 264349cc55cSDimitry Andric// Enable the contents of the header only when libc++ was built with LIBCXX_ENABLE_INCOMPLETE_FEATURES. 2656e75b2fbSDimitry Andric#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) 2666e75b2fbSDimitry Andric 267fe6060f1SDimitry Andric#include <__config> 268349cc55cSDimitry Andric#include <__debug> 269349cc55cSDimitry Andric#include <__format/format_arg.h> 270349cc55cSDimitry Andric#include <__format/format_args.h> 271349cc55cSDimitry Andric#include <__format/format_context.h> 272fe6060f1SDimitry Andric#include <__format/format_error.h> 273349cc55cSDimitry Andric#include <__format/format_fwd.h> 274fe6060f1SDimitry Andric#include <__format/format_parse_context.h> 275349cc55cSDimitry Andric#include <__format/format_string.h> 276349cc55cSDimitry Andric#include <__format/format_to_n_result.h> 277349cc55cSDimitry Andric#include <__format/formatter.h> 278349cc55cSDimitry Andric#include <__format/formatter_bool.h> 279349cc55cSDimitry Andric#include <__format/formatter_char.h> 280349cc55cSDimitry Andric#include <__format/formatter_integer.h> 281349cc55cSDimitry Andric#include <__format/formatter_string.h> 282349cc55cSDimitry Andric#include <__format/parser_std_format_spec.h> 283349cc55cSDimitry Andric#include <__variant/monostate.h> 284349cc55cSDimitry Andric#include <array> 285349cc55cSDimitry Andric#include <concepts> 286349cc55cSDimitry Andric#include <string> 287349cc55cSDimitry Andric#include <string_view> 288349cc55cSDimitry Andric#include <type_traits> 289349cc55cSDimitry Andric 290349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_LOCALIZATION 291349cc55cSDimitry Andric#include <locale> 292349cc55cSDimitry Andric#endif 293fe6060f1SDimitry Andric 294fe6060f1SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 295fe6060f1SDimitry Andric#pragma GCC system_header 296fe6060f1SDimitry Andric#endif 297fe6060f1SDimitry Andric 298fe6060f1SDimitry Andric_LIBCPP_PUSH_MACROS 299fe6060f1SDimitry Andric#include <__undef_macros> 300fe6060f1SDimitry Andric 301fe6060f1SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 302fe6060f1SDimitry Andric 303fe6060f1SDimitry Andric#if _LIBCPP_STD_VER > 17 304fe6060f1SDimitry Andric 305349cc55cSDimitry Andric// TODO FMT Remove this once we require compilers with proper C++20 support. 306349cc55cSDimitry Andric// If the compiler has no concepts support, the format header will be disabled. 307349cc55cSDimitry Andric// Without concepts support enable_if needs to be used and that too much effort 308349cc55cSDimitry Andric// to support compilers with partial C++20 support. 309349cc55cSDimitry Andric#if !defined(_LIBCPP_HAS_NO_CONCEPTS) 310349cc55cSDimitry Andric 311349cc55cSDimitry Andric// TODO FMT Move the implementation in this file to its own granular headers. 312349cc55cSDimitry Andric 313349cc55cSDimitry Andric// TODO FMT Evaluate which templates should be external templates. This 314349cc55cSDimitry Andric// improves the efficiency of the header. However since the header is still 315349cc55cSDimitry Andric// under heavy development and not all classes are stable it makes no sense 316349cc55cSDimitry Andric// to do this optimization now. 317349cc55cSDimitry Andric 318349cc55cSDimitry Andricusing format_args = basic_format_args<format_context>; 319349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 320349cc55cSDimitry Andricusing wformat_args = basic_format_args<wformat_context>; 321349cc55cSDimitry Andric#endif 322349cc55cSDimitry Andric 323349cc55cSDimitry Andrictemplate <class _Context, class... _Args> 324349cc55cSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS __format_arg_store { 325349cc55cSDimitry Andric // TODO FMT Use a built-in array. 326349cc55cSDimitry Andric array<basic_format_arg<_Context>, sizeof...(_Args)> __args; 327349cc55cSDimitry Andric}; 328349cc55cSDimitry Andric 329349cc55cSDimitry Andrictemplate <class _Context = format_context, class... _Args> 330349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> 331349cc55cSDimitry Andricmake_format_args(const _Args&... __args) { 332349cc55cSDimitry Andric return {basic_format_arg<_Context>(__args)...}; 333349cc55cSDimitry Andric} 334349cc55cSDimitry Andric 335349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 336349cc55cSDimitry Andrictemplate <class... _Args> 337349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI __format_arg_store<wformat_context, _Args...> 338349cc55cSDimitry Andricmake_wformat_args(const _Args&... __args) { 339349cc55cSDimitry Andric return _VSTD::make_format_args<wformat_context>(__args...); 340349cc55cSDimitry Andric} 341349cc55cSDimitry Andric#endif 342349cc55cSDimitry Andric 343349cc55cSDimitry Andricnamespace __format { 344349cc55cSDimitry Andric 345349cc55cSDimitry Andrictemplate <class _CharT, class _ParseCtx, class _Ctx> 346349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI const _CharT* 347349cc55cSDimitry Andric__handle_replacement_field(const _CharT* __begin, const _CharT* __end, 348349cc55cSDimitry Andric _ParseCtx& __parse_ctx, _Ctx& __ctx) { 349349cc55cSDimitry Andric __format::__parse_number_result __r = 350349cc55cSDimitry Andric __format::__parse_arg_id(__begin, __end, __parse_ctx); 351349cc55cSDimitry Andric 352349cc55cSDimitry Andric switch (*__r.__ptr) { 353349cc55cSDimitry Andric case _CharT(':'): 354349cc55cSDimitry Andric // The arg-id has a format-specifier, advance the input to the format-spec. 355349cc55cSDimitry Andric __parse_ctx.advance_to(__r.__ptr + 1); 356349cc55cSDimitry Andric break; 357349cc55cSDimitry Andric case _CharT('}'): 358349cc55cSDimitry Andric // The arg-id has no format-specifier. 359349cc55cSDimitry Andric __parse_ctx.advance_to(__r.__ptr); 360349cc55cSDimitry Andric break; 361349cc55cSDimitry Andric default: 362349cc55cSDimitry Andric __throw_format_error( 363349cc55cSDimitry Andric "The replacement field arg-id should terminate at a ':' or '}'"); 364349cc55cSDimitry Andric } 365349cc55cSDimitry Andric 366349cc55cSDimitry Andric _VSTD::visit_format_arg( 367349cc55cSDimitry Andric [&](auto __arg) { 368349cc55cSDimitry Andric if constexpr (same_as<decltype(__arg), monostate>) 369349cc55cSDimitry Andric __throw_format_error("Argument index out of bounds"); 370349cc55cSDimitry Andric else { 371349cc55cSDimitry Andric formatter<decltype(__arg), _CharT> __formatter; 372349cc55cSDimitry Andric __parse_ctx.advance_to(__formatter.parse(__parse_ctx)); 373349cc55cSDimitry Andric __ctx.advance_to(__formatter.format(__arg, __ctx)); 374349cc55cSDimitry Andric } 375349cc55cSDimitry Andric }, 376349cc55cSDimitry Andric __ctx.arg(__r.__value)); 377349cc55cSDimitry Andric 378349cc55cSDimitry Andric __begin = __parse_ctx.begin(); 379349cc55cSDimitry Andric if (__begin == __end || *__begin != _CharT('}')) 380349cc55cSDimitry Andric __throw_format_error("The replacement field misses a terminating '}'"); 381349cc55cSDimitry Andric 382349cc55cSDimitry Andric return ++__begin; 383349cc55cSDimitry Andric} 384349cc55cSDimitry Andric 385349cc55cSDimitry Andrictemplate <class _ParseCtx, class _Ctx> 386349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI typename _Ctx::iterator 387349cc55cSDimitry Andric__vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) { 388349cc55cSDimitry Andric using _CharT = typename _ParseCtx::char_type; 389349cc55cSDimitry Andric static_assert(same_as<typename _Ctx::char_type, _CharT>); 390349cc55cSDimitry Andric 391349cc55cSDimitry Andric const _CharT* __begin = __parse_ctx.begin(); 392349cc55cSDimitry Andric const _CharT* __end = __parse_ctx.end(); 393349cc55cSDimitry Andric typename _Ctx::iterator __out_it = __ctx.out(); 394349cc55cSDimitry Andric while (__begin != __end) { 395349cc55cSDimitry Andric switch (*__begin) { 396349cc55cSDimitry Andric case _CharT('{'): 397349cc55cSDimitry Andric ++__begin; 398349cc55cSDimitry Andric if (__begin == __end) 399349cc55cSDimitry Andric __throw_format_error("The format string terminates at a '{'"); 400349cc55cSDimitry Andric 401349cc55cSDimitry Andric if (*__begin != _CharT('{')) [[likely]] { 402349cc55cSDimitry Andric __ctx.advance_to(_VSTD::move(__out_it)); 403349cc55cSDimitry Andric __begin = 404349cc55cSDimitry Andric __handle_replacement_field(__begin, __end, __parse_ctx, __ctx); 405349cc55cSDimitry Andric __out_it = __ctx.out(); 406349cc55cSDimitry Andric 407349cc55cSDimitry Andric // The output is written and __begin points to the next character. So 408349cc55cSDimitry Andric // start the next iteration. 409349cc55cSDimitry Andric continue; 410349cc55cSDimitry Andric } 411349cc55cSDimitry Andric // The string is an escape character. 412349cc55cSDimitry Andric break; 413349cc55cSDimitry Andric 414349cc55cSDimitry Andric case _CharT('}'): 415349cc55cSDimitry Andric ++__begin; 416349cc55cSDimitry Andric if (__begin == __end || *__begin != _CharT('}')) 417349cc55cSDimitry Andric __throw_format_error( 418349cc55cSDimitry Andric "The format string contains an invalid escape sequence"); 419349cc55cSDimitry Andric 420349cc55cSDimitry Andric break; 421349cc55cSDimitry Andric } 422349cc55cSDimitry Andric 423349cc55cSDimitry Andric // Copy the character to the output verbatim. 424349cc55cSDimitry Andric *__out_it++ = *__begin++; 425349cc55cSDimitry Andric } 426349cc55cSDimitry Andric return __out_it; 427349cc55cSDimitry Andric} 428349cc55cSDimitry Andric 429349cc55cSDimitry Andric} // namespace __format 430349cc55cSDimitry Andric 431*4824e7fdSDimitry Andrictemplate <class _OutIt, class _CharT, class _FormatOutIt> 432349cc55cSDimitry Andricrequires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt 433*4824e7fdSDimitry Andric __vformat_to( 434*4824e7fdSDimitry Andric _OutIt __out_it, basic_string_view<_CharT> __fmt, 435*4824e7fdSDimitry Andric basic_format_args<basic_format_context<_FormatOutIt, _CharT>> __args) { 436*4824e7fdSDimitry Andric if constexpr (same_as<_OutIt, _FormatOutIt>) 437*4824e7fdSDimitry Andric return _VSTD::__format::__vformat_to( 438349cc55cSDimitry Andric basic_format_parse_context{__fmt, __args.__size()}, 439349cc55cSDimitry Andric _VSTD::__format_context_create(_VSTD::move(__out_it), __args)); 440*4824e7fdSDimitry Andric else { 441*4824e7fdSDimitry Andric basic_string<_CharT> __str; 442*4824e7fdSDimitry Andric _VSTD::__format::__vformat_to( 443*4824e7fdSDimitry Andric basic_format_parse_context{__fmt, __args.__size()}, 444*4824e7fdSDimitry Andric _VSTD::__format_context_create(_VSTD::back_inserter(__str), __args)); 445*4824e7fdSDimitry Andric return _VSTD::copy_n(__str.begin(), __str.size(), _VSTD::move(__out_it)); 446*4824e7fdSDimitry Andric } 447349cc55cSDimitry Andric} 448349cc55cSDimitry Andric 449349cc55cSDimitry Andrictemplate <output_iterator<const char&> _OutIt> 450*4824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt 451*4824e7fdSDimitry Andricvformat_to(_OutIt __out_it, string_view __fmt, format_args __args) { 452349cc55cSDimitry Andric return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args); 453349cc55cSDimitry Andric} 454349cc55cSDimitry Andric 455349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 456349cc55cSDimitry Andrictemplate <output_iterator<const wchar_t&> _OutIt> 457*4824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt 458*4824e7fdSDimitry Andricvformat_to(_OutIt __out_it, wstring_view __fmt, wformat_args __args) { 459349cc55cSDimitry Andric return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args); 460349cc55cSDimitry Andric} 461349cc55cSDimitry Andric#endif 462349cc55cSDimitry Andric 463349cc55cSDimitry Andrictemplate <output_iterator<const char&> _OutIt, class... _Args> 464*4824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt 465349cc55cSDimitry Andricformat_to(_OutIt __out_it, string_view __fmt, const _Args&... __args) { 466*4824e7fdSDimitry Andric return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt, 467*4824e7fdSDimitry Andric _VSTD::make_format_args(__args...)); 468349cc55cSDimitry Andric} 469349cc55cSDimitry Andric 470349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 471349cc55cSDimitry Andrictemplate <output_iterator<const wchar_t&> _OutIt, class... _Args> 472*4824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt 473349cc55cSDimitry Andricformat_to(_OutIt __out_it, wstring_view __fmt, const _Args&... __args) { 474*4824e7fdSDimitry Andric return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt, 475*4824e7fdSDimitry Andric _VSTD::make_wformat_args(__args...)); 476349cc55cSDimitry Andric} 477349cc55cSDimitry Andric#endif 478349cc55cSDimitry Andric 479*4824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string 480349cc55cSDimitry Andricvformat(string_view __fmt, format_args __args) { 481349cc55cSDimitry Andric string __res; 482349cc55cSDimitry Andric _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args); 483349cc55cSDimitry Andric return __res; 484349cc55cSDimitry Andric} 485349cc55cSDimitry Andric 486349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 487*4824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring 488349cc55cSDimitry Andricvformat(wstring_view __fmt, wformat_args __args) { 489349cc55cSDimitry Andric wstring __res; 490349cc55cSDimitry Andric _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args); 491349cc55cSDimitry Andric return __res; 492349cc55cSDimitry Andric} 493349cc55cSDimitry Andric#endif 494349cc55cSDimitry Andric 495349cc55cSDimitry Andrictemplate <class... _Args> 496*4824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string 497349cc55cSDimitry Andricformat(string_view __fmt, const _Args&... __args) { 498349cc55cSDimitry Andric return _VSTD::vformat(__fmt, _VSTD::make_format_args(__args...)); 499349cc55cSDimitry Andric} 500349cc55cSDimitry Andric 501349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 502349cc55cSDimitry Andrictemplate <class... _Args> 503*4824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring 504349cc55cSDimitry Andricformat(wstring_view __fmt, const _Args&... __args) { 505349cc55cSDimitry Andric return _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...)); 506349cc55cSDimitry Andric} 507349cc55cSDimitry Andric#endif 508349cc55cSDimitry Andric 509349cc55cSDimitry Andrictemplate <output_iterator<const char&> _OutIt, class... _Args> 510349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> 511349cc55cSDimitry Andricformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, string_view __fmt, 512349cc55cSDimitry Andric const _Args&... __args) { 513349cc55cSDimitry Andric // TODO FMT Improve PoC: using std::string is inefficient. 514349cc55cSDimitry Andric string __str = _VSTD::vformat(__fmt, _VSTD::make_format_args(__args...)); 515349cc55cSDimitry Andric iter_difference_t<_OutIt> __s = __str.size(); 516349cc55cSDimitry Andric iter_difference_t<_OutIt> __m = 517349cc55cSDimitry Andric _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s); 518349cc55cSDimitry Andric __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it)); 519349cc55cSDimitry Andric return {_VSTD::move(__out_it), __s}; 520349cc55cSDimitry Andric} 521349cc55cSDimitry Andric 522349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 523349cc55cSDimitry Andrictemplate <output_iterator<const wchar_t&> _OutIt, class... _Args> 524349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> 525349cc55cSDimitry Andricformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, wstring_view __fmt, 526349cc55cSDimitry Andric const _Args&... __args) { 527349cc55cSDimitry Andric // TODO FMT Improve PoC: using std::string is inefficient. 528349cc55cSDimitry Andric wstring __str = _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...)); 529349cc55cSDimitry Andric iter_difference_t<_OutIt> __s = __str.size(); 530349cc55cSDimitry Andric iter_difference_t<_OutIt> __m = 531349cc55cSDimitry Andric _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s); 532349cc55cSDimitry Andric __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it)); 533349cc55cSDimitry Andric return {_VSTD::move(__out_it), __s}; 534349cc55cSDimitry Andric} 535349cc55cSDimitry Andric#endif 536349cc55cSDimitry Andric 537349cc55cSDimitry Andrictemplate <class... _Args> 538349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t 539349cc55cSDimitry Andricformatted_size(string_view __fmt, const _Args&... __args) { 540349cc55cSDimitry Andric // TODO FMT Improve PoC: using std::string is inefficient. 541349cc55cSDimitry Andric return _VSTD::vformat(__fmt, _VSTD::make_format_args(__args...)).size(); 542349cc55cSDimitry Andric} 543349cc55cSDimitry Andric 544349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 545349cc55cSDimitry Andrictemplate <class... _Args> 546349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t 547349cc55cSDimitry Andricformatted_size(wstring_view __fmt, const _Args&... __args) { 548349cc55cSDimitry Andric // TODO FMT Improve PoC: using std::string is inefficient. 549349cc55cSDimitry Andric return _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...)).size(); 550349cc55cSDimitry Andric} 551349cc55cSDimitry Andric#endif 552349cc55cSDimitry Andric 553349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_LOCALIZATION 554349cc55cSDimitry Andric 555*4824e7fdSDimitry Andrictemplate <class _OutIt, class _CharT, class _FormatOutIt> 556349cc55cSDimitry Andricrequires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt 557*4824e7fdSDimitry Andric __vformat_to( 558*4824e7fdSDimitry Andric _OutIt __out_it, locale __loc, basic_string_view<_CharT> __fmt, 559*4824e7fdSDimitry Andric basic_format_args<basic_format_context<_FormatOutIt, _CharT>> __args) { 560*4824e7fdSDimitry Andric if constexpr (same_as<_OutIt, _FormatOutIt>) 561*4824e7fdSDimitry Andric return _VSTD::__format::__vformat_to( 562349cc55cSDimitry Andric basic_format_parse_context{__fmt, __args.__size()}, 563349cc55cSDimitry Andric _VSTD::__format_context_create(_VSTD::move(__out_it), __args, 564349cc55cSDimitry Andric _VSTD::move(__loc))); 565*4824e7fdSDimitry Andric else { 566*4824e7fdSDimitry Andric basic_string<_CharT> __str; 567*4824e7fdSDimitry Andric _VSTD::__format::__vformat_to( 568*4824e7fdSDimitry Andric basic_format_parse_context{__fmt, __args.__size()}, 569*4824e7fdSDimitry Andric _VSTD::__format_context_create(_VSTD::back_inserter(__str), __args, 570*4824e7fdSDimitry Andric _VSTD::move(__loc))); 571*4824e7fdSDimitry Andric return _VSTD::copy_n(__str.begin(), __str.size(), _VSTD::move(__out_it)); 572*4824e7fdSDimitry Andric } 573349cc55cSDimitry Andric} 574349cc55cSDimitry Andric 575349cc55cSDimitry Andrictemplate <output_iterator<const char&> _OutIt> 576*4824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt vformat_to( 577*4824e7fdSDimitry Andric _OutIt __out_it, locale __loc, string_view __fmt, format_args __args) { 578349cc55cSDimitry Andric return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, 579349cc55cSDimitry Andric __args); 580349cc55cSDimitry Andric} 581349cc55cSDimitry Andric 582349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 583349cc55cSDimitry Andrictemplate <output_iterator<const wchar_t&> _OutIt> 584*4824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt vformat_to( 585*4824e7fdSDimitry Andric _OutIt __out_it, locale __loc, wstring_view __fmt, wformat_args __args) { 586349cc55cSDimitry Andric return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, 587349cc55cSDimitry Andric __args); 588349cc55cSDimitry Andric} 589349cc55cSDimitry Andric#endif 590349cc55cSDimitry Andric 591349cc55cSDimitry Andrictemplate <output_iterator<const char&> _OutIt, class... _Args> 592*4824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to( 593349cc55cSDimitry Andric _OutIt __out_it, locale __loc, string_view __fmt, const _Args&... __args) { 594*4824e7fdSDimitry Andric return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, 595*4824e7fdSDimitry Andric _VSTD::make_format_args(__args...)); 596349cc55cSDimitry Andric} 597349cc55cSDimitry Andric 598349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 599349cc55cSDimitry Andrictemplate <output_iterator<const wchar_t&> _OutIt, class... _Args> 600*4824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to( 601349cc55cSDimitry Andric _OutIt __out_it, locale __loc, wstring_view __fmt, const _Args&... __args) { 602*4824e7fdSDimitry Andric return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, 603*4824e7fdSDimitry Andric _VSTD::make_wformat_args(__args...)); 604349cc55cSDimitry Andric} 605349cc55cSDimitry Andric#endif 606349cc55cSDimitry Andric 607*4824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string 608349cc55cSDimitry Andricvformat(locale __loc, string_view __fmt, format_args __args) { 609349cc55cSDimitry Andric string __res; 610349cc55cSDimitry Andric _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt, 611349cc55cSDimitry Andric __args); 612349cc55cSDimitry Andric return __res; 613349cc55cSDimitry Andric} 614349cc55cSDimitry Andric 615349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 616*4824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring 617349cc55cSDimitry Andricvformat(locale __loc, wstring_view __fmt, wformat_args __args) { 618349cc55cSDimitry Andric wstring __res; 619349cc55cSDimitry Andric _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt, 620349cc55cSDimitry Andric __args); 621349cc55cSDimitry Andric return __res; 622349cc55cSDimitry Andric} 623349cc55cSDimitry Andric#endif 624349cc55cSDimitry Andric 625349cc55cSDimitry Andrictemplate <class... _Args> 626*4824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string 627349cc55cSDimitry Andricformat(locale __loc, string_view __fmt, const _Args&... __args) { 628349cc55cSDimitry Andric return _VSTD::vformat(_VSTD::move(__loc), __fmt, 629349cc55cSDimitry Andric _VSTD::make_format_args(__args...)); 630349cc55cSDimitry Andric} 631349cc55cSDimitry Andric 632349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 633349cc55cSDimitry Andrictemplate <class... _Args> 634*4824e7fdSDimitry Andric_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring 635349cc55cSDimitry Andricformat(locale __loc, wstring_view __fmt, const _Args&... __args) { 636349cc55cSDimitry Andric return _VSTD::vformat(_VSTD::move(__loc), __fmt, 637349cc55cSDimitry Andric _VSTD::make_wformat_args(__args...)); 638349cc55cSDimitry Andric} 639349cc55cSDimitry Andric#endif 640349cc55cSDimitry Andric 641349cc55cSDimitry Andrictemplate <output_iterator<const char&> _OutIt, class... _Args> 642349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> 643349cc55cSDimitry Andricformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, 644349cc55cSDimitry Andric string_view __fmt, const _Args&... __args) { 645349cc55cSDimitry Andric // TODO FMT Improve PoC: using std::string is inefficient. 646349cc55cSDimitry Andric string __str = _VSTD::vformat(_VSTD::move(__loc), __fmt, 647349cc55cSDimitry Andric _VSTD::make_format_args(__args...)); 648349cc55cSDimitry Andric iter_difference_t<_OutIt> __s = __str.size(); 649349cc55cSDimitry Andric iter_difference_t<_OutIt> __m = 650349cc55cSDimitry Andric _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s); 651349cc55cSDimitry Andric __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it)); 652349cc55cSDimitry Andric return {_VSTD::move(__out_it), __s}; 653349cc55cSDimitry Andric} 654349cc55cSDimitry Andric 655349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 656349cc55cSDimitry Andrictemplate <output_iterator<const wchar_t&> _OutIt, class... _Args> 657349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> 658349cc55cSDimitry Andricformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, 659349cc55cSDimitry Andric wstring_view __fmt, const _Args&... __args) { 660349cc55cSDimitry Andric // TODO FMT Improve PoC: using std::string is inefficient. 661349cc55cSDimitry Andric wstring __str = _VSTD::vformat(_VSTD::move(__loc), __fmt, 662349cc55cSDimitry Andric _VSTD::make_wformat_args(__args...)); 663349cc55cSDimitry Andric iter_difference_t<_OutIt> __s = __str.size(); 664349cc55cSDimitry Andric iter_difference_t<_OutIt> __m = 665349cc55cSDimitry Andric _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s); 666349cc55cSDimitry Andric __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it)); 667349cc55cSDimitry Andric return {_VSTD::move(__out_it), __s}; 668349cc55cSDimitry Andric} 669349cc55cSDimitry Andric#endif 670349cc55cSDimitry Andric 671349cc55cSDimitry Andrictemplate <class... _Args> 672349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t 673349cc55cSDimitry Andricformatted_size(locale __loc, string_view __fmt, const _Args&... __args) { 674349cc55cSDimitry Andric // TODO FMT Improve PoC: using std::string is inefficient. 675349cc55cSDimitry Andric return _VSTD::vformat(_VSTD::move(__loc), __fmt, 676349cc55cSDimitry Andric _VSTD::make_format_args(__args...)) 677349cc55cSDimitry Andric .size(); 678349cc55cSDimitry Andric} 679349cc55cSDimitry Andric 680349cc55cSDimitry Andric#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 681349cc55cSDimitry Andrictemplate <class... _Args> 682349cc55cSDimitry Andric_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t 683349cc55cSDimitry Andricformatted_size(locale __loc, wstring_view __fmt, const _Args&... __args) { 684349cc55cSDimitry Andric // TODO FMT Improve PoC: using std::string is inefficient. 685349cc55cSDimitry Andric return _VSTD::vformat(_VSTD::move(__loc), __fmt, 686349cc55cSDimitry Andric _VSTD::make_wformat_args(__args...)) 687349cc55cSDimitry Andric .size(); 688349cc55cSDimitry Andric} 689349cc55cSDimitry Andric#endif 690349cc55cSDimitry Andric 691349cc55cSDimitry Andric#endif // _LIBCPP_HAS_NO_LOCALIZATION 692349cc55cSDimitry Andric 693349cc55cSDimitry Andric#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) 694fe6060f1SDimitry Andric#endif //_LIBCPP_STD_VER > 17 695fe6060f1SDimitry Andric 696fe6060f1SDimitry Andric_LIBCPP_END_NAMESPACE_STD 697fe6060f1SDimitry Andric 698fe6060f1SDimitry Andric_LIBCPP_POP_MACROS 699fe6060f1SDimitry Andric 7006e75b2fbSDimitry Andric#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) 7016e75b2fbSDimitry Andric 702fe6060f1SDimitry Andric#endif // _LIBCPP_FORMAT 703