brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.0 KiB · 0201e9c Raw
166 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// UNSUPPORTED: c++0310 11// <memory>12 13// unique_ptr14 15// Test unique_ptr converting move assignment16 17#include <memory>18#include <utility>19#include <cassert>20 21#include "test_macros.h"22#include "deleter_types.h"23#include "unique_ptr_test_helper.h"24 25template <class APtr, class BPtr>26TEST_CONSTEXPR_CXX23 void testAssign(APtr& aptr, BPtr& bptr) {27  A* p = bptr.get();28  if (!TEST_IS_CONSTANT_EVALUATED)29    assert(A::count == 2);30  aptr = std::move(bptr);31  assert(aptr.get() == p);32  assert(bptr.get() == 0);33  if (!TEST_IS_CONSTANT_EVALUATED) {34    assert(A::count == 1);35    assert(B::count == 1);36  }37}38 39template <class LHS, class RHS>40TEST_CONSTEXPR_CXX23 void checkDeleter(LHS& lhs, RHS& rhs, int LHSState, int RHSState) {41  assert(lhs.get_deleter().state() == LHSState);42  assert(rhs.get_deleter().state() == RHSState);43}44 45template <class T>46struct NCConvertingDeleter {47  TEST_CONSTEXPR_CXX23 NCConvertingDeleter()                      = default;48  NCConvertingDeleter(NCConvertingDeleter const&) = delete;49  TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter&&) = default;50 51  template <class U>52  TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter<U>&&) {}53 54  TEST_CONSTEXPR_CXX23 void operator()(T*) const {}55};56 57template <class T>58struct NCConvertingDeleter<T[]> {59  TEST_CONSTEXPR_CXX23 NCConvertingDeleter()                      = default;60  NCConvertingDeleter(NCConvertingDeleter const&) = delete;61  TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter&&) = default;62 63  template <class U>64  TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter<U>&&) {}65 66  TEST_CONSTEXPR_CXX23 void operator()(T*) const {}67};68 69struct NCGenericDeleter {70  TEST_CONSTEXPR_CXX23 NCGenericDeleter()                   = default;71  NCGenericDeleter(NCGenericDeleter const&) = delete;72  TEST_CONSTEXPR_CXX23 NCGenericDeleter(NCGenericDeleter&&) = default;73 74  TEST_CONSTEXPR_CXX23 void operator()(void*) const {}75};76 77TEST_CONSTEXPR_CXX23 void test_sfinae() {78  using DA = NCConvertingDeleter<A>; // non-copyable deleters79  using DB = NCConvertingDeleter<B>;80  using UA = std::unique_ptr<A>;81  using UB = std::unique_ptr<B>;82  using UAD = std::unique_ptr<A, DA>;83  using UBD = std::unique_ptr<B, DB>;84  { // cannot move from an lvalue85    static_assert(std::is_assignable<UA, UB&&>::value, "");86    static_assert(!std::is_assignable<UA, UB&>::value, "");87    static_assert(!std::is_assignable<UA, const UB&>::value, "");88  }89  { // cannot move if the deleter-types cannot convert90    static_assert(std::is_assignable<UAD, UBD&&>::value, "");91    static_assert(!std::is_assignable<UAD, UB&&>::value, "");92    static_assert(!std::is_assignable<UA, UBD&&>::value, "");93  }94  { // cannot move-convert with reference deleters of different types95    using UA1 = std::unique_ptr<A, DA&>;96    using UB1 = std::unique_ptr<B, DB&>;97    static_assert(!std::is_assignable<UA1, UB1&&>::value, "");98  }99  { // cannot move-convert with reference deleters of different types100    using UA1 = std::unique_ptr<A, const DA&>;101    using UB1 = std::unique_ptr<B, const DB&>;102    static_assert(!std::is_assignable<UA1, UB1&&>::value, "");103  }104  { // cannot move-convert from unique_ptr<Array[]>105    using UA1 = std::unique_ptr<A>;106    using UA2 = std::unique_ptr<A[]>;107    using UB1 = std::unique_ptr<B[]>;108    static_assert(!std::is_assignable<UA1, UA2&&>::value, "");109    static_assert(!std::is_assignable<UA1, UB1&&>::value, "");110  }111  { // cannot move-convert from unique_ptr<Array[]>112    using UA1 = std::unique_ptr<A, NCGenericDeleter>;113    using UA2 = std::unique_ptr<A[], NCGenericDeleter>;114    using UB1 = std::unique_ptr<B[], NCGenericDeleter>;115    static_assert(!std::is_assignable<UA1, UA2&&>::value, "");116    static_assert(!std::is_assignable<UA1, UB1&&>::value, "");117  }118}119 120TEST_CONSTEXPR_CXX23 bool test() {121  test_sfinae();122  {123    std::unique_ptr<B> bptr(new B);124    std::unique_ptr<A> aptr(new A);125    testAssign(aptr, bptr);126  }127  if (!TEST_IS_CONSTANT_EVALUATED) {128    assert(A::count == 0);129    assert(B::count == 0);130  }131  {132    Deleter<B> del(42);133    std::unique_ptr<B, Deleter<B> > bptr(new B, std::move(del));134    std::unique_ptr<A, Deleter<A> > aptr(new A);135    testAssign(aptr, bptr);136    checkDeleter(aptr, bptr, 42, 0);137  }138  if (!TEST_IS_CONSTANT_EVALUATED) {139    assert(A::count == 0);140    assert(B::count == 0);141  }142  {143    CDeleter<A> adel(6);144    CDeleter<B> bdel(42);145    std::unique_ptr<B, CDeleter<B>&> bptr(new B, bdel);146    std::unique_ptr<A, CDeleter<A>&> aptr(new A, adel);147    testAssign(aptr, bptr);148    checkDeleter(aptr, bptr, 42, 42);149  }150  if (!TEST_IS_CONSTANT_EVALUATED) {151    assert(A::count == 0);152    assert(B::count == 0);153  }154 155  return true;156}157 158int main(int, char**) {159  test();160#if TEST_STD_VER >= 23161  static_assert(test());162#endif163 164  return 0;165}166