[libcxx-commits] [libcxx] [libc++] Move numpunct into <__locale_dir/num.h> (PR #212465)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jul 28 05:56:30 PDT 2026


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

>From 5f86bf7ee8f8ed80b23c35b617156782719e5175 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Tue, 28 Jul 2026 13:21:03 +0200
Subject: [PATCH] [libc++] Move numpunct into <__locale_dir/num.h>

---
 libcxx/include/__chrono/formatter.h           |  1 +
 .../__format/formatter_floating_point.h       |  1 +
 libcxx/include/__format/formatter_integral.h  |  1 +
 libcxx/include/__locale                       | 98 -------------------
 libcxx/include/__locale_dir/num.h             | 98 +++++++++++++++++++
 .../test/libcxx/transitive_includes/cxx26.csv |  6 ++
 .../locale-specific_form.pass.cpp             |  1 +
 .../locale-specific_form.pass.cpp             |  1 +
 8 files changed, 109 insertions(+), 98 deletions(-)

diff --git a/libcxx/include/__chrono/formatter.h b/libcxx/include/__chrono/formatter.h
index 49758397f6185..49b7bee157243 100644
--- a/libcxx/include/__chrono/formatter.h
+++ b/libcxx/include/__chrono/formatter.h
@@ -52,6 +52,7 @@
 #  include <__format/write_escaped.h>
 #  include <__iterator/istreambuf_iterator.h>
 #  include <__iterator/ostreambuf_iterator.h>
+#  include <__locale_dir/num.h>
 #  include <__locale_dir/time.h>
 #  include <__memory/addressof.h>
 #  include <__type_traits/is_specialization.h>
diff --git a/libcxx/include/__format/formatter_floating_point.h b/libcxx/include/__format/formatter_floating_point.h
index f4de8b927651a..ea6d2b7f31783 100644
--- a/libcxx/include/__format/formatter_floating_point.h
+++ b/libcxx/include/__format/formatter_floating_point.h
@@ -32,6 +32,7 @@
 #include <__format/formatter_output.h>
 #include <__format/parser_std_format_spec.h>
 #include <__iterator/concepts.h>
+#include <__locale_dir/num.h>
 #include <__math/traits.h>
 #include <__memory/allocator.h>
 #include <__system_error/errc.h>
diff --git a/libcxx/include/__format/formatter_integral.h b/libcxx/include/__format/formatter_integral.h
index 85f509fad4f5d..6e26ea7397d49 100644
--- a/libcxx/include/__format/formatter_integral.h
+++ b/libcxx/include/__format/formatter_integral.h
@@ -22,6 +22,7 @@
 #include <__format/parser_std_format_spec.h>
 #include <__iterator/concepts.h>
 #include <__iterator/iterator_traits.h>
+#include <__locale_dir/num.h>
 #include <__memory/pointer_traits.h>
 #include <__system_error/errc.h>
 #include <__type_traits/make_unsigned.h>
diff --git a/libcxx/include/__locale b/libcxx/include/__locale
index f878aa48071ca..28bc17f8368a6 100644
--- a/libcxx/include/__locale
+++ b/libcxx/include/__locale
@@ -1425,104 +1425,6 @@ struct _LIBCPP_EXPORTED_FROM_ABI __widen_from_utf8<32> : public codecvt<char32_t
   }
 };
 
