[libcxx-commits] [libcxx] [libc++] Avoid including <format> code in <optional> (PR #179466)
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Feb 19 02:09:44 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: Nikolas Klauser (philnik777)
<details>
<summary>Changes</summary>
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 `<optional>` by ~14%.
---
Full diff: https://github.com/llvm/llvm-project/pull/179466.diff
5 Files Affected:
- (modified) libcxx/include/__format/format_context.h (+4-7)
- (modified) libcxx/include/__format/range_default_formatter.h (+1)
- (modified) libcxx/include/__format/range_format.h (+1-15)
- (modified) libcxx/include/__fwd/format.h (+19-2)
- (modified) libcxx/include/optional (+1-1)
``````````diff
diff --git a/libcxx/include/__format/format_context.h b/libcxx/include/__format/format_context.h
index 9732ea9bf7f85..cf3131b80e52f 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 <class _OutIt, class _CharT>
- 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 <class _OutIt, class _CharT>
- 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 <class _Tp>
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<basic_format_context> 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 2d2190657b1af..23dfb54957b64 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 fe43923f9d940..0e297022cccdd 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 <class _Rp>
-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 <ranges::input_range _Rp>
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 b7f4cecb65c1e..e9d15360f12e6 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 _Context>
class basic_format_arg;
template <class _OutIt, class _CharT>
- requires output_iterator<_OutIt, const _CharT&>
class basic_format_context;
template <class _Tp, class _CharT = char>
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 <class _Rp>
+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 b851a858ed26a..9a8fb15c02dae 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>
``````````
</details>
https://github.com/llvm/llvm-project/pull/179466
More information about the libcxx-commits
mailing list