15a83710eSEric Fiselier //===----------------------------------------------------------------------===//
25a83710eSEric Fiselier //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65a83710eSEric Fiselier //
75a83710eSEric Fiselier //===----------------------------------------------------------------------===//
85a83710eSEric Fiselier 
95a83710eSEric Fiselier // <string>
105a83710eSEric Fiselier 
115a83710eSEric Fiselier // template<class InputIterator>
12*425620ccSNikolas Klauser //   basic_string& assign(InputIterator first, InputIterator last); // constexpr since C++20
135a83710eSEric Fiselier 
145a83710eSEric Fiselier #include <string>
155a83710eSEric Fiselier #include <cassert>
165a83710eSEric Fiselier 
171f4231f8SEric Fiselier #include "test_macros.h"
1876b4afc0SMarshall Clow #include "test_iterators.h"
195a83710eSEric Fiselier #include "min_allocator.h"
205a83710eSEric Fiselier 
215a83710eSEric Fiselier template <class S, class It>
2285e9b268SNikolas Klauser TEST_CONSTEXPR_CXX20 void
test(S s,It first,It last,S expected)235a83710eSEric Fiselier test(S s, It first, It last, S expected)
245a83710eSEric Fiselier {
255a83710eSEric Fiselier     s.assign(first, last);
261f4231f8SEric Fiselier     LIBCPP_ASSERT(s.__invariants());
275a83710eSEric Fiselier     assert(s == expected);
285a83710eSEric Fiselier }
295a83710eSEric Fiselier 
30e612a887SMarshall Clow #ifndef TEST_HAS_NO_EXCEPTIONS
operator charWidget31e87479b0SArthur O'Dwyer struct Widget { operator char() const { throw 42; } };
32e87479b0SArthur O'Dwyer 
3376b4afc0SMarshall Clow template <class S, class It>
3476b4afc0SMarshall Clow void
test_exceptions(S s,It first,It last)3576b4afc0SMarshall Clow test_exceptions(S s, It first, It last)
3676b4afc0SMarshall Clow {
37036b80fcSArthur O'Dwyer     S original = s;
38036b80fcSArthur O'Dwyer     typename S::iterator begin = s.begin();
39036b80fcSArthur O'Dwyer     typename S::iterator end = s.end();
40036b80fcSArthur O'Dwyer 
4176b4afc0SMarshall Clow     try {
4276b4afc0SMarshall Clow         s.assign(first, last);
4376b4afc0SMarshall Clow         assert(false);
44036b80fcSArthur O'Dwyer     } catch (...) {}
45036b80fcSArthur O'Dwyer 
46036b80fcSArthur O'Dwyer     // Part of "no effects" is that iterators and pointers
47036b80fcSArthur O'Dwyer     // into the string must not have been invalidated.
481f4231f8SEric Fiselier     LIBCPP_ASSERT(s.__invariants());
49036b80fcSArthur O'Dwyer     assert(s == original);
50036b80fcSArthur O'Dwyer     assert(s.begin() == begin);
51036b80fcSArthur O'Dwyer     assert(s.end() == end);
5276b4afc0SMarshall Clow }
53e612a887SMarshall Clow #endif
5476b4afc0SMarshall Clow 
test()55*425620ccSNikolas Klauser TEST_CONSTEXPR_CXX20 bool test() {
565a83710eSEric Fiselier   {
575a83710eSEric Fiselier     typedef std::string S;
585a83710eSEric Fiselier     const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
595a83710eSEric Fiselier     test(S(), s, s, S());
605a83710eSEric Fiselier     test(S(), s, s+1, S("A"));
615a83710eSEric Fiselier     test(S(), s, s+10, S("ABCDEFGHIJ"));
625a83710eSEric Fiselier     test(S(), s, s+52, S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
635a83710eSEric Fiselier 
645a83710eSEric Fiselier     test(S("12345"), s, s, S());
655a83710eSEric Fiselier     test(S("12345"), s, s+1, S("A"));
665a83710eSEric Fiselier     test(S("12345"), s, s+10, S("ABCDEFGHIJ"));
675a83710eSEric Fiselier     test(S("12345"), s, s+52, S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
685a83710eSEric Fiselier 
695a83710eSEric Fiselier     test(S("1234567890"), s, s, S());
705a83710eSEric Fiselier     test(S("1234567890"), s, s+1, S("A"));
715a83710eSEric Fiselier     test(S("1234567890"), s, s+10, S("ABCDEFGHIJ"));
725a83710eSEric Fiselier     test(S("1234567890"), s, s+52, S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
735a83710eSEric Fiselier 
745a83710eSEric Fiselier     test(S("12345678901234567890"), s, s, S());
755a83710eSEric Fiselier     test(S("12345678901234567890"), s, s+1, S("A"));
765a83710eSEric Fiselier     test(S("12345678901234567890"), s, s+10, S("ABCDEFGHIJ"));
775a83710eSEric Fiselier     test(S("12345678901234567890"), s, s+52,
785a83710eSEric Fiselier          S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
795a83710eSEric Fiselier 
80773ae441SChristopher Di Bella     test(S(), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s), S());
81773ae441SChristopher Di Bella     test(S(), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1), S("A"));
82773ae441SChristopher Di Bella     test(S(), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10),
835a83710eSEric Fiselier          S("ABCDEFGHIJ"));
84773ae441SChristopher Di Bella     test(S(), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52),
855a83710eSEric Fiselier          S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
865a83710eSEric Fiselier 
87773ae441SChristopher Di Bella     test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s),
885a83710eSEric Fiselier          S());
89773ae441SChristopher Di Bella     test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1),
905a83710eSEric Fiselier          S("A"));
91773ae441SChristopher Di Bella     test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10),
925a83710eSEric Fiselier          S("ABCDEFGHIJ"));
93773ae441SChristopher Di Bella     test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52),
945a83710eSEric Fiselier          S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
955a83710eSEric Fiselier 
96773ae441SChristopher Di Bella     test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s),
975a83710eSEric Fiselier          S());
98773ae441SChristopher Di Bella     test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1),
995a83710eSEric Fiselier          S("A"));
100773ae441SChristopher Di Bella     test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10),
1015a83710eSEric Fiselier          S("ABCDEFGHIJ"));
102773ae441SChristopher Di Bella     test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52),
1035a83710eSEric Fiselier          S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
1045a83710eSEric Fiselier 
105773ae441SChristopher Di Bella     test(S("12345678901234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s),
1065a83710eSEric Fiselier          S());
107773ae441SChristopher Di Bella     test(S("12345678901234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1),
1085a83710eSEric Fiselier          S("A"));
109773ae441SChristopher Di Bella     test(S("12345678901234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10),
1105a83710eSEric Fiselier          S("ABCDEFGHIJ"));
111773ae441SChristopher Di Bella     test(S("12345678901234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52),
1125a83710eSEric Fiselier          S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
1135a83710eSEric Fiselier   }
1141f4231f8SEric Fiselier #if TEST_STD_VER >= 11
1155a83710eSEric Fiselier   {
1165a83710eSEric Fiselier     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
1175a83710eSEric Fiselier     const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
1185a83710eSEric Fiselier     test(S(), s, s, S());
1195a83710eSEric Fiselier     test(S(), s, s+1, S("A"));
1205a83710eSEric Fiselier     test(S(), s, s+10, S("ABCDEFGHIJ"));
1215a83710eSEric Fiselier     test(S(), s, s+52, S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
1225a83710eSEric Fiselier 
1235a83710eSEric Fiselier     test(S("12345"), s, s, S());
1245a83710eSEric Fiselier     test(S("12345"), s, s+1, S("A"));
1255a83710eSEric Fiselier     test(S("12345"), s, s+10, S("ABCDEFGHIJ"));
1265a83710eSEric Fiselier     test(S("12345"), s, s+52, S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
1275a83710eSEric Fiselier 
1285a83710eSEric Fiselier     test(S("1234567890"), s, s, S());
1295a83710eSEric Fiselier     test(S("1234567890"), s, s+1, S("A"));
1305a83710eSEric Fiselier     test(S("1234567890"), s, s+10, S("ABCDEFGHIJ"));
1315a83710eSEric Fiselier     test(S("1234567890"), s, s+52, S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
1325a83710eSEric Fiselier 
1335a83710eSEric Fiselier     test(S("12345678901234567890"), s, s, S());
1345a83710eSEric Fiselier     test(S("12345678901234567890"), s, s+1, S("A"));
1355a83710eSEric Fiselier     test(S("12345678901234567890"), s, s+10, S("ABCDEFGHIJ"));
1365a83710eSEric Fiselier     test(S("12345678901234567890"), s, s+52,
1375a83710eSEric Fiselier          S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
1385a83710eSEric Fiselier 
139773ae441SChristopher Di Bella     test(S(), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s), S());
140773ae441SChristopher Di Bella     test(S(), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1), S("A"));
141773ae441SChristopher Di Bella     test(S(), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10),
1425a83710eSEric Fiselier          S("ABCDEFGHIJ"));
143773ae441SChristopher Di Bella     test(S(), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52),
1445a83710eSEric Fiselier          S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
1455a83710eSEric Fiselier 
146773ae441SChristopher Di Bella     test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s),
1475a83710eSEric Fiselier          S());
148773ae441SChristopher Di Bella     test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1),
1495a83710eSEric Fiselier          S("A"));
150773ae441SChristopher Di Bella     test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10),
1515a83710eSEric Fiselier          S("ABCDEFGHIJ"));
152773ae441SChristopher Di Bella     test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52),
1535a83710eSEric Fiselier          S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
1545a83710eSEric Fiselier 
155773ae441SChristopher Di Bella     test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s),
1565a83710eSEric Fiselier          S());
157773ae441SChristopher Di Bella     test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1),
1585a83710eSEric Fiselier          S("A"));
159773ae441SChristopher Di Bella     test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10),
1605a83710eSEric Fiselier          S("ABCDEFGHIJ"));
161773ae441SChristopher Di Bella     test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52),
1625a83710eSEric Fiselier          S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
1635a83710eSEric Fiselier 
164773ae441SChristopher Di Bella     test(S("12345678901234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s),
1655a83710eSEric Fiselier          S());
166773ae441SChristopher Di Bella     test(S("12345678901234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1),
1675a83710eSEric Fiselier          S("A"));
168773ae441SChristopher Di Bella     test(S("12345678901234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10),
1695a83710eSEric Fiselier          S("ABCDEFGHIJ"));
170773ae441SChristopher Di Bella     test(S("12345678901234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52),
1715a83710eSEric Fiselier          S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
1725a83710eSEric Fiselier   }
1735a83710eSEric Fiselier #endif
1749d10d27cSMarshall Clow #ifndef TEST_HAS_NO_EXCEPTIONS
17585e9b268SNikolas Klauser   if (!TEST_IS_CONSTANT_EVALUATED) { // test iterator operations that throw
17676b4afc0SMarshall Clow     typedef std::string S;
17776b4afc0SMarshall Clow     typedef ThrowingIterator<char> TIter;
178773ae441SChristopher Di Bella     typedef cpp17_input_iterator<TIter> IIter;
17976b4afc0SMarshall Clow     const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
1804a47ac7dSLouis Dionne     test_exceptions(S(), IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter(TIter()));
1814a47ac7dSLouis Dionne     test_exceptions(S(), IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter(TIter()));
1824a47ac7dSLouis Dionne     test_exceptions(S(), IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter(TIter()));
18376b4afc0SMarshall Clow 
18476b4afc0SMarshall Clow     test_exceptions(S(), TIter(s, s+10, 4, TIter::TAIncrement), TIter());
18576b4afc0SMarshall Clow     test_exceptions(S(), TIter(s, s+10, 5, TIter::TADereference), TIter());
18676b4afc0SMarshall Clow     test_exceptions(S(), TIter(s, s+10, 6, TIter::TAComparison), TIter());
187e87479b0SArthur O'Dwyer 
188e87479b0SArthur O'Dwyer     Widget w[100];
189e87479b0SArthur O'Dwyer     test_exceptions(S(), w, w+100);
19076b4afc0SMarshall Clow   }
1919d10d27cSMarshall Clow #endif
1927e1a2300SMarshall Clow 
1937e1a2300SMarshall Clow   { // test assigning to self
1947e1a2300SMarshall Clow     typedef std::string S;
1957e1a2300SMarshall Clow     S s_short = "123/";
1967e1a2300SMarshall Clow     S s_long  = "Lorem ipsum dolor sit amet, consectetur/";
1977e1a2300SMarshall Clow 
1987e1a2300SMarshall Clow     s_short.assign(s_short.begin(), s_short.end());
1997e1a2300SMarshall Clow     assert(s_short == "123/");
2007e1a2300SMarshall Clow     s_short.assign(s_short.begin() + 2, s_short.end());
2017e1a2300SMarshall Clow     assert(s_short == "3/");
2027e1a2300SMarshall Clow 
2037e1a2300SMarshall Clow     s_long.assign(s_long.begin(), s_long.end());
2047e1a2300SMarshall Clow     assert(s_long == "Lorem ipsum dolor sit amet, consectetur/");
2057e1a2300SMarshall Clow 
2067e1a2300SMarshall Clow     s_long.assign(s_long.begin() + 30, s_long.end());
2077e1a2300SMarshall Clow     assert(s_long == "nsectetur/");
2087e1a2300SMarshall Clow   }
209a77bb8efSMarshall Clow 
210a77bb8efSMarshall Clow   { // test assigning a different type
211a77bb8efSMarshall Clow     typedef std::string S;
212a77bb8efSMarshall Clow     const uint8_t p[] = "ABCD";
213a77bb8efSMarshall Clow 
214a77bb8efSMarshall Clow     S s;
215a77bb8efSMarshall Clow     s.assign(p, p + 4);
216a77bb8efSMarshall Clow     assert(s == "ABCD");
217a77bb8efSMarshall Clow   }
2182df59c50SJF Bastien 
219e87479b0SArthur O'Dwyer   { // regression-test assigning to self in sneaky ways
220e87479b0SArthur O'Dwyer     std::string sneaky = "hello";
221e87479b0SArthur O'Dwyer     sneaky.resize(sneaky.capacity(), 'x');
222e87479b0SArthur O'Dwyer     std::string expected = sneaky + std::string(1, '\0');
223e87479b0SArthur O'Dwyer     test(sneaky, sneaky.data(), sneaky.data() + sneaky.size() + 1, expected);
224e87479b0SArthur O'Dwyer   }
225e87479b0SArthur O'Dwyer 
226dcffa7d3SNikolas Klauser   return true;
227dcffa7d3SNikolas Klauser }
228dcffa7d3SNikolas Klauser 
main(int,char **)229dcffa7d3SNikolas Klauser int main(int, char**)
230dcffa7d3SNikolas Klauser {
231dcffa7d3SNikolas Klauser   test();
232dcffa7d3SNikolas Klauser #if TEST_STD_VER > 17
233*425620ccSNikolas Klauser   static_assert(test());
234dcffa7d3SNikolas Klauser #endif
235dcffa7d3SNikolas Klauser 
2362df59c50SJF Bastien     return 0;
2375a83710eSEric Fiselier }
238