-// template <class charT> class numpunct
-
-template <class _CharT>
-class numpunct;
-
-template <>
-class _LIBCPP_EXPORTED_FROM_ABI numpunct<char> : public locale::facet {
-public:
-  typedef char char_type;
-  typedef basic_string<char_type> string_type;
-
-  explicit numpunct(size_t __refs = 0);
-
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI char_type decimal_point() const { return do_decimal_point(); }
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI char_type thousands_sep() const { return do_thousands_sep(); }
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI string grouping() const { return do_grouping(); }
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI string_type truename() const { return do_truename(); }
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI string_type falsename() const { return do_falsename(); }
-
-  static locale::id id;
-
-protected:
-  ~numpunct() override;
-  virtual char_type do_decimal_point() const;
-  virtual char_type do_thousands_sep() const;
-  virtual string do_grouping() const;
-  virtual string_type do_truename() const;
-  virtual string_type do_falsename() const;
-
-  char_type __decimal_point_;
-  char_type __thousands_sep_;
-  string __grouping_;
-};
-
-#  if _LIBCPP_HAS_WIDE_CHARACTERS
-template <>
-class _LIBCPP_EXPORTED_FROM_ABI numpunct<wchar_t> : public locale::facet {
-public:
-  typedef wchar_t char_type;
-  typedef basic_string<char_type> string_type;
-
-  explicit numpunct(size_t __refs = 0);
-
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI char_type decimal_point() const { return do_decimal_point(); }
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI char_type thousands_sep() const { return do_thousands_sep(); }
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI string grouping() const { return do_grouping(); }
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI string_type truename() const { return do_truename(); }
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI string_type falsename() const { return do_falsename(); }
-
-  static locale::id id;
-
-protected:
-  ~numpunct() override;
-  virtual char_type do_decimal_point() const;
-  virtual char_type do_thousands_sep() const;
-  virtual string do_grouping() const;
-  virtual string_type do_truename() const;
-  virtual string_type do_falsename() const;
-
-  char_type __decimal_point_;
-  char_type __thousands_sep_;
-  string __grouping_;
-};
-#  endif // _LIBCPP_HAS_WIDE_CHARACTERS
-
-// template <class charT> class numpunct_byname
-
-template <class _CharT>
-class numpunct_byname;
-
-template <>
-class _LIBCPP_EXPORTED_FROM_ABI numpunct_byname<char> : public numpunct<char> {
-public:
-  typedef char char_type;
-  typedef basic_string<char_type> string_type;
-
-  explicit numpunct_byname(const char* __nm, size_t __refs = 0);
-  explicit numpunct_byname(const string& __nm, size_t __refs = 0);
-
-protected:
-  ~numpunct_byname() override;
-};
-
-#  if _LIBCPP_HAS_WIDE_CHARACTERS
-template <>
-class _LIBCPP_EXPORTED_FROM_ABI numpunct_byname<wchar_t> : public numpunct<wchar_t> {
-public:
-  typedef wchar_t char_type;
-  typedef basic_string<char_type> string_type;
-
-  explicit numpunct_byname(const char* __nm, size_t __refs = 0);
-  explicit numpunct_byname(const string& __nm, size_t __refs = 0);
-
-protected:
-  ~numpunct_byname() override;
-};
-#  endif // _LIBCPP_HAS_WIDE_CHARACTERS
-
 _LIBCPP_END_EXPLICIT_ABI_ANNOTATIONS
 _LIBCPP_END_NAMESPACE_STD
 
diff --git a/libcxx/include/__locale_dir/num.h b/libcxx/include/__locale_dir/num.h
index 5b3b917384121..d50d0e9ba4ab8 100644
--- a/libcxx/include/__locale_dir/num.h
+++ b/libcxx/include/__locale_dir/num.h
@@ -44,6 +44,104 @@ _LIBCPP_PUSH_MACROS
 _LIBCPP_BEGIN_NAMESPACE_STD
 _LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS
 
