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 // libc++ cannot safely provide the auto_ptr constructor without rvalue
10 // references.
11 // REQUIRES: c++11 || c++14
12 // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
13 
14 // <memory>
15 
16 // unique_ptr
17 
18 // template <class U> unique_ptr(auto_ptr<U>&&) noexcept
19 
20 #include <memory>
21 #include <utility>
22 #include <cassert>
23 
24 #include "test_macros.h"
25 
26 struct A {
27   static int count;
AA28   A() { ++count; }
AA29   A(const A&) { ++count; }
~AA30   virtual ~A() { --count; }
31 };
32 
33 int A::count = 0;
34 
35 struct B : public A {
36   static int count;
BB37   B() { ++count; }
BB38   B(const B& b) : A(b) { ++count; }
~BB39   virtual ~B() { --count; }
40 };
41 
42 int B::count = 0;
43 
44 struct C {};
45 
46 struct Deleter {
operator ()Deleter47   void operator()(void*) {}
48 };
49 
test_sfinae()50 void test_sfinae() {
51   {
52     // the auto_ptr constructor should be disable with a non-default deleter.
53     using AP = std::auto_ptr<int>;
54     using U = std::unique_ptr<int, Deleter>;
55     static_assert(!std::is_constructible<U, AP&&>::value, "");
56   }
57   {
58     // the auto_ptr constructor should be disabled when the pointer types are incompatible.
59     using AP = std::auto_ptr<A>;
60     using U = std::unique_ptr<C>;
61     static_assert(!std::is_constructible<U, AP&&>::value, "");
62   }
63 }
64 
main(int,char **)65 int main(int, char**) {
66   {
67     B* p = new B;
68     std::auto_ptr<B> ap(p);
69     std::unique_ptr<A> up(std::move(ap));
70     assert(up.get() == p);
71     assert(ap.get() == 0);
72     assert(A::count == 1);
73     assert(B::count == 1);
74   }
75   assert(A::count == 0);
76   assert(B::count == 0);
77   {
78     B* p = new B;
79     std::auto_ptr<B> ap(p);
80     std::unique_ptr<A> up;
81     up = std::move(ap);
82     assert(up.get() == p);
83     assert(ap.get() == 0);
84     assert(A::count == 1);
85     assert(B::count == 1);
86   }
87   assert(A::count == 0);
88   assert(B::count == 0);
89 #if TEST_STD_VER >= 11
90   {
91     static_assert(std::is_nothrow_constructible<std::unique_ptr<A>,
92                                                 std::auto_ptr<B>&&>::value,
93                   "");
94   }
95 #endif
96   test_sfinae();
97 
98   return 0;
99 }
100