brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.3 KiB · 4776672 Raw
162 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// <memory>10 11// unique_ptr12 13// T& unique_ptr::operator[](size_t) const14 15#include <memory>16#include <cassert>17#include <type_traits>18#include <array>19 20#include "test_macros.h"21#include "type_algorithms.h"22 23static int next = 0;24struct EnumeratedDefaultCtor {25  EnumeratedDefaultCtor() : value(0) { value = ++next; }26  int value;27};28 29template <std::size_t Size>30struct WithTrivialDtor {31  std::array<char, Size> padding = {'x'};32  TEST_CONSTEXPR_CXX23 friend bool operator==(WithTrivialDtor const& x, WithTrivialDtor const& y) {33    return x.padding == y.padding;34  }35};36 37template <std::size_t Size>38struct WithNonTrivialDtor {39  std::array<char, Size> padding = {'x'};40  TEST_CONSTEXPR_CXX23 friend bool operator==(WithNonTrivialDtor const& x, WithNonTrivialDtor const& y) {41    return x.padding == y.padding;42  }43  TEST_CONSTEXPR_CXX23 ~WithNonTrivialDtor() {}44};45 46template <class T>47struct CustomDeleter : std::default_delete<T> {};48 49struct NoopDeleter {50  template <class T>51  TEST_CONSTEXPR_CXX23 void operator()(T*) const {}52};53 54TEST_CONSTEXPR_CXX23 bool test() {55  // Basic test56  {57    std::unique_ptr<int[]> p(new int[3]);58    {59      int& result = p[0];60      result      = 0;61    }62    {63      int& result = p[1];64      result      = 1;65    }66    {67      int& result = p[2];68      result      = 2;69    }70 71    assert(p[0] == 0);72    assert(p[1] == 1);73    assert(p[2] == 2);74  }75 76  // Ensure that the order of access is correct after initializing a unique_ptr but77  // before actually modifying any of its elements. The implementation would have to78  // really try for this not to be the case, but we still check it.79  //80  // This requires assigning known values to the elements when they are first constructed,81  // which requires global state.82  {83    if (!TEST_IS_CONSTANT_EVALUATED) {84      std::unique_ptr<EnumeratedDefaultCtor[]> p(new EnumeratedDefaultCtor[3]);85      assert(p[0].value == 1);86      assert(p[1].value == 2);87      assert(p[2].value == 3);88    }89  }90 91  // Make sure operator[] is const-qualified92  {93    std::unique_ptr<int[]> const p(new int[3]);94    p[0] = 42;95    assert(p[0] == 42);96  }97 98  // Make sure we properly handle types with trivial and non-trivial destructors of different99  // sizes. This is relevant because some implementations may want to use properties of the100  // ABI like array cookies and these properties often depend on e.g. the triviality of T's101  // destructor, T's size and so on.102#if TEST_STD_VER >= 20 // this test is too painful to write before C++20103  {104    using TrickyCookieTypes = types::type_list<105        WithTrivialDtor<1>,106        WithTrivialDtor<2>,107        WithTrivialDtor<3>,108        WithTrivialDtor<4>,109        WithTrivialDtor<8>,110        WithTrivialDtor<16>,111        WithTrivialDtor<256>,112        WithNonTrivialDtor<1>,113        WithNonTrivialDtor<2>,114        WithNonTrivialDtor<3>,115        WithNonTrivialDtor<4>,116        WithNonTrivialDtor<8>,117        WithNonTrivialDtor<16>,118        WithNonTrivialDtor<256>>;119    types::for_each(TrickyCookieTypes(), []<class T> {120      // Array allocated with `new T[n]`, default deleter121      {122        std::unique_ptr<T[], std::default_delete<T[]>> p(new T[3]);123        assert(p[0] == T());124        assert(p[1] == T());125        assert(p[2] == T());126      }127 128      // Array allocated with `new T[n]`, custom deleter129      {130        std::unique_ptr<T[], CustomDeleter<T[]>> p(new T[3]);131        assert(p[0] == T());132        assert(p[1] == T());133        assert(p[2] == T());134      }135 136      // Array not allocated with `new T[n]`, custom deleter137      //138      // This test aims to ensure that the implementation doesn't try to use an array cookie139      // when there is none.140      {141        T array[50] = {};142        std::unique_ptr<T[], NoopDeleter> p(&array[0]);143        assert(p[0] == T());144        assert(p[1] == T());145        assert(p[2] == T());146      }147    });148  }149#endif // C++20150 151  return true;152}153 154int main(int, char**) {155  test();156#if TEST_STD_VER >= 23157  static_assert(test());158#endif159 160  return 0;161}162