Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libcxx / test / std / strings / basic.string / string.capacity / resize_and_overwrite.pass.cpp
blobbbe6551a0ff1181dc1e99b8b09d476607662f952
1 //===----------------------------------------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
11 // <string>
13 // template<class Operation>
14 // void resize_and_overwrite(size_type n, Operation op)
16 #include <algorithm>
17 #include <cassert>
18 #include <string>
20 #include "make_string.h"
21 #include "test_macros.h"
23 template <class S>
24 constexpr void test_appending(std::size_t k, size_t N, size_t new_capacity) {
25 assert(N > k);
26 assert(new_capacity >= N);
27 auto s = S(k, 'a');
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
35 return N;
36 });
37 const S expected = S(k, 'a') + S(N - k, 'b');
38 assert(s == expected);
39 assert(s.c_str()[N] == '\0');
42 template <class S>
43 constexpr void test_truncating(std::size_t o, size_t N) {
44 assert(N < o);
45 auto s = S(o, 'a');
46 s.resize_and_overwrite(N, [&](auto* p, auto n) {
47 assert(n == 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'; }));
51 p[n - 1] = 'b';
52 p[n] = 'c'; // will be overwritten
53 return n;
54 });
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);
73 return true;
76 void test_value_categories() {
77 std::string s;
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; });
80 struct RefQualified {
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>>>());
100 #endif
101 return 0;