[libcxx-commits] [libcxx] [libc++] Reduce the amount of formatter code included in <vector> (PR #178683)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Feb 16 01:54:17 PST 2026
https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/178683
>From 0c5551a5edf8d9a2c9275a856932b025f93c2652 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Thu, 29 Jan 2026 16:44:01 +0100
Subject: [PATCH] [libc++] Reduce the amount of formatter code included in
<vector>
---
libcxx/include/CMakeLists.txt | 1 +
libcxx/include/__format/format_functions.h | 2 +-
libcxx/include/__format/formatter_bool.h | 35 ++---------
libcxx/include/__format/formatter_bool_impl.h | 58 +++++++++++++++++++
libcxx/include/format | 2 +-
libcxx/include/module.modulemap.in | 10 +++-
libcxx/include/vector | 14 +++--
.../test/libcxx/transitive_includes/cxx26.csv | 14 -----
libcxx/test/support/platform_support.h | 7 ++-
9 files changed, 88 insertions(+), 55 deletions(-)
create mode 100644 libcxx/include/__format/formatter_bool_impl.h
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 5cdf29b94e3eb..53165f0336b2d 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -404,6 +404,7 @@ set(files
__format/format_to_n_result.h
__format/formatter.h
__format/formatter_bool.h
+ __format/formatter_bool_impl.h
__format/formatter_char.h
__format/formatter_floating_point.h
__format/formatter_integer.h
diff --git a/libcxx/include/__format/format_functions.h b/libcxx/include/__format/format_functions.h
index 873265bc17c24..7b0fcc0ea585a 100644
--- a/libcxx/include/__format/format_functions.h
+++ b/libcxx/include/__format/format_functions.h
@@ -26,7 +26,7 @@
#include <__format/format_string.h>
#include <__format/format_to_n_result.h>
#include <__format/formatter.h>
-#include <__format/formatter_bool.h>
+#include <__format/formatter_bool_impl.h>
#include <__format/formatter_char.h>
#include <__format/formatter_floating_point.h>
#include <__format/formatter_integer.h>
diff --git a/libcxx/include/__format/formatter_bool.h b/libcxx/include/__format/formatter_bool.h
index 33a148a54668b..2280ff131bcde 100644
--- a/libcxx/include/__format/formatter_bool.h
+++ b/libcxx/include/__format/formatter_bool.h
@@ -10,19 +10,10 @@
#ifndef _LIBCPP___FORMAT_FORMATTER_BOOL_H
#define _LIBCPP___FORMAT_FORMATTER_BOOL_H
-#include <__algorithm/copy.h>
-#include <__assert>
#include <__config>
#include <__format/concepts.h>
-#include <__format/format_parse_context.h>
#include <__format/formatter.h>
-#include <__format/formatter_integral.h>
#include <__format/parser_std_format_spec.h>
-#include <__utility/unreachable.h>
-
-#if _LIBCPP_HAS_LOCALIZATION
-# include <__locale>
-#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -32,9 +23,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
+template <__fmt_char_type _CharT, class _FormatContext>
+_LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
+__formatter_bool_format(bool __value, __format_spec::__parser<_CharT>, _FormatContext&);
+
template <__fmt_char_type _CharT>
struct formatter<bool, _CharT> {
-public:
template <class _ParseContext>
_LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_integral);
@@ -44,26 +38,7 @@ struct formatter<bool, _CharT> {
template <class _FormatContext>
_LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(bool __value, _FormatContext& __ctx) const {
- switch (__parser_.__type_) {
- case __format_spec::__type::__default:
- case __format_spec::__type::__string:
- return __formatter::__format_bool(__value, __ctx, __parser_.__get_parsed_std_specifications(__ctx));
-
- case __format_spec::__type::__binary_lower_case:
- case __format_spec::__type::__binary_upper_case:
- case __format_spec::__type::__octal:
- case __format_spec::__type::__decimal:
- case __format_spec::__type::__hexadecimal_lower_case:
- case __format_spec::__type::__hexadecimal_upper_case:
- // Promotes bool to an integral type. This reduces the number of
- // instantiations of __format_integer reducing code size.
- return __formatter::__format_integer(
- static_cast<unsigned>(__value), __ctx, __parser_.__get_parsed_std_specifications(__ctx));
-
- default:
- _LIBCPP_ASSERT_INTERNAL(false, "The parse function should have validated the type");
- __libcpp_unreachable();
- }
+ return std::__formatter_bool_format(__value, __parser_, __ctx);
}
__format_spec::__parser<_CharT> __parser_;
diff --git a/libcxx/include/__format/formatter_bool_impl.h b/libcxx/include/__format/formatter_bool_impl.h
new file mode 100644
index 0000000000000..00bc863709f50
--- /dev/null
+++ b/libcxx/include/__format/formatter_bool_impl.h
@@ -0,0 +1,58 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FORMAT_FORMATTER_BOOL_IMPL_H
+#define _LIBCPP___FORMAT_FORMATTER_BOOL_IMPL_H
+
+#include <__assert>
+#include <__config>
+#include <__format/concepts.h>
+#include <__format/formatter_bool.h>
+#include <__format/formatter_integral.h>
+#include <__format/parser_std_format_spec.h>
+#include <__utility/unreachable.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 20
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <__fmt_char_type _CharT, class _FormatContext>
+_LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
+__formatter_bool_format(bool __value, __format_spec::__parser<_CharT> __parser, _FormatContext& __ctx) {
+ switch (__parser.__type_) {
+ case __format_spec::__type::__default:
+ case __format_spec::__type::__string:
+ return __formatter::__format_bool(__value, __ctx, __parser.__get_parsed_std_specifications(__ctx));
+
+ case __format_spec::__type::__binary_lower_case:
+ case __format_spec::__type::__binary_upper_case:
+ case __format_spec::__type::__octal:
+ case __format_spec::__type::__decimal:
+ case __format_spec::__type::__hexadecimal_lower_case:
+ case __format_spec::__type::__hexadecimal_upper_case:
+ // Promotes bool to an integral type. This reduces the number of
+ // instantiations of __format_integer reducing code size.
+ return __formatter::__format_integer(
+ static_cast<unsigned>(__value), __ctx, __parser.__get_parsed_std_specifications(__ctx));
+
+ default:
+ _LIBCPP_ASSERT_INTERNAL(false, "The parse function should have validated the type");
+ __libcpp_unreachable();
+ }
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 20
+
+#endif // _LIBCPP___FORMAT_FORMATTER_BOOL_IMPL_H
diff --git a/libcxx/include/format b/libcxx/include/format
index e29563a715164..f8f54df8352b8 100644
--- a/libcxx/include/format
+++ b/libcxx/include/format
@@ -213,7 +213,7 @@ namespace std {
# include <__format/format_string.h>
# include <__format/format_to_n_result.h>
# include <__format/formatter.h>
-# include <__format/formatter_bool.h>
+# include <__format/formatter_bool_impl.h>
# include <__format/formatter_char.h>
# include <__format/formatter_floating_point.h>
# include <__format/formatter_integer.h>
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 9012ed18cbd79..d6e8289b7c8b0 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -1365,7 +1365,15 @@ module std [system] {
module format_string { header "__format/format_string.h" }
module format_to_n_result { header "__format/format_to_n_result.h" }
module formatter { header "__format/formatter.h" }
- module formatter_bool { header "__format/formatter_bool.h" }
+ module formatter_bool {
+ header "__format/formatter_bool.h"
+ export std.format.formatter
+ }
+ module formatter_bool_impl {
+ header "__format/formatter_bool_impl.h"
+ export std.format.formatter_bool
+ export std.format.formatter
+ }
module formatter_char { header "__format/formatter_char.h" }
module formatter_floating_point { header "__format/formatter_floating_point.h" }
module formatter_integer { header "__format/formatter_integer.h" }
diff --git a/libcxx/include/vector b/libcxx/include/vector
index d2d5fcf4a3199..7f260a096ca60 100644
--- a/libcxx/include/vector
+++ b/libcxx/include/vector
@@ -348,16 +348,21 @@ template<class T, class charT> requires is-vector-bool-reference<T> // Since C++
# pragma GCC system_header
# endif
+# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 23
+# include <array>
+# include <cerrno>
+# include <clocale>
+# include <cstddef>
+# include <cstdlib>
+# include <typeinfo>
+# endif
+
# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <algorithm>
-# include <array>
# include <atomic>
# include <cctype>
-# include <cerrno>
-# include <clocale>
# include <concepts>
# include <cstdint>
-# include <cstdlib>
# include <iosfwd>
# if _LIBCPP_HAS_LOCALIZATION
# include <locale>
@@ -367,7 +372,6 @@ template<class T, class charT> requires is-vector-bool-reference<T> // Since C++
# include <string_view>
# include <tuple>
# include <type_traits>
-# include <typeinfo>
# include <utility>
# endif
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
diff --git a/libcxx/test/libcxx/transitive_includes/cxx26.csv b/libcxx/test/libcxx/transitive_includes/cxx26.csv
index c11fb5ac10016..12716c7f496b1 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx26.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx26.csv
@@ -744,16 +744,11 @@ print string_view
print tuple
print typeinfo
print version
-queue array
queue cctype
-queue cerrno
queue climits
-queue clocale
queue compare
-queue cstddef
queue cstdint
queue cstdio
-queue cstdlib
queue cstring
queue cwchar
queue cwctype
@@ -765,7 +760,6 @@ queue stdexcept
queue string
queue string_view
queue tuple
-queue typeinfo
queue vector
queue version
random cctype
@@ -811,9 +805,7 @@ ranges version
ratio climits
ratio cstdint
ratio version
-regex array
regex cctype
-regex cerrno
regex climits
regex clocale
regex compare
@@ -1125,16 +1117,11 @@ variant cstring
variant initializer_list
variant limits
variant version
-vector array
vector cctype
-vector cerrno
vector climits
-vector clocale
vector compare
-vector cstddef
vector cstdint
vector cstdio
-vector cstdlib
vector cstring
vector cwchar
vector cwctype
@@ -1145,5 +1132,4 @@ vector stdexcept
vector string
vector string_view
vector tuple
-vector typeinfo
vector version
diff --git a/libcxx/test/support/platform_support.h b/libcxx/test/support/platform_support.h
index b66fdff9b0491..ff44096bf7171 100644
--- a/libcxx/test/support/platform_support.h
+++ b/libcxx/test/support/platform_support.h
@@ -37,9 +37,10 @@
#include <stdlib.h>
#include <string>
#if defined(_WIN32)
-# include <io.h> // _mktemp_s
-# include <fcntl.h> // _O_EXCL, ...
-# include <sys/stat.h> // _S_IREAD, ...
+# include <io.h> // _mktemp_s
+# include <fcntl.h> // _O_EXCL, ...
+# include <sys/stat.h> // _S_IREAD, ...
+# include <cerrno>
#elif __has_include(<unistd.h>)
# include <unistd.h> // close
#endif
More information about the libcxx-commits
mailing list