+// template <class charT> class numpunct
+
+template <class _CharT>
+class numpunct;
+
+template <>
+class _LIBCPP_EXPORTED_FROM_ABI numpunct<char> : public locale::facet {
+public:
+  typedef char char_type;
+  typedef basic_string<char_type> string_type;
+
+  explicit numpunct(size_t __refs = 0);
+
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI char_type decimal_point() const { return do_decimal_point(); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI char_type thousands_sep() const { return do_thousands_sep(); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI string grouping() const { return do_grouping(); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI string_type truename() const { return do_truename(); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI string_type falsename() const { return do_falsename(); }
+
+  static locale::id id;
+
+protected:
+  ~numpunct() override;
+  virtual char_type do_decimal_point() const;
+  virtual char_type do_thousands_sep() const;
+  virtual string do_grouping() const;
+  virtual string_type do_truename() const;
+  virtual string_type do_falsename() const;
+
+  char_type __decimal_point_;
+  char_type __thousands_sep_;
+  string __grouping_;
+};
+
+#  if _LIBCPP_HAS_WIDE_CHARACTERS
+template <>
+class _LIBCPP_EXPORTED_FROM_ABI numpunct<wchar_t> : public locale::facet {
+public:
+  typedef wchar_t char_type;
+  typedef basic_string<char_type> string_type;
+
+  explicit numpunct(size_t __refs = 0);
+
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI char_type decimal_point() const { return do_decimal_point(); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI char_type thousands_sep() const { return do_thousands_sep(); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI string grouping() const { return do_grouping(); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI string_type truename() const { return do_truename(); }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI string_type falsename() const { return do_falsename(); }
+
+  static locale::id id;
+
+protected:
+  ~numpunct() override;
+  virtual char_type do_decimal_point() const;
+  virtual char_type do_thousands_sep() const;
+  virtual string do_grouping() const;
+  virtual string_type do_truename() const;
+  virtual string_type do_falsename() const;
+
+  char_type __decimal_point_;
+  char_type __thousands_sep_;
+  string __grouping_;
+};
+#  endif // _LIBCPP_HAS_WIDE_CHARACTERS
+
+// template <class charT> class numpunct_byname
+
+template <class _CharT>
+class numpunct_byname;
+
+template <>
+class _LIBCPP_EXPORTED_FROM_ABI numpunct_byname<char> : public numpunct<char> {
+public:
+  typedef char char_type;
+  typedef basic_string<char_type> string_type;
+
+  explicit numpunct_byname(const char* __nm, size_t __refs = 0);
+  explicit numpunct_byname(const string& __nm, size_t __refs = 0);
+
+protected:
+  ~numpunct_byname() override;
+};
+
+#  if _LIBCPP_HAS_WIDE_CHARACTERS
+template <>
+class _LIBCPP_EXPORTED_FROM_ABI numpunct_byname<wchar_t> : public numpunct<wchar_t> {
+public:
+  typedef wchar_t char_type;
+  typedef basic_string<char_type> string_type;
+
+  explicit numpunct_byname(const char* __nm, size_t __refs = 0);
+  explicit numpunct_byname(const string& __nm, size_t __refs = 0);
+
+protected:
+  ~numpunct_byname() override;
+};
+#  endif // _LIBCPP_HAS_WIDE_CHARACTERS
+
 struct _LIBCPP_EXPORTED_FROM_ABI __num_get_base {
   static const int __num_get_buf_sz = 40;
 
diff --git a/libcxx/test/libcxx/transitive_includes/cxx26.csv b/libcxx/test/libcxx/transitive_includes/cxx26.csv
index f712f36caa9fc..9b047ca3d97db 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx26.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx26.csv
@@ -362,10 +362,12 @@ format cstring
 format cwchar
 format cwctype
 format initializer_list
+format ios
 format iosfwd
 format limits
 format optional
 format stdexcept
+format streambuf
 format string
 format string_view
 format text_encoding
@@ -719,10 +721,12 @@ print cwchar
 print cwctype
 print format
 print initializer_list
+print ios
 print iosfwd
 print limits
 print optional
 print stdexcept
+print streambuf
 print string
 print string_view
 print text_encoding
@@ -1051,10 +1055,12 @@ thread ctime
 thread cwchar
 thread cwctype
 thread initializer_list
+thread ios
 thread iosfwd
 thread limits
 thread ratio
 thread stdexcept
+thread streambuf
 thread string
 thread string_view
 thread text_encoding
diff --git a/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/locale-specific_form.pass.cpp b/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/locale-specific_form.pass.cpp
index 98fa56b7f4b6d..ba47aa294e521 100644
--- a/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/locale-specific_form.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/locale-specific_form.pass.cpp
@@ -33,6 +33,7 @@
 // void vprint_nonunicode(ostream& os, string_view fmt, format_args args);
 
 #include <cassert>
+#include <locale>
 #include <ostream>
 
 #include "test_macros.h"
diff --git a/libcxx/test/std/utilities/format/format.functions/locale-specific_form.pass.cpp b/libcxx/test/std/utilities/format/format.functions/locale-specific_form.pass.cpp
index 51be78e1a02f8..e573f8d47dc99 100644
--- a/libcxx/test/std/utilities/format/format.functions/locale-specific_form.pass.cpp
+++ b/libcxx/test/std/utilities/format/format.functions/locale-specific_form.pass.cpp
@@ -88,6 +88,7 @@
 #include <format>
 #include <cassert>
 #include <iostream>
+#include <locale>
 #include <vector>
 
 #include "test_macros.h"



More information about the libcxx-commits mailing list