brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.7 KiB · c183def Raw
190 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& assign(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.assign(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>36void 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.assign(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());66    test(S("12345"), s, s + 1, S("A"));67    test(S("12345"), s, s + 10, S("ABCDEFGHIJ"));68    test(S("12345"), s, s + 52, S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));69 70    test(S("1234567890"), s, s, S());71    test(S("1234567890"), s, s + 1, S("A"));72    test(S("1234567890"), s, s + 10, S("ABCDEFGHIJ"));73    test(S("1234567890"), s, s + 52, S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));74 75    test(S("12345678901234567890"), s, s, S());76    test(S("12345678901234567890"), s, s + 1, S("A"));77    test(S("12345678901234567890"), s, s + 10, S("ABCDEFGHIJ"));78    test(S("12345678901234567890"), s, s + 52, S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));79 80    test(S(), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s), S());81    test(S(), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s + 1), S("A"));82    test(S(), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s + 10), S("ABCDEFGHIJ"));83    test(S(),84         cpp17_input_iterator<const char*>(s),85         cpp17_input_iterator<const char*>(s + 52),86         S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));87 88    test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s), S());89    test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s + 1), S("A"));90    test(S("12345"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s + 10), S("ABCDEFGHIJ"));91    test(S("12345"),92         cpp17_input_iterator<const char*>(s),93         cpp17_input_iterator<const char*>(s + 52),94         S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));95 96    test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s), S());97    test(S("1234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s + 1), S("A"));98    test(S("1234567890"),99         cpp17_input_iterator<const char*>(s),100         cpp17_input_iterator<const char*>(s + 10),101         S("ABCDEFGHIJ"));102    test(S("1234567890"),103         cpp17_input_iterator<const char*>(s),104         cpp17_input_iterator<const char*>(s + 52),105         S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));106 107    test(S("12345678901234567890"), cpp17_input_iterator<const char*>(s), cpp17_input_iterator<const char*>(s), S());108    test(S("12345678901234567890"),109         cpp17_input_iterator<const char*>(s),110         cpp17_input_iterator<const char*>(s + 1),111         S("A"));112    test(S("12345678901234567890"),113         cpp17_input_iterator<const char*>(s),114         cpp17_input_iterator<const char*>(s + 10),115         S("ABCDEFGHIJ"));116    test(S("12345678901234567890"),117         cpp17_input_iterator<const char*>(s),118         cpp17_input_iterator<const char*>(s + 52),119         S("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));120  }121 122#ifndef TEST_HAS_NO_EXCEPTIONS123  if (!TEST_IS_CONSTANT_EVALUATED) { // test iterator operations that throw124    typedef ThrowingIterator<char> TIter;125    typedef cpp17_input_iterator<TIter> IIter;126    const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";127    test_exceptions(S(), IIter(TIter(s, s + 10, 4, TIter::TAIncrement)), IIter(TIter()));128    test_exceptions(S(), IIter(TIter(s, s + 10, 5, TIter::TADereference)), IIter(TIter()));129    test_exceptions(S(), IIter(TIter(s, s + 10, 6, TIter::TAComparison)), IIter(TIter()));130 131    test_exceptions(S(), TIter(s, s + 10, 4, TIter::TAIncrement), TIter());132    test_exceptions(S(), TIter(s, s + 10, 5, TIter::TADereference), TIter());133    test_exceptions(S(), TIter(s, s + 10, 6, TIter::TAComparison), TIter());134 135    Widget w[100];136    test_exceptions(S(), w, w + 100);137  }138#endif139 140  { // test assigning to self141    S s_short = "123/";142    S s_long  = "Lorem ipsum dolor sit amet, consectetur/";143 144    s_short.assign(s_short.begin(), s_short.end());145    assert(s_short == "123/");146    s_short.assign(s_short.begin() + 2, s_short.end());147    assert(s_short == "3/");148 149    s_long.assign(s_long.begin(), s_long.end());150    assert(s_long == "Lorem ipsum dolor sit amet, consectetur/");151 152    s_long.assign(s_long.begin() + 30, s_long.end());153    assert(s_long == "nsectetur/");154  }155 156  { // test assigning a different type157    const std::uint8_t p[] = "ABCD";158 159    S s;160    s.assign(p, p + 4);161    assert(s == "ABCD");162  }163 164  { // regression-test assigning to self in sneaky ways165    S sneaky = "hello";166    sneaky.resize(sneaky.capacity(), 'x');167    S expected = sneaky + S(1, '\0');168    test(sneaky, sneaky.data(), sneaky.data() + sneaky.size() + 1, expected);169  }170}171 172TEST_CONSTEXPR_CXX20 bool test() {173  test_string<std::string>();174#if TEST_STD_VER >= 11175  test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();176  test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char> > >();177#endif178 179  return true;180}181 182int main(int, char**) {183  test();184#if TEST_STD_VER > 17185  static_assert(test());186#endif187 188  return 0;189}190