From e65218149d16824b4689b2bec29d1c773d38cd4b Mon Sep 17 00:00:00 2001 From: Nikolas Klauser Date: Thu, 19 Feb 2026 11:09:10 +0100 Subject: [PATCH] [libc++] Avoid including code in (#179466) This patch moves `format_kind` to `<__fwd/format.h>` and moves the mandate of `basic_format_context` into the class body. This reduces the time it takes to parse `` by ~14%. --- libcxx/include/__format/format_context.h | 11 ++++------ .../__format/range_default_formatter.h | 1 + libcxx/include/__format/range_format.h | 16 +------------- libcxx/include/__fwd/format.h | 21 +++++++++++++++++-- libcxx/include/optional | 2 +- 5 files changed, 26 insertions(+), 25 deletions(-) diff --git a/libcxx/include/__format/format_context.h b/libcxx/include/__format/format_context.h index 9732ea9bf7f8..cf3131b80e52 100644 --- a/libcxx/include/__format/format_context.h +++ b/libcxx/include/__format/format_context.h @@ -40,10 +40,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 -template - requires output_iterator<_OutIt, const _CharT&> -class basic_format_context; - # if _LIBCPP_HAS_LOCALIZATION /** * Helper to create a basic_format_context. @@ -71,15 +67,16 @@ using wformat_context = basic_format_context< back_insert_iterator<__format::__o # endif template - requires output_iterator<_OutIt, const _CharT&> -class _LIBCPP_PREFERRED_NAME(format_context) - _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wformat_context)) basic_format_context { +class _LIBCPP_PREFERRED_NAME(format_context) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wformat_context)) + basic_format_context { public: using iterator = _OutIt; using char_type = _CharT; template using formatter_type = formatter<_Tp, _CharT>; + static_assert(output_iterator<_OutIt, const _CharT&>, "[format.context]/p3 requires OutIt to be an output_iterator"); + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_format_arg arg(size_t __id) const noexcept { return __args_.get(__id); } diff --git a/libcxx/include/__format/range_default_formatter.h b/libcxx/include/__format/range_default_formatter.h index 2d2190657b1a..23dfb54957b6 100644 --- a/libcxx/include/__format/range_default_formatter.h +++ b/libcxx/include/__format/range_default_formatter.h @@ -22,6 +22,7 @@ #include <__format/formatter.h> #include <__format/range_format.h> #include <__format/range_formatter.h> +#include <__fwd/format.h> #include <__iterator/back_insert_iterator.h> #include <__ranges/concepts.h> #include <__ranges/data.h> diff --git a/libcxx/include/__format/range_format.h b/libcxx/include/__format/range_format.h index fe43923f9d94..0e297022cccd 100644 --- a/libcxx/include/__format/range_format.h +++ b/libcxx/include/__format/range_format.h @@ -17,6 +17,7 @@ #include <__concepts/same_as.h> #include <__config> #include <__format/fmt_pair_like.h> +#include <__fwd/format.h> #include <__ranges/concepts.h> #include <__type_traits/remove_cvref.h> @@ -24,21 +25,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 23 -_LIBCPP_DIAGNOSTIC_PUSH -_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wshadow") -_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshadow") -// This shadows map, set, and string. -enum class range_format { disabled, map, set, sequence, string, debug_string }; -_LIBCPP_DIAGNOSTIC_POP - -template -constexpr range_format format_kind = [] { - // [format.range.fmtkind]/1 - // A program that instantiates the primary template of format_kind is ill-formed. - static_assert(sizeof(_Rp) != sizeof(_Rp), "create a template specialization of format_kind for your type"); - return range_format::disabled; -}(); - template requires same_as<_Rp, remove_cvref_t<_Rp>> inline constexpr range_format format_kind<_Rp> = [] { diff --git a/libcxx/include/__fwd/format.h b/libcxx/include/__fwd/format.h index b7f4cecb65c1..e9d15360f12e 100644 --- a/libcxx/include/__fwd/format.h +++ b/libcxx/include/__fwd/format.h @@ -11,7 +11,6 @@ #define _LIBCPP___FWD_FORMAT_H #include <__config> -#include <__iterator/concepts.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -25,12 +24,30 @@ template class basic_format_arg; template - requires output_iterator<_OutIt, const _CharT&> class basic_format_context; template struct formatter; +# if _LIBCPP_STD_VER >= 23 + +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wshadow") +_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshadow") +// This shadows map, set, and string. +enum class range_format { disabled, map, set, sequence, string, debug_string }; +_LIBCPP_DIAGNOSTIC_POP + +template +constexpr range_format format_kind = [] { + // [format.range.fmtkind]/1 + // A program that instantiates the primary template of format_kind is ill-formed. + static_assert(sizeof(_Rp) != sizeof(_Rp), "create a template specialization of format_kind for your type"); + return range_format::disabled; +}(); + +# endif // _LIBCPP_STD_VER >= 23 + #endif // _LIBCPP_STD_VER >= 20 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/optional b/libcxx/include/optional index b851a858ed26..9a8fb15c02da 100644 --- a/libcxx/include/optional +++ b/libcxx/include/optional @@ -265,10 +265,10 @@ namespace std { # include <__concepts/invocable.h> # include <__config> # include <__exception/exception.h> -# include <__format/range_format.h> # include <__functional/hash.h> # include <__functional/invoke.h> # include <__functional/unary_function.h> +# include <__fwd/format.h> # include <__fwd/functional.h> # include <__iterator/bounded_iter.h> # include <__iterator/capacity_aware_iterator.h>