brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.3 KiB · c4fd5af Raw
137 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// basic_string(const basic_string& str, const Allocator& alloc); // constexpr since C++2012 13#include <string>14#include <cassert>15 16#include "test_macros.h"17#include "test_allocator.h"18#include "min_allocator.h"19#include "asan_testing.h"20 21#ifndef TEST_HAS_NO_EXCEPTIONS22struct alloc_imp {23  bool active;24 25  TEST_CONSTEXPR alloc_imp() : active(true) {}26 27  template <class T>28  T* allocate(std::size_t n) {29    if (active)30      return static_cast<T*>(std::malloc(n * sizeof(T)));31    else32      throw std::bad_alloc();33  }34 35  template <class T>36  void deallocate(T* p, std::size_t) {37    std::free(p);38  }39  void activate() { active = true; }40  void deactivate() { active = false; }41};42 43template <class T>44struct poca_alloc {45  typedef T value_type;46  typedef std::true_type propagate_on_container_copy_assignment;47 48  alloc_imp* imp;49 50  TEST_CONSTEXPR poca_alloc(alloc_imp* imp_) : imp(imp_) {}51 52  template <class U>53  TEST_CONSTEXPR poca_alloc(const poca_alloc<U>& other) : imp(other.imp) {}54 55  T* allocate(std::size_t n) { return imp->allocate<T>(n); }56  void deallocate(T* p, std::size_t n) { imp->deallocate(p, n); }57};58 59template <typename T, typename U>60bool operator==(const poca_alloc<T>& lhs, const poca_alloc<U>& rhs) {61  return lhs.imp == rhs.imp;62}63 64template <typename T, typename U>65bool operator!=(const poca_alloc<T>& lhs, const poca_alloc<U>& rhs) {66  return lhs.imp != rhs.imp;67}68#endif69 70template <class S>71TEST_CONSTEXPR_CXX20 void test(S s1, const typename S::allocator_type& a) {72  S s2(s1, a);73  LIBCPP_ASSERT(s2.__invariants());74  assert(s2 == s1);75  assert(s2.capacity() >= s2.size());76  assert(s2.get_allocator() == a);77  LIBCPP_ASSERT(is_string_asan_correct(s1));78  LIBCPP_ASSERT(is_string_asan_correct(s2));79}80 81template <class Alloc>82TEST_CONSTEXPR_CXX20 void test_string(const Alloc& a) {83  typedef std::basic_string<char, std::char_traits<char>, Alloc> S;84  test(S(), Alloc(a));85  test(S("1"), Alloc(a));86  test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), Alloc(a));87}88 89TEST_CONSTEXPR_CXX20 bool test() {90  test_string(std::allocator<char>());91  test_string(test_allocator<char>());92  test_string(test_allocator<char>(3));93#if TEST_STD_VER >= 1194  test_string(min_allocator<char>());95  test_string(safe_allocator<char>());96#endif97 98#if TEST_STD_VER >= 1199#  ifndef TEST_HAS_NO_EXCEPTIONS100  if (!TEST_IS_CONSTANT_EVALUATED) {101    typedef poca_alloc<char> A;102    typedef std::basic_string<char, std::char_traits<char>, A> S;103    const char* p1 = "This is my first string";104    const char* p2 = "This is my second string";105 106    alloc_imp imp1;107    alloc_imp imp2;108    S s1(p1, A(&imp1));109    S s2(p2, A(&imp2));110 111    assert(s1 == p1);112    assert(s2 == p2);113 114    imp2.deactivate();115    try {116      s1 = s2;117      assert(false);118    } catch (std::bad_alloc&) {119    }120    assert(s1 == p1);121    assert(s2 == p2);122  }123#  endif124#endif125 126  return true;127}128 129int main(int, char**) {130  test();131#if TEST_STD_VER > 17132  static_assert(test());133#endif134 135  return 0;136}137