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