1 | // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s |
2 | |
3 | template<typename T> |
4 | class unique_ptr { |
5 | T *ptr; |
6 | |
7 | unique_ptr(const unique_ptr&) = delete; // expected-note 3{{'unique_ptr' has been explicitly marked deleted here}} |
8 | unique_ptr &operator=(const unique_ptr&) = delete; // expected-note{{candidate function has been explicitly deleted}} |
9 | public: |
10 | unique_ptr() : ptr(0) { } |
11 | unique_ptr(unique_ptr &&other) : ptr(other.ptr) { other.ptr = 0; } |
12 | explicit unique_ptr(T *ptr) : ptr(ptr) { } |
13 | |
14 | ~unique_ptr() { delete ptr; } |
15 | |
16 | unique_ptr &operator=(unique_ptr &&other) { // expected-note{{candidate function not viable: no known conversion from 'unique_ptr<int>' to 'unique_ptr<int> &&' for 1st argument}} |
17 | if (this == &other) |
18 | return *this; |
19 | |
20 | delete ptr; |
21 | ptr = other.ptr; |
22 | other.ptr = 0; |
23 | return *this; |
24 | } |
25 | }; |
26 | |
27 | template<typename T> |
28 | struct remove_reference { |
29 | typedef T type; |
30 | }; |
31 | |
32 | template<typename T> |
33 | struct remove_reference<T&> { |
34 | typedef T type; |
35 | }; |
36 | |
37 | template<typename T> |
38 | struct remove_reference<T&&> { |
39 | typedef T type; |
40 | }; |
41 | |
42 | |
43 | template <class T> typename remove_reference<T>::type&& move(T&& t) { |
44 | return static_cast<typename remove_reference<T>::type&&>(t); |
45 | } |
46 | |
47 | template <class T> T&& forward(typename remove_reference<T>::type& t) { |
48 | return static_cast<T&&>(t); |
49 | } |
50 | |
51 | template <class T> T&& forward(typename remove_reference<T>::type&& t) { |
52 | return static_cast<T&&>(t); |
53 | } |
54 | |
55 | template<typename T, typename ...Args> |
56 | unique_ptr<T> make_unique_ptr(Args &&...args) { |
57 | return unique_ptr<T>(new T(forward<Args>(args)...)); |
58 | } |
59 | |
60 | template<typename T> void accept_unique_ptr(unique_ptr<T>); // expected-note{{passing argument to parameter here}} |
61 | |
62 | unique_ptr<int> test_unique_ptr() { |
63 | // Simple construction |
64 | unique_ptr<int> p; |
65 | unique_ptr<int> p1(new int); |
66 | |
67 | // Move construction |
68 | unique_ptr<int> p2(make_unique_ptr<int>(17)); |
69 | unique_ptr<int> p3 = make_unique_ptr<int>(17); |
70 | |
71 | // Copy construction (failures) |
72 | unique_ptr<int> p4(p); // expected-error{{call to deleted constructor of 'unique_ptr<int>'}} |
73 | unique_ptr<int> p5 = p; // expected-error{{call to deleted constructor of 'unique_ptr<int>'}} |
74 | |
75 | // Move assignment |
76 | p2 = move(p); |
77 | p2 = make_unique_ptr<int>(0); |
78 | |
79 | // Copy assignment (failures); |
80 | p2 = p3; // expected-error{{overload resolution selected deleted operator '='}} |
81 | |
82 | // Implicit copies |
83 | accept_unique_ptr(make_unique_ptr<double>(0.0)); |
84 | accept_unique_ptr(move(p2)); |
85 | |
86 | // Implicit copies (failures); |
87 | accept_unique_ptr(p); // expected-error{{call to deleted constructor of 'unique_ptr<int>'}} |
88 | |
89 | return p; |
90 | } |
91 | |
92 | namespace perfect_forwarding { |
93 | struct A { }; |
94 | |
95 | struct F0 { |
96 | void operator()(A&, const A&, A&&, const A&&, A&&, const A&&); // expected-note{{candidate function not viable: 5th argument ('const perfect_forwarding::A') would lose const qualifier}} |
97 | }; |
98 | |
99 | template<typename F, typename ...Args> |
100 | void forward(F f, Args &&...args) { |
101 | f(static_cast<Args&&>(args)...); // expected-error{{no matching function for call to object of type 'perfect_forwarding::F0'}} |
102 | } |
103 | |
104 | template<typename T> T get(); |
105 | |
106 | void test_forward() { |
107 | forward(F0(), get<A&>(), get<A const&>(), get<A>(), get<const A>(), |
108 | get<A&&>(), get<const A&&>()); |
109 | forward(F0(), get<A&>(), get<A const&>(), get<A>(), get<const A>(), // expected-note{{in instantiation of function template specialization 'perfect_forwarding::forward<perfect_forwarding::F0, perfect_forwarding::A &, const perfect_forwarding::A &, perfect_forwarding::A, const perfect_forwarding::A, const perfect_forwarding::A, const perfect_forwarding::A>' requested here}} |
110 | get<const A&&>(), get<const A&&>()); |
111 | } |
112 | }; |
113 | |