brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · 318f4b1 Raw
201 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// Test unique_ptr move ctor14 15#include <memory>16#include <utility>17#include <cassert>18 19#include "test_macros.h"20#include "unique_ptr_test_helper.h"21 22//=============================================================================23// TESTING unique_ptr(unique_ptr&&)24//25// Concerns26//   1 The moved from pointer is empty and the new pointer stores the old value.27//   2 The only requirement on the deleter is that it is MoveConstructible28//     or a reference.29//   3 The constructor works for explicitly moved values (i.e. std::move(x))30//   4 The constructor works for true temporaries (e.g. a return value)31//32// Plan33//  1 Explicitly construct unique_ptr<T, D> for various deleter types 'D'.34//    check that the value and deleter have been properly moved. (C-1,2,3)35//36//  2 Use the expression 'sink(source())' to move construct a unique_ptr<T, D>37//    from a temporary. 'source' should return the unique_ptr by value and38//    'sink' should accept the unique_ptr by value. (C-1,2,4)39 40template <class VT>41TEST_CONSTEXPR_CXX23 std::unique_ptr<VT> source1() {42  return std::unique_ptr<VT>(newValue<VT>(1));43}44 45template <class VT>46TEST_CONSTEXPR_CXX23 std::unique_ptr<VT, Deleter<VT> > source2() {47  return std::unique_ptr<VT, Deleter<VT> >(newValue<VT>(1), Deleter<VT>(5));48}49 50template <class VT>51std::unique_ptr<VT, NCDeleter<VT>&> source3() {52  static NCDeleter<VT> d(5);53  return std::unique_ptr<VT, NCDeleter<VT>&>(newValue<VT>(1), d);54}55 56template <class VT>57TEST_CONSTEXPR_CXX23 void sink1(std::unique_ptr<VT> p) {58  assert(p.get() != nullptr);59}60 61template <class VT>62TEST_CONSTEXPR_CXX23 void sink2(std::unique_ptr<VT, Deleter<VT> > p) {63  assert(p.get() != nullptr);64  assert(p.get_deleter().state() == 5);65}66 67template <class VT>68void sink3(std::unique_ptr<VT, NCDeleter<VT>&> p) {69  assert(p.get() != nullptr);70  assert(p.get_deleter().state() == 5);71  assert(&p.get_deleter() == &source3<VT>().get_deleter());72}73 74template <class ValueT>75TEST_CONSTEXPR_CXX23 void test_sfinae() {76  typedef std::unique_ptr<ValueT> U;77  { // Ensure unique_ptr is non-copyable78    static_assert((!std::is_constructible<U, U const&>::value), "");79    static_assert((!std::is_constructible<U, U&>::value), "");80  }81}82 83template <bool IsArray>84TEST_CONSTEXPR_CXX23 void test_basic() {85  typedef typename std::conditional<!IsArray, A, A[]>::type VT;86  const int expect_alive = IsArray ? 5 : 1;87  {88    typedef std::unique_ptr<VT> APtr;89    APtr s(newValue<VT>(expect_alive));90    A* p = s.get();91    APtr s2 = std::move(s);92    assert(s2.get() == p);93    assert(s.get() == 0);94    if (!TEST_IS_CONSTANT_EVALUATED)95      assert(A::count == expect_alive);96  }97  if (!TEST_IS_CONSTANT_EVALUATED)98    assert(A::count == 0);99  {100    typedef Deleter<VT> MoveDel;101    typedef std::unique_ptr<VT, MoveDel> APtr;102    MoveDel d(5);103    APtr s(newValue<VT>(expect_alive), std::move(d));104    assert(d.state() == 0);105    assert(s.get_deleter().state() == 5);106    A* p = s.get();107    APtr s2 = std::move(s);108    assert(s2.get() == p);109    assert(s.get() == 0);110    if (!TEST_IS_CONSTANT_EVALUATED)111      assert(A::count == expect_alive);112    assert(s2.get_deleter().state() == 5);113    assert(s.get_deleter().state() == 0);114  }115  if (!TEST_IS_CONSTANT_EVALUATED)116    assert(A::count == 0);117  {118    typedef NCDeleter<VT> NonCopyDel;119    typedef std::unique_ptr<VT, NonCopyDel&> APtr;120 121    NonCopyDel d;122    APtr s(newValue<VT>(expect_alive), d);123    A* p = s.get();124    APtr s2 = std::move(s);125    assert(s2.get() == p);126    assert(s.get() == 0);127    if (!TEST_IS_CONSTANT_EVALUATED)128      assert(A::count == expect_alive);129    d.set_state(6);130    assert(s2.get_deleter().state() == d.state());131    assert(s.get_deleter().state() == d.state());132  }133  if (!TEST_IS_CONSTANT_EVALUATED)134    assert(A::count == 0);135  {136    sink1<VT>(source1<VT>());137    if (!TEST_IS_CONSTANT_EVALUATED)138      assert(A::count == 0);139    sink2<VT>(source2<VT>());140    if (!TEST_IS_CONSTANT_EVALUATED)141      assert(A::count == 0);142  }143  if (!TEST_IS_CONSTANT_EVALUATED)144    assert(A::count == 0);145}146 147template <class VT>148TEST_CONSTEXPR_CXX23 void test_noexcept() {149#if TEST_STD_VER >= 11150  {151    typedef std::unique_ptr<VT> U;152    static_assert(std::is_nothrow_move_constructible<U>::value, "");153  }154  {155    typedef std::unique_ptr<VT, Deleter<VT> > U;156    static_assert(std::is_nothrow_move_constructible<U>::value, "");157  }158  {159    typedef std::unique_ptr<VT, NCDeleter<VT> &> U;160    static_assert(std::is_nothrow_move_constructible<U>::value, "");161  }162  {163    typedef std::unique_ptr<VT, const NCConstDeleter<VT> &> U;164    static_assert(std::is_nothrow_move_constructible<U>::value, "");165  }166#endif167}168 169TEST_CONSTEXPR_CXX23 bool test() {170  {171    test_basic</*IsArray*/ false>();172    test_sfinae<int>();173    test_noexcept<int>();174  }175  {176    test_basic</*IsArray*/ true>();177    test_sfinae<int[]>();178    test_noexcept<int[]>();179  }180 181  return true;182}183 184template <bool IsArray>185void test_sink3() {186  typedef typename std::conditional<!IsArray, A, A[]>::type VT;187  sink3<VT>(source3<VT>());188  assert(A::count == 0);189}190 191int main(int, char**) {192  test_sink3</*IsArray*/ false>();193  test_sink3</*IsArray*/ true>();194  test();195#if TEST_STD_VER >= 23196  static_assert(test());197#endif198 199  return 0;200}201