[libcxx-commits] [libcxx] [libc++] Avoid including <format> code in <optional> (PR #179466)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Feb 16 03:06:41 PST 2026
https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/179466
>From 2bf46120706f8ae2faa08247cf361f88e0c73e5f Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Tue, 3 Feb 2026 14:57:58 +0100
Subject: [PATCH] [libc++] Avoid including <format> code in <optional>
---
libcxx/include/__format/format_context.h | 7 ++-----
.../__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, 24 insertions(+), 23 deletions(-)
diff --git a/libcxx/include/__format/format_context.h b/libcxx/include/__format/format_context.h
index 9732ea9bf7f85..18eb13691a950 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,7 +67,6 @@ 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 {
public:
@@ -80,6 +75,8 @@ class _LIBCPP_PREFERRED_NAME(format_context)
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>
More information about the libcxx-commits
mailing list