diff options
author | Andrey Khalyavin <halyavin@gmail.com> | 2022-02-10 16:46:30 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:46:30 +0300 |
commit | 4b839d0704ee9be1dabb0310a1f03af24963637b (patch) | |
tree | 1a2c5ffcf89eb53ecd79dbc9bc0a195c27404d0c /contrib/libs/cxxsupp/libcxx/include/format | |
parent | f773626848a7c7456803654292e716b83d69cc12 (diff) | |
download | ydb-4b839d0704ee9be1dabb0310a1f03af24963637b.tar.gz |
Restoring authorship annotation for Andrey Khalyavin <halyavin@gmail.com>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/cxxsupp/libcxx/include/format')
-rw-r--r-- | contrib/libs/cxxsupp/libcxx/include/format | 1552 |
1 files changed, 776 insertions, 776 deletions
diff --git a/contrib/libs/cxxsupp/libcxx/include/format b/contrib/libs/cxxsupp/libcxx/include/format index f37f5194ab..19f642716b 100644 --- a/contrib/libs/cxxsupp/libcxx/include/format +++ b/contrib/libs/cxxsupp/libcxx/include/format @@ -1,776 +1,776 @@ -// -*- C++ -*- -//===--------------------------- format -----------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP_FORMAT -#define _LIBCPP_FORMAT - -/* - -namespace std { - // [format.context], class template basic_format_context - template<class Out, class charT> - class basic_format_context { - basic_format_args<basic_format_context> args_; // exposition only - Out out_; // exposition only - - public: - using iterator = Out; - using char_type = charT; - template<class T> using formatter_type = formatter<T, charT>; - - basic_format_arg<basic_format_context> arg(size_t id) const; - std::locale locale(); - - iterator out(); - void advance_to(iterator it); - }; - using format_context = basic_format_context<unspecified, char>; - using wformat_context = basic_format_context<unspecified, wchar_t>; - - // [format.args], class template basic_format_args - template<class Context> - class basic_format_args { - size_t size_; // exposition only - const basic_format_arg<Context>* data_; // exposition only - - public: - basic_format_args() noexcept; - - template<class... Args> - basic_format_args(const format-arg-store<Context, Args...>& store) noexcept; - - basic_format_arg<Context> get(size_t i) const noexcept; - }; - using format_args = basic_format_args<format_context>; - using wformat_args = basic_format_args<wformat_context>; - - - template<class Out, class charT> - using format_args_t = basic_format_args<basic_format_context<Out, charT>>; - - // [format.functions], formatting functions - template<class... Args> - string format(string_view fmt, const Args&... args); - template<class... Args> - wstring format(wstring_view fmt, const Args&... args); - template<class... Args> - string format(const locale& loc, string_view fmt, const Args&... args); - template<class... Args> - wstring format(const locale& loc, wstring_view fmt, const Args&... args); - - string vformat(string_view fmt, format_args args); - wstring vformat(wstring_view fmt, wformat_args args); - string vformat(const locale& loc, string_view fmt, format_args args); - wstring vformat(const locale& loc, wstring_view fmt, wformat_args args); - - template<class Out, class... Args> - Out format_to(Out out, string_view fmt, const Args&... args); - template<class Out, class... Args> - Out format_to(Out out, wstring_view fmt, const Args&... args); - template<class Out, class... Args> - Out format_to(Out out, const locale& loc, string_view fmt, const Args&... args); - template<class Out, class... Args> - Out format_to(Out out, const locale& loc, wstring_view fmt, const Args&... args); - - template<class Out> - Out vformat_to(Out out, string_view fmt, - format_args_t<type_identity_t<Out>, char> args); - template<class Out> - Out vformat_to(Out out, wstring_view fmt, - format_args_t<type_identity_t<Out>, wchar_t> args); - template<class Out> - Out vformat_to(Out out, const locale& loc, string_view fmt, - format_args_t<type_identity_t<Out>, char> args); - template<class Out> - Out vformat_to(Out out, const locale& loc, wstring_view fmt, - format_args_t<type_identity_t<Out>, wchar_t> args); - - template<class Out> struct format_to_n_result { - Out out; - iter_difference_t<Out> size; - }; - - template<class Out, class... Args> - format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, - string_view fmt, const Args&... args); - template<class Out, class... Args> - format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, - wstring_view fmt, const Args&... args); - template<class Out, class... Args> - format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, - const locale& loc, string_view fmt, - const Args&... args); - template<class Out, class... Args> - format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, - const locale& loc, wstring_view fmt, - const Args&... args); - - template<class... Args> - size_t formatted_size(string_view fmt, const Args&... args); - template<class... Args> - size_t formatted_size(wstring_view fmt, const Args&... args); - template<class... Args> - size_t formatted_size(const locale& loc, string_view fmt, const Args&... args); - template<class... Args> - size_t formatted_size(const locale& loc, wstring_view fmt, const Args&... args); - - // [format.formatter], formatter - template<> struct formatter<char, char>; - template<> struct formatter<char, wchar_t>; - template<> struct formatter<wchar_t, wchar_t>; - - template<> struct formatter<charT*, charT>; - template<> struct formatter<const charT*, charT>; - template<size_t N> struct formatter<const charT[N], charT>; - template<class traits, class Allocator> - struct formatter<basic_string<charT, traits, Allocator>, charT>; - template<class traits> - struct formatter<basic_string_view<charT, traits>, charT>; - - // [format.parse.ctx], class template basic_format_parse_context - template<class charT> - class basic_format_parse_context { - public: - using char_type = charT; - using const_iterator = typename basic_string_view<charT>::const_iterator; - using iterator = const_iterator; - - private: - iterator begin_; // exposition only - iterator end_; // exposition only - enum indexing { unknown, manual, automatic }; // exposition only - indexing indexing_; // exposition only - size_t next_arg_id_; // exposition only - size_t num_args_; // exposition only - - public: - constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt, - size_t num_args = 0) noexcept; - basic_format_parse_context(const basic_format_parse_context&) = delete; - basic_format_parse_context& operator=(const basic_format_parse_context&) = delete; - - constexpr const_iterator begin() const noexcept; - constexpr const_iterator end() const noexcept; - constexpr void advance_to(const_iterator it); - - constexpr size_t next_arg_id(); - constexpr void check_arg_id(size_t id); - }; - using format_parse_context = basic_format_parse_context<char>; - using wformat_parse_context = basic_format_parse_context<wchar_t>; - - // [format.arguments], arguments - // [format.arg], class template basic_format_arg - template<class Context> - class basic_format_arg { - public: - class handle; - - private: - using char_type = typename Context::char_type; // exposition only - - variant<monostate, bool, char_type, - int, unsigned int, long long int, unsigned long long int, - float, double, long double, - const char_type*, basic_string_view<char_type>, - const void*, handle> value; // exposition only - - template<class T> explicit basic_format_arg(const T& v) noexcept; // exposition only - explicit basic_format_arg(float n) noexcept; // exposition only - explicit basic_format_arg(double n) noexcept; // exposition only - explicit basic_format_arg(long double n) noexcept; // exposition only - explicit basic_format_arg(const char_type* s); // exposition only - - template<class traits> - explicit basic_format_arg( - basic_string_view<char_type, traits> s) noexcept; // exposition only - - template<class traits, class Allocator> - explicit basic_format_arg( - const basic_string<char_type, traits, Allocator>& s) noexcept; // exposition only - - explicit basic_format_arg(nullptr_t) noexcept; // exposition only - - template<class T> - explicit basic_format_arg(const T* p) noexcept; // exposition only - - public: - basic_format_arg() noexcept; - - explicit operator bool() const noexcept; - }; - - template<class Visitor, class Context> - see below visit_format_arg(Visitor&& vis, basic_format_arg<Context> arg); - - // [format.arg.store], class template format-arg-store - template<class Context, class... Args> - struct format-arg-store { // exposition only - array<basic_format_arg<Context>, sizeof...(Args)> args; - }; - - template<class Context = format_context, class... Args> - format-arg-store<Context, Args...> - make_format_args(const Args&... args); - template<class... Args> - format-arg-store<wformat_context, Args...> - make_wformat_args(const Args&... args); - - // [format.error], class format_error - class format_error : public runtime_error { - public: - explicit format_error(const string& what_arg); - explicit format_error(const char* what_arg); - }; - - // [format.parse.ctx], class template basic_format_parse_context - template<class charT> - class basic_format_parse_context { - public: - using char_type = charT; - using const_iterator = typename basic_string_view<charT>::const_iterator; - using iterator = const_iterator; - - private: - iterator begin_; // exposition only - iterator end_; // exposition only - enum indexing { unknown, manual, automatic }; // exposition only - indexing indexing_; // exposition only - size_t next_arg_id_; // exposition only - size_t num_args_; // exposition only - - public: - constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt, - size_t num_args = 0) noexcept; - basic_format_parse_context(const basic_format_parse_context&) = delete; - basic_format_parse_context& operator=(const basic_format_parse_context&) = delete; - - constexpr const_iterator begin() const noexcept; - constexpr const_iterator end() const noexcept; - constexpr void advance_to(const_iterator it); - - constexpr size_t next_arg_id(); - constexpr void check_arg_id(size_t id); - }; - using format_parse_context = basic_format_parse_context<char>; - using wformat_parse_context = basic_format_parse_context<wchar_t>; -} - -*/ - -// Make sure all feature-test macros are available. -#include <version> -// Enable the contents of the header only when libc++ was built with LIBCXX_ENABLE_INCOMPLETE_FEATURES. -#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) - -#include <__config> -#include <__debug> -#include <__format/format_arg.h> -#include <__format/format_args.h> -#include <__format/format_context.h> -#include <__format/format_error.h> -#include <__format/format_fwd.h> -#include <__format/format_parse_context.h> -#include <__format/format_string.h> -#include <__format/formatter.h> -#include <__format/formatter_bool.h> -#include <__format/formatter_char.h> -#include <__format/formatter_integer.h> -#include <__format/formatter_string.h> -#include <__format/parser_std_format_spec.h> -#include <__variant/monostate.h> -#include <array> -#include <concepts> -#include <string> -#include <string_view> -#include <type_traits> - -#ifndef _LIBCPP_HAS_NO_LOCALIZATION -#include <locale> -#endif - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header -#endif - -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if _LIBCPP_STD_VER > 17 - -// TODO FMT Remove this once we require compilers with proper C++20 support. -// If the compiler has no concepts support, the format header will be disabled. -// Without concepts support enable_if needs to be used and that too much effort -// to support compilers with partial C++20 support. -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) - -// TODO FMT Evaluate which templates should be external templates. This -// improves the efficiency of the header. However since the header is still -// under heavy development and not all classes are stable it makes no sense -// to do this optimization now. - -using format_args = basic_format_args<format_context>; -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -using wformat_args = basic_format_args<wformat_context>; -#endif - -template <class _OutIt, class _CharT> -using format_args_t = basic_format_args<basic_format_context<_OutIt, _CharT>>; - -template <class _Context, class... _Args> -struct _LIBCPP_TEMPLATE_VIS __format_arg_store { - // TODO FMT Use a built-in array. - array<basic_format_arg<_Context>, sizeof...(_Args)> __args; -}; - -template <class _Context = format_context, class... _Args> -_LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> -make_format_args(const _Args&... __args) { - return {basic_format_arg<_Context>(__args)...}; -} - -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -template <class... _Args> -_LIBCPP_HIDE_FROM_ABI __format_arg_store<wformat_context, _Args...> -make_wformat_args(const _Args&... __args) { - return _VSTD::make_format_args<wformat_context>(__args...); -} -#endif - -namespace __format { - -template <class _Tp, class _CharT> -requires(is_arithmetic_v<_Tp> && - !same_as<_Tp, bool>) struct _LIBCPP_HIDE_FROM_ABI - __formatter_arithmetic { - _LIBCPP_HIDE_FROM_ABI - auto parse(auto& __parse_ctx) -> decltype(__parse_ctx.begin()) { - // TODO FMT Implement - return __parse_ctx.begin(); - } - - _LIBCPP_HIDE_FROM_ABI - auto format(_Tp __value, auto& __ctx) -> decltype(__ctx.out()) { - return __handle_format(__value, __ctx); - } - -private: - template <class _Uv> - _LIBCPP_HIDDEN static string - __convert(_Uv __value) requires(same_as<_CharT, char>) { - return _VSTD::to_string(__value); - } -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS - template <class _Uv> - _LIBCPP_HIDDEN static wstring - __convert(_Uv __value) requires(same_as<_CharT, wchar_t>) { - return _VSTD::to_wstring(__value); - } -#endif - - template <class _Uv> - _LIBCPP_HIDDEN auto __handle_format(_Uv __value, auto& __ctx) - -> decltype(__ctx.out()) - { - // TODO FMT Implement using formatting arguments - // TODO FMT Improve PoC since using std::to_string is inefficient. - // Note the code doesn't use std::string::iterator since the unit tests - // test with debug iterators and they fail with strings created from - // std::to_string. - auto __str = __convert(__value); - auto __out_it = __ctx.out(); - for (size_t __i = 0, __e = __str.size(); __i != __e; ++__i) - *__out_it++ = __str[__i]; - return __out_it; - } -}; -} // namespace __format - -// These specializations are helper stubs and not proper formatters. -// TODO FMT Implement the proper formatter specializations. - -// Floating point types. -// TODO FMT There are no replacements for the floating point stubs due to not -// having floating point support in std::to_chars yet. These stubs aren't -// removed since they are useful for developing the real versions. -// Ultimately the stubs should be implemented properly and this code can be -// removed. -#if 0 -template <class _CharT> -struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<float, _CharT> - : public __format::__formatter_arithmetic<float, _CharT> {}; -template <class _CharT> -struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT - formatter<double, _CharT> - : public __format::__formatter_arithmetic<double, _CharT> {}; -template <class _CharT> -struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT - formatter<long double, _CharT> - : public __format::__formatter_arithmetic<long double, _CharT> {}; -#endif - -namespace __format { - -template <class _CharT, class _ParseCtx, class _Ctx> -_LIBCPP_HIDE_FROM_ABI const _CharT* -__handle_replacement_field(const _CharT* __begin, const _CharT* __end, - _ParseCtx& __parse_ctx, _Ctx& __ctx) { - __format::__parse_number_result __r = - __format::__parse_arg_id(__begin, __end, __parse_ctx); - - switch (*__r.__ptr) { - case _CharT(':'): - // The arg-id has a format-specifier, advance the input to the format-spec. - __parse_ctx.advance_to(__r.__ptr + 1); - break; - case _CharT('}'): - // The arg-id has no format-specifier. - __parse_ctx.advance_to(__r.__ptr); - break; - default: - __throw_format_error( - "The replacement field arg-id should terminate at a ':' or '}'"); - } - - _VSTD::visit_format_arg( - [&](auto __arg) { - if constexpr (same_as<decltype(__arg), monostate>) - __throw_format_error("Argument index out of bounds"); - else { - formatter<decltype(__arg), _CharT> __formatter; - __parse_ctx.advance_to(__formatter.parse(__parse_ctx)); - __ctx.advance_to(__formatter.format(__arg, __ctx)); - } - }, - __ctx.arg(__r.__value)); - - __begin = __parse_ctx.begin(); - if (__begin == __end || *__begin != _CharT('}')) - __throw_format_error("The replacement field misses a terminating '}'"); - - return ++__begin; -} - -template <class _ParseCtx, class _Ctx> -_LIBCPP_HIDE_FROM_ABI typename _Ctx::iterator -__vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) { - using _CharT = typename _ParseCtx::char_type; - static_assert(same_as<typename _Ctx::char_type, _CharT>); - - const _CharT* __begin = __parse_ctx.begin(); - const _CharT* __end = __parse_ctx.end(); - typename _Ctx::iterator __out_it = __ctx.out(); - while (__begin != __end) { - switch (*__begin) { - case _CharT('{'): - ++__begin; - if (__begin == __end) - __throw_format_error("The format string terminates at a '{'"); - - if (*__begin != _CharT('{')) [[likely]] { - __ctx.advance_to(_VSTD::move(__out_it)); - __begin = - __handle_replacement_field(__begin, __end, __parse_ctx, __ctx); - __out_it = __ctx.out(); - - // The output is written and __begin points to the next character. So - // start the next iteration. - continue; - } - // The string is an escape character. - break; - - case _CharT('}'): - ++__begin; - if (__begin == __end || *__begin != _CharT('}')) - __throw_format_error( - "The format string contains an invalid escape sequence"); - - break; - } - - // Copy the character to the output verbatim. - *__out_it++ = *__begin++; - } - return __out_it; -} - -} // namespace __format - -template <class _OutIt, class _CharT> -requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt - __vformat_to(_OutIt __out_it, basic_string_view<_CharT> __fmt, - format_args_t<type_identity_t<_OutIt>, _CharT> __args) { - return __format::__vformat_to( - basic_format_parse_context{__fmt, __args.__size()}, - _VSTD::__format_context_create(_VSTD::move(__out_it), __args)); -} - -template <output_iterator<const char&> _OutIt> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt -vformat_to(_OutIt __out_it, string_view __fmt, - format_args_t<type_identity_t<_OutIt>, char> __args) { - return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args); -} - -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -template <output_iterator<const wchar_t&> _OutIt> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt -vformat_to(_OutIt __out_it, wstring_view __fmt, - format_args_t<type_identity_t<_OutIt>, wchar_t> __args) { - return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args); -} -#endif - -template <output_iterator<const char&> _OutIt, class... _Args> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt -format_to(_OutIt __out_it, string_view __fmt, const _Args&... __args) { - return _VSTD::vformat_to( - _VSTD::move(__out_it), __fmt, - _VSTD::make_format_args<basic_format_context<_OutIt, char>>(__args...)); -} - -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -template <output_iterator<const wchar_t&> _OutIt, class... _Args> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt -format_to(_OutIt __out_it, wstring_view __fmt, const _Args&... __args) { - return _VSTD::vformat_to( - _VSTD::move(__out_it), __fmt, - _VSTD::make_format_args<basic_format_context<_OutIt, wchar_t>>( - __args...)); -} -#endif - -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string -vformat(string_view __fmt, format_args __args) { - string __res; - _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args); - return __res; -} - -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring -vformat(wstring_view __fmt, wformat_args __args) { - wstring __res; - _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args); - return __res; -} -#endif - -template <class... _Args> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string -format(string_view __fmt, const _Args&... __args) { - return _VSTD::vformat(__fmt, _VSTD::make_format_args(__args...)); -} - -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -template <class... _Args> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring -format(wstring_view __fmt, const _Args&... __args) { - return _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...)); -} -#endif - -template <class _OutIt> -struct _LIBCPP_TEMPLATE_VIS format_to_n_result { - _OutIt out; - iter_difference_t<_OutIt> size; -}; - -template <output_iterator<const char&> _OutIt, class... _Args> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> -format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, string_view __fmt, - const _Args&... __args) { - // TODO FMT Improve PoC: using std::string is inefficient. - string __str = _VSTD::vformat(__fmt, _VSTD::make_format_args(__args...)); - iter_difference_t<_OutIt> __s = __str.size(); - iter_difference_t<_OutIt> __m = - _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s); - __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it)); - return {_VSTD::move(__out_it), __s}; -} - -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -template <output_iterator<const wchar_t&> _OutIt, class... _Args> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> -format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, wstring_view __fmt, - const _Args&... __args) { - // TODO FMT Improve PoC: using std::string is inefficient. - wstring __str = _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...)); - iter_difference_t<_OutIt> __s = __str.size(); - iter_difference_t<_OutIt> __m = - _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s); - __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it)); - return {_VSTD::move(__out_it), __s}; -} -#endif - -template <class... _Args> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t -formatted_size(string_view __fmt, const _Args&... __args) { - // TODO FMT Improve PoC: using std::string is inefficient. - return _VSTD::vformat(__fmt, _VSTD::make_format_args(__args...)).size(); -} - -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -template <class... _Args> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t -formatted_size(wstring_view __fmt, const _Args&... __args) { - // TODO FMT Improve PoC: using std::string is inefficient. - return _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...)).size(); -} -#endif - -#ifndef _LIBCPP_HAS_NO_LOCALIZATION - -template <class _OutIt, class _CharT> -requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt - __vformat_to(_OutIt __out_it, locale __loc, basic_string_view<_CharT> __fmt, - format_args_t<type_identity_t<_OutIt>, _CharT> __args) { - return __format::__vformat_to( - basic_format_parse_context{__fmt, __args.__size()}, - _VSTD::__format_context_create(_VSTD::move(__out_it), __args, - _VSTD::move(__loc))); -} - -template <output_iterator<const char&> _OutIt> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt -vformat_to(_OutIt __out_it, locale __loc, string_view __fmt, - format_args_t<type_identity_t<_OutIt>, char> __args) { - return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, - __args); -} - -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -template <output_iterator<const wchar_t&> _OutIt> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt -vformat_to(_OutIt __out_it, locale __loc, wstring_view __fmt, - format_args_t<type_identity_t<_OutIt>, wchar_t> __args) { - return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, - __args); -} -#endif - -template <output_iterator<const char&> _OutIt, class... _Args> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to( - _OutIt __out_it, locale __loc, string_view __fmt, const _Args&... __args) { - return _VSTD::vformat_to( - _VSTD::move(__out_it), _VSTD::move(__loc), __fmt, - _VSTD::make_format_args<basic_format_context<_OutIt, char>>(__args...)); -} - -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -template <output_iterator<const wchar_t&> _OutIt, class... _Args> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to( - _OutIt __out_it, locale __loc, wstring_view __fmt, const _Args&... __args) { - return _VSTD::vformat_to( - _VSTD::move(__out_it), _VSTD::move(__loc), __fmt, - _VSTD::make_format_args<basic_format_context<_OutIt, wchar_t>>( - __args...)); -} -#endif - -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string -vformat(locale __loc, string_view __fmt, format_args __args) { - string __res; - _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt, - __args); - return __res; -} - -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring -vformat(locale __loc, wstring_view __fmt, wformat_args __args) { - wstring __res; - _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt, - __args); - return __res; -} -#endif - -template <class... _Args> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string -format(locale __loc, string_view __fmt, const _Args&... __args) { - return _VSTD::vformat(_VSTD::move(__loc), __fmt, - _VSTD::make_format_args(__args...)); -} - -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -template <class... _Args> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring -format(locale __loc, wstring_view __fmt, const _Args&... __args) { - return _VSTD::vformat(_VSTD::move(__loc), __fmt, - _VSTD::make_wformat_args(__args...)); -} -#endif - -template <output_iterator<const char&> _OutIt, class... _Args> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> -format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, - string_view __fmt, const _Args&... __args) { - // TODO FMT Improve PoC: using std::string is inefficient. - string __str = _VSTD::vformat(_VSTD::move(__loc), __fmt, - _VSTD::make_format_args(__args...)); - iter_difference_t<_OutIt> __s = __str.size(); - iter_difference_t<_OutIt> __m = - _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s); - __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it)); - return {_VSTD::move(__out_it), __s}; -} - -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -template <output_iterator<const wchar_t&> _OutIt, class... _Args> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> -format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, - wstring_view __fmt, const _Args&... __args) { - // TODO FMT Improve PoC: using std::string is inefficient. - wstring __str = _VSTD::vformat(_VSTD::move(__loc), __fmt, - _VSTD::make_wformat_args(__args...)); - iter_difference_t<_OutIt> __s = __str.size(); - iter_difference_t<_OutIt> __m = - _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s); - __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it)); - return {_VSTD::move(__out_it), __s}; -} -#endif - -template <class... _Args> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t -formatted_size(locale __loc, string_view __fmt, const _Args&... __args) { - // TODO FMT Improve PoC: using std::string is inefficient. - return _VSTD::vformat(_VSTD::move(__loc), __fmt, - _VSTD::make_format_args(__args...)) - .size(); -} - -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -template <class... _Args> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t -formatted_size(locale __loc, wstring_view __fmt, const _Args&... __args) { - // TODO FMT Improve PoC: using std::string is inefficient. - return _VSTD::vformat(_VSTD::move(__loc), __fmt, - _VSTD::make_wformat_args(__args...)) - .size(); -} -#endif - -#endif // _LIBCPP_HAS_NO_LOCALIZATION - -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) -#endif //_LIBCPP_STD_VER > 17 - -_LIBCPP_END_NAMESPACE_STD - -_LIBCPP_POP_MACROS - -#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) - -#endif // _LIBCPP_FORMAT +// -*- C++ -*- +//===--------------------------- format -----------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_FORMAT +#define _LIBCPP_FORMAT + +/* + +namespace std { + // [format.context], class template basic_format_context + template<class Out, class charT> + class basic_format_context { + basic_format_args<basic_format_context> args_; // exposition only + Out out_; // exposition only + + public: + using iterator = Out; + using char_type = charT; + template<class T> using formatter_type = formatter<T, charT>; + + basic_format_arg<basic_format_context> arg(size_t id) const; + std::locale locale(); + + iterator out(); + void advance_to(iterator it); + }; + using format_context = basic_format_context<unspecified, char>; + using wformat_context = basic_format_context<unspecified, wchar_t>; + + // [format.args], class template basic_format_args + template<class Context> + class basic_format_args { + size_t size_; // exposition only + const basic_format_arg<Context>* data_; // exposition only + + public: + basic_format_args() noexcept; + + template<class... Args> + basic_format_args(const format-arg-store<Context, Args...>& store) noexcept; + + basic_format_arg<Context> get(size_t i) const noexcept; + }; + using format_args = basic_format_args<format_context>; + using wformat_args = basic_format_args<wformat_context>; + + + template<class Out, class charT> + using format_args_t = basic_format_args<basic_format_context<Out, charT>>; + + // [format.functions], formatting functions + template<class... Args> + string format(string_view fmt, const Args&... args); + template<class... Args> + wstring format(wstring_view fmt, const Args&... args); + template<class... Args> + string format(const locale& loc, string_view fmt, const Args&... args); + template<class... Args> + wstring format(const locale& loc, wstring_view fmt, const Args&... args); + + string vformat(string_view fmt, format_args args); + wstring vformat(wstring_view fmt, wformat_args args); + string vformat(const locale& loc, string_view fmt, format_args args); + wstring vformat(const locale& loc, wstring_view fmt, wformat_args args); + + template<class Out, class... Args> + Out format_to(Out out, string_view fmt, const Args&... args); + template<class Out, class... Args> + Out format_to(Out out, wstring_view fmt, const Args&... args); + template<class Out, class... Args> + Out format_to(Out out, const locale& loc, string_view fmt, const Args&... args); + template<class Out, class... Args> + Out format_to(Out out, const locale& loc, wstring_view fmt, const Args&... args); + + template<class Out> + Out vformat_to(Out out, string_view fmt, + format_args_t<type_identity_t<Out>, char> args); + template<class Out> + Out vformat_to(Out out, wstring_view fmt, + format_args_t<type_identity_t<Out>, wchar_t> args); + template<class Out> + Out vformat_to(Out out, const locale& loc, string_view fmt, + format_args_t<type_identity_t<Out>, char> args); + template<class Out> + Out vformat_to(Out out, const locale& loc, wstring_view fmt, + format_args_t<type_identity_t<Out>, wchar_t> args); + + template<class Out> struct format_to_n_result { + Out out; + iter_difference_t<Out> size; + }; + + template<class Out, class... Args> + format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, + string_view fmt, const Args&... args); + template<class Out, class... Args> + format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, + wstring_view fmt, const Args&... args); + template<class Out, class... Args> + format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, + const locale& loc, string_view fmt, + const Args&... args); + template<class Out, class... Args> + format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, + const locale& loc, wstring_view fmt, + const Args&... args); + + template<class... Args> + size_t formatted_size(string_view fmt, const Args&... args); + template<class... Args> + size_t formatted_size(wstring_view fmt, const Args&... args); + template<class... Args> + size_t formatted_size(const locale& loc, string_view fmt, const Args&... args); + template<class... Args> + size_t formatted_size(const locale& loc, wstring_view fmt, const Args&... args); + + // [format.formatter], formatter + template<> struct formatter<char, char>; + template<> struct formatter<char, wchar_t>; + template<> struct formatter<wchar_t, wchar_t>; + + template<> struct formatter<charT*, charT>; + template<> struct formatter<const charT*, charT>; + template<size_t N> struct formatter<const charT[N], charT>; + template<class traits, class Allocator> + struct formatter<basic_string<charT, traits, Allocator>, charT>; + template<class traits> + struct formatter<basic_string_view<charT, traits>, charT>; + + // [format.parse.ctx], class template basic_format_parse_context + template<class charT> + class basic_format_parse_context { + public: + using char_type = charT; + using const_iterator = typename basic_string_view<charT>::const_iterator; + using iterator = const_iterator; + + private: + iterator begin_; // exposition only + iterator end_; // exposition only + enum indexing { unknown, manual, automatic }; // exposition only + indexing indexing_; // exposition only + size_t next_arg_id_; // exposition only + size_t num_args_; // exposition only + + public: + constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt, + size_t num_args = 0) noexcept; + basic_format_parse_context(const basic_format_parse_context&) = delete; + basic_format_parse_context& operator=(const basic_format_parse_context&) = delete; + + constexpr const_iterator begin() const noexcept; + constexpr const_iterator end() const noexcept; + constexpr void advance_to(const_iterator it); + + constexpr size_t next_arg_id(); + constexpr void check_arg_id(size_t id); + }; + using format_parse_context = basic_format_parse_context<char>; + using wformat_parse_context = basic_format_parse_context<wchar_t>; + + // [format.arguments], arguments + // [format.arg], class template basic_format_arg + template<class Context> + class basic_format_arg { + public: + class handle; + + private: + using char_type = typename Context::char_type; // exposition only + + variant<monostate, bool, char_type, + int, unsigned int, long long int, unsigned long long int, + float, double, long double, + const char_type*, basic_string_view<char_type>, + const void*, handle> value; // exposition only + + template<class T> explicit basic_format_arg(const T& v) noexcept; // exposition only + explicit basic_format_arg(float n) noexcept; // exposition only + explicit basic_format_arg(double n) noexcept; // exposition only + explicit basic_format_arg(long double n) noexcept; // exposition only + explicit basic_format_arg(const char_type* s); // exposition only + + template<class traits> + explicit basic_format_arg( + basic_string_view<char_type, traits> s) noexcept; // exposition only + + template<class traits, class Allocator> + explicit basic_format_arg( + const basic_string<char_type, traits, Allocator>& s) noexcept; // exposition only + + explicit basic_format_arg(nullptr_t) noexcept; // exposition only + + template<class T> + explicit basic_format_arg(const T* p) noexcept; // exposition only + + public: + basic_format_arg() noexcept; + + explicit operator bool() const noexcept; + }; + + template<class Visitor, class Context> + see below visit_format_arg(Visitor&& vis, basic_format_arg<Context> arg); + + // [format.arg.store], class template format-arg-store + template<class Context, class... Args> + struct format-arg-store { // exposition only + array<basic_format_arg<Context>, sizeof...(Args)> args; + }; + + template<class Context = format_context, class... Args> + format-arg-store<Context, Args...> + make_format_args(const Args&... args); + template<class... Args> + format-arg-store<wformat_context, Args...> + make_wformat_args(const Args&... args); + + // [format.error], class format_error + class format_error : public runtime_error { + public: + explicit format_error(const string& what_arg); + explicit format_error(const char* what_arg); + }; + + // [format.parse.ctx], class template basic_format_parse_context + template<class charT> + class basic_format_parse_context { + public: + using char_type = charT; + using const_iterator = typename basic_string_view<charT>::const_iterator; + using iterator = const_iterator; + + private: + iterator begin_; // exposition only + iterator end_; // exposition only + enum indexing { unknown, manual, automatic }; // exposition only + indexing indexing_; // exposition only + size_t next_arg_id_; // exposition only + size_t num_args_; // exposition only + + public: + constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt, + size_t num_args = 0) noexcept; + basic_format_parse_context(const basic_format_parse_context&) = delete; + basic_format_parse_context& operator=(const basic_format_parse_context&) = delete; + + constexpr const_iterator begin() const noexcept; + constexpr const_iterator end() const noexcept; + constexpr void advance_to(const_iterator it); + + constexpr size_t next_arg_id(); + constexpr void check_arg_id(size_t id); + }; + using format_parse_context = basic_format_parse_context<char>; + using wformat_parse_context = basic_format_parse_context<wchar_t>; +} + +*/ + +// Make sure all feature-test macros are available. +#include <version> +// Enable the contents of the header only when libc++ was built with LIBCXX_ENABLE_INCOMPLETE_FEATURES. +#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) + +#include <__config> +#include <__debug> +#include <__format/format_arg.h> +#include <__format/format_args.h> +#include <__format/format_context.h> +#include <__format/format_error.h> +#include <__format/format_fwd.h> +#include <__format/format_parse_context.h> +#include <__format/format_string.h> +#include <__format/formatter.h> +#include <__format/formatter_bool.h> +#include <__format/formatter_char.h> +#include <__format/formatter_integer.h> +#include <__format/formatter_string.h> +#include <__format/parser_std_format_spec.h> +#include <__variant/monostate.h> +#include <array> +#include <concepts> +#include <string> +#include <string_view> +#include <type_traits> + +#ifndef _LIBCPP_HAS_NO_LOCALIZATION +#include <locale> +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +// TODO FMT Remove this once we require compilers with proper C++20 support. +// If the compiler has no concepts support, the format header will be disabled. +// Without concepts support enable_if needs to be used and that too much effort +// to support compilers with partial C++20 support. +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +// TODO FMT Evaluate which templates should be external templates. This +// improves the efficiency of the header. However since the header is still +// under heavy development and not all classes are stable it makes no sense +// to do this optimization now. + +using format_args = basic_format_args<format_context>; +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +using wformat_args = basic_format_args<wformat_context>; +#endif + +template <class _OutIt, class _CharT> +using format_args_t = basic_format_args<basic_format_context<_OutIt, _CharT>>; + +template <class _Context, class... _Args> +struct _LIBCPP_TEMPLATE_VIS __format_arg_store { + // TODO FMT Use a built-in array. + array<basic_format_arg<_Context>, sizeof...(_Args)> __args; +}; + +template <class _Context = format_context, class... _Args> +_LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> +make_format_args(const _Args&... __args) { + return {basic_format_arg<_Context>(__args)...}; +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template <class... _Args> +_LIBCPP_HIDE_FROM_ABI __format_arg_store<wformat_context, _Args...> +make_wformat_args(const _Args&... __args) { + return _VSTD::make_format_args<wformat_context>(__args...); +} +#endif + +namespace __format { + +template <class _Tp, class _CharT> +requires(is_arithmetic_v<_Tp> && + !same_as<_Tp, bool>) struct _LIBCPP_HIDE_FROM_ABI + __formatter_arithmetic { + _LIBCPP_HIDE_FROM_ABI + auto parse(auto& __parse_ctx) -> decltype(__parse_ctx.begin()) { + // TODO FMT Implement + return __parse_ctx.begin(); + } + + _LIBCPP_HIDE_FROM_ABI + auto format(_Tp __value, auto& __ctx) -> decltype(__ctx.out()) { + return __handle_format(__value, __ctx); + } + +private: + template <class _Uv> + _LIBCPP_HIDDEN static string + __convert(_Uv __value) requires(same_as<_CharT, char>) { + return _VSTD::to_string(__value); + } +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS + template <class _Uv> + _LIBCPP_HIDDEN static wstring + __convert(_Uv __value) requires(same_as<_CharT, wchar_t>) { + return _VSTD::to_wstring(__value); + } +#endif + + template <class _Uv> + _LIBCPP_HIDDEN auto __handle_format(_Uv __value, auto& __ctx) + -> decltype(__ctx.out()) + { + // TODO FMT Implement using formatting arguments + // TODO FMT Improve PoC since using std::to_string is inefficient. + // Note the code doesn't use std::string::iterator since the unit tests + // test with debug iterators and they fail with strings created from + // std::to_string. + auto __str = __convert(__value); + auto __out_it = __ctx.out(); + for (size_t __i = 0, __e = __str.size(); __i != __e; ++__i) + *__out_it++ = __str[__i]; + return __out_it; + } +}; +} // namespace __format + +// These specializations are helper stubs and not proper formatters. +// TODO FMT Implement the proper formatter specializations. + +// Floating point types. +// TODO FMT There are no replacements for the floating point stubs due to not +// having floating point support in std::to_chars yet. These stubs aren't +// removed since they are useful for developing the real versions. +// Ultimately the stubs should be implemented properly and this code can be +// removed. +#if 0 +template <class _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<float, _CharT> + : public __format::__formatter_arithmetic<float, _CharT> {}; +template <class _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT + formatter<double, _CharT> + : public __format::__formatter_arithmetic<double, _CharT> {}; +template <class _CharT> +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT + formatter<long double, _CharT> + : public __format::__formatter_arithmetic<long double, _CharT> {}; +#endif + +namespace __format { + +template <class _CharT, class _ParseCtx, class _Ctx> +_LIBCPP_HIDE_FROM_ABI const _CharT* +__handle_replacement_field(const _CharT* __begin, const _CharT* __end, + _ParseCtx& __parse_ctx, _Ctx& __ctx) { + __format::__parse_number_result __r = + __format::__parse_arg_id(__begin, __end, __parse_ctx); + + switch (*__r.__ptr) { + case _CharT(':'): + // The arg-id has a format-specifier, advance the input to the format-spec. + __parse_ctx.advance_to(__r.__ptr + 1); + break; + case _CharT('}'): + // The arg-id has no format-specifier. + __parse_ctx.advance_to(__r.__ptr); + break; + default: + __throw_format_error( + "The replacement field arg-id should terminate at a ':' or '}'"); + } + + _VSTD::visit_format_arg( + [&](auto __arg) { + if constexpr (same_as<decltype(__arg), monostate>) + __throw_format_error("Argument index out of bounds"); + else { + formatter<decltype(__arg), _CharT> __formatter; + __parse_ctx.advance_to(__formatter.parse(__parse_ctx)); + __ctx.advance_to(__formatter.format(__arg, __ctx)); + } + }, + __ctx.arg(__r.__value)); + + __begin = __parse_ctx.begin(); + if (__begin == __end || *__begin != _CharT('}')) + __throw_format_error("The replacement field misses a terminating '}'"); + + return ++__begin; +} + +template <class _ParseCtx, class _Ctx> +_LIBCPP_HIDE_FROM_ABI typename _Ctx::iterator +__vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) { + using _CharT = typename _ParseCtx::char_type; + static_assert(same_as<typename _Ctx::char_type, _CharT>); + + const _CharT* __begin = __parse_ctx.begin(); + const _CharT* __end = __parse_ctx.end(); + typename _Ctx::iterator __out_it = __ctx.out(); + while (__begin != __end) { + switch (*__begin) { + case _CharT('{'): + ++__begin; + if (__begin == __end) + __throw_format_error("The format string terminates at a '{'"); + + if (*__begin != _CharT('{')) [[likely]] { + __ctx.advance_to(_VSTD::move(__out_it)); + __begin = + __handle_replacement_field(__begin, __end, __parse_ctx, __ctx); + __out_it = __ctx.out(); + + // The output is written and __begin points to the next character. So + // start the next iteration. + continue; + } + // The string is an escape character. + break; + + case _CharT('}'): + ++__begin; + if (__begin == __end || *__begin != _CharT('}')) + __throw_format_error( + "The format string contains an invalid escape sequence"); + + break; + } + + // Copy the character to the output verbatim. + *__out_it++ = *__begin++; + } + return __out_it; +} + +} // namespace __format + +template <class _OutIt, class _CharT> +requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt + __vformat_to(_OutIt __out_it, basic_string_view<_CharT> __fmt, + format_args_t<type_identity_t<_OutIt>, _CharT> __args) { + return __format::__vformat_to( + basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(_VSTD::move(__out_it), __args)); +} + +template <output_iterator<const char&> _OutIt> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt +vformat_to(_OutIt __out_it, string_view __fmt, + format_args_t<type_identity_t<_OutIt>, char> __args) { + return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template <output_iterator<const wchar_t&> _OutIt> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt +vformat_to(_OutIt __out_it, wstring_view __fmt, + format_args_t<type_identity_t<_OutIt>, wchar_t> __args) { + return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args); +} +#endif + +template <output_iterator<const char&> _OutIt, class... _Args> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt +format_to(_OutIt __out_it, string_view __fmt, const _Args&... __args) { + return _VSTD::vformat_to( + _VSTD::move(__out_it), __fmt, + _VSTD::make_format_args<basic_format_context<_OutIt, char>>(__args...)); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template <output_iterator<const wchar_t&> _OutIt, class... _Args> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt +format_to(_OutIt __out_it, wstring_view __fmt, const _Args&... __args) { + return _VSTD::vformat_to( + _VSTD::move(__out_it), __fmt, + _VSTD::make_format_args<basic_format_context<_OutIt, wchar_t>>( + __args...)); +} +#endif + +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string +vformat(string_view __fmt, format_args __args) { + string __res; + _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args); + return __res; +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring +vformat(wstring_view __fmt, wformat_args __args) { + wstring __res; + _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args); + return __res; +} +#endif + +template <class... _Args> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string +format(string_view __fmt, const _Args&... __args) { + return _VSTD::vformat(__fmt, _VSTD::make_format_args(__args...)); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template <class... _Args> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring +format(wstring_view __fmt, const _Args&... __args) { + return _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...)); +} +#endif + +template <class _OutIt> +struct _LIBCPP_TEMPLATE_VIS format_to_n_result { + _OutIt out; + iter_difference_t<_OutIt> size; +}; + +template <output_iterator<const char&> _OutIt, class... _Args> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> +format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, string_view __fmt, + const _Args&... __args) { + // TODO FMT Improve PoC: using std::string is inefficient. + string __str = _VSTD::vformat(__fmt, _VSTD::make_format_args(__args...)); + iter_difference_t<_OutIt> __s = __str.size(); + iter_difference_t<_OutIt> __m = + _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s); + __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it)); + return {_VSTD::move(__out_it), __s}; +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template <output_iterator<const wchar_t&> _OutIt, class... _Args> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> +format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, wstring_view __fmt, + const _Args&... __args) { + // TODO FMT Improve PoC: using std::string is inefficient. + wstring __str = _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...)); + iter_difference_t<_OutIt> __s = __str.size(); + iter_difference_t<_OutIt> __m = + _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s); + __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it)); + return {_VSTD::move(__out_it), __s}; +} +#endif + +template <class... _Args> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t +formatted_size(string_view __fmt, const _Args&... __args) { + // TODO FMT Improve PoC: using std::string is inefficient. + return _VSTD::vformat(__fmt, _VSTD::make_format_args(__args...)).size(); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template <class... _Args> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t +formatted_size(wstring_view __fmt, const _Args&... __args) { + // TODO FMT Improve PoC: using std::string is inefficient. + return _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...)).size(); +} +#endif + +#ifndef _LIBCPP_HAS_NO_LOCALIZATION + +template <class _OutIt, class _CharT> +requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt + __vformat_to(_OutIt __out_it, locale __loc, basic_string_view<_CharT> __fmt, + format_args_t<type_identity_t<_OutIt>, _CharT> __args) { + return __format::__vformat_to( + basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(_VSTD::move(__out_it), __args, + _VSTD::move(__loc))); +} + +template <output_iterator<const char&> _OutIt> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt +vformat_to(_OutIt __out_it, locale __loc, string_view __fmt, + format_args_t<type_identity_t<_OutIt>, char> __args) { + return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, + __args); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template <output_iterator<const wchar_t&> _OutIt> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt +vformat_to(_OutIt __out_it, locale __loc, wstring_view __fmt, + format_args_t<type_identity_t<_OutIt>, wchar_t> __args) { + return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, + __args); +} +#endif + +template <output_iterator<const char&> _OutIt, class... _Args> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to( + _OutIt __out_it, locale __loc, string_view __fmt, const _Args&... __args) { + return _VSTD::vformat_to( + _VSTD::move(__out_it), _VSTD::move(__loc), __fmt, + _VSTD::make_format_args<basic_format_context<_OutIt, char>>(__args...)); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template <output_iterator<const wchar_t&> _OutIt, class... _Args> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to( + _OutIt __out_it, locale __loc, wstring_view __fmt, const _Args&... __args) { + return _VSTD::vformat_to( + _VSTD::move(__out_it), _VSTD::move(__loc), __fmt, + _VSTD::make_format_args<basic_format_context<_OutIt, wchar_t>>( + __args...)); +} +#endif + +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string +vformat(locale __loc, string_view __fmt, format_args __args) { + string __res; + _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt, + __args); + return __res; +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring +vformat(locale __loc, wstring_view __fmt, wformat_args __args) { + wstring __res; + _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt, + __args); + return __res; +} +#endif + +template <class... _Args> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string +format(locale __loc, string_view __fmt, const _Args&... __args) { + return _VSTD::vformat(_VSTD::move(__loc), __fmt, + _VSTD::make_format_args(__args...)); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template <class... _Args> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring +format(locale __loc, wstring_view __fmt, const _Args&... __args) { + return _VSTD::vformat(_VSTD::move(__loc), __fmt, + _VSTD::make_wformat_args(__args...)); +} +#endif + +template <output_iterator<const char&> _OutIt, class... _Args> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> +format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, + string_view __fmt, const _Args&... __args) { + // TODO FMT Improve PoC: using std::string is inefficient. + string __str = _VSTD::vformat(_VSTD::move(__loc), __fmt, + _VSTD::make_format_args(__args...)); + iter_difference_t<_OutIt> __s = __str.size(); + iter_difference_t<_OutIt> __m = + _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s); + __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it)); + return {_VSTD::move(__out_it), __s}; +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template <output_iterator<const wchar_t&> _OutIt, class... _Args> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> +format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, + wstring_view __fmt, const _Args&... __args) { + // TODO FMT Improve PoC: using std::string is inefficient. + wstring __str = _VSTD::vformat(_VSTD::move(__loc), __fmt, + _VSTD::make_wformat_args(__args...)); + iter_difference_t<_OutIt> __s = __str.size(); + iter_difference_t<_OutIt> __m = + _VSTD::clamp(__n, iter_difference_t<_OutIt>(0), __s); + __out_it = _VSTD::copy_n(__str.begin(), __m, _VSTD::move(__out_it)); + return {_VSTD::move(__out_it), __s}; +} +#endif + +template <class... _Args> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t +formatted_size(locale __loc, string_view __fmt, const _Args&... __args) { + // TODO FMT Improve PoC: using std::string is inefficient. + return _VSTD::vformat(_VSTD::move(__loc), __fmt, + _VSTD::make_format_args(__args...)) + .size(); +} + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +template <class... _Args> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t +formatted_size(locale __loc, wstring_view __fmt, const _Args&... __args) { + // TODO FMT Improve PoC: using std::string is inefficient. + return _VSTD::vformat(_VSTD::move(__loc), __fmt, + _VSTD::make_wformat_args(__args...)) + .size(); +} +#endif + +#endif // _LIBCPP_HAS_NO_LOCALIZATION + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) +#endif //_LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) + +#endif // _LIBCPP_FORMAT |