[libc++] Move preferred_name declarations into the forward declaring headers and add pmr preferred names
We currently define the preferred names in multiple places. `basic_string` and `basic_string_view` also have a lot of aliases, which makes the declarations quite long. So let's only add the preferred names in forward-declaring headers to make the implementation more readable and have all the preferred names in one place.
Reviewed By: ldionne
Spies: EricWF, krytarowski, libcxx-commits
Differential Revision: https://reviews.llvm.org/D135824
NOKEYCHECK=True
GitOrigin-RevId: 627465cf9fa71ac1933986c20b32d6842a5b2678
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index 99a1529..7603b37 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -342,8 +342,10 @@
__fwd/array.h
__fwd/get.h
__fwd/hash.h
+ __fwd/memory_resource.h
__fwd/pair.h
__fwd/span.h
+ __fwd/string.h
__fwd/string_view.h
__fwd/tuple.h
__hash_table
diff --git a/include/__fwd/memory_resource.h b/include/__fwd/memory_resource.h
new file mode 100644
index 0000000..718a907
--- /dev/null
+++ b/include/__fwd/memory_resource.h
@@ -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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FWD_MEMORY_RESOURCE_H
+#define _LIBCPP___FWD_MEMORY_RESOURCE_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace pmr {
+template <class _ValueType>
+class _LIBCPP_TEMPLATE_VIS polymorphic_allocator;
+} // namespace pmr
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FWD_MEMORY_RESOURCE_H
diff --git a/include/__fwd/string.h b/include/__fwd/string.h
new file mode 100644
index 0000000..7ab5561
--- /dev/null
+++ b/include/__fwd/string.h
@@ -0,0 +1,110 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___FWD_STRING_H
+#define _LIBCPP___FWD_STRING_H
+
+#include <__config>
+#include <__fwd/memory_resource.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _CharT>
+struct _LIBCPP_TEMPLATE_VIS char_traits;
+template <>
+struct char_traits<char>;
+
+#ifndef _LIBCPP_HAS_NO_CHAR8_T
+template <>
+struct char_traits<char8_t>;
+#endif
+
+template <>
+struct char_traits<char16_t>;
+template <>
+struct char_traits<char32_t>;
+
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+template <>
+struct char_traits<wchar_t>;
+#endif
+
+template <class _Tp>
+class _LIBCPP_TEMPLATE_VIS allocator;
+
+template <class _CharT, class _Traits = char_traits<_CharT>, class _Allocator = allocator<_CharT> >
+class _LIBCPP_TEMPLATE_VIS basic_string;
+
+using string = basic_string<char>;
+
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+using wstring = basic_string<wchar_t>;
+#endif
+
+#ifndef _LIBCPP_HAS_NO_CHAR8_T
+using u8string = basic_string<char8_t>;
+#endif
+
+using u16string = basic_string<char16_t>;
+using u32string = basic_string<char32_t>;
+
+#if _LIBCPP_STD_VER >= 17
+
+namespace pmr {
+template <class _CharT, class _Traits = char_traits<_CharT>>
+using basic_string = std::basic_string<_CharT, _Traits, polymorphic_allocator<_CharT>>;
+
+using string = basic_string<char>;
+
+# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+using wstring = basic_string<wchar_t>;
+# endif
+
+# ifndef _LIBCPP_HAS_NO_CHAR8_T
+using u8string = basic_string<char8_t>;
+# endif
+
+using u16string = basic_string<char16_t>;
+using u32string = basic_string<char32_t>;
+
+} // namespace pmr
+
+#endif // _LIBCPP_STD_VER >= 17
+
+// clang-format off
+template <class _CharT, class _Traits, class _Allocator>
+class _LIBCPP_PREFERRED_NAME(string)
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+ _LIBCPP_PREFERRED_NAME(wstring)
+#endif
+#ifndef _LIBCPP_HAS_NO_CHAR8_T
+ _LIBCPP_PREFERRED_NAME(u8string)
+#endif
+ _LIBCPP_PREFERRED_NAME(u16string)
+ _LIBCPP_PREFERRED_NAME(u32string)
+#if _LIBCPP_STD_VER >= 17
+ _LIBCPP_PREFERRED_NAME(pmr::string)
+# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+ _LIBCPP_PREFERRED_NAME(pmr::wstring)
+# endif
+# ifndef _LIBCPP_HAS_NO_CHAR8_T
+ _LIBCPP_PREFERRED_NAME(pmr::u8string)
+# endif
+ _LIBCPP_PREFERRED_NAME(pmr::u16string)
+ _LIBCPP_PREFERRED_NAME(pmr::u32string)
+#endif
+ basic_string;
+// clang-format on
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FWD_STRING_H
diff --git a/include/__fwd/string_view.h b/include/__fwd/string_view.h
index 4324c9f..4818990 100644
--- a/include/__fwd/string_view.h
+++ b/include/__fwd/string_view.h
@@ -32,6 +32,19 @@
typedef basic_string_view<wchar_t> wstring_view;
#endif
+// clang-format off
+template <class _CharT, class _Traits>
+class _LIBCPP_PREFERRED_NAME(string_view)
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+ _LIBCPP_PREFERRED_NAME(wstring_view)
+#endif
+#ifndef _LIBCPP_HAS_NO_CHAR8_T
+ _LIBCPP_PREFERRED_NAME(u8string_view)
+#endif
+ _LIBCPP_PREFERRED_NAME(u16string_view)
+ _LIBCPP_PREFERRED_NAME(u32string_view)
+ basic_string_view;
+// clang-format on
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___FWD_STRING_VIEW_H
diff --git a/include/iosfwd b/include/iosfwd
index 9cd9450..7948606 100644
--- a/include/iosfwd
+++ b/include/iosfwd
@@ -96,6 +96,7 @@
#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
+#include <__fwd/string.h>
#include <__mbstate_t.h>
#include <version>
@@ -107,19 +108,6 @@
class _LIBCPP_TYPE_VIS ios_base;
-template<class _CharT> struct _LIBCPP_TEMPLATE_VIS char_traits;
-template<> struct char_traits<char>;
-#ifndef _LIBCPP_HAS_NO_CHAR8_T
-template<> struct char_traits<char8_t>;
-#endif
-template<> struct char_traits<char16_t>;
-template<> struct char_traits<char32_t>;
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-template<> struct char_traits<wchar_t>;
-#endif
-
-template<class _Tp> class _LIBCPP_TEMPLATE_VIS allocator;
-
template <class _CharT, class _Traits = char_traits<_CharT> >
class _LIBCPP_TEMPLATE_VIS basic_ios;
@@ -242,18 +230,6 @@
typedef long long streamoff; // for char_traits in <string>
#endif
-template <class _CharT, // for <stdexcept>
- class _Traits = char_traits<_CharT>,
- class _Allocator = allocator<_CharT> >
- class _LIBCPP_TEMPLATE_VIS basic_string;
-typedef basic_string<char, char_traits<char>, allocator<char> > string;
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > wstring;
-#endif
-
-template <class _CharT, class _Traits, class _Allocator>
- class _LIBCPP_PREFERRED_NAME(string) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wstring)) basic_string;
-
// Include other forward declarations here
template <class _Tp, class _Alloc = allocator<_Tp> >
class _LIBCPP_TEMPLATE_VIS vector;
diff --git a/include/module.modulemap.in b/include/module.modulemap.in
index a7e3ff0..c33f5a8 100644
--- a/include/module.modulemap.in
+++ b/include/module.modulemap.in
@@ -988,6 +988,7 @@
module __memory_resource {
module memory_resource { private header "__memory_resource/memory_resource.h" }
+ module memory_resource_fwd { private header "__fwd/memory_resource.h" }
module monotonic_buffer_resource { private header "__memory_resource/monotonic_buffer_resource.h" }
module polymorphic_allocator { private header "__memory_resource/polymorphic_allocator.h" }
module pool_options { private header "__memory_resource/pool_options.h" }
@@ -1218,6 +1219,7 @@
module __string {
module char_traits { private header "__string/char_traits.h" }
module extern_template_lists { private header "__string/extern_template_lists.h" }
+ module string_fwd { private header "__fwd/string.h" }
}
export *
}
diff --git a/include/regex b/include/regex
index d45f6c1..91a10fe 100644
--- a/include/regex
+++ b/include/regex
@@ -6845,9 +6845,12 @@
using match_results = std::match_results<_BidirT, polymorphic_allocator<std::sub_match<_BidirT>>>;
using cmatch = match_results<const char*>;
-using wcmatch = match_results<const wchar_t*>;
using smatch = match_results<std::pmr::string::const_iterator>;
+
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+using wcmatch = match_results<const wchar_t*>;
using wsmatch = match_results<std::pmr::wstring::const_iterator>;
+#endif
} // namespace pmr
_LIBCPP_END_NAMESPACE_STD
#endif
diff --git a/include/string b/include/string
index 652fa32..8eb1d30 100644
--- a/include/string
+++ b/include/string
@@ -539,6 +539,7 @@
#include <__format/enable_insertable.h>
#include <__functional/hash.h>
#include <__functional/unary_function.h>
+#include <__fwd/string.h>
#include <__ios/fpos.h>
#include <__iterator/distance.h>
#include <__iterator/iterator_traits.h>
@@ -565,7 +566,6 @@
#include <cstdio> // EOF
#include <cstdlib>
#include <cstring>
-#include <iosfwd>
#include <limits>
#include <stdexcept>
#include <string_view>
@@ -646,23 +646,10 @@
!is_convertible<const _Tp&, const _CharT*>::value
> {};
-#ifndef _LIBCPP_HAS_NO_CHAR8_T
-typedef basic_string<char8_t> u8string;
-#endif
-typedef basic_string<char16_t> u16string;
-typedef basic_string<char32_t> u32string;
-
struct __uninitialized_size_tag {};
template<class _CharT, class _Traits, class _Allocator>
-class
- _LIBCPP_TEMPLATE_VIS
-#ifndef _LIBCPP_HAS_NO_CHAR8_T
- _LIBCPP_PREFERRED_NAME(u8string)
-#endif
- _LIBCPP_PREFERRED_NAME(u16string)
- _LIBCPP_PREFERRED_NAME(u32string)
- basic_string
+class basic_string
{
public:
typedef basic_string __self;
@@ -4674,20 +4661,6 @@
_LIBCPP_END_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 14
-_LIBCPP_BEGIN_NAMESPACE_STD
-namespace pmr {
-template <class _CharT, class _TraitsT = std::char_traits<_CharT>>
-using basic_string = std::basic_string<_CharT, _TraitsT, polymorphic_allocator<_CharT>>;
-
-using string = basic_string<char>;
-using u16string = basic_string<char16_t>;
-using u32string = basic_string<char32_t>;
-using wstring = basic_string<wchar_t>;
-} // namespace pmr
-_LIBCPP_END_NAMESPACE_STD
-#endif
-
_LIBCPP_POP_MACROS
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
diff --git a/include/string_view b/include/string_view
index 2941f71..2c4f306 100644
--- a/include/string_view
+++ b/include/string_view
@@ -256,15 +256,7 @@
}
template<class _CharT, class _Traits>
-class
- _LIBCPP_PREFERRED_NAME(string_view)
-#ifndef _LIBCPP_HAS_NO_CHAR8_T
- _LIBCPP_PREFERRED_NAME(u8string_view)
-#endif
- _LIBCPP_PREFERRED_NAME(u16string_view)
- _LIBCPP_PREFERRED_NAME(u32string_view)
- _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wstring_view))
- basic_string_view {
+class basic_string_view {
public:
// types
typedef _Traits traits_type;
diff --git a/test/libcxx/private_headers.verify.cpp b/test/libcxx/private_headers.verify.cpp
index 23c6940..928ce0c 100644
--- a/test/libcxx/private_headers.verify.cpp
+++ b/test/libcxx/private_headers.verify.cpp
@@ -374,8 +374,10 @@
#include <__fwd/array.h> // expected-error@*:* {{use of private header from outside its module: '__fwd/array.h'}}
#include <__fwd/get.h> // expected-error@*:* {{use of private header from outside its module: '__fwd/get.h'}}
#include <__fwd/hash.h> // expected-error@*:* {{use of private header from outside its module: '__fwd/hash.h'}}
+#include <__fwd/memory_resource.h> // expected-error@*:* {{use of private header from outside its module: '__fwd/memory_resource.h'}}
#include <__fwd/pair.h> // expected-error@*:* {{use of private header from outside its module: '__fwd/pair.h'}}
#include <__fwd/span.h> // expected-error@*:* {{use of private header from outside its module: '__fwd/span.h'}}
+#include <__fwd/string.h> // expected-error@*:* {{use of private header from outside its module: '__fwd/string.h'}}
#include <__fwd/string_view.h> // expected-error@*:* {{use of private header from outside its module: '__fwd/string_view.h'}}
#include <__fwd/tuple.h> // expected-error@*:* {{use of private header from outside its module: '__fwd/tuple.h'}}
#include <__ios/fpos.h> // expected-error@*:* {{use of private header from outside its module: '__ios/fpos.h'}}
diff --git a/test/std/utilities/utility/mem.res/mem.res.aliases/header_regex_synop.pass.cpp b/test/std/utilities/utility/mem.res/mem.res.aliases/header_regex_synop.pass.cpp
index 14c605e..1414108 100644
--- a/test/std/utilities/utility/mem.res/mem.res.aliases/header_regex_synop.pass.cpp
+++ b/test/std/utilities/utility/mem.res/mem.res.aliases/header_regex_synop.pass.cpp
@@ -32,6 +32,8 @@
#include <memory_resource>
#include <type_traits>
+#include "test_macros.h"
+
template <class Iter, class PmrTypedef>
void test_match_result_typedef() {
using StdMR = std::match_results<Iter, std::pmr::polymorphic_allocator<std::sub_match<Iter>>>;
@@ -43,9 +45,11 @@
int main(int, char**) {
{
test_match_result_typedef<const char*, std::pmr::cmatch>();
- test_match_result_typedef<const wchar_t*, std::pmr::wcmatch>();
test_match_result_typedef<std::pmr::string::const_iterator, std::pmr::smatch>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test_match_result_typedef<const wchar_t*, std::pmr::wcmatch>();
test_match_result_typedef<std::pmr::wstring::const_iterator, std::pmr::wsmatch>();
+#endif
}
{
// Check that std::match_results has been included and is complete.
diff --git a/test/std/utilities/utility/mem.res/mem.res.aliases/header_string_synop.pass.cpp b/test/std/utilities/utility/mem.res/mem.res.aliases/header_string_synop.pass.cpp
index d694a39..9ae4b67 100644
--- a/test/std/utilities/utility/mem.res/mem.res.aliases/header_string_synop.pass.cpp
+++ b/test/std/utilities/utility/mem.res/mem.res.aliases/header_string_synop.pass.cpp
@@ -30,6 +30,7 @@
#include <type_traits>
#include "constexpr_char_traits.h"
+#include "test_macros.h"
template <class Char, class PmrTypedef>
void test_string_typedef() {
@@ -49,13 +50,17 @@
int main(int, char**) {
{
test_string_typedef<char, std::pmr::string>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
test_string_typedef<wchar_t, std::pmr::wstring>();
+#endif
test_string_typedef<char16_t, std::pmr::u16string>();
test_string_typedef<char32_t, std::pmr::u32string>();
}
{
test_basic_string_alias<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
test_basic_string_alias<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
test_basic_string_alias<char16_t, constexpr_char_traits<char16_t>>();
test_basic_string_alias<char32_t, constexpr_char_traits<char32_t>>();
}
diff --git a/test/std/utilities/utility/mem.res/mem.res.aliases/header_string_synop2.pass.cpp b/test/std/utilities/utility/mem.res/mem.res.aliases/header_string_synop2.pass.cpp
index b25300a..2f70806 100644
--- a/test/std/utilities/utility/mem.res/mem.res.aliases/header_string_synop2.pass.cpp
+++ b/test/std/utilities/utility/mem.res/mem.res.aliases/header_string_synop2.pass.cpp
@@ -23,11 +23,15 @@
#include <string>
+#include "test_macros.h"
+
int main(int, char**) {
{
// Check that std::pmr::string is usable without <memory_resource>.
std::pmr::string s;
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
std::pmr::wstring ws;
+#endif
std::pmr::u16string u16s;
std::pmr::u32string u32s;
}