[libc++] Enable libc++-specific tests for constexpr string

Reviewed By: ldionne, Mordante, #libc

Spies: libcxx-commits

Differential Revision: https://reviews.llvm.org/D128578
This commit is contained in:
Nikolas Klauser 2022-10-01 15:37:24 +02:00
parent ed2d3644ab
commit 7e6a193f13
6 changed files with 64 additions and 46 deletions

View File

@ -1786,7 +1786,7 @@ private:
allocator_type __a = __str.__alloc(); allocator_type __a = __str.__alloc();
auto __allocation = std::__allocate_at_least(__a, __str.__get_long_cap()); auto __allocation = std::__allocate_at_least(__a, __str.__get_long_cap());
__begin_lifetime(__allocation.ptr, __allocation.count); __begin_lifetime(__allocation.ptr, __allocation.count);
__clear_and_shrink(); __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
__alloc() = std::move(__a); __alloc() = std::move(__a);
__set_long_pointer(__allocation.ptr); __set_long_pointer(__allocation.ptr);
__set_long_cap(__allocation.count); __set_long_cap(__allocation.count);
@ -4050,9 +4050,7 @@ basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT
if(__is_long()) if(__is_long())
{ {
__alloc_traits::deallocate(__alloc(), __get_long_pointer(), capacity() + 1); __alloc_traits::deallocate(__alloc(), __get_long_pointer(), capacity() + 1);
__set_long_cap(0); __default_init();
__set_short_size(0);
traits_type::assign(*__get_short_pointer(), value_type());
} }
} }

View File

