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