xref: /llvm-project/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp (revision 773ae4412468433c134e668b4047c94f4599e0fd)
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 // XFAIL: LIBCXX-DEBUG-FIXME
10 
11 // <string>
12 
13 // template<class InputIterator>
14 //   basic_string& assign(InputIterator first, InputIterator last);
15 
16 #include <string>
17 #include <cassert>
18 
19 #include "test_macros.h"
20 #include "test_iterators.h"
21 #include "min_allocator.h"
22 
23 template <class S, class It>
24 void
25 test(S s, It first, It last, S expected)
26 {
27     s.assign(first, last);
28     LIBCPP_ASSERT(s.__invariants());
29     assert(s == expected);
30 }
31 
32 #ifndef TEST_HAS_NO_EXCEPTIONS
33 struct Widget { operator char() const { throw 42; } };
34 
35 template <class S, class It>
36 void
37 test_exceptions(S s, It first, It last)
38 {
39     S original = s;
40     typename S::iterator begin = s.begin();
41     typename S::iterator end = s.end();
42 
43     try {
44         s.assign(first, last);
45         assert(false);
46     } catch (...) {}
47 
48     // Part of "no effects" is that iterators and pointers
49     // into the string must not have been invalidated.
50     LIBCPP_ASSERT(s.__invariants());
51     assert(s == original);
52     assert(s.begin() == begin);
53     assert(s.end() == end);
54 }
55 #endif
56 
57 int main(int, char**)
58 {
59     {
60     typedef std::string S;
61     const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
62     test(S(), s, s, S());
63     test(S(), s, s+1, S("A"));
64     test(S(), s, s+10, S("ABCDEFGHIJ"));
65     test(S(), s, s+52, S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
66 
67     test(S("12345"), s, s, S());
68     test(S("12345"), s, s+1, S("A"));
69     test(S("12345"), s, s+10, S("ABCDEFGHIJ"));
70     test(S("12345"), s, s+52, S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
71 
72     test(S("1234567890"), s, s, S());
73     test(S("1234567890"), s, s+1, S("A"));
74     test(S("1234567890"), s, s+10, S("ABCDEFGHIJ"));
75     test(S("1234567890"), s, s+52, S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
76 
77     test(S("12345678901234567890"), s, s, S());
78     test(S("12345678901234567890"), s, s+1, S("A"));
79     test(S("12345678901234567890"), s, s+10, S("ABCDEFGHIJ"));
80     test(S("12345678901234567890"), s, s+52,
81          S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
82 
83     test(S(), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s), S());
84     test(S(), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1), S("A"));
85     test(S(), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10),
86          S("ABCDEFGHIJ"));
87     test(S(), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52),
88          S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
89 
90     test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s),
91          S());
92     test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1),
93          S("A"));
94     test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10),
95          S("ABCDEFGHIJ"));
96     test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52),
97          S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
98 
99     test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s),
100          S());
101     test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1),
102          S("A"));
103     test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10),
104          S("ABCDEFGHIJ"));
105     test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52),
106          S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
107 
108     test(S("12345678901234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s),
109          S());
110     test(S("12345678901234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1),
111          S("A"));
112     test(S("12345678901234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10),
113          S("ABCDEFGHIJ"));
114     test(S("12345678901234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52),
115          S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
116     }
117 #if TEST_STD_VER >= 11
118     {
119     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
120     const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
121     test(S(), s, s, S());
122     test(S(), s, s+1, S("A"));
123     test(S(), s, s+10, S("ABCDEFGHIJ"));
124     test(S(), s, s+52, S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
125 
126     test(S("12345"), s, s, S());
127     test(S("12345"), s, s+1, S("A"));
128     test(S("12345"), s, s+10, S("ABCDEFGHIJ"));
129     test(S("12345"), s, s+52, S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
130 
131     test(S("1234567890"), s, s, S());
132     test(S("1234567890"), s, s+1, S("A"));
133     test(S("1234567890"), s, s+10, S("ABCDEFGHIJ"));
134     test(S("1234567890"), s, s+52, S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
135 
136     test(S("12345678901234567890"), s, s, S());
137     test(S("12345678901234567890"), s, s+1, S("A"));
138     test(S("12345678901234567890"), s, s+10, S("ABCDEFGHIJ"));
139     test(S("12345678901234567890"), s, s+52,
140          S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
141 
142     test(S(), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s), S());
143     test(S(), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1), S("A"));
144     test(S(), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10),
145          S("ABCDEFGHIJ"));
146     test(S(), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52),
147          S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
148 
149     test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s),
150          S());
151     test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1),
152          S("A"));
153     test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10),
154          S("ABCDEFGHIJ"));
155     test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52),
156          S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
157 
158     test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s),
159          S());
160     test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1),
161          S("A"));
162     test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10),
163          S("ABCDEFGHIJ"));
164     test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52),
165          S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
166 
167     test(S("12345678901234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s),
168          S());
169     test(S("12345678901234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1),
170          S("A"));
171     test(S("12345678901234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10),
172          S("ABCDEFGHIJ"));
173     test(S("12345678901234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52),
174          S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
175     }
176 #endif
177 #ifndef TEST_HAS_NO_EXCEPTIONS
178     { // test iterator operations that throw
179     typedef std::string S;
180     typedef ThrowingIterator<char> TIter;
181     typedef cpp17_input_iterator<TIter> IIter;
182     const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
183     test_exceptions(S(), IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter());
184     test_exceptions(S(), IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter());
185     test_exceptions(S(), IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter());
186 
187     test_exceptions(S(), TIter(s, s+10, 4, TIter::TAIncrement), TIter());
188     test_exceptions(S(), TIter(s, s+10, 5, TIter::TADereference), TIter());
189     test_exceptions(S(), TIter(s, s+10, 6, TIter::TAComparison), TIter());
190 
191     Widget w[100];
192     test_exceptions(S(), w, w+100);
193     }
194 #endif
195 
196     { // test assigning to self
197     typedef std::string S;
198     S s_short = "123/";
199     S s_long  = "Lorem ipsum dolor sit amet, consectetur/";
200 
201     s_short.assign(s_short.begin(), s_short.end());
202     assert(s_short == "123/");
203     s_short.assign(s_short.begin() + 2, s_short.end());
204     assert(s_short == "3/");
205 
206     s_long.assign(s_long.begin(), s_long.end());
207     assert(s_long == "Lorem ipsum dolor sit amet, consectetur/");
208 
209     s_long.assign(s_long.begin() + 30, s_long.end());
210     assert(s_long == "nsectetur/");
211     }
212 
213     { // test assigning a different type
214     typedef std::string S;
215     const uint8_t p[] = "ABCD";
216 
217     S s;
218     s.assign(p, p + 4);
219     assert(s == "ABCD");
220     }
221 
222     { // regression-test assigning to self in sneaky ways
223     std::string sneaky = "hello";
224     sneaky.resize(sneaky.capacity(), 'x');
225     std::string expected = sneaky + std::string(1, '\0');
226     test(sneaky, sneaky.data(), sneaky.data() + sneaky.size() + 1, expected);
227     }
228 
229     return 0;
230 }
231