[libc++] Add an option to disable wide character support in libc++

Some embedded platforms do not wish to support the C library functionality
for handling wchar_t because they have no use for it. It makes sense for
libc++ to work properly on those platforms, so this commit adds a carve-out
of functionality for wchar_t.

Unfortunately, unlike some other carve-outs (e.g. random device), this
patch touches several parts of the library. However, despite the wide
impact of this patch, I still think it is important to support this
configuration since it makes it much simpler to port libc++ to some
embedded platforms.

Differential Revision: https://reviews.llvm.org/D111265
This commit is contained in:
Louis Dionne
2021-08-23 15:32:36 -04:00
parent c6828e0cea
commit f4c1258d56
612 changed files with 3833 additions and 1633 deletions

View File

@@ -30,7 +30,9 @@ struct throwing_alloc
// Test that it's possible to take the address of basic_string's destructors
// by creating globals which will register their destructors with cxa_atexit.
std::string s;
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
std::wstring ws;
#endif
int main(int, char**)
{

View File

@@ -62,18 +62,22 @@ int main(int, char**)
ASSERT_SAME_TYPE(decltype(s), std::string);
assert(s == "aaaaaa");
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
std::basic_string w(2ull, L'b');
ASSERT_SAME_TYPE(decltype(w), std::wstring);
assert(w == L"bb");
#endif
}
{ // Testing (3) w/ allocator
std::basic_string s(6ull, 'a', test_allocator<char>{});
ASSERT_SAME_TYPE(decltype(s), BStr<char,test_allocator<char>>);
assert(s == "aaaaaa");
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
std::basic_string w(2ull, L'b', test_allocator<wchar_t>{});
ASSERT_SAME_TYPE(decltype(w), BStr<wchar_t, test_allocator<wchar_t>>);
assert(w == L"bb");
#endif
}
{ // Testing (4) w/o allocator
const std::string sin("abc");
@@ -81,6 +85,7 @@ int main(int, char**)
ASSERT_SAME_TYPE(decltype(s), std::string);
assert(s == "bc");
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
using WStr = std::basic_string<wchar_t,
constexpr_char_traits<wchar_t>,
test_allocator<wchar_t>>;
@@ -88,6 +93,7 @@ int main(int, char**)
std::basic_string w(win, (TestSizeT)3);
ASSERT_SAME_TYPE(decltype(w), WStr);
assert(w == L"def");
#endif
}
{ // Testing (4) w/ allocator
const std::string sin("abc");
@@ -95,6 +101,7 @@ int main(int, char**)
ASSERT_SAME_TYPE(decltype(s), std::string);
assert(s == "bc");
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
using WStr = std::basic_string<wchar_t,
constexpr_char_traits<wchar_t>,
test_allocator<wchar_t>>;
@@ -102,6 +109,7 @@ int main(int, char**)
std::basic_string w(win, (TestSizeT)3, test_allocator<wchar_t>{});
ASSERT_SAME_TYPE(decltype(w), WStr);
assert(w == L"def");
#endif
}
{ // Testing (5) w/o allocator
const std::string sin("abc");
@@ -109,6 +117,7 @@ int main(int, char**)
ASSERT_SAME_TYPE(decltype(s), std::string);
assert(s == "bc");
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
using WStr = std::basic_string<wchar_t,
constexpr_char_traits<wchar_t>,
test_allocator<wchar_t>>;
@@ -116,6 +125,7 @@ int main(int, char**)
std::basic_string w(win, (TestSizeT)2, (TestSizeT)3);
ASSERT_SAME_TYPE(decltype(w), WStr);
assert(w == L"cde");
#endif
}
{ // Testing (5) w/ allocator
const std::string sin("abc");
@@ -123,6 +133,7 @@ int main(int, char**)
ASSERT_SAME_TYPE(decltype(s), std::string);
assert(s == "bc");
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
using WStr = std::basic_string<wchar_t,
constexpr_char_traits<wchar_t>,
test_allocator<wchar_t>>;
@@ -130,48 +141,57 @@ int main(int, char**)
std::basic_string w(win, (TestSizeT)2, (TestSizeT)3, test_allocator<wchar_t>{});
ASSERT_SAME_TYPE(decltype(w), WStr);
assert(w == L"cde");
#endif
}
{ // Testing (6) w/o allocator
std::basic_string s("abc", (size_t)2);
ASSERT_SAME_TYPE(decltype(s), std::string);
assert(s == "ab");
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
std::basic_string w(L"abcdef", (size_t)3);
ASSERT_SAME_TYPE(decltype(w), std::wstring);
assert(w == L"abc");
#endif
}
{ // Testing (6) w/ allocator
std::basic_string s("abc", (size_t)2, std::allocator<char>{});
ASSERT_SAME_TYPE(decltype(s), std::string);
assert(s == "ab");
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
using WStr = std::basic_string<wchar_t,
std::char_traits<wchar_t>,
test_allocator<wchar_t>>;
std::basic_string w(L"abcdef", (TestSizeT)3, test_allocator<wchar_t>{});
ASSERT_SAME_TYPE(decltype(w), WStr);
assert(w == L"abc");
#endif
}
{ // Testing (7) w/o allocator
std::basic_string s("abc");
ASSERT_SAME_TYPE(decltype(s), std::string);
assert(s == "abc");
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
std::basic_string w(L"abcdef");
ASSERT_SAME_TYPE(decltype(w), std::wstring);
assert(w == L"abcdef");
#endif
}
{ // Testing (7) w/ allocator
std::basic_string s("abc", std::allocator<char>{});
ASSERT_SAME_TYPE(decltype(s), std::string);
assert(s == "abc");
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
using WStr = std::basic_string<wchar_t,
std::char_traits<wchar_t>,
test_allocator<wchar_t>>;
std::basic_string w(L"abcdef", test_allocator<wchar_t>{});
ASSERT_SAME_TYPE(decltype(w), WStr);
assert(w == L"abcdef");
#endif
}
{ // (8) w/o allocator
using It = cpp17_input_iterator<const char*>;
@@ -181,12 +201,24 @@ int main(int, char**)
assert(s == "abc");
}
{ // (8) w/ allocator
using ExpectW = std::basic_string<wchar_t, std::char_traits<wchar_t>, test_allocator<wchar_t>>;
using It = cpp17_input_iterator<const wchar_t*>;
const wchar_t* input = L"abcdef";
std::basic_string s(It(input), It(input + 3), test_allocator<wchar_t>{});
ASSERT_SAME_TYPE(decltype(s), ExpectW);
assert(s == L"abc");
{
using Expect = std::basic_string<char, std::char_traits<char>, test_allocator<char>>;
using It = cpp17_input_iterator<const char*>;
const char* input = "abcdef";
std::basic_string s(It(input), It(input + 3), test_allocator<char>{});
ASSERT_SAME_TYPE(decltype(s), Expect);
assert(s == "abc");
}
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
{
using ExpectW = std::basic_string<wchar_t, std::char_traits<wchar_t>, test_allocator<wchar_t>>;
using It = cpp17_input_iterator<const wchar_t*>;
const wchar_t* input = L"abcdef";
std::basic_string s(It(input), It(input + 3), test_allocator<wchar_t>{});
ASSERT_SAME_TYPE(decltype(s), ExpectW);
assert(s == L"abc");
}
#endif
}
{ // Testing (9)
const std::string sin("abc");
@@ -194,6 +226,7 @@ int main(int, char**)
ASSERT_SAME_TYPE(decltype(s), std::string);
assert(s == "abc");
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
using WStr = std::basic_string<wchar_t,
constexpr_char_traits<wchar_t>,
test_allocator<wchar_t>>;
@@ -201,6 +234,7 @@ int main(int, char**)
std::basic_string w(win);
ASSERT_SAME_TYPE(decltype(w), WStr);
assert(w == L"abcdef");
#endif
}
{ // Testing (10)
const std::string sin("abc");
@@ -208,6 +242,7 @@ int main(int, char**)
ASSERT_SAME_TYPE(decltype(s), std::string);
assert(s == "abc");
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
using WStr = std::basic_string<wchar_t,
constexpr_char_traits<wchar_t>,
test_allocator<wchar_t>>;
@@ -215,6 +250,7 @@ int main(int, char**)
std::basic_string w(win, test_allocator<wchar_t>{});
ASSERT_SAME_TYPE(decltype(w), WStr);
assert(w == L"abcdef");
#endif
}
{ // Testing (11)
std::string sin("abc");
@@ -222,6 +258,7 @@ int main(int, char**)
ASSERT_SAME_TYPE(decltype(s), std::string);
assert(s == "abc");
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
using WStr = std::basic_string<wchar_t,
constexpr_char_traits<wchar_t>,
test_allocator<wchar_t>>;
@@ -229,6 +266,7 @@ int main(int, char**)
std::basic_string w(std::move(win));
ASSERT_SAME_TYPE(decltype(w), WStr);
assert(w == L"abcdef");
#endif
}
{ // Testing (12)
std::string sin("abc");
@@ -236,6 +274,7 @@ int main(int, char**)
ASSERT_SAME_TYPE(decltype(s), std::string);
assert(s == "abc");
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
using WStr = std::basic_string<wchar_t,
constexpr_char_traits<wchar_t>,
test_allocator<wchar_t>>;
@@ -243,24 +282,29 @@ int main(int, char**)
std::basic_string w(std::move(win), test_allocator<wchar_t>{});
ASSERT_SAME_TYPE(decltype(w), WStr);
assert(w == L"abcdef");
#endif
}
{ // Testing (13) w/o allocator
std::basic_string s({'a', 'b', 'c'});
ASSERT_SAME_TYPE(decltype(s), std::string);
assert(s == "abc");
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
std::basic_string w({L'a', L'b', L'c'});
ASSERT_SAME_TYPE(decltype(w), std::wstring);
assert(w == L"abc");
#endif
}
{ // Testing (13) w/ allocator
std::basic_string s({'a', 'b', 'c'}, test_allocator<char>{});
ASSERT_SAME_TYPE(decltype(s), BStr<char, test_allocator<char>>);
assert(s == "abc");
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
std::basic_string w({L'a', L'b', L'c'}, test_allocator<wchar_t>{});
ASSERT_SAME_TYPE(decltype(w), BStr<wchar_t, test_allocator<wchar_t>>);
assert(w == L"abc");
#endif
}
{ // Testing (14) w/o allocator
std::string_view sv("abc");
@@ -268,11 +312,13 @@ int main(int, char**)
ASSERT_SAME_TYPE(decltype(s), std::string);
assert(s == "abc");
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
using Expect = std::basic_string<wchar_t, constexpr_char_traits<wchar_t>>;
std::basic_string_view<wchar_t, constexpr_char_traits<wchar_t>> BSV(L"abcdef");
std::basic_string w(BSV);
ASSERT_SAME_TYPE(decltype(w), Expect);
assert(w == L"abcdef");
#endif
}
{ // Testing (14) w/ allocator
using ExpectS = std::basic_string<char, std::char_traits<char>, test_allocator<char>>;
@@ -281,12 +327,14 @@ int main(int, char**)
ASSERT_SAME_TYPE(decltype(s), ExpectS);
assert(s == "abc");
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
using ExpectW = std::basic_string<wchar_t, constexpr_char_traits<wchar_t>,
test_allocator<wchar_t>>;
std::basic_string_view<wchar_t, constexpr_char_traits<wchar_t>> BSV(L"abcdef");
std::basic_string w(BSV, test_allocator<wchar_t>{});
ASSERT_SAME_TYPE(decltype(w), ExpectW);
assert(w == L"abcdef");
#endif
}
{ // Testing (15) w/o allocator
std::string s0("abc");
@@ -294,10 +342,12 @@ int main(int, char**)
ASSERT_SAME_TYPE(decltype(s), std::string);
assert(s == "b");
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
std::wstring w0(L"abcdef");
std::basic_string w(w0, 2, 2);
ASSERT_SAME_TYPE(decltype(w), std::wstring);
assert(w == L"cd");
#endif
}
{ // Testing (15) w/ allocator
using ExpectS = std::basic_string<char, std::char_traits<char>, test_allocator<char>>;
@@ -306,11 +356,13 @@ int main(int, char**)
ASSERT_SAME_TYPE(decltype(s), ExpectS);
assert(s == "b");
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
using ExpectW = std::basic_string<wchar_t, std::char_traits<wchar_t>, test_allocator<wchar_t>>;
ExpectW w0(L"abcdef");
std::basic_string w(w0, 2, 2, test_allocator<wchar_t>{6});
ASSERT_SAME_TYPE(decltype(w), ExpectW);
assert(w == L"cd");
#endif
}
return 0;

