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 //===----------------------------------------------------------------------===//
8
9 // <string>
10
11 // template<class InputIterator>
12 // iterator insert(const_iterator p, InputIterator first, InputIterator last); // constexpr since C++20
13
14 #include <string>
15 #include <cassert>
16
17 #include "test_macros.h"
18 #include "test_iterators.h"
19 #include "min_allocator.h"
20
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 test(S s, typename S::difference_type pos, It first, It last, S expected)
24 {
25 typename S::const_iterator p = s.cbegin() + pos;
26 typename S::iterator i = s.insert(p, first, last);
27 LIBCPP_ASSERT(s.__invariants());
28 assert(i - s.begin() == pos);
29 assert(s == expected);
30 }
31
32 #ifndef TEST_HAS_NO_EXCEPTIONS
operator charWidget33 struct Widget { operator char() const { throw 42; } };
34
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 test_exceptions(S s, typename S::difference_type pos, It first, It last)
38 {
39 typename S::const_iterator p = s.cbegin() + pos;
40
41 S original = s;
42 typename S::iterator begin = s.begin();
43 typename S::iterator end = s.end();
44
45 try {
46 s.insert(p, first, last);
47 assert(false);
48 } catch (...) {}
49
50 // Part of "no effects" is that iterators and pointers
51 // into the string must not have been invalidated.
52 LIBCPP_ASSERT(s.__invariants());
53 assert(s == original);
54 assert(s.begin() == begin);
55 assert(s.end() == end);
56 }
57 #endif
58
test()59 TEST_CONSTEXPR_CXX20 bool test() {
60 {
61 typedef std::string S;
62 const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
63 test(S(), 0, s, s, S());
64 test(S(), 0, s, s+1, S("A"));
65 test(S(), 0, s, s+10, S("ABCDEFGHIJ"));
66 test(S(), 0, s, s+52, S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
67
68 test(S("12345"), 0, s, s, S("12345"));
69 test(S("12345"), 1, s, s+1, S("1A2345"));
70 test(S("12345"), 4, s, s+10, S("1234ABCDEFGHIJ5"));
71 test(S("12345"), 5, s, s+52, S("12345ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
72
73 test(S("1234567890"), 0, s, s, S("1234567890"));
74 test(S("1234567890"), 1, s, s+1, S("1A234567890"));
75 test(S("1234567890"), 10, s, s+10, S("1234567890ABCDEFGHIJ"));
76 test(S("1234567890"), 8, s, s+52, S("12345678ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz90"));
77
78 test(S("12345678901234567890"), 3, s, s, S("12345678901234567890"));
79 test(S("12345678901234567890"), 3, s, s+1, S("123A45678901234567890"));
80 test(S("12345678901234567890"), 15, s, s+10, S("123456789012345ABCDEFGHIJ67890"));
81 test(S("12345678901234567890"), 20, s, s+52,
82 S("12345678901234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
83
84 test(S(), 0, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s), S());
85 test(S(), 0, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1), S("A"));
86 test(S(), 0, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10), S("ABCDEFGHIJ"));
87 test(S(), 0, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52), S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
88
89 test(S("12345"), 0, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s), S("12345"));
90 test(S("12345"), 1, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1), S("1A2345"));
91 test(S("12345"), 4, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10), S("1234ABCDEFGHIJ5"));
92 test(S("12345"), 5, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52), S("12345ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
93
94 test(S("1234567890"), 0, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s), S("1234567890"));
95 test(S("1234567890"), 1, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1), S("1A234567890"));
96 test(S("1234567890"), 10, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10), S("1234567890ABCDEFGHIJ"));
97 test(S("1234567890"), 8, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52), S("12345678ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz90"));
98
99 test(S("12345678901234567890"), 3, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s), S("12345678901234567890"));
100 test(S("12345678901234567890"), 3, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1), S("123A45678901234567890"));
101 test(S("12345678901234567890"), 15, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10), S("123456789012345ABCDEFGHIJ67890"));
102 test(S("12345678901234567890"), 20, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52),
103 S("12345678901234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
104 }
105 #if TEST_STD_VER >= 11
106 {
107 typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
108 const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
109 test(S(), 0, s, s, S());
110 test(S(), 0, s, s+1, S("A"));
111 test(S(), 0, s, s+10, S("ABCDEFGHIJ"));
112 test(S(), 0, s, s+52, S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
113
114 test(S("12345"), 0, s, s, S("12345"));
115 test(S("12345"), 1, s, s+1, S("1A2345"));
116 test(S("12345"), 4, s, s+10, S("1234ABCDEFGHIJ5"));
117 test(S("12345"), 5, s, s+52, S("12345ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
118
119 test(S("1234567890"), 0, s, s, S("1234567890"));
120 test(S("1234567890"), 1, s, s+1, S("1A234567890"));
121 test(S("1234567890"), 10, s, s+10, S("1234567890ABCDEFGHIJ"));
122 test(S("1234567890"), 8, s, s+52, S("12345678ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz90"));
123
124 test(S("12345678901234567890"), 3, s, s, S("12345678901234567890"));
125 test(S("12345678901234567890"), 3, s, s+1, S("123A45678901234567890"));
126 test(S("12345678901234567890"), 15, s, s+10, S("123456789012345ABCDEFGHIJ67890"));
127 test(S("12345678901234567890"), 20, s, s+52,
128 S("12345678901234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
129
130 test(S(), 0, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s), S());
131 test(S(), 0, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1), S("A"));
132 test(S(), 0, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10), S("ABCDEFGHIJ"));
133 test(S(), 0, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52), S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
134
135 test(S("12345"), 0, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s), S("12345"));
136 test(S("12345"), 1, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1), S("1A2345"));
137 test(S("12345"), 4, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10), S("1234ABCDEFGHIJ5"));
138 test(S("12345"), 5, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52), S("12345ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
139
140 test(S("1234567890"), 0, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s), S("1234567890"));
141 test(S("1234567890"), 1, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1), S("1A234567890"));
142 test(S("1234567890"), 10, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10), S("1234567890ABCDEFGHIJ"));
143 test(S("1234567890"), 8, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52), S("12345678ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz90"));
144
145 test(S("12345678901234567890"), 3, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s), S("12345678901234567890"));
146 test(S("12345678901234567890"), 3, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1), S("123A45678901234567890"));
147 test(S("12345678901234567890"), 15, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10), S("123456789012345ABCDEFGHIJ67890"));
148 test(S("12345678901234567890"), 20, cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52),
149 S("12345678901234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
150 }
151 #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()));
161
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());
165
166 Widget w[100];
167 test_exceptions(S(), 0, w, w+100);
168 }
169 #endif
170
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/";
175
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/");
182
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/");
185 }
186
187 { // test assigning a different type
188 typedef std::string S;
189 const uint8_t p[] = "ABCD";
190
191 S s;
192 s.insert(s.begin(), p, p + 4);
193 assert(s == "ABCD");
194 }
195
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());
201
202 test(s_short, 0, s_short.data() + s_short.size(), s_short.data() + s_short.size() + 1,
203 std::string("\0hello", 6));
204 test(s_long, 0, s_long.data() + s_long.size(), s_long.data() + s_long.size() + 1,
205 std::string("\0Lorem ipsum dolor sit amet, consectetur/", 41));
206 test(s_othertype, 1, first + 2, first + 5, std::string("hlloello"));
207 }
208
209 { // test with a move iterator that returns char&&
210 typedef cpp17_input_iterator<const char*> It;
211 typedef std::move_iterator<It> MoveIt;
212 const char p[] = "ABCD";
213 std::string s;
214 s.insert(s.begin(), MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1)));
215 assert(s == "ABCD");
216 }
217 { // test with a move iterator that returns char&&
218 typedef forward_iterator<const char*> It;
219 typedef std::move_iterator<It> MoveIt;
220 const char p[] = "ABCD";
221 std::string s;
222 s.insert(s.begin(), MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1)));
223 assert(s == "ABCD");
224 }
225 { // test with a move iterator that returns char&&
226 typedef const char* It;
227 typedef std::move_iterator<It> MoveIt;
228 const char p[] = "ABCD";
229 std::string s;
230 s.insert(s.begin(), MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1)));
231 assert(s == "ABCD");
232 }
233
234 return true;
235 }
236
main(int,char **)237 int main(int, char**)
238 {
239 test();
240 #if TEST_STD_VER > 17
241 static_assert(test());
242 #endif
243
244 return 0;
245 }
246