diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /contrib/libs/cxxsupp/libcxx/include/format | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'contrib/libs/cxxsupp/libcxx/include/format')
-rw-r--r-- | contrib/libs/cxxsupp/libcxx/include/format | 776 |
1 files changed, 776 insertions, 0 deletions
diff --git a/contrib/libs/cxxsupp/libcxx/include/format b/contrib/libs/cxxsupp/libcxx/include/format new file mode 100644 index 0000000000..19f642716b --- /dev/null +++ b/contrib/libs/cxxsupp/libcxx/include/format @@ -0,0 +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 |