View File

@@ -25,22 +25,26 @@ int main(int, char**)
std::string s = {'a', 'b', 'c'};
assert(s == "abc");
}
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
{
std::wstring s;
s = {L'a', L'b', L'c'};
assert(s == L"abc");
}
#endif
{
typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
S s = {'a', 'b', 'c'};
assert(s == "abc");
}
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
{
typedef std::basic_string<wchar_t, std::char_traits<wchar_t>, min_allocator<wchar_t>> S;
S s;
s = {L'a', L'b', L'c'};
assert(s == L"abc");
}
#endif
return 0;
}

View File

@@ -59,6 +59,7 @@ int main(int, char**)
assert(s1.size() == sv.size());
assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0);
}
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
{
std::wstring_view sv = L"12345678901234";
std::basic_string s1{sv, test_allocator<wchar_t>{}};
@@ -69,6 +70,7 @@ int main(int, char**)
assert(s1.size() == sv.size());
assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0);
}
#endif
#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
{
std::u8string_view sv = u8"12345678901234";

View File

@@ -63,6 +63,7 @@ int main(int, char**)
assert(s1.size() == 4);
assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0);
}
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
{
std::wstring_view sv = L"12345678901234";
std::basic_string s1{sv, 0, 4, test_allocator<wchar_t>{}};
@@ -73,6 +74,7 @@ int main(int, char**)
assert(s1.size() == 4);
assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0);
}
#endif
#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L
{
std::u8string_view sv = u8"12345678901234";