brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.9 KiB · 7a86dd3 Raw
130 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 "unique_ptr_test_helper.h"23 24template <class APtr, class BPtr>25void testAssign(APtr& aptr, BPtr& bptr) {26  A* p = bptr.get();27  assert(A::count == 2);28  aptr = std::move(bptr);29  assert(aptr.get() == p);30  assert(bptr.get() == 0);31  assert(A::count == 1);32  assert(B::count == 1);33}34 35template <class LHS, class RHS>36void checkDeleter(LHS& lhs, RHS& rhs, int LHSState, int RHSState) {37  assert(lhs.get_deleter().state() == LHSState);38  assert(rhs.get_deleter().state() == RHSState);39}40 41template <class T>42struct NCConvertingDeleter {43  NCConvertingDeleter() = default;44  NCConvertingDeleter(NCConvertingDeleter const&) = delete;45  NCConvertingDeleter(NCConvertingDeleter&&) = default;46 47  template <class U>48  NCConvertingDeleter(NCConvertingDeleter<U>&&) {}49 50  void operator()(T*) const {}51};52 53template <class T>54struct NCConvertingDeleter<T[]> {55  NCConvertingDeleter() = default;56  NCConvertingDeleter(NCConvertingDeleter const&) = delete;57  NCConvertingDeleter(NCConvertingDeleter&&) = default;58 59  template <class U>60  NCConvertingDeleter(NCConvertingDeleter<U>&&) {}61 62  void operator()(T*) const {}63};64 65struct GenericDeleter {66  void operator()(void*) const;67};68 69struct NCGenericDeleter {70  NCGenericDeleter() = default;71  NCGenericDeleter(NCGenericDeleter const&) = delete;72  NCGenericDeleter(NCGenericDeleter&&) = default;73 74  void operator()(void*) const {}75};76 77void test_sfinae() {78  using DA = NCConvertingDeleter<A[]>;        // non-copyable deleters79  using DAC = NCConvertingDeleter<const A[]>; // non-copyable deleters80 81  using UA = std::unique_ptr<A[]>;82  using UAC = std::unique_ptr<const A[]>;83  using UAD = std::unique_ptr<A[], DA>;84  using UACD = std::unique_ptr<const A[], DAC>;85 86  { // cannot move from an lvalue87    static_assert(std::is_assignable<UAC, UA&&>::value, "");88    static_assert(!std::is_assignable<UAC, UA&>::value, "");89    static_assert(!std::is_assignable<UAC, const UA&>::value, "");90  }91  { // cannot move if the deleter-types cannot convert92    static_assert(std::is_assignable<UACD, UAD&&>::value, "");93    static_assert(!std::is_assignable<UACD, UAC&&>::value, "");94    static_assert(!std::is_assignable<UAC, UACD&&>::value, "");95  }96  { // cannot move-convert with reference deleters of different types97    using UA1 = std::unique_ptr<A[], DA&>;98    using UA2 = std::unique_ptr<A[], DAC&>;99    static_assert(!std::is_assignable<UA1, UA2&&>::value, "");100  }101  { // cannot move-convert with reference deleters of different types102    using UA1 = std::unique_ptr<A[], const DA&>;103    using UA2 = std::unique_ptr<A[], const DAC&>;104    static_assert(!std::is_assignable<UA1, UA2&&>::value, "");105  }106  { // cannot move-convert with reference deleters with different qualifiers107    using UA1 = std::unique_ptr<A[], DA&>;108    using UA2 = std::unique_ptr<A[], const DA&>;109    static_assert(!std::is_assignable<UA1, UA2&&>::value, "");110    static_assert(!std::is_assignable<UA2, UA1&&>::value, "");111  }112  { // cannot move-convert from unique_ptr<Single>113    using UA1 = std::unique_ptr<A[]>;114    using UA2 = std::unique_ptr<A>;115    static_assert(!std::is_assignable<UA1, UA2&&>::value, "");116  }117  { // cannot move-convert from unique_ptr<Array[]>118    using UA1 = std::unique_ptr<A[], NCGenericDeleter>;119    using UA2 = std::unique_ptr<A, NCGenericDeleter>;120    static_assert(!std::is_assignable<UA1, UA2&&>::value, "");121  }122}123 124int main(int, char**) {125  test_sfinae();126  // FIXME: add tests127 128  return 0;129}130