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& append(InputIterator first, InputIterator last); // constexpr since C++20
135a83710eSEric Fiselier
145a83710eSEric Fiselier #include <string>
155a83710eSEric Fiselier #include <cassert>
165a83710eSEric Fiselier
177fc6a556SMarshall Clow #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>
22dcffa7d3SNikolas 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.append(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>
34dcffa7d3SNikolas Klauser TEST_CONSTEXPR_CXX20 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.append(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("12345"));
655a83710eSEric Fiselier test(S("12345"), s, s+1, S("12345A"));
665a83710eSEric Fiselier test(S("12345"), s, s+10, S("12345ABCDEFGHIJ"));
675a83710eSEric Fiselier test(S("12345"), s, s+52, S("12345ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
685a83710eSEric Fiselier
695a83710eSEric Fiselier test(S("1234567890"), s, s, S("1234567890"));
705a83710eSEric Fiselier test(S("1234567890"), s, s+1, S("1234567890A"));
715a83710eSEric Fiselier test(S("1234567890"), s, s+10, S("1234567890ABCDEFGHIJ"));
725a83710eSEric Fiselier test(S("1234567890"), s, s+52, S("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
735a83710eSEric Fiselier
745a83710eSEric Fiselier test(S("12345678901234567890"), s, s, S("12345678901234567890"));
755a83710eSEric Fiselier test(S("12345678901234567890"), s, s+1, S("12345678901234567890""A"));
765a83710eSEric Fiselier test(S("12345678901234567890"), s, s+10, S("12345678901234567890""ABCDEFGHIJ"));
775a83710eSEric Fiselier test(S("12345678901234567890"), s, s+52,
785a83710eSEric Fiselier S("12345678901234567890""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("12345"));
89773ae441SChristopher Di Bella test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1),
905a83710eSEric Fiselier S("12345A"));
91773ae441SChristopher Di Bella test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10),
925a83710eSEric Fiselier S("12345ABCDEFGHIJ"));
93773ae441SChristopher Di Bella test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52),
945a83710eSEric Fiselier S("12345ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
955a83710eSEric Fiselier
96773ae441SChristopher Di Bella test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s),
975a83710eSEric Fiselier S("1234567890"));
98773ae441SChristopher Di Bella test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1),
995a83710eSEric Fiselier S("1234567890A"));
100773ae441SChristopher Di Bella test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10),
1015a83710eSEric Fiselier S("1234567890ABCDEFGHIJ"));
102773ae441SChristopher Di Bella test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52),
1035a83710eSEric Fiselier S("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
1045a83710eSEric Fiselier
105773ae441SChristopher Di Bella test(S("12345678901234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s),
1065a83710eSEric Fiselier S("12345678901234567890"));
107773ae441SChristopher Di Bella test(S("12345678901234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1),
1085a83710eSEric Fiselier S("12345678901234567890""A"));
109773ae441SChristopher Di Bella test(S("12345678901234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10),
1105a83710eSEric Fiselier S("12345678901234567890""ABCDEFGHIJ"));
111773ae441SChristopher Di Bella test(S("12345678901234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52),
1125a83710eSEric Fiselier S("12345678901234567890""ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
1135a83710eSEric Fiselier }
11476b4afc0SMarshall Clow #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("12345"));
1245a83710eSEric Fiselier test(S("12345"), s, s+1, S("12345A"));
1255a83710eSEric Fiselier test(S("12345"), s, s+10, S("12345ABCDEFGHIJ"));
1265a83710eSEric Fiselier test(S("12345"), s, s+52, S("12345ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
1275a83710eSEric Fiselier
1285a83710eSEric Fiselier test(S("1234567890"), s, s, S("1234567890"));
1295a83710eSEric Fiselier test(S("1234567890"), s, s+1, S("1234567890A"));
1305a83710eSEric Fiselier test(S("1234567890"), s, s+10, S("1234567890ABCDEFGHIJ"));
1315a83710eSEric Fiselier test(S("1234567890"), s, s+52, S("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
1325a83710eSEric Fiselier
1335a83710eSEric Fiselier test(S("12345678901234567890"), s, s, S("12345678901234567890"));
1345a83710eSEric Fiselier test(S("12345678901234567890"), s, s+1, S("12345678901234567890""A"));
1355a83710eSEric Fiselier test(S("12345678901234567890"), s, s+10, S("12345678901234567890""ABCDEFGHIJ"));
1365a83710eSEric Fiselier test(S("12345678901234567890"), s, s+52,
1375a83710eSEric Fiselier S("12345678901234567890""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("12345"));
148773ae441SChristopher Di Bella test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1),
1495a83710eSEric Fiselier S("12345A"));
150773ae441SChristopher Di Bella test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10),
1515a83710eSEric Fiselier S("12345ABCDEFGHIJ"));
152773ae441SChristopher Di Bella test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52),
1535a83710eSEric Fiselier S("12345ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
1545a83710eSEric Fiselier
155773ae441SChristopher Di Bella test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s),
1565a83710eSEric Fiselier S("1234567890"));
157773ae441SChristopher Di Bella test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1),
1585a83710eSEric Fiselier S("1234567890A"));
159773ae441SChristopher Di Bella test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10),
1605a83710eSEric Fiselier S("1234567890ABCDEFGHIJ"));
161773ae441SChristopher Di Bella test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52),
1625a83710eSEric Fiselier S("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
1635a83710eSEric Fiselier
164773ae441SChristopher Di Bella test(S("12345678901234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s),
1655a83710eSEric Fiselier S("12345678901234567890"));
166773ae441SChristopher Di Bella test(S("12345678901234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+1),
1675a83710eSEric Fiselier S("12345678901234567890""A"));
168773ae441SChristopher Di Bella test(S("12345678901234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+10),
1695a83710eSEric Fiselier S("12345678901234567890""ABCDEFGHIJ"));
170773ae441SChristopher Di Bella test(S("12345678901234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s+52),
1715a83710eSEric Fiselier S("12345678901234567890""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 appending 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.append(s_short.begin(), s_short.end());
1997e1a2300SMarshall Clow assert(s_short == "123/123/");
2007e1a2300SMarshall Clow s_short.append(s_short.begin(), s_short.end());
2017e1a2300SMarshall Clow assert(s_short == "123/123/123/123/");
2027e1a2300SMarshall Clow s_short.append(s_short.begin(), s_short.end());
2037e1a2300SMarshall Clow assert(s_short == "123/123/123/123/123/123/123/123/");
2047e1a2300SMarshall Clow
2057e1a2300SMarshall Clow s_long.append(s_long.begin(), s_long.end());
2067e1a2300SMarshall Clow assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/");
2077e1a2300SMarshall Clow }
2087e1a2300SMarshall Clow
209a77bb8efSMarshall Clow { // test appending a different type
210a77bb8efSMarshall Clow typedef std::string S;
211a77bb8efSMarshall Clow const uint8_t p[] = "ABCD";
212a77bb8efSMarshall Clow
213a77bb8efSMarshall Clow S s;
214a77bb8efSMarshall Clow s.append(p, p + 4);
215a77bb8efSMarshall Clow assert(s == "ABCD");
216a77bb8efSMarshall Clow }
217a77bb8efSMarshall Clow
218e87479b0SArthur O'Dwyer { // regression-test appending to self in sneaky ways
219e87479b0SArthur O'Dwyer std::string s_short = "hello";
220e87479b0SArthur O'Dwyer std::string s_long = "Lorem ipsum dolor sit amet, consectetur/";
221e87479b0SArthur O'Dwyer std::string s_othertype = "hello";
222e87479b0SArthur O'Dwyer std::string s_sneaky = "hello";
223e87479b0SArthur O'Dwyer
224e87479b0SArthur O'Dwyer test(s_short, s_short.data() + s_short.size(), s_short.data() + s_short.size() + 1,
225e87479b0SArthur O'Dwyer std::string("hello\0", 6));
226e87479b0SArthur O'Dwyer test(s_long, s_long.data() + s_long.size(), s_long.data() + s_long.size() + 1,
227e87479b0SArthur O'Dwyer std::string("Lorem ipsum dolor sit amet, consectetur/\0", 41));
228e87479b0SArthur O'Dwyer
229e87479b0SArthur O'Dwyer s_sneaky.reserve(12);
230e87479b0SArthur O'Dwyer test(s_sneaky, s_sneaky.data(), s_sneaky.data() + 6, std::string("hellohello\0", 11));
23185e9b268SNikolas Klauser
23285e9b268SNikolas Klauser if (!TEST_IS_CONSTANT_EVALUATED) {
23385e9b268SNikolas Klauser const unsigned char *first = reinterpret_cast<const unsigned char*>(s_othertype.data());
23485e9b268SNikolas Klauser test(s_othertype, first + 2, first + 5, std::string("hellollo"));
23585e9b268SNikolas Klauser }
236e87479b0SArthur O'Dwyer }
237e87479b0SArthur O'Dwyer
238e84fcb5fSEric Fiselier { // test with a move iterator that returns char&&
239e84fcb5fSEric Fiselier typedef forward_iterator<const char*> It;
240e84fcb5fSEric Fiselier typedef std::move_iterator<It> MoveIt;
241e84fcb5fSEric Fiselier const char p[] = "ABCD";
242e84fcb5fSEric Fiselier std::string s;
243e84fcb5fSEric Fiselier s.append(MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1)));
244e84fcb5fSEric Fiselier assert(s == "ABCD");
245e84fcb5fSEric Fiselier }
246e84fcb5fSEric Fiselier { // test with a move iterator that returns char&&
247e84fcb5fSEric Fiselier typedef const char* It;
248e84fcb5fSEric Fiselier typedef std::move_iterator<It> MoveIt;
249e84fcb5fSEric Fiselier const char p[] = "ABCD";
250e84fcb5fSEric Fiselier std::string s;
251e84fcb5fSEric Fiselier s.append(MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1)));
252e84fcb5fSEric Fiselier assert(s == "ABCD");
253e84fcb5fSEric Fiselier }
2542df59c50SJF Bastien
255dcffa7d3SNikolas Klauser return true;
256dcffa7d3SNikolas Klauser }
257dcffa7d3SNikolas Klauser
main(int,char **)258dcffa7d3SNikolas Klauser int main(int, char**)
259dcffa7d3SNikolas Klauser {
260dcffa7d3SNikolas Klauser test();
261dcffa7d3SNikolas Klauser #if TEST_STD_VER > 17
262*425620ccSNikolas Klauser static_assert(test());
263dcffa7d3SNikolas Klauser #endif
264dcffa7d3SNikolas Klauser
2652df59c50SJF Bastien return 0;
2665a83710eSEric Fiselier }
267