Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libcxx / test / std / strings / basic.string / string.modifiers / string_insert / iter_iter_iter.pass.cpp
blobe3d0f1322e85de2b255ca36c369604f255f62a9e
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 // <string>
11 // template<class InputIterator>
12 // iterator insert(const_iterator p, InputIterator first, InputIterator last); // constexpr since C++20
14 #include <string>
15 #include <cassert>
17 #include "test_macros.h"
18 #include "test_iterators.h"
19 #include "min_allocator.h"
21 template <class S, class It>
22 TEST_CONSTEXPR_CXX20 void test(S s, typename S::difference_type pos, It first, It last, S expected) {
23 typename S::const_iterator p = s.cbegin() + pos;
24 typename S::iterator i = s.insert(p, first, last);
25 LIBCPP_ASSERT(s.__invariants());
26 assert(i - s.begin() == pos);
27 assert(s == expected);
30 #ifndef TEST_HAS_NO_EXCEPTIONS
31 struct Widget {
32 operator char() const { throw 42; }
35 template <class S, class It>
36 TEST_CONSTEXPR_CXX20 void test_exceptions(S s, typename S::difference_type pos, It first, It last) {
37 typename S::const_iterator p = s.cbegin() + pos;
39 S original = s;
40 typename S::iterator begin = s.begin();
41 typename S::iterator end = s.end();
43 try {
44 s.insert(p, first, last);
45 assert(false);
46 } catch (...) {
49 // Part of "no effects" is that iterators and pointers
50 // into the string must not have been invalidated.
51 LIBCPP_ASSERT(s.__invariants());
52 assert(s == original);
53 assert(s.begin() == begin);
54 assert(s.end() == end);
56 #endif
58 template <class S>
59 TEST_CONSTEXPR_CXX20 void test_string() {
60 const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
61 test(S(), 0, s, s, S());
62 test(S(), 0, s, s + 1, S("A"));
63 test(S(), 0, s, s + 10, S("ABCDEFGHIJ"));
64 test(S(), 0, s, s + 52, S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
66 test(S("12345"), 0, s, s, S("12345"));
67 test(S("12345"), 1, s, s + 1, S("1A2345"));
68 test(S("12345"), 4, s, s + 10, S("1234ABCDEFGHIJ5"));
69 test(S("12345"), 5, s, s + 52, S("12345ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
71 test(S("1234567890"), 0, s, s, S("1234567890"));
72 test(S("1234567890"), 1, s, s + 1, S("1A234567890"));
73 test(S("1234567890"), 10, s, s + 10, S("1234567890ABCDEFGHIJ"));
74 test(S("1234567890"), 8, s, s + 52, S("12345678ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz90"));
76 test(S("12345678901234567890"), 3, s, s, S("12345678901234567890"));
77 test(S("12345678901234567890"), 3, s, s + 1, S("123A45678901234567890"));
78 test(S("12345678901234567890"), 15, s, s + 10, S("123456789012345ABCDEFGHIJ67890"));
79 test(S("12345678901234567890"),
80 20,
82 s + 52,
83 S("12345678901234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
85 test(S(), 0, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s), S());
86 test(S(), 0, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s + 1), S("A"));
87 test(S(), 0, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s + 10), S("ABCDEFGHIJ"));
88 test(S(),
90 cpp17_input_iterator<const char*>(s),
91 cpp17_input_iterator<const char*>(s + 52),
92 S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
94 test(S("12345"), 0, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s), S("12345"));
95 test(S("12345"), 1, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s + 1), S("1A2345"));
96 test(S("12345"),
98 cpp17_input_iterator<const char*>(s),
99 cpp17_input_iterator<const char*>(s + 10),
100 S("1234ABCDEFGHIJ5"));
101 test(S("12345"),
103 cpp17_input_iterator<const char*>(s),
104 cpp17_input_iterator<const char*>(s + 52),
105 S("12345ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
107 test(S("1234567890"), 0, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s), S("1234567890"));
108 test(S("1234567890"),
110 cpp17_input_iterator<const char*>(s),
111 cpp17_input_iterator<const char*>(s + 1),
112 S("1A234567890"));
113 test(S("1234567890"),
115 cpp17_input_iterator<const char*>(s),
116 cpp17_input_iterator<const char*>(s + 10),
117 S("1234567890ABCDEFGHIJ"));
118 test(S("1234567890"),
120 cpp17_input_iterator<const char*>(s),
121 cpp17_input_iterator<const char*>(s + 52),
122 S("12345678ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz90"));
124 test(S("12345678901234567890"),
126 cpp17_input_iterator<const char*>(s),
127 cpp17_input_iterator<const char*>(s),
128 S("12345678901234567890"));
129 test(S("12345678901234567890"),
131 cpp17_input_iterator<const char*>(s),
132 cpp17_input_iterator<const char*>(s + 1),
133 S("123A45678901234567890"));
134 test(S("12345678901234567890"),
136 cpp17_input_iterator<const char*>(s),
137 cpp17_input_iterator<const char*>(s + 10),
138 S("123456789012345ABCDEFGHIJ67890"));
139 test(S("12345678901234567890"),
141 cpp17_input_iterator<const char*>(s),
142 cpp17_input_iterator<const char*>(s + 52),
143 S("12345678901234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
146 TEST_CONSTEXPR_CXX20 bool test() {
147 test_string<std::string>();
148 #if TEST_STD_VER >= 11
149 test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
150 #endif
152 #ifndef TEST_HAS_NO_EXCEPTIONS
153 if (!TEST_IS_CONSTANT_EVALUATED) { // test iterator operations that throw
154 typedef std::string S;
155 typedef ThrowingIterator<char> TIter;
156 typedef cpp17_input_iterator<TIter> IIter;
157 const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
158 test_exceptions(S(), 0, IIter(TIter(s, s + 10, 4, TIter::TAIncrement)), IIter(TIter()));
159 test_exceptions(S(), 0, IIter(TIter(s, s + 10, 5, TIter::TADereference)), IIter(TIter()));
160 test_exceptions(S(), 0, IIter(TIter(s, s + 10, 6, TIter::TAComparison)), IIter(TIter()));
162 test_exceptions(S(), 0, TIter(s, s + 10, 4, TIter::TAIncrement), TIter());
163 test_exceptions(S(), 0, TIter(s, s + 10, 5, TIter::TADereference), TIter());
164 test_exceptions(S(), 0, TIter(s, s + 10, 6, TIter::TAComparison), TIter());
166 Widget w[100];
167 test_exceptions(S(), 0, w, w + 100);
169 #endif
171 { // test inserting into self
172 typedef std::string S;
173 S s_short = "123/";
174 S s_long = "Lorem ipsum dolor sit amet, consectetur/";
176 s_short.insert(s_short.begin(), s_short.begin(), s_short.end());
177 assert(s_short == "123/123/");
178 s_short.insert(s_short.begin(), s_short.begin(), s_short.end());
179 assert(s_short == "123/123/123/123/");
180 s_short.insert(s_short.begin(), s_short.begin(), s_short.end());
181 assert(s_short == "123/123/123/123/123/123/123/123/");
183 s_long.insert(s_long.begin(), s_long.begin(), s_long.end());
184 assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/");
187 { // test assigning a different type
188 typedef std::string S;
189 const std::uint8_t p[] = "ABCD";
191 S s;
192 s.insert(s.begin(), p, p + 4);
193 assert(s == "ABCD");
196 if (!TEST_IS_CONSTANT_EVALUATED) { // regression-test inserting into self in sneaky ways
197 std::string s_short = "hello";
198 std::string s_long = "Lorem ipsum dolor sit amet, consectetur/";
199 std::string s_othertype = "hello";
200 const unsigned char* first = reinterpret_cast<const unsigned char*>(s_othertype.data());
202 test(s_short, 0, s_short.data() + s_short.size(), s_short.data() + s_short.size() + 1, std::string("\0hello", 6));
203 test(s_long,
205 s_long.data() + s_long.size(),
206 s_long.data() + s_long.size() + 1,
207 std::string("\0Lorem ipsum dolor sit amet, consectetur/", 41));
208 test(s_othertype, 1, first + 2, first + 5, std::string("hlloello"));
211 { // test with a move iterator that returns char&&
212 typedef cpp17_input_iterator<const char*> It;
213 typedef std::move_iterator<It> MoveIt;
214 const char p[] = "ABCD";
215 std::string s;
216 s.insert(s.begin(), MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1)));
217 assert(s == "ABCD");
219 { // test with a move iterator that returns char&&
220 typedef forward_iterator<const char*> It;
221 typedef std::move_iterator<It> MoveIt;
222 const char p[] = "ABCD";
223 std::string s;
224 s.insert(s.begin(), MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1)));
225 assert(s == "ABCD");
227 { // test with a move iterator that returns char&&
228 typedef const char* It;
229 typedef std::move_iterator<It> MoveIt;
230 const char p[] = "ABCD";
231 std::string s;
232 s.insert(s.begin(), MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1)));
233 assert(s == "ABCD");
235 return true;
238 int main(int, char**) {
239 test();
240 #if TEST_STD_VER > 17
241 static_assert(test());
242 #endif
244 return 0;