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 // basic_string& append(InputIterator first, InputIterator last); 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 void 23 test(S s, It first, It last, S expected) 24 { 25 s.append(first, last); 26 LIBCPP_ASSERT(s.__invariants()); 27 assert(s == expected); 28 } 29 30 #ifndef TEST_HAS_NO_EXCEPTIONS 31 struct Widget { operator char() const { throw 42; } }; 32 33 template <class S, class It> 34 void 35 test_exceptions(S s, It first, It last) 36 { 37 S aCopy = s; 38 try { 39 s.append(first, last); 40 assert(false); 41 } 42 catch (...) {} 43 LIBCPP_ASSERT(s.__invariants()); 44 assert(s == aCopy); 45 } 46 #endif 47 48 int main(int, char**) 49 { 50 { 51 typedef std::string S; 52 const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 53 test(S(), s, s, S()); 54 test(S(), s, s+1, S("A")); 55 test(S(), s, s+10, S("ABCDEFGHIJ")); 56 test(S(), s, s+52, S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); 57 58 test(S("12345"), s, s, S("12345")); 59 test(S("12345"), s, s+1, S("12345A")); 60 test(S("12345"), s, s+10, S("12345ABCDEFGHIJ")); 61 test(S("12345"), s, s+52, S("12345ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); 62 63 test(S("1234567890"), s, s, S("1234567890")); 64 test(S("1234567890"), s, s+1, S("1234567890A")); 65 test(S("1234567890"), s, s+10, S("1234567890ABCDEFGHIJ")); 66 test(S("1234567890"), s, s+52, S("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); 67 68 test(S("12345678901234567890"), s, s, S("12345678901234567890")); 69 test(S("12345678901234567890"), s, s+1, S("12345678901234567890""A")); 70 test(S("12345678901234567890"), s, s+10, S("12345678901234567890""ABCDEFGHIJ")); 71 test(S("12345678901234567890"), s, s+52, 72 S("12345678901234567890""ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); 73 74 test(S(), input_iterator<const char*>(s), input_iterator<const char*>(s), S()); 75 test(S(), input_iterator<const char*>(s), input_iterator<const char*>(s+1), S("A")); 76 test(S(), input_iterator<const char*>(s), input_iterator<const char*>(s+10), 77 S("ABCDEFGHIJ")); 78 test(S(), input_iterator<const char*>(s), input_iterator<const char*>(s+52), 79 S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); 80 81 test(S("12345"), input_iterator<const char*>(s), input_iterator<const char*>(s), 82 S("12345")); 83 test(S("12345"), input_iterator<const char*>(s), input_iterator<const char*>(s+1), 84 S("12345A")); 85 test(S("12345"), input_iterator<const char*>(s), input_iterator<const char*>(s+10), 86 S("12345ABCDEFGHIJ")); 87 test(S("12345"), input_iterator<const char*>(s), input_iterator<const char*>(s+52), 88 S("12345ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); 89 90 test(S("1234567890"), input_iterator<const char*>(s), input_iterator<const char*>(s), 91 S("1234567890")); 92 test(S("1234567890"), input_iterator<const char*>(s), input_iterator<const char*>(s+1), 93 S("1234567890A")); 94 test(S("1234567890"), input_iterator<const char*>(s), input_iterator<const char*>(s+10), 95 S("1234567890ABCDEFGHIJ")); 96 test(S("1234567890"), input_iterator<const char*>(s), input_iterator<const char*>(s+52), 97 S("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); 98 99 test(S("12345678901234567890"), input_iterator<const char*>(s), input_iterator<const char*>(s), 100 S("12345678901234567890")); 101 test(S("12345678901234567890"), input_iterator<const char*>(s), input_iterator<const char*>(s+1), 102 S("12345678901234567890""A")); 103 test(S("12345678901234567890"), input_iterator<const char*>(s), input_iterator<const char*>(s+10), 104 S("12345678901234567890""ABCDEFGHIJ")); 105 test(S("12345678901234567890"), input_iterator<const char*>(s), input_iterator<const char*>(s+52), 106 S("12345678901234567890""ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); 107 } 108 #if TEST_STD_VER >= 11 109 { 110 typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S; 111 const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 112 test(S(), s, s, S()); 113 test(S(), s, s+1, S("A")); 114 test(S(), s, s+10, S("ABCDEFGHIJ")); 115 test(S(), s, s+52, S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); 116 117 test(S("12345"), s, s, S("12345")); 118 test(S("12345"), s, s+1, S("12345A")); 119 test(S("12345"), s, s+10, S("12345ABCDEFGHIJ")); 120 test(S("12345"), s, s+52, S("12345ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); 121 122 test(S("1234567890"), s, s, S("1234567890")); 123 test(S("1234567890"), s, s+1, S("1234567890A")); 124 test(S("1234567890"), s, s+10, S("1234567890ABCDEFGHIJ")); 125 test(S("1234567890"), s, s+52, S("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); 126 127 test(S("12345678901234567890"), s, s, S("12345678901234567890")); 128 test(S("12345678901234567890"), s, s+1, S("12345678901234567890""A")); 129 test(S("12345678901234567890"), s, s+10, S("12345678901234567890""ABCDEFGHIJ")); 130 test(S("12345678901234567890"), s, s+52, 131 S("12345678901234567890""ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); 132 133 test(S(), input_iterator<const char*>(s), input_iterator<const char*>(s), S()); 134 test(S(), input_iterator<const char*>(s), input_iterator<const char*>(s+1), S("A")); 135 test(S(), input_iterator<const char*>(s), input_iterator<const char*>(s+10), 136 S("ABCDEFGHIJ")); 137 test(S(), input_iterator<const char*>(s), input_iterator<const char*>(s+52), 138 S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); 139 140 test(S("12345"), input_iterator<const char*>(s), input_iterator<const char*>(s), 141 S("12345")); 142 test(S("12345"), input_iterator<const char*>(s), input_iterator<const char*>(s+1), 143 S("12345A")); 144 test(S("12345"), input_iterator<const char*>(s), input_iterator<const char*>(s+10), 145 S("12345ABCDEFGHIJ")); 146 test(S("12345"), input_iterator<const char*>(s), input_iterator<const char*>(s+52), 147 S("12345ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); 148 149 test(S("1234567890"), input_iterator<const char*>(s), input_iterator<const char*>(s), 150 S("1234567890")); 151 test(S("1234567890"), input_iterator<const char*>(s), input_iterator<const char*>(s+1), 152 S("1234567890A")); 153 test(S("1234567890"), input_iterator<const char*>(s), input_iterator<const char*>(s+10), 154 S("1234567890ABCDEFGHIJ")); 155 test(S("1234567890"), input_iterator<const char*>(s), input_iterator<const char*>(s+52), 156 S("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); 157 158 test(S("12345678901234567890"), input_iterator<const char*>(s), input_iterator<const char*>(s), 159 S("12345678901234567890")); 160 test(S("12345678901234567890"), input_iterator<const char*>(s), input_iterator<const char*>(s+1), 161 S("12345678901234567890""A")); 162 test(S("12345678901234567890"), input_iterator<const char*>(s), input_iterator<const char*>(s+10), 163 S("12345678901234567890""ABCDEFGHIJ")); 164 test(S("12345678901234567890"), input_iterator<const char*>(s), input_iterator<const char*>(s+52), 165 S("12345678901234567890""ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); 166 } 167 #endif 168 #ifndef TEST_HAS_NO_EXCEPTIONS 169 { // test iterator operations that throw 170 typedef std::string S; 171 typedef ThrowingIterator<char> TIter; 172 typedef input_iterator<TIter> IIter; 173 const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 174 test_exceptions(S(), IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter()); 175 test_exceptions(S(), IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter()); 176 test_exceptions(S(), IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter()); 177 178 test_exceptions(S(), TIter(s, s+10, 4, TIter::TAIncrement), TIter()); 179 test_exceptions(S(), TIter(s, s+10, 5, TIter::TADereference), TIter()); 180 test_exceptions(S(), TIter(s, s+10, 6, TIter::TAComparison), TIter()); 181 182 Widget w[100]; 183 test_exceptions(S(), w, w+100); 184 } 185 #endif 186 187 { // test appending to self 188 typedef std::string S; 189 S s_short = "123/"; 190 S s_long = "Lorem ipsum dolor sit amet, consectetur/"; 191 192 s_short.append(s_short.begin(), s_short.end()); 193 assert(s_short == "123/123/"); 194 s_short.append(s_short.begin(), s_short.end()); 195 assert(s_short == "123/123/123/123/"); 196 s_short.append(s_short.begin(), s_short.end()); 197 assert(s_short == "123/123/123/123/123/123/123/123/"); 198 199 s_long.append(s_long.begin(), s_long.end()); 200 assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/"); 201 } 202 203 { // test appending a different type 204 typedef std::string S; 205 const uint8_t p[] = "ABCD"; 206 207 S s; 208 s.append(p, p + 4); 209 assert(s == "ABCD"); 210 } 211 212 { // regression-test appending to self in sneaky ways 213 std::string s_short = "hello"; 214 std::string s_long = "Lorem ipsum dolor sit amet, consectetur/"; 215 std::string s_othertype = "hello"; 216 const unsigned char *first = reinterpret_cast<const unsigned char*>(s_othertype.data()); 217 std::string s_sneaky = "hello"; 218 219 test(s_short, s_short.data() + s_short.size(), s_short.data() + s_short.size() + 1, 220 std::string("hello\0", 6)); 221 test(s_long, s_long.data() + s_long.size(), s_long.data() + s_long.size() + 1, 222 std::string("Lorem ipsum dolor sit amet, consectetur/\0", 41)); 223 test(s_othertype, first + 2, first + 5, std::string("hellollo")); 224 225 s_sneaky.reserve(12); 226 test(s_sneaky, s_sneaky.data(), s_sneaky.data() + 6, std::string("hellohello\0", 11)); 227 } 228 229 { // test with a move iterator that returns char&& 230 typedef forward_iterator<const char*> It; 231 typedef std::move_iterator<It> MoveIt; 232 const char p[] = "ABCD"; 233 std::string s; 234 s.append(MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1))); 235 assert(s == "ABCD"); 236 } 237 { // test with a move iterator that returns char&& 238 typedef const char* It; 239 typedef std::move_iterator<It> MoveIt; 240 const char p[] = "ABCD"; 241 std::string s; 242 s.append(MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1))); 243 assert(s == "ABCD"); 244 } 245 246 return 0; 247 } 248