152 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// Self assignment post-conditions are tested.12// ADDITIONAL_COMPILE_FLAGS(gcc-style-warnings): -Wno-self-move13 14// <memory>15 16// unique_ptr17 18// Test unique_ptr move assignment19 20// test move assignment. Should only require a MoveConstructible deleter, or if21// deleter is a reference, not even that.22 23#include <memory>24#include <utility>25#include <cassert>26 27#include "test_macros.h"28#include "deleter_types.h"29#include "unique_ptr_test_helper.h"30 31struct GenericDeleter {32 void operator()(void*) const;33};34 35template <bool IsArray>36TEST_CONSTEXPR_CXX23 void test_basic() {37 typedef typename std::conditional<IsArray, A[], A>::type VT;38 const int expect_alive = IsArray ? 5 : 1;39 {40 std::unique_ptr<VT> s1(newValue<VT>(expect_alive));41 A* p = s1.get();42 std::unique_ptr<VT> s2(newValue<VT>(expect_alive));43 if (!TEST_IS_CONSTANT_EVALUATED)44 assert(A::count == (expect_alive * 2));45 s2 = std::move(s1);46 if (!TEST_IS_CONSTANT_EVALUATED)47 assert(A::count == expect_alive);48 assert(s2.get() == p);49 assert(s1.get() == 0);50 }51 if (!TEST_IS_CONSTANT_EVALUATED)52 assert(A::count == 0);53 {54 std::unique_ptr<VT, Deleter<VT> > s1(newValue<VT>(expect_alive),55 Deleter<VT>(5));56 A* p = s1.get();57 std::unique_ptr<VT, Deleter<VT> > s2(newValue<VT>(expect_alive));58 if (!TEST_IS_CONSTANT_EVALUATED)59 assert(A::count == (expect_alive * 2));60 s2 = std::move(s1);61 assert(s2.get() == p);62 assert(s1.get() == 0);63 if (!TEST_IS_CONSTANT_EVALUATED)64 assert(A::count == expect_alive);65 assert(s2.get_deleter().state() == 5);66 assert(s1.get_deleter().state() == 0);67 }68 if (!TEST_IS_CONSTANT_EVALUATED)69 assert(A::count == 0);70 {71 CDeleter<VT> d1(5);72 std::unique_ptr<VT, CDeleter<VT>&> s1(newValue<VT>(expect_alive), d1);73 A* p = s1.get();74 CDeleter<VT> d2(6);75 std::unique_ptr<VT, CDeleter<VT>&> s2(newValue<VT>(expect_alive), d2);76 s2 = std::move(s1);77 assert(s2.get() == p);78 assert(s1.get() == 0);79 if (!TEST_IS_CONSTANT_EVALUATED)80 assert(A::count == expect_alive);81 assert(d1.state() == 5);82 assert(d2.state() == 5);83 }84 if (!TEST_IS_CONSTANT_EVALUATED)85 assert(A::count == 0);86 {87 std::unique_ptr<VT> s(newValue<VT>(expect_alive));88 A* p = s.get();89 s = std::move(s);90 if (!TEST_IS_CONSTANT_EVALUATED)91 assert(A::count == expect_alive);92 assert(s.get() == p);93 }94 if (!TEST_IS_CONSTANT_EVALUATED)95 assert(A::count == 0);96}97 98template <bool IsArray>99TEST_CONSTEXPR_CXX23 void test_sfinae() {100 typedef typename std::conditional<IsArray, int[], int>::type VT;101 {102 typedef std::unique_ptr<VT> U;103 static_assert(!std::is_assignable<U, U&>::value, "");104 static_assert(!std::is_assignable<U, const U&>::value, "");105 static_assert(!std::is_assignable<U, const U&&>::value, "");106 static_assert(std::is_nothrow_assignable<U, U&&>::value, "");107 }108 {109 typedef std::unique_ptr<VT, GenericDeleter> U;110 static_assert(!std::is_assignable<U, U&>::value, "");111 static_assert(!std::is_assignable<U, const U&>::value, "");112 static_assert(!std::is_assignable<U, const U&&>::value, "");113 static_assert(std::is_nothrow_assignable<U, U&&>::value, "");114 }115 {116 typedef std::unique_ptr<VT, NCDeleter<VT>&> U;117 static_assert(!std::is_assignable<U, U&>::value, "");118 static_assert(!std::is_assignable<U, const U&>::value, "");119 static_assert(!std::is_assignable<U, const U&&>::value, "");120 static_assert(std::is_nothrow_assignable<U, U&&>::value, "");121 }122 {123 typedef std::unique_ptr<VT, const NCDeleter<VT>&> U;124 static_assert(!std::is_assignable<U, U&>::value, "");125 static_assert(!std::is_assignable<U, const U&>::value, "");126 static_assert(!std::is_assignable<U, const U&&>::value, "");127 static_assert(std::is_nothrow_assignable<U, U&&>::value, "");128 }129}130 131TEST_CONSTEXPR_CXX23 bool test() {132 {133 test_basic</*IsArray*/ false>();134 test_sfinae<false>();135 }136 {137 test_basic</*IsArray*/ true>();138 test_sfinae<true>();139 }140 141 return true;142}143 144int main(int, char**) {145 test();146#if TEST_STD_VER >= 23147 static_assert(test());148#endif149 150 return 0;151}152