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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03
10 
11 // <memory>
12 
13 // unique_ptr
14 
15 // Test unique_ptr converting move ctor
16 
17 #include <memory>
18 #include <cassert>
19 
20 #include "test_macros.h"
21 #include "deleter_types.h"
22 #include "unique_ptr_test_helper.h"
23 
24 template <int ID = 0>
25 struct GenericDeleter {
operator ()GenericDeleter26   void operator()(void*) const {}
27 };
28 
29 template <int ID = 0>
30 struct GenericConvertingDeleter {
31   template <int OID>
GenericConvertingDeleterGenericConvertingDeleter32   GenericConvertingDeleter(GenericConvertingDeleter<OID>) {}
operator ()GenericConvertingDeleter33   void operator()(void*) const {}
34 };
35 
test_sfinae()36 TEST_CONSTEXPR_CXX23 void test_sfinae() {
37   { // Disallow copying
38     using U1 = std::unique_ptr<A[], GenericConvertingDeleter<0> >;
39     using U2 = std::unique_ptr<A[], GenericConvertingDeleter<1> >;
40     static_assert(std::is_constructible<U1, U2&&>::value, "");
41     static_assert(!std::is_constructible<U1, U2&>::value, "");
42     static_assert(!std::is_constructible<U1, const U2&>::value, "");
43     static_assert(!std::is_constructible<U1, const U2&&>::value, "");
44   }
45   { // Disallow illegal qualified conversions
46     using U1 = std::unique_ptr<const A[]>;
47     using U2 = std::unique_ptr<A[]>;
48     static_assert(std::is_constructible<U1, U2&&>::value, "");
49     static_assert(!std::is_constructible<U2, U1&&>::value, "");
50   }
51   { // Disallow base-to-derived conversions.
52     using UA = std::unique_ptr<A[]>;
53     using UB = std::unique_ptr<B[]>;
54     static_assert(!std::is_constructible<UA, UB&&>::value, "");
55   }
56   { // Disallow base-to-derived conversions.
57     using UA = std::unique_ptr<A[], GenericConvertingDeleter<0> >;
58     using UB = std::unique_ptr<B[], GenericConvertingDeleter<1> >;
59     static_assert(!std::is_constructible<UA, UB&&>::value, "");
60   }
61   { // Disallow invalid deleter initialization
62     using U1 = std::unique_ptr<A[], GenericDeleter<0> >;
63     using U2 = std::unique_ptr<A[], GenericDeleter<1> >;
64     static_assert(!std::is_constructible<U1, U2&&>::value, "");
65   }
66   { // Disallow reference deleters with different qualifiers
67     using U1 = std::unique_ptr<A[], Deleter<A[]>&>;
68     using U2 = std::unique_ptr<A[], const Deleter<A[]>&>;
69     static_assert(!std::is_constructible<U1, U2&&>::value, "");
70     static_assert(!std::is_constructible<U2, U1&&>::value, "");
71   }
72   {
73     using U1 = std::unique_ptr<A[]>;
74     using U2 = std::unique_ptr<A>;
75     static_assert(!std::is_constructible<U1, U2&&>::value, "");
76     static_assert(!std::is_constructible<U2, U1&&>::value, "");
77   }
78 }
79 
test()80 TEST_CONSTEXPR_CXX23 bool test() {
81   test_sfinae();
82 
83   return true;
84 }
85 
main(int,char **)86 int main(int, char**) {
87   test();
88 #if TEST_STD_VER >= 23
89   static_assert(test());
90 #endif
91 
92   return 0;
93 }
94