[libcxx-commits] [libcxx] 7e7013c - [libc++][cuchar] Declare std::c8rtomb and std::mbrtoc8 in <cuchar> if available.
Tom Honermann via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Sep 10 18:11:12 PDT 2022
Author: Tom Honermann
Date: 2022-09-10T21:10:33-04:00
New Revision: 7e7013c5d4b1b3996c8dba668c5a94bb33b2999b
URL: https://github.com/llvm/llvm-project/commit/7e7013c5d4b1b3996c8dba668c5a94bb33b2999b
DIFF: https://github.com/llvm/llvm-project/commit/7e7013c5d4b1b3996c8dba668c5a94bb33b2999b.diff
LOG: [libc++][cuchar] Declare std::c8rtomb and std::mbrtoc8 in <cuchar> if available.
This change implements the C library dependent portions of P0482R6
(char8_t: A type for UTF-8 characters and strings (Revision 6)) by
declaring std::c8rtomb() and std::mbrtoc8() in the <cuchar> header
when implementations are provided by the C library as specified by
WG14 N2653 (char8_t: A type for UTF-8 characters and strings
(Revision 1)) as adopted for C23.
A _LIBCPP_HAS_NO_C8RTOMB_MBRTOC8 macro is defined by the libc++ __config
header unless it is known that the C library provides these functions
in the current compilation mode. This macro is used for testing purposes
and may be of use to libc++ users. At present, the only C library known
to implement these functions is GNU libc as of its 2.36 release.
Reviewed By: ldionne
Differential Revision: https://reviews.llvm.org/D130946
Added:
libcxx/test/std/strings/c.strings/no_c8rtomb_mbrtoc8.verify.cpp
Modified:
libcxx/docs/ReleaseNotes.rst
libcxx/docs/Status/Cxx20.rst
libcxx/docs/Status/Cxx20Papers.csv
libcxx/include/__config
libcxx/include/cuchar
libcxx/include/uchar.h
libcxx/test/std/depr/depr.c.headers/uchar_h.compile.pass.cpp
libcxx/test/std/strings/c.strings/cuchar.compile.pass.cpp
libcxx/test/support/test_macros.h
Removed:
################################################################################
diff --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst
index 9c46642e703cf..f745a770db229 100644
--- a/libcxx/docs/ReleaseNotes.rst
+++ b/libcxx/docs/ReleaseNotes.rst
@@ -44,6 +44,9 @@ Implemented Papers
Improvements and New Features
-----------------------------
+- Declarations of ``std::c8rtomb()`` and ``std::mbrtoc8()`` from P0482R6 are
+ now provided when implementations in the global namespace are provided by
+ the C library.
Deprecations and Removals
-------------------------
diff --git a/libcxx/docs/Status/Cxx20.rst b/libcxx/docs/Status/Cxx20.rst
index 43d29c5c9d886..90f2acc6a7bb8 100644
--- a/libcxx/docs/Status/Cxx20.rst
+++ b/libcxx/docs/Status/Cxx20.rst
@@ -49,6 +49,8 @@ Paper Status
.. [#note-P0883.1] P0883: shared_ptr and floating-point changes weren't applied as they themselves aren't implemented yet.
.. [#note-P0883.2] P0883: ``ATOMIC_FLAG_INIT`` was marked deprecated in version 14.0, but was undeprecated with the implementation of LWG3659 in version 15.0.
.. [#note-P2231] P2231: Optional is complete. The changes to variant haven't been implemented yet.
+ .. [#note-P0482] P0482: Declarations of ``std::pmr::u8string`` and ``std::hash<std::pmr::u8string>`` are blocked pending implementation
+ of polymorphic allocator support from P0220.
.. _issues-status-cxx20:
diff --git a/libcxx/docs/Status/Cxx20Papers.csv b/libcxx/docs/Status/Cxx20Papers.csv
index f9c58b2be7384..ed1d0cea6f109 100644
--- a/libcxx/docs/Status/Cxx20Papers.csv
+++ b/libcxx/docs/Status/Cxx20Papers.csv
@@ -53,7 +53,7 @@
"`P0318R1 <https://wg21.link/P0318R1>`__","LWG","unwrap_ref_decay and unwrap_reference","San Diego","|Complete|","8.0"
"`P0356R5 <https://wg21.link/P0356R5>`__","LWG","Simplified partial function application","San Diego","|Complete|","13.0"
"`P0357R3 <https://wg21.link/P0357R3>`__","LWG","reference_wrapper for incomplete types","San Diego","|Complete|","8.0"
-"`P0482R6 <https://wg21.link/P0482R6>`__","CWG","char8_t: A type for UTF-8 characters and strings","San Diego","|In Progress|",""
+"`P0482R6 <https://wg21.link/P0482R6>`__","CWG","char8_t: A type for UTF-8 characters and strings","San Diego","|Partial| [#note-P0482]_","16.0"
"`P0487R1 <https://wg21.link/P0487R1>`__","LWG","Fixing ``operator>>(basic_istream&, CharT*)``\ (LWG 2499)","San Diego","|Complete|","8.0"
"`P0591R4 <https://wg21.link/P0591R4>`__","LWG","Utility functions to implement uses-allocator construction","San Diego","* *",""
"`P0595R2 <https://wg21.link/P0595R2>`__","CWG","P0595R2 std::is_constant_evaluated()","San Diego","|Complete|","9.0"
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 364607ef1c864..a6f3b4e88aa1d 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -1208,6 +1208,22 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
# define _LIBCPP_PACKED
# endif
+// c8rtomb() and mbrtoc8() were added in C++20 and C23. Support for these
+// functions is gradually being added to existing C libraries. The conditions
+// below check for known C library versions and conditions under which these
+// functions are declared by the C library.
+# define _LIBCPP_HAS_NO_C8RTOMB_MBRTOC8
+// GNU libc 2.36 and newer declare c8rtomb() and mbrtoc8() in C++ modes if
+// __cpp_char8_t is defined or if C2X extensions are enabled. Unfortunately,
+// determining the latter depends on internal GNU libc details. If the
+// __cpp_char8_t feature test macro is not defined, then a char8_t typedef
+// will be declared as well.
+# if defined(_LIBCPP_GLIBC_PREREQ)
+# if _LIBCPP_GLIBC_PREREQ(2, 36) && (defined(__cpp_char8_t) || __GLIBC_USE(ISOC2X))
+# undef _LIBCPP_HAS_NO_C8RTOMB_MBRTOC8
+# endif
+# endif
+
#endif // __cplusplus
#endif // _LIBCPP___CONFIG
diff --git a/libcxx/include/cuchar b/libcxx/include/cuchar
index b685f470301de..93e657e84b6dc 100644
--- a/libcxx/include/cuchar
+++ b/libcxx/include/cuchar
@@ -25,6 +25,8 @@ Types:
mbstate_t
size_t
+size_t mbrtoc8(char8_t* pc8, const char* s, size_t n, mbstate_t* ps); // since C++20
+size_t c8rtomb(char* s, char8_t c8, mbstate_t* ps); // since C++20
size_t mbrtoc16(char16_t* pc16, const char* s, size_t n, mbstate_t* ps);
size_t c16rtomb(char* s, char16_t c16, mbstate_t* ps);
size_t mbrtoc32(char32_t* pc32, const char* s, size_t n, mbstate_t* ps);
@@ -58,6 +60,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD
using ::mbstate_t _LIBCPP_USING_IF_EXISTS;
using ::size_t _LIBCPP_USING_IF_EXISTS;
+# if !defined(_LIBCPP_HAS_NO_C8RTOMB_MBRTOC8)
+using ::mbrtoc8 _LIBCPP_USING_IF_EXISTS;
+using ::c8rtomb _LIBCPP_USING_IF_EXISTS;
+# endif
using ::mbrtoc16 _LIBCPP_USING_IF_EXISTS;
using ::c16rtomb _LIBCPP_USING_IF_EXISTS;
using ::mbrtoc32 _LIBCPP_USING_IF_EXISTS;
diff --git a/libcxx/include/uchar.h b/libcxx/include/uchar.h
index bb152c72cb3c6..3a51bb7a9f61f 100644
--- a/libcxx/include/uchar.h
+++ b/libcxx/include/uchar.h
@@ -23,6 +23,8 @@
mbstate_t
size_t
+size_t mbrtoc8(char8_t* pc8, const char* s, size_t n, mbstate_t* ps); // since C++20
+size_t c8rtomb(char* s, char8_t c8, mbstate_t* ps); // since C++20
size_t mbrtoc16(char16_t* pc16, const char* s, size_t n, mbstate_t* ps);
size_t c16rtomb(char* s, char16_t c16, mbstate_t* ps);
size_t mbrtoc32(char32_t* pc32, const char* s, size_t n, mbstate_t* ps);
diff --git a/libcxx/test/std/depr/depr.c.headers/uchar_h.compile.pass.cpp b/libcxx/test/std/depr/depr.c.headers/uchar_h.compile.pass.cpp
index f031ed11a899c..016e51d99c597 100644
--- a/libcxx/test/std/depr/depr.c.headers/uchar_h.compile.pass.cpp
+++ b/libcxx/test/std/depr/depr.c.headers/uchar_h.compile.pass.cpp
@@ -23,6 +23,11 @@
// __STDC_UTF_16__ may or may not be defined by the C standard library
// __STDC_UTF_32__ may or may not be defined by the C standard library
+#if !defined(TEST_HAS_NO_C8RTOMB_MBRTOC8)
+ASSERT_SAME_TYPE(size_t, decltype(mbrtoc8((char8_t*)0, (const char*)0, (size_t)0, (mbstate_t*)0)));
+ASSERT_SAME_TYPE(size_t, decltype(c8rtomb((char*)0, (char8_t)0, (mbstate_t*)0)));
+#endif
+
ASSERT_SAME_TYPE(size_t, decltype(mbrtoc16((char16_t*)0, (const char*)0, (size_t)0, (mbstate_t*)0)));
ASSERT_SAME_TYPE(size_t, decltype(c16rtomb((char*)0, (char16_t)0, (mbstate_t*)0)));
diff --git a/libcxx/test/std/strings/c.strings/cuchar.compile.pass.cpp b/libcxx/test/std/strings/c.strings/cuchar.compile.pass.cpp
index 388aa20ac0c44..909f2c025bdf8 100644
--- a/libcxx/test/std/strings/c.strings/cuchar.compile.pass.cpp
+++ b/libcxx/test/std/strings/c.strings/cuchar.compile.pass.cpp
@@ -20,11 +20,14 @@
#include "test_macros.h"
-// TODO: Implement mbrtoc8 and c8rtomb, and add tests for those
-
// __STDC_UTF_16__ may or may not be defined by the C standard library
// __STDC_UTF_32__ may or may not be defined by the C standard library
+#if !defined(TEST_HAS_NO_C8RTOMB_MBRTOC8)
+ASSERT_SAME_TYPE(size_t, decltype(std::mbrtoc8((char8_t*)0, (const char*)0, (size_t)0, (mbstate_t*)0)));
+ASSERT_SAME_TYPE(size_t, decltype(std::c8rtomb((char*)0, (char8_t)0, (mbstate_t*)0)));
+#endif
+
ASSERT_SAME_TYPE(size_t, decltype(std::mbrtoc16((char16_t*)0, (const char*)0, (size_t)0, (mbstate_t*)0)));
ASSERT_SAME_TYPE(size_t, decltype(std::c16rtomb((char*)0, (char16_t)0, (mbstate_t*)0)));
diff --git a/libcxx/test/std/strings/c.strings/no_c8rtomb_mbrtoc8.verify.cpp b/libcxx/test/std/strings/c.strings/no_c8rtomb_mbrtoc8.verify.cpp
new file mode 100644
index 0000000000000..f39aef43c2cb8
--- /dev/null
+++ b/libcxx/test/std/strings/c.strings/no_c8rtomb_mbrtoc8.verify.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// The system-provided <uchar.h> seems to be broken on AIX:
+// error: 'error' diagnostics seen but not expected:
+// File /usr/include/uchar.h Line 38: cannot combine with previous 'type-name' declaration specifier
+// File /usr/include/uchar.h Line 39: cannot combine with previous 'type-name' declaration specifier
+// 2 errors generated.
+// XFAIL: LIBCXX-AIX-FIXME
+
+#include <uchar.h>
+
+using U = decltype(::c8rtomb);
+using V = decltype(::mbrtoc8);
+#if defined(_LIBCPP_HAS_NO_C8RTOMB_MBRTOC8)
+// expected-error at -3 {{no member named 'c8rtomb' in the global namespace}}
+// expected-error at -3 {{no member named 'mbrtoc8' in the global namespace}}
+#else
+// expected-no-diagnostics
+#endif
diff --git a/libcxx/test/support/test_macros.h b/libcxx/test/support/test_macros.h
index 7f7c6832a2565..0e0500b58d446 100644
--- a/libcxx/test/support/test_macros.h
+++ b/libcxx/test/support/test_macros.h
@@ -391,6 +391,10 @@ inline void DoNotOptimize(Tp const& value) {
# define TEST_HAS_NO_FGETPOS_FSETPOS
#endif
+#if defined(_LIBCPP_HAS_NO_C8RTOMB_MBRTOC8)
+# define TEST_HAS_NO_C8RTOMB_MBRTOC8
+#endif
+
#if defined(TEST_COMPILER_CLANG)
# define TEST_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
# define TEST_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
More information about the libcxx-commits
mailing list