@ -33,9 +33,9 @@
#include "min_allocator.h" #include "min_allocator.h"
template <class S> template <class S>
void test() { TEST_CONSTEXPR_CXX20 bool test() {
// Test that a call to reserve() does shrink the string. // Test that a call to reserve() does shrink the string.
{ if (!TEST_IS_CONSTANT_EVALUATED) {
S s(1000, 'a'); S s(1000, 'a');
typename S::size_type old_cap = s.capacity(); typename S::size_type old_cap = s.capacity();
s.resize(20); s.resize(20);
@ -66,6 +66,8 @@ void test() {
s.reserve(0); s.reserve(0);
assert(s.capacity() == old_cap); assert(s.capacity() == old_cap);
} }
return true;
} }
int main(int, char**) { int main(int, char**) {
@ -75,5 +77,9 @@ int main(int, char**) {
test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >(); test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
#endif #endif
#if TEST_STD_VER > 17
static_assert(test<std::string>());
#endif
return 0; return 0;
} }

View File

@ -20,7 +20,8 @@
// alignment of the string heap buffer is hardcoded to 16 // alignment of the string heap buffer is hardcoded to 16
static const size_t alignment = 16; static const size_t alignment = 16;
void full_size() { template <class = int>
TEST_CONSTEXPR_CXX20 void full_size() {
std::string str; std::string str;
assert(str.max_size() == std::numeric_limits<size_t>::max() - alignment); assert(str.max_size() == std::numeric_limits<size_t>::max() - alignment);
@ -40,7 +41,8 @@ void full_size() {
assert(u32str.max_size() == std::numeric_limits<size_t>::max() / 4 - alignment); assert(u32str.max_size() == std::numeric_limits<size_t>::max() / 4 - alignment);
} }
void half_size() { template <class = int>
TEST_CONSTEXPR_CXX20 void half_size() {
std::string str; std::string str;
assert(str.max_size() == std::numeric_limits<size_t>::max() / 2 - alignment); assert(str.max_size() == std::numeric_limits<size_t>::max() / 2 - alignment);
@ -60,7 +62,7 @@ void half_size() {
assert(u32str.max_size() == std::numeric_limits<size_t>::max() / 4 - alignment); assert(u32str.max_size() == std::numeric_limits<size_t>::max() / 4 - alignment);
} }
bool test() { TEST_CONSTEXPR_CXX20 bool test() {
#if _LIBCPP_ABI_VERSION == 1 #if _LIBCPP_ABI_VERSION == 1
@ -100,7 +102,7 @@ bool test() {
int main(int, char**) { int main(int, char**) {
test(); test();
#if TEST_STD_VER > 17 #if TEST_STD_VER > 17
// static_assert(test()); static_assert(test());
#endif #endif
return 0; return 0;

View File

@ -18,8 +18,7 @@
#include "min_allocator.h" #include "min_allocator.h"
template <class S> template <class S>
void TEST_CONSTEXPR_CXX20 bool test()
test()
{ {
// Tests that a long string holding a SSO size string results in // Tests that a long string holding a SSO size string results in
// an SSO copy constructed value. // an SSO copy constructed value.
@ -29,21 +28,19 @@ test()
LIBCPP_ASSERT(s2.__invariants()); LIBCPP_ASSERT(s2.__invariants());
assert(s2 == s1); assert(s2 == s1);
assert(s2.capacity() < sizeof(S)); assert(s2.capacity() < sizeof(S));
return true;
} }
int main(int, char**) int main(int, char**)
{ {
{ test<std::basic_string<char, std::char_traits<char>, test_allocator<char> > >();
typedef test_allocator<char> A;
typedef std::basic_string<char, std::char_traits<char>, A> S;
test<S>();
}
#if TEST_STD_VER >= 11 #if TEST_STD_VER >= 11
{ test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
typedef min_allocator<char> A; #endif
typedef std::basic_string<char, std::char_traits<char>, A> S; #if TEST_STD_VER > 17
test<S>(); static_assert(test<std::basic_string<char, std::char_traits<char>, test_allocator<char>>>());
} static_assert(test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>());
#endif #endif
return 0; return 0;

View File

@ -15,25 +15,31 @@
#include "test_macros.h" #include "test_macros.h"
TEST_CONSTEXPR_CXX20 bool test() {
std::string l = "Long string so that allocation definitely, for sure, absolutely happens. Probably.";
std::string s = "short";
assert(l.__invariants());
assert(s.__invariants());
s.__clear_and_shrink();
assert(s.__invariants());
assert(s.size() == 0);
std::string::size_type cap = l.capacity();
l.__clear_and_shrink();
assert(l.__invariants());
assert(l.size() == 0);
assert(l.capacity() < cap);
return true;
}
int main(int, char**) int main(int, char**)
{ {
std::string l = "Long string so that allocation definitely, for sure, absolutely happens. Probably."; test();
std::string s = "short"; #if TEST_STD_VER > 17
static_assert(test());
assert(l.__invariants()); #endif
assert(s.__invariants()); return 0;
s.__clear_and_shrink();
assert(s.__invariants());
assert(s.size() == 0);
{
std::string::size_type cap = l.capacity();
l.__clear_and_shrink();
assert(l.__invariants());
assert(l.size() == 0);
assert(l.capacity() < cap);
}
return 0;
} }

View File

@ -15,14 +15,14 @@
#include "test_macros.h" #include "test_macros.h"
void write_c_str(char *buf, int size) { TEST_CONSTEXPR_CXX20 void write_c_str(char *buf, int size) {
for (int i=0; i < size; ++i) { for (int i=0; i < size; ++i) {
buf[i] = 'a'; buf[i] = 'a';
} }
buf[size] = '\0'; buf[size] = '\0';
} }
void test_buffer_usage() TEST_CONSTEXPR_CXX20 void test_buffer_usage()
{ {
{ {
unsigned buff_size = 125; unsigned buff_size = 125;
@ -31,7 +31,7 @@ void test_buffer_usage()
s.__resize_default_init(buff_size); s.__resize_default_init(buff_size);
write_c_str(&s[0], used_size); write_c_str(&s[0], used_size);
assert(s.size() == buff_size); assert(s.size() == buff_size);
assert(strlen(s.data()) == used_size); assert(std::char_traits<char>().length(s.data()) == used_size);
s.__resize_default_init(used_size); s.__resize_default_init(used_size);
assert(s.size() == used_size); assert(s.size() == used_size);
assert(s.data()[used_size] == '\0'); assert(s.data()[used_size] == '\0');
@ -41,7 +41,7 @@ void test_buffer_usage()
} }
} }
void test_basic() { TEST_CONSTEXPR_CXX20 void test_basic() {
{ {
std::string s; std::string s;
s.__resize_default_init(3); s.__resize_default_init(3);
@ -56,9 +56,18 @@ void test_basic() {
} }
} }
int main(int, char**) { TEST_CONSTEXPR_CXX20 bool test() {
test_basic(); test_basic();
test_buffer_usage(); test_buffer_usage();
return true;
}
int main(int, char**) {
test();
#if TEST_STD_VER > 17
static_assert(test());
#endif
return 0; return 0;
} }