Please use GitHub pull requests for new patches. Avoid migrating existing patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
libcxx/include/format
Show First 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | template<class... Args> | ||||
basic_format_args(const format-arg-store<Context, Args...>& store) noexcept; | basic_format_args(const format-arg-store<Context, Args...>& store) noexcept; | ||||
basic_format_arg<Context> get(size_t i) const noexcept; | basic_format_arg<Context> get(size_t i) const noexcept; | ||||
}; | }; | ||||
using format_args = basic_format_args<format_context>; | using format_args = basic_format_args<format_context>; | ||||
using wformat_args = basic_format_args<wformat_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 | // [format.functions], formatting functions | ||||
template<class... Args> | template<class... Args> | ||||
string format(string_view fmt, const Args&... args); | string format(string_view fmt, const Args&... args); | ||||
template<class... Args> | template<class... Args> | ||||
wstring format(wstring_view fmt, const Args&... args); | wstring format(wstring_view fmt, const Args&... args); | ||||
template<class... Args> | template<class... Args> | ||||
string format(const locale& loc, string_view fmt, const Args&... args); | string format(const locale& loc, string_view fmt, const Args&... args); | ||||
template<class... Args> | template<class... Args> | ||||
Show All 9 Lines | namespace std { | ||||
template<class Out, class... Args> | template<class Out, class... Args> | ||||
Out format_to(Out out, wstring_view fmt, const Args&... args); | Out format_to(Out out, wstring_view fmt, const Args&... args); | ||||
template<class Out, class... Args> | template<class Out, class... Args> | ||||
Out format_to(Out out, const locale& loc, string_view fmt, const Args&... args); | Out format_to(Out out, const locale& loc, string_view fmt, const Args&... args); | ||||
template<class Out, class... Args> | template<class Out, class... Args> | ||||
Out format_to(Out out, const locale& loc, wstring_view fmt, const Args&... args); | Out format_to(Out out, const locale& loc, wstring_view fmt, const Args&... args); | ||||
template<class Out> | template<class Out> | ||||
Out vformat_to(Out out, string_view fmt, | Out vformat_to(Out out, string_view fmt, format_args args); | ||||
format_args_t<type_identity_t<Out>, char> args); | |||||
template<class Out> | template<class Out> | ||||
Out vformat_to(Out out, wstring_view fmt, | Out vformat_to(Out out, wstring_view fmt, wformat_args args); | ||||
format_args_t<type_identity_t<Out>, wchar_t> args); | |||||
template<class Out> | template<class Out> | ||||
Out vformat_to(Out out, const locale& loc, string_view fmt, | Out vformat_to(Out out, const locale& loc, string_view fmt, | ||||
format_args_t<type_identity_t<Out>, char> args); | format_args char> args); | ||||
template<class Out> | template<class Out> | ||||
Out vformat_to(Out out, const locale& loc, wstring_view fmt, | Out vformat_to(Out out, const locale& loc, wstring_view fmt, | ||||
format_args_t<type_identity_t<Out>, wchar_t> args); | wformat_args args); | ||||
template<class Out> struct format_to_n_result { | template<class Out> struct format_to_n_result { | ||||
Out out; | Out out; | ||||
iter_difference_t<Out> size; | iter_difference_t<Out> size; | ||||
}; | }; | ||||
template<class Out, class... Args> | template<class Out, class... Args> | ||||
format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, | format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, | ||||
▲ Show 20 Lines • Show All 214 Lines • ▼ Show 20 Lines | |||||
// TODO FMT Evaluate which templates should be external templates. This | // TODO FMT Evaluate which templates should be external templates. This | ||||
// improves the efficiency of the header. However since the header is still | // 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 | // under heavy development and not all classes are stable it makes no sense | ||||
// to do this optimization now. | // to do this optimization now. | ||||
using format_args = basic_format_args<format_context>; | using format_args = basic_format_args<format_context>; | ||||
using wformat_args = basic_format_args<wformat_context>; | using wformat_args = basic_format_args<wformat_context>; | ||||
template <class _OutIt, class _CharT> | |||||
using format_args_t = basic_format_args<basic_format_context<_OutIt, _CharT>>; | |||||
template <class _Context, class... _Args> | template <class _Context, class... _Args> | ||||
struct _LIBCPP_TEMPLATE_VIS __format_arg_store { | struct _LIBCPP_TEMPLATE_VIS __format_arg_store { | ||||
// TODO FMT Use a built-in array. | // TODO FMT Use a built-in array. | ||||
array<basic_format_arg<_Context>, sizeof...(_Args)> __args; | array<basic_format_arg<_Context>, sizeof...(_Args)> __args; | ||||
}; | }; | ||||
template <class _Context = format_context, class... _Args> | template <class _Context = format_context, class... _Args> | ||||
_LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> | _LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> | ||||
Show All 32 Lines | private: | ||||
template <class _Uv> | template <class _Uv> | ||||
_LIBCPP_HIDDEN static wstring | _LIBCPP_HIDDEN static wstring | ||||
__convert(_Uv __value) requires(same_as<_CharT, wchar_t>) { | __convert(_Uv __value) requires(same_as<_CharT, wchar_t>) { | ||||
return _VSTD::to_wstring(__value); | return _VSTD::to_wstring(__value); | ||||
} | } | ||||
template <class _Uv> | template <class _Uv> | ||||
_LIBCPP_HIDDEN auto __handle_format(_Uv __value, auto& __ctx) | _LIBCPP_HIDDEN auto __handle_format(_Uv __value, auto& __ctx) | ||||
-> decltype(__ctx.out()) | -> decltype(__ctx.out()) { | ||||
{ | |||||
// TODO FMT Implement using formatting arguments | // TODO FMT Implement using formatting arguments | ||||
// TODO FMT Improve PoC since using std::to_string is inefficient. | // TODO FMT Improve PoC since using std::to_string is inefficient. | ||||
// Note the code doesn't use std::string::iterator since the unit tests | // Note the code doesn't use std::string::iterator since the unit tests | ||||
// test with debug iterators and they fail with strings created from | // test with debug iterators and they fail with strings created from | ||||
// std::to_string. | // std::to_string. | ||||
auto __str = __convert(__value); | auto __str = __convert(__value); | ||||
auto __out_it = __ctx.out(); | auto __out_it = __ctx.out(); | ||||
for (size_t __i = 0, __e = __str.size(); __i != __e; ++__i) | for (size_t __i = 0, __e = __str.size(); __i != __e; ++__i) | ||||
▲ Show 20 Lines • Show All 109 Lines • ▼ Show 20 Lines | while (__begin != __end) { | ||||
// Copy the character to the output verbatim. | // Copy the character to the output verbatim. | ||||
*__out_it++ = *__begin++; | *__out_it++ = *__begin++; | ||||
} | } | ||||
return __out_it; | return __out_it; | ||||
} | } | ||||
} // namespace __format | } // namespace __format | ||||
template <class _OutIt, class _CharT> | template <class _OutIt, class _CharT, class _FormatOutIt> | ||||
requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt | requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt | ||||
__vformat_to(_OutIt __out_it, basic_string_view<_CharT> __fmt, | __vformat_to_wrapped( | ||||
format_args_t<type_identity_t<_OutIt>, _CharT> __args) { | _OutIt __out_it, basic_string_view<_CharT> __fmt, | ||||
return __format::__vformat_to( | basic_format_args<basic_format_context<_FormatOutIt, _CharT>> __args) { | ||||
basic_string<_CharT> __str; | |||||
_VSTD::__format::__vformat_to( | |||||
vitaut: Is there a good reason to introduce this function as opposed to having this logic directly in… | |||||
It was easier for testing, but it seems during cleaning up the patch I never moved it back. Will do so. Mordante: It was easier for testing, but it seems during cleaning up the patch I never moved it back. | |||||
basic_format_parse_context{__fmt, __args.__size()}, | |||||
_VSTD::__format_context_create(_VSTD::back_inserter(__str), __args)); | |||||
return _VSTD::copy_n(__str.begin(), __str.size(), _VSTD::move(__out_it)); | |||||
} | |||||
template <class _OutIt, class _CharT, class _FormatOutIt> | |||||
requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt | |||||
__vformat_to( | |||||
_OutIt __out_it, basic_string_view<_CharT> __fmt, | |||||
basic_format_args<basic_format_context<_FormatOutIt, _CharT>> __args) { | |||||
if constexpr (same_as<_OutIt, _FormatOutIt>) | |||||
return _VSTD::__format::__vformat_to( | |||||
basic_format_parse_context{__fmt, __args.__size()}, | basic_format_parse_context{__fmt, __args.__size()}, | ||||
_VSTD::__format_context_create(_VSTD::move(__out_it), __args)); | _VSTD::__format_context_create(_VSTD::move(__out_it), __args)); | ||||
else | |||||
return _VSTD::__vformat_to_wrapped(_VSTD::move(__out_it), __fmt, __args); | |||||
} | } | ||||
template <output_iterator<const char&> _OutIt> | template <output_iterator<const char&> _OutIt> | ||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt | ||||
vformat_to(_OutIt __out_it, string_view __fmt, | vformat_to(_OutIt __out_it, string_view __fmt, format_args __args) { | ||||
Maybe force inline format_to* / vformat_to* to make debug codegen less horrible (https://godbolt.org/z/Kah4sqY5z) and since they are just trivial wrappers around __vformat_to*? vitaut: Maybe force inline `format_to*` / `vformat_to*` to make debug codegen less horrible (https… | |||||
Note that without this code bloat prevention isn't working even with -O2 right now which is quite worrying: https://godbolt.org/z/1dn836jzG. vitaut: Note that without this code bloat prevention isn't working even with -O2 right now which is… | |||||
I've added force inlines. I still want to look at the size of the generated code at a later point in time. I think it makes more sense to look at after the all papers and LWG issues have been implemented. Mordante: I've added force inlines. I still want to look at the size of the generated code at a later… | |||||
format_args_t<type_identity_t<_OutIt>, char> __args) { | |||||
return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args); | return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args); | ||||
} | } | ||||
template <output_iterator<const wchar_t&> _OutIt> | template <output_iterator<const wchar_t&> _OutIt> | ||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt | ||||
vformat_to(_OutIt __out_it, wstring_view __fmt, | vformat_to(_OutIt __out_it, wstring_view __fmt, wformat_args __args) { | ||||
format_args_t<type_identity_t<_OutIt>, wchar_t> __args) { | |||||
return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args); | return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args); | ||||
} | } | ||||
template <output_iterator<const char&> _OutIt, class... _Args> | template <output_iterator<const char&> _OutIt, class... _Args> | ||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt | ||||
format_to(_OutIt __out_it, string_view __fmt, const _Args&... __args) { | format_to(_OutIt __out_it, string_view __fmt, const _Args&... __args) { | ||||
return _VSTD::vformat_to( | return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt, | ||||
_VSTD::move(__out_it), __fmt, | _VSTD::make_format_args(__args...)); | ||||
_VSTD::make_format_args<basic_format_context<_OutIt, char>>(__args...)); | |||||
} | } | ||||
template <output_iterator<const wchar_t&> _OutIt, class... _Args> | template <output_iterator<const wchar_t&> _OutIt, class... _Args> | ||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt | ||||
format_to(_OutIt __out_it, wstring_view __fmt, const _Args&... __args) { | format_to(_OutIt __out_it, wstring_view __fmt, const _Args&... __args) { | ||||
return _VSTD::vformat_to( | return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt, | ||||
_VSTD::move(__out_it), __fmt, | _VSTD::make_wformat_args(__args...)); | ||||
_VSTD::make_format_args<basic_format_context<_OutIt, wchar_t>>( | |||||
__args...)); | |||||
} | } | ||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string | ||||
vformat(string_view __fmt, format_args __args) { | vformat(string_view __fmt, format_args __args) { | ||||
string __res; | string __res; | ||||
_VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args); | _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args); | ||||
return __res; | return __res; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | |||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t | ||||
formatted_size(wstring_view __fmt, const _Args&... __args) { | formatted_size(wstring_view __fmt, const _Args&... __args) { | ||||
// TODO FMT Improve PoC: using std::string is inefficient. | // TODO FMT Improve PoC: using std::string is inefficient. | ||||
return _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...)).size(); | return _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...)).size(); | ||||
} | } | ||||
#ifndef _LIBCPP_HAS_NO_LOCALIZATION | #ifndef _LIBCPP_HAS_NO_LOCALIZATION | ||||
template <class _OutIt, class _CharT> | template <class _OutIt, class _CharT, class _FormatOutIt> | ||||
requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt | requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt | ||||
__vformat_to(_OutIt __out_it, locale __loc, basic_string_view<_CharT> __fmt, | __vformat_to_wrapped( | ||||
format_args_t<type_identity_t<_OutIt>, _CharT> __args) { | _OutIt __out_it, locale __loc, basic_string_view<_CharT> __fmt, | ||||
return __format::__vformat_to( | basic_format_args<basic_format_context<_FormatOutIt, _CharT>> __args) { | ||||
basic_string<_CharT> __str; | |||||
_VSTD::__format::__vformat_to( | |||||
basic_format_parse_context{__fmt, __args.__size()}, | |||||
_VSTD::__format_context_create(_VSTD::back_inserter(__str), __args, | |||||
_VSTD::move(__loc))); | |||||
return _VSTD::copy_n(__str.begin(), __str.size(), _VSTD::move(__out_it)); | |||||
} | |||||
template <class _OutIt, class _CharT, class _FormatOutIt> | |||||
requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt | |||||
__vformat_to( | |||||
_OutIt __out_it, locale __loc, basic_string_view<_CharT> __fmt, | |||||
basic_format_args<basic_format_context<_FormatOutIt, _CharT>> __args) { | |||||
if constexpr (same_as<_OutIt, _FormatOutIt>) | |||||
return _VSTD::__format::__vformat_to( | |||||
basic_format_parse_context{__fmt, __args.__size()}, | basic_format_parse_context{__fmt, __args.__size()}, | ||||
_VSTD::__format_context_create(_VSTD::move(__out_it), __args, | _VSTD::__format_context_create(_VSTD::move(__out_it), __args, | ||||
_VSTD::move(__loc))); | _VSTD::move(__loc))); | ||||
else | |||||
return _VSTD::__vformat_to_wrapped(_VSTD::move(__out_it), | |||||
_VSTD::move(__loc), __fmt, __args); | |||||
} | } | ||||
template <output_iterator<const char&> _OutIt> | template <output_iterator<const char&> _OutIt> | ||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt vformat_to( | ||||
vformat_to(_OutIt __out_it, locale __loc, string_view __fmt, | _OutIt __out_it, locale __loc, string_view __fmt, format_args __args) { | ||||
format_args_t<type_identity_t<_OutIt>, char> __args) { | |||||
return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, | return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, | ||||
__args); | __args); | ||||
} | } | ||||
template <output_iterator<const wchar_t&> _OutIt> | template <output_iterator<const wchar_t&> _OutIt> | ||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt vformat_to( | ||||
vformat_to(_OutIt __out_it, locale __loc, wstring_view __fmt, | _OutIt __out_it, locale __loc, wstring_view __fmt, wformat_args __args) { | ||||
format_args_t<type_identity_t<_OutIt>, wchar_t> __args) { | |||||
return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, | return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, | ||||
__args); | __args); | ||||
} | } | ||||
template <output_iterator<const char&> _OutIt, class... _Args> | template <output_iterator<const char&> _OutIt, class... _Args> | ||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to( | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to( | ||||
_OutIt __out_it, locale __loc, string_view __fmt, const _Args&... __args) { | _OutIt __out_it, locale __loc, string_view __fmt, const _Args&... __args) { | ||||
return _VSTD::vformat_to( | return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, | ||||
_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, | _VSTD::make_format_args(__args...)); | ||||
_VSTD::make_format_args<basic_format_context<_OutIt, char>>(__args...)); | |||||
} | } | ||||
template <output_iterator<const wchar_t&> _OutIt, class... _Args> | template <output_iterator<const wchar_t&> _OutIt, class... _Args> | ||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to( | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt format_to( | ||||
_OutIt __out_it, locale __loc, wstring_view __fmt, const _Args&... __args) { | _OutIt __out_it, locale __loc, wstring_view __fmt, const _Args&... __args) { | ||||
return _VSTD::vformat_to( | return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, | ||||
_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, | _VSTD::make_wformat_args(__args...)); | ||||
_VSTD::make_format_args<basic_format_context<_OutIt, wchar_t>>( | |||||
__args...)); | |||||
} | } | ||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string | ||||
vformat(locale __loc, string_view __fmt, format_args __args) { | vformat(locale __loc, string_view __fmt, format_args __args) { | ||||
string __res; | string __res; | ||||
_VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt, | _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt, | ||||
__args); | __args); | ||||
return __res; | return __res; | ||||
▲ Show 20 Lines • Show All 82 Lines • Show Last 20 Lines |
Is there a good reason to introduce this function as opposed to having this logic directly in __vformat_to?