1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
13 // template<class Operation>
14 // void resize_and_overwrite(size_type n, Operation op)
20 #include "make_string.h"
21 #include "test_macros.h"
24 constexpr void test_appending(std::size_t k
, size_t N
, size_t new_capacity
) {
26 assert(new_capacity
>= N
);
28 s
.resize_and_overwrite(new_capacity
, [&](auto* p
, auto n
) {
29 assert(n
== new_capacity
);
30 LIBCPP_ASSERT(s
.size() == new_capacity
);
31 LIBCPP_ASSERT(s
.begin().base() == p
);
32 assert(std::all_of(p
, p
+ k
, [](const auto ch
) { return ch
== 'a'; }));
33 std::fill(p
+ k
, p
+ n
, 'b');
34 p
[n
] = 'c'; // will be overwritten
37 const S expected
= S(k
, 'a') + S(N
- k
, 'b');
38 assert(s
== expected
);
39 assert(s
.c_str()[N
] == '\0');
43 constexpr void test_truncating(std::size_t o
, size_t N
) {
46 s
.resize_and_overwrite(N
, [&](auto* p
, auto n
) {
48 LIBCPP_ASSERT(s
.size() == n
);
49 LIBCPP_ASSERT(s
.begin().base() == p
);
50 assert(std::all_of(p
, p
+ n
, [](auto ch
) { return ch
== 'a'; }));
52 p
[n
] = 'c'; // will be overwritten
55 const S expected
= S(N
- 1, 'a') + S(1, 'b');
56 assert(s
== expected
);
57 assert(s
.c_str()[N
] == '\0');
60 template <class String
>
61 constexpr bool test() {
62 test_appending
<String
>(10, 15, 15);
63 test_appending
<String
>(10, 15, 20);
64 test_appending
<String
>(10, 40, 40);
65 test_appending
<String
>(10, 40, 50);
66 test_appending
<String
>(30, 35, 35);
67 test_appending
<String
>(30, 35, 45);
68 test_appending
<String
>(10, 15, 30);
69 test_truncating
<String
>(15, 10);
70 test_truncating
<String
>(40, 35);
71 test_truncating
<String
>(40, 10);
76 void test_value_categories() {
78 s
.resize_and_overwrite(10, [](char*&&, std::size_t&&) { return 0; });
79 s
.resize_and_overwrite(10, [](char* const&, const std::size_t&) { return 0; });
81 int operator()(char*, std::size_t) && { return 0; }
83 s
.resize_and_overwrite(10, RefQualified
{});
86 int main(int, char**) {
87 test
<std::basic_string
<char, std::char_traits
<char>, std::allocator
<char>>>();
88 test
<std::basic_string
<char8_t
, std::char_traits
<char8_t
>, std::allocator
<char8_t
>>>();
89 test
<std::basic_string
<char16_t
, std::char_traits
<char16_t
>, std::allocator
<char16_t
>>>();
90 test
<std::basic_string
<char32_t
, std::char_traits
<char32_t
>, std::allocator
<char32_t
>>>();
92 static_assert(test
<std::basic_string
<char, std::char_traits
<char>, std::allocator
<char>>>());
93 static_assert(test
<std::basic_string
<char8_t
, std::char_traits
<char8_t
>, std::allocator
<char8_t
>>>());
94 static_assert(test
<std::basic_string
<char16_t
, std::char_traits
<char16_t
>, std::allocator
<char16_t
>>>());
95 static_assert(test
<std::basic_string
<char32_t
, std::char_traits
<char32_t
>, std::allocator
<char32_t
>>>());
97 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
98 test
<std::basic_string
<wchar_t, std::char_traits
<wchar_t>, std::allocator
<wchar_t>>>();
99 static_assert(test
<std::basic_string
<wchar_t, std::char_traits
<wchar_t>, std::allocator
<wchar_t>>>());