Skip to content

Commit

Permalink
[libc++][format] Implements P3107R5 in <format>. (llvm#86713)
Browse files Browse the repository at this point in the history
This adds the new std::enable_nonlocking_formatter_optimization trait in
<format>. This trait will be used in std::print to implement the
performance benefits.

Implements parts of
- P3107R5 - Permit an efficient implementation of ``std::print``
  • Loading branch information
mordante authored and banach-space committed Aug 7, 2024
1 parent bf51086 commit 61e313f
Show file tree
Hide file tree
Showing 10 changed files with 337 additions and 10 deletions.
3 changes: 3 additions & 0 deletions libcxx/include/__format/formatter.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ struct _LIBCPP_TEMPLATE_VIS formatter {

# if _LIBCPP_STD_VER >= 23

template <class _Tp>
constexpr bool enable_nonlocking_formatter_optimization = false;

template <class _Tp>
_LIBCPP_HIDE_FROM_ABI constexpr void __set_debug_format(_Tp& __formatter) {
if constexpr (requires { __formatter.set_debug_format(); })
Expand Down
6 changes: 5 additions & 1 deletion libcxx/include/__format/formatter_bool.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,11 @@ struct _LIBCPP_TEMPLATE_VIS formatter<bool, _CharT> {
__format_spec::__parser<_CharT> __parser_;
};

#endif //_LIBCPP_STD_VER >= 20
# if _LIBCPP_STD_VER >= 23
template <>
inline constexpr bool enable_nonlocking_formatter_optimization<bool> = true;
# endif //_LIBCPP_STD_VER >= 23
#endif //_LIBCPP_STD_VER >= 20

_LIBCPP_END_NAMESPACE_STD

Expand Down
10 changes: 9 additions & 1 deletion libcxx/include/__format/formatter_char.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,17 @@ struct _LIBCPP_TEMPLATE_VIS formatter<char, wchar_t> : public __formatter_char<w

template <>
struct _LIBCPP_TEMPLATE_VIS formatter<wchar_t, wchar_t> : public __formatter_char<wchar_t> {};

# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS

# if _LIBCPP_STD_VER >= 23
template <>
inline constexpr bool enable_nonlocking_formatter_optimization<char> = true;
# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <>
inline constexpr bool enable_nonlocking_formatter_optimization<wchar_t> = true;
# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
# endif //_LIBCPP_STD_VER >= 23

#endif //_LIBCPP_STD_VER >= 20

_LIBCPP_END_NAMESPACE_STD
Expand Down
8 changes: 8 additions & 0 deletions libcxx/include/__format/formatter_floating_point.h
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,14 @@ struct _LIBCPP_TEMPLATE_VIS formatter<double, _CharT> : public __formatter_float
template <__fmt_char_type _CharT>
struct _LIBCPP_TEMPLATE_VIS formatter<long double, _CharT> : public __formatter_floating_point<_CharT> {};

# if _LIBCPP_STD_VER >= 23
template <>
inline constexpr bool enable_nonlocking_formatter_optimization<float> = true;
template <>
inline constexpr bool enable_nonlocking_formatter_optimization<double> = true;
template <>
inline constexpr bool enable_nonlocking_formatter_optimization<long double> = true;
# endif //_LIBCPP_STD_VER >= 23
#endif //_LIBCPP_STD_VER >= 20

_LIBCPP_END_NAMESPACE_STD
Expand Down
33 changes: 32 additions & 1 deletion libcxx/include/__format/formatter_integer.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,38 @@ template <__fmt_char_type _CharT>
struct _LIBCPP_TEMPLATE_VIS formatter<__uint128_t, _CharT> : public __formatter_integer<_CharT> {};
# endif

#endif //_LIBCPP_STD_VER >= 20
# if _LIBCPP_STD_VER >= 23
template <>
inline constexpr bool enable_nonlocking_formatter_optimization<signed char> = true;
template <>
inline constexpr bool enable_nonlocking_formatter_optimization<short> = true;
template <>
inline constexpr bool enable_nonlocking_formatter_optimization<int> = true;
template <>
inline constexpr bool enable_nonlocking_formatter_optimization<long> = true;
template <>
inline constexpr bool enable_nonlocking_formatter_optimization<long long> = true;
# ifndef _LIBCPP_HAS_NO_INT128
template <>
inline constexpr bool enable_nonlocking_formatter_optimization<__int128_t> = true;
# endif

template <>
inline constexpr bool enable_nonlocking_formatter_optimization<unsigned char> = true;
template <>
inline constexpr bool enable_nonlocking_formatter_optimization<unsigned short> = true;
template <>
inline constexpr bool enable_nonlocking_formatter_optimization<unsigned> = true;
template <>
inline constexpr bool enable_nonlocking_formatter_optimization<unsigned long> = true;
template <>
inline constexpr bool enable_nonlocking_formatter_optimization<unsigned long long> = true;
# ifndef _LIBCPP_HAS_NO_INT128
template <>
inline constexpr bool enable_nonlocking_formatter_optimization<__uint128_t> = true;
# endif
# endif //_LIBCPP_STD_VER >= 23
#endif //_LIBCPP_STD_VER >= 20

_LIBCPP_END_NAMESPACE_STD

Expand Down
8 changes: 8 additions & 0 deletions libcxx/include/__format/formatter_pointer.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ struct _LIBCPP_TEMPLATE_VIS formatter<void*, _CharT> : public __formatter_pointe
template <__fmt_char_type _CharT>
struct _LIBCPP_TEMPLATE_VIS formatter<const void*, _CharT> : public __formatter_pointer<_CharT> {};

# if _LIBCPP_STD_VER >= 23
template <>
inline constexpr bool enable_nonlocking_formatter_optimization<nullptr_t> = true;
template <>
inline constexpr bool enable_nonlocking_formatter_optimization<void*> = true;
template <>
inline constexpr bool enable_nonlocking_formatter_optimization<const void*> = true;
# endif //_LIBCPP_STD_VER >= 23
#endif //_LIBCPP_STD_VER >= 20

_LIBCPP_END_NAMESPACE_STD
Expand Down
27 changes: 26 additions & 1 deletion libcxx/include/__format/formatter_string.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,32 @@ struct _LIBCPP_TEMPLATE_VIS formatter<basic_string_view<_CharT, _Traits>, _CharT
}
};

#endif //_LIBCPP_STD_VER >= 20
# if _LIBCPP_STD_VER >= 23
template <>
inline constexpr bool enable_nonlocking_formatter_optimization<char*> = true;
template <>
inline constexpr bool enable_nonlocking_formatter_optimization<const char*> = true;
template <size_t _Size>
inline constexpr bool enable_nonlocking_formatter_optimization<char[_Size]> = true;
template <class _Traits, class _Allocator>
inline constexpr bool enable_nonlocking_formatter_optimization<basic_string<char, _Traits, _Allocator>> = true;
template <class _Traits>
inline constexpr bool enable_nonlocking_formatter_optimization<basic_string_view<char, _Traits>> = true;

# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <>
inline constexpr bool enable_nonlocking_formatter_optimization<wchar_t*> = true;
template <>
inline constexpr bool enable_nonlocking_formatter_optimization<const wchar_t*> = true;
template <size_t _Size>
inline constexpr bool enable_nonlocking_formatter_optimization<wchar_t[_Size]> = true;
template <class _Traits, class _Allocator>
inline constexpr bool enable_nonlocking_formatter_optimization<basic_string<wchar_t, _Traits, _Allocator>> = true;
template <class _Traits>
inline constexpr bool enable_nonlocking_formatter_optimization<basic_string_view<wchar_t, _Traits>> = true;
# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
# endif //_LIBCPP_STD_VER >= 23
#endif //_LIBCPP_STD_VER >= 20

_LIBCPP_END_NAMESPACE_STD

Expand Down
15 changes: 9 additions & 6 deletions libcxx/include/format
Original file line number Diff line number Diff line change
Expand Up @@ -126,14 +126,17 @@ namespace std {
// [format.formatter], formatter
template<class T, class charT = char> struct formatter;
template<class T>
constexpr bool enable_nonlocking_formatter_optimization = false; // since C++23
// [format.parse.ctx], class template basic_format_parse_context
template<class charT> class basic_format_parse_context;
using format_parse_context = basic_format_parse_context<char>;
using wformat_parse_context = basic_format_parse_context<wchar_t>;
// [format.range], formatting of ranges
// [format.range.fmtkind], variable template format_kind
enum class range_format { // since C++23
enum class range_format { // since C++23
disabled,
map,
set,
Expand All @@ -143,20 +146,20 @@ namespace std {
};
template<class R>
constexpr unspecified format_kind = unspecified; // since C++23
constexpr unspecified format_kind = unspecified; // since C++23
template<ranges::input_range R>
requires same_as<R, remove_cvref_t<R>>
constexpr range_format format_kind<R> = see below; // since C++23
constexpr range_format format_kind<R> = see below; // since C++23
// [format.range.formatter], class template range_formatter
template<class T, class charT = char>
requires same_as<remove_cvref_t<T>, T> && formattable<T, charT>
class range_formatter; // since C++23
class range_formatter; // since C++23
// [format.range.fmtdef], class template range-default-formatter
template<range_format K, ranges::input_range R, class charT>
struct range-default-formatter; // exposition only, since C++23
struct range-default-formatter; // exposition only, since C++23
// [format.range.fmtmap], [format.range.fmtset], [format.range.fmtstr],
// specializations for maps, sets, and strings
Expand All @@ -173,7 +176,7 @@ namespace std {
see below visit_format_arg(Visitor&& vis, basic_format_arg<Context> arg); // Deprecated in C++26
// [format.arg.store], class template format-arg-store
template<class Context, class... Args> struct format-arg-store; // exposition only
template<class Context, class... Args> struct format-arg-store; // exposition only
template<class Context = format_context, class... Args>
format-arg-store<Context, Args...>
Expand Down
2 changes: 2 additions & 0 deletions libcxx/modules/std/format.inc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ export namespace std {
using std::formatter;

#if _LIBCPP_STD_VER >= 23
using std::enable_nonlocking_formatter_optimization;

// [format.formattable], concept formattable
using std::formattable;
#endif
Expand Down
Loading

0 comments on commit 61e313f

Please sign in to comment.