[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