brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.4 KiB · 684661a Raw
244 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// <string>10 11// template<class InputIterator>12//   basic_string& append(InputIterator first, InputIterator last); // constexpr since C++2013 14#include <string>15#include <cassert>16 17#include "test_macros.h"18#include "test_iterators.h"19#include "min_allocator.h"20#include "asan_testing.h"21 22template <class S, class It>23TEST_CONSTEXPR_CXX20 void test(S s, It first, It last, S expected) {24  s.append(first, last);25  LIBCPP_ASSERT(s.__invariants());26  assert(s == expected);27  LIBCPP_ASSERT(is_string_asan_correct(s));28}29 30#ifndef TEST_HAS_NO_EXCEPTIONS31struct Widget {32  operator char() const { throw 42; }33};34 35template <class S, class It>36TEST_CONSTEXPR_CXX20 void test_exceptions(S s, It first, It last) {37  S original                 = s;38  typename S::iterator begin = s.begin();39  typename S::iterator end   = s.end();40 41  try {42    s.append(first, last);43    assert(false);44  } catch (...) {45  }46 47  // Part of "no effects" is that iterators and pointers48  // into the string must not have been invalidated.49  LIBCPP_ASSERT(s.__invariants());50  assert(s == original);51  assert(s.begin() == begin);52  assert(s.end() == end);53}54#endif55 56template <class S>57TEST_CONSTEXPR_CXX20 void test_string() {58  {59    const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";60    test(S(), s, s, S());61    test(S(), s, s + 1, S("A"));62    test(S(), s, s + 10, S("ABCDEFGHIJ"));63    test(S(), s, s + 52, S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));64 65    test(S("12345"), s, s, S("12345"));66    test(S("12345"), s, s + 1, S("12345A"));67    test(S("12345"), s, s + 10, S("12345ABCDEFGHIJ"));68    test(S("12345"), s, s + 52, S("12345ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));69 70    test(S("1234567890"), s, s, S("1234567890"));71    test(S("1234567890"), s, s + 1, S("1234567890A"));72    test(S("1234567890"), s, s + 10, S("1234567890ABCDEFGHIJ"));73    test(S("1234567890"), s, s + 52, S("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));74 75    test(S("12345678901234567890"), s, s, S("12345678901234567890"));76    test(S("12345678901234567890"),77         s,78         s + 1,79         S("12345678901234567890"80           "A"));81    test(S("12345678901234567890"),82         s,83         s + 10,84         S("12345678901234567890"85           "ABCDEFGHIJ"));86    test(S("12345678901234567890"),87         s,88         s + 52,89         S("12345678901234567890"90           "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));91 92    test(S(), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s), S());93    test(S(), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s + 1), S("A"));94    test(S(), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s + 10), S("ABCDEFGHIJ"));95    test(S(),96         cpp17_input_iterator<const char*>(s),97         cpp17_input_iterator<const char*>(s + 52),98         S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));99 100    test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s), S("12345"));101    test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s + 1), S("12345A"));102    test(S("12345"),103         cpp17_input_iterator<const char*>(s),104         cpp17_input_iterator<const char*>(s + 10),105         S("12345ABCDEFGHIJ"));106    test(S("12345"),107         cpp17_input_iterator<const char*>(s),108         cpp17_input_iterator<const char*>(s + 52),109         S("12345ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));110 111    test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s), S("1234567890"));112    test(S("1234567890"),113         cpp17_input_iterator<const char*>(s),114         cpp17_input_iterator<const char*>(s + 1),115         S("1234567890A"));116    test(S("1234567890"),117         cpp17_input_iterator<const char*>(s),118         cpp17_input_iterator<const char*>(s + 10),119         S("1234567890ABCDEFGHIJ"));120    test(S("1234567890"),121         cpp17_input_iterator<const char*>(s),122         cpp17_input_iterator<const char*>(s + 52),123         S("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));124 125    test(S("12345678901234567890"),126         cpp17_input_iterator<const char*>(s),127         cpp17_input_iterator<const char*>(s),128         S("12345678901234567890"));129    test(S("12345678901234567890"),130         cpp17_input_iterator<const char*>(s),131         cpp17_input_iterator<const char*>(s + 1),132         S("12345678901234567890"133           "A"));134    test(S("12345678901234567890"),135         cpp17_input_iterator<const char*>(s),136         cpp17_input_iterator<const char*>(s + 10),137         S("12345678901234567890"138           "ABCDEFGHIJ"));139    test(S("12345678901234567890"),140         cpp17_input_iterator<const char*>(s),141         cpp17_input_iterator<const char*>(s + 52),142         S("12345678901234567890"143           "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));144  }145 146#ifndef TEST_HAS_NO_EXCEPTIONS147  if (!TEST_IS_CONSTANT_EVALUATED) { // test iterator operations that throw148    typedef ThrowingIterator<char> TIter;149    typedef cpp17_input_iterator<TIter> IIter;150    const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";151    test_exceptions(S(), IIter(TIter(s, s + 10, 4, TIter::TAIncrement)), IIter(TIter()));152    test_exceptions(S(), IIter(TIter(s, s + 10, 5, TIter::TADereference)), IIter(TIter()));153    test_exceptions(S(), IIter(TIter(s, s + 10, 6, TIter::TAComparison)), IIter(TIter()));154 155    test_exceptions(S(), TIter(s, s + 10, 4, TIter::TAIncrement), TIter());156    test_exceptions(S(), TIter(s, s + 10, 5, TIter::TADereference), TIter());157    test_exceptions(S(), TIter(s, s + 10, 6, TIter::TAComparison), TIter());158 159    Widget w[100];160    test_exceptions(S(), w, w + 100);161  }162#endif163 164  { // test appending to self165    S s_short = "123/";166    S s_long  = "Lorem ipsum dolor sit amet, consectetur/";167 168    s_short.append(s_short.begin(), s_short.end());169    assert(s_short == "123/123/");170    s_short.append(s_short.begin(), s_short.end());171    assert(s_short == "123/123/123/123/");172    s_short.append(s_short.begin(), s_short.end());173    assert(s_short == "123/123/123/123/123/123/123/123/");174 175    s_long.append(s_long.begin(), s_long.end());176    assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/");177  }178 179  { // test appending a different type180    const std::uint8_t p[] = "ABCD";181 182    S s;183    s.append(p, p + 4);184    assert(s == "ABCD");185  }186 187  { // regression-test appending to self in sneaky ways188    S s_short     = "hello";189    S s_long      = "Lorem ipsum dolor sit amet, consectetur/";190    S s_othertype = "hello";191    S s_sneaky    = "hello";192 193    test(s_short, s_short.data() + s_short.size(), s_short.data() + s_short.size() + 1, S("hello\0", 6));194    test(s_long,195         s_long.data() + s_long.size(),196         s_long.data() + s_long.size() + 1,197         S("Lorem ipsum dolor sit amet, consectetur/\0", 41));198 199    s_sneaky.reserve(12);200    test(s_sneaky, s_sneaky.data(), s_sneaky.data() + 6, S("hellohello\0", 11));201 202    if (!TEST_IS_CONSTANT_EVALUATED) {203      const unsigned char* first = reinterpret_cast<const unsigned char*>(s_othertype.data());204      test(s_othertype, first + 2, first + 5, S("hellollo"));205    }206  }207 208  { // test with a move iterator that returns char&&209    typedef forward_iterator<const char*> It;210    typedef std::move_iterator<It> MoveIt;211    const char p[] = "ABCD";212    S s;213    s.append(MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1)));214    assert(s == "ABCD");215  }216  { // test with a move iterator that returns char&&217    typedef const char* It;218    typedef std::move_iterator<It> MoveIt;219    const char p[] = "ABCD";220    S s;221    s.append(MoveIt(It(std::begin(p))), MoveIt(It(std::end(p) - 1)));222    assert(s == "ABCD");223  }224}225 226TEST_CONSTEXPR_CXX20 bool test() {227  test_string<std::string>();228#if TEST_STD_VER >= 11229  test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();230  test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char> > >();231#endif232 233  return true;234}235 236int main(int, char**) {237  test();238#if TEST_STD_VER > 17239  static_assert(test());240#endif241 242  return 0;243}244