[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
Fri Jan 30 07:52:23 PST 2026


https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/178683

>From e3fea8442cf82140a02e620871578a1818f6b0ff 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                 |  3 +-
 libcxx/include/__format/format_functions.h    |  2 +-
 ...formatter_bool.h => formatter_bool_decl.h} | 39 ++----------
 libcxx/include/__format/formatter_bool_impl.h | 59 +++++++++++++++++++
 .../include/__vector/vector_bool_formatter.h  |  2 +-
 libcxx/include/format                         |  2 +-
 libcxx/include/module.modulemap.in            | 10 +++-
 7 files changed, 77 insertions(+), 40 deletions(-)
 rename libcxx/include/__format/{formatter_bool.h => formatter_bool_decl.h} (50%)
 create mode 100644 libcxx/include/__format/formatter_bool_impl.h

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 494c21bd30019..51810c3f8be63 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -402,7 +402,8 @@ set(files
   __format/format_string.h
   __format/format_to_n_result.h
   __format/formatter.h
-  __format/formatter_bool.h
+  __format/formatter_bool_decl.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_decl.h
similarity index 50%
rename from libcxx/include/__format/formatter_bool.h
rename to libcxx/include/__format/formatter_bool_decl.h
index 33a148a54668b..36616d3c2be13 100644
--- a/libcxx/include/__format/formatter_bool.h
+++ b/libcxx/include/__format/formatter_bool_decl.h
@@ -7,22 +7,13 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef _LIBCPP___FORMAT_FORMATTER_BOOL_H
-#define _LIBCPP___FORMAT_FORMATTER_BOOL_H
+#ifndef _LIBCPP___FORMAT_FORMATTER_BOOL_DECL_H
+#define _LIBCPP___FORMAT_FORMATTER_BOOL_DECL_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
@@ -34,7 +25,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 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);
@@ -43,28 +33,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();
-    }
-  }
+  _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(bool __value, _FormatContext& __ctx) const;
 
   __format_spec::__parser<_CharT> __parser_;
 };
@@ -77,4 +46,4 @@ inline constexpr bool enable_nonlocking_formatter_optimization<bool> = true;
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP___FORMAT_FORMATTER_BOOL_H
+#endif // _LIBCPP___FORMAT_FORMATTER_BOOL_DECL_H
diff --git a/libcxx/include/__format/formatter_bool_impl.h b/libcxx/include/__format/formatter_bool_impl.h
new file mode 100644
index 0000000000000..c5163b6792bad
--- /dev/null
+++ b/libcxx/include/__format/formatter_bool_impl.h
@@ -0,0 +1,59 @@
+// -*- 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_decl.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>
+template <class _FormatContext>
+_LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
+formatter<bool, _CharT>::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();
+  }
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 20
+
+#endif // _LIBCPP___FORMAT_FORMATTER_BOOL_IMPL_H
diff --git a/libcxx/include/__vector/vector_bool_formatter.h b/libcxx/include/__vector/vector_bool_formatter.h
index b08c39c6d574b..e431b0ed569cb 100644
--- a/libcxx/include/__vector/vector_bool_formatter.h
+++ b/libcxx/include/__vector/vector_bool_formatter.h
@@ -12,7 +12,7 @@
 #include <__concepts/same_as.h>
 #include <__config>
 #include <__format/formatter.h>
-#include <__format/formatter_bool.h>
+#include <__format/formatter_bool_decl.h>
 #include <__fwd/vector.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
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 58fc4941cb7d8..f77bc819d2517 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -1361,7 +1361,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_decl                {
+      header "__format/formatter_bool_decl.h"
+      export std.format.formatter
+    }
+    module formatter_bool_impl                {
+      header "__format/formatter_bool_impl.h"
+      export std.format.formatter_bool_decl
+      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" }



More information about the libcxx-commits mailing list