1762bb9d0ad20320b9f97a841dce57ba5e8e48b07Richard Smith// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s 271fdb354520178c2663f56f466f7abca538b877fDouglas Gregor 371fdb354520178c2663f56f466f7abca538b877fDouglas Gregortemplate<typename T> 471fdb354520178c2663f56f466f7abca538b877fDouglas Gregorclass unique_ptr { 571fdb354520178c2663f56f466f7abca538b877fDouglas Gregor T *ptr; 671fdb354520178c2663f56f466f7abca538b877fDouglas Gregor 7651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unique_ptr(const unique_ptr&) = delete; // expected-note 3{{'unique_ptr' has been explicitly marked deleted here}} 871fdb354520178c2663f56f466f7abca538b877fDouglas Gregor unique_ptr &operator=(const unique_ptr&) = delete; // expected-note{{candidate function has been explicitly deleted}} 971fdb354520178c2663f56f466f7abca538b877fDouglas Gregorpublic: 1071fdb354520178c2663f56f466f7abca538b877fDouglas Gregor unique_ptr() : ptr(0) { } 1171fdb354520178c2663f56f466f7abca538b877fDouglas Gregor unique_ptr(unique_ptr &&other) : ptr(other.ptr) { other.ptr = 0; } 1271fdb354520178c2663f56f466f7abca538b877fDouglas Gregor explicit unique_ptr(T *ptr) : ptr(ptr) { } 1371fdb354520178c2663f56f466f7abca538b877fDouglas Gregor 1471fdb354520178c2663f56f466f7abca538b877fDouglas Gregor ~unique_ptr() { delete ptr; } 1571fdb354520178c2663f56f466f7abca538b877fDouglas Gregor 1671fdb354520178c2663f56f466f7abca538b877fDouglas Gregor 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}} 1771fdb354520178c2663f56f466f7abca538b877fDouglas Gregor if (this == &other) 1871fdb354520178c2663f56f466f7abca538b877fDouglas Gregor return *this; 1971fdb354520178c2663f56f466f7abca538b877fDouglas Gregor 2071fdb354520178c2663f56f466f7abca538b877fDouglas Gregor delete ptr; 2171fdb354520178c2663f56f466f7abca538b877fDouglas Gregor ptr = other.ptr; 2271fdb354520178c2663f56f466f7abca538b877fDouglas Gregor other.ptr = 0; 2371fdb354520178c2663f56f466f7abca538b877fDouglas Gregor return *this; 2471fdb354520178c2663f56f466f7abca538b877fDouglas Gregor } 2571fdb354520178c2663f56f466f7abca538b877fDouglas Gregor}; 2671fdb354520178c2663f56f466f7abca538b877fDouglas Gregor 2771fdb354520178c2663f56f466f7abca538b877fDouglas Gregortemplate<typename T> 2871fdb354520178c2663f56f466f7abca538b877fDouglas Gregorstruct remove_reference { 2971fdb354520178c2663f56f466f7abca538b877fDouglas Gregor typedef T type; 3071fdb354520178c2663f56f466f7abca538b877fDouglas Gregor}; 3171fdb354520178c2663f56f466f7abca538b877fDouglas Gregor 3271fdb354520178c2663f56f466f7abca538b877fDouglas Gregortemplate<typename T> 3371fdb354520178c2663f56f466f7abca538b877fDouglas Gregorstruct remove_reference<T&> { 3471fdb354520178c2663f56f466f7abca538b877fDouglas Gregor typedef T type; 3571fdb354520178c2663f56f466f7abca538b877fDouglas Gregor}; 3671fdb354520178c2663f56f466f7abca538b877fDouglas Gregor 3771fdb354520178c2663f56f466f7abca538b877fDouglas Gregortemplate<typename T> 3871fdb354520178c2663f56f466f7abca538b877fDouglas Gregorstruct remove_reference<T&&> { 3971fdb354520178c2663f56f466f7abca538b877fDouglas Gregor typedef T type; 4071fdb354520178c2663f56f466f7abca538b877fDouglas Gregor}; 4171fdb354520178c2663f56f466f7abca538b877fDouglas Gregor 4271fdb354520178c2663f56f466f7abca538b877fDouglas Gregor 4371fdb354520178c2663f56f466f7abca538b877fDouglas Gregortemplate <class T> typename remove_reference<T>::type&& move(T&& t) { 4471fdb354520178c2663f56f466f7abca538b877fDouglas Gregor return static_cast<typename remove_reference<T>::type&&>(t); 4571fdb354520178c2663f56f466f7abca538b877fDouglas Gregor} 4671fdb354520178c2663f56f466f7abca538b877fDouglas Gregor 4771fdb354520178c2663f56f466f7abca538b877fDouglas Gregortemplate <class T> T&& forward(typename remove_reference<T>::type& t) { 4871fdb354520178c2663f56f466f7abca538b877fDouglas Gregor return static_cast<T&&>(t); 4971fdb354520178c2663f56f466f7abca538b877fDouglas Gregor} 5071fdb354520178c2663f56f466f7abca538b877fDouglas Gregor 5171fdb354520178c2663f56f466f7abca538b877fDouglas Gregortemplate <class T> T&& forward(typename remove_reference<T>::type&& t) { 5271fdb354520178c2663f56f466f7abca538b877fDouglas Gregor return static_cast<T&&>(t); 5371fdb354520178c2663f56f466f7abca538b877fDouglas Gregor} 5471fdb354520178c2663f56f466f7abca538b877fDouglas Gregor 5571fdb354520178c2663f56f466f7abca538b877fDouglas Gregortemplate<typename T, typename ...Args> 5671fdb354520178c2663f56f466f7abca538b877fDouglas Gregorunique_ptr<T> make_unique_ptr(Args &&...args) { 5771fdb354520178c2663f56f466f7abca538b877fDouglas Gregor return unique_ptr<T>(new T(forward<Args>(args)...)); 5871fdb354520178c2663f56f466f7abca538b877fDouglas Gregor} 5971fdb354520178c2663f56f466f7abca538b877fDouglas Gregor 6071fdb354520178c2663f56f466f7abca538b877fDouglas Gregortemplate<typename T> void accept_unique_ptr(unique_ptr<T>); // expected-note{{passing argument to parameter here}} 6171fdb354520178c2663f56f466f7abca538b877fDouglas Gregor 62cc15f010672a13b38104a32e3cefc7adc07ffbf7Douglas Gregorunique_ptr<int> test_unique_ptr() { 6371fdb354520178c2663f56f466f7abca538b877fDouglas Gregor // Simple construction 6471fdb354520178c2663f56f466f7abca538b877fDouglas Gregor unique_ptr<int> p; 6571fdb354520178c2663f56f466f7abca538b877fDouglas Gregor unique_ptr<int> p1(new int); 6671fdb354520178c2663f56f466f7abca538b877fDouglas Gregor 6771fdb354520178c2663f56f466f7abca538b877fDouglas Gregor // Move construction 6871fdb354520178c2663f56f466f7abca538b877fDouglas Gregor unique_ptr<int> p2(make_unique_ptr<int>(17)); 6971fdb354520178c2663f56f466f7abca538b877fDouglas Gregor unique_ptr<int> p3 = make_unique_ptr<int>(17); 7071fdb354520178c2663f56f466f7abca538b877fDouglas Gregor 7171fdb354520178c2663f56f466f7abca538b877fDouglas Gregor // Copy construction (failures) 7271fdb354520178c2663f56f466f7abca538b877fDouglas Gregor unique_ptr<int> p4(p); // expected-error{{call to deleted constructor of 'unique_ptr<int>'}} 7371fdb354520178c2663f56f466f7abca538b877fDouglas Gregor unique_ptr<int> p5 = p; // expected-error{{call to deleted constructor of 'unique_ptr<int>'}} 7471fdb354520178c2663f56f466f7abca538b877fDouglas Gregor 7571fdb354520178c2663f56f466f7abca538b877fDouglas Gregor // Move assignment 7671fdb354520178c2663f56f466f7abca538b877fDouglas Gregor p2 = move(p); 7771fdb354520178c2663f56f466f7abca538b877fDouglas Gregor p2 = make_unique_ptr<int>(0); 7871fdb354520178c2663f56f466f7abca538b877fDouglas Gregor 7971fdb354520178c2663f56f466f7abca538b877fDouglas Gregor // Copy assignment (failures); 8071fdb354520178c2663f56f466f7abca538b877fDouglas Gregor p2 = p3; // expected-error{{overload resolution selected deleted operator '='}} 8171fdb354520178c2663f56f466f7abca538b877fDouglas Gregor 8271fdb354520178c2663f56f466f7abca538b877fDouglas Gregor // Implicit copies 8371fdb354520178c2663f56f466f7abca538b877fDouglas Gregor accept_unique_ptr(make_unique_ptr<double>(0.0)); 8471fdb354520178c2663f56f466f7abca538b877fDouglas Gregor accept_unique_ptr(move(p2)); 8571fdb354520178c2663f56f466f7abca538b877fDouglas Gregor 8671fdb354520178c2663f56f466f7abca538b877fDouglas Gregor // Implicit copies (failures); 8771fdb354520178c2663f56f466f7abca538b877fDouglas Gregor accept_unique_ptr(p); // expected-error{{call to deleted constructor of 'unique_ptr<int>'}} 88cc15f010672a13b38104a32e3cefc7adc07ffbf7Douglas Gregor 89cc15f010672a13b38104a32e3cefc7adc07ffbf7Douglas Gregor return p; 9071fdb354520178c2663f56f466f7abca538b877fDouglas Gregor} 915232011c942820bba5d033fbd4aa06d4bcbeb6c6Douglas Gregor 925232011c942820bba5d033fbd4aa06d4bcbeb6c6Douglas Gregornamespace perfect_forwarding { 935232011c942820bba5d033fbd4aa06d4bcbeb6c6Douglas Gregor struct A { }; 945232011c942820bba5d033fbd4aa06d4bcbeb6c6Douglas Gregor 955232011c942820bba5d033fbd4aa06d4bcbeb6c6Douglas Gregor struct F0 { 965232011c942820bba5d033fbd4aa06d4bcbeb6c6Douglas Gregor 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}} 975232011c942820bba5d033fbd4aa06d4bcbeb6c6Douglas Gregor }; 985232011c942820bba5d033fbd4aa06d4bcbeb6c6Douglas Gregor 995232011c942820bba5d033fbd4aa06d4bcbeb6c6Douglas Gregor template<typename F, typename ...Args> 1005232011c942820bba5d033fbd4aa06d4bcbeb6c6Douglas Gregor void forward(F f, Args &&...args) { 1015232011c942820bba5d033fbd4aa06d4bcbeb6c6Douglas Gregor f(static_cast<Args&&>(args)...); // expected-error{{no matching function for call to object of type 'perfect_forwarding::F0'}} 1025232011c942820bba5d033fbd4aa06d4bcbeb6c6Douglas Gregor } 1035232011c942820bba5d033fbd4aa06d4bcbeb6c6Douglas Gregor 1045232011c942820bba5d033fbd4aa06d4bcbeb6c6Douglas Gregor template<typename T> T get(); 1055232011c942820bba5d033fbd4aa06d4bcbeb6c6Douglas Gregor 1065232011c942820bba5d033fbd4aa06d4bcbeb6c6Douglas Gregor void test_forward() { 1075232011c942820bba5d033fbd4aa06d4bcbeb6c6Douglas Gregor forward(F0(), get<A&>(), get<A const&>(), get<A>(), get<const A>(), 1085232011c942820bba5d033fbd4aa06d4bcbeb6c6Douglas Gregor get<A&&>(), get<const A&&>()); 1095232011c942820bba5d033fbd4aa06d4bcbeb6c6Douglas Gregor 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}} 1105232011c942820bba5d033fbd4aa06d4bcbeb6c6Douglas Gregor get<const A&&>(), get<const A&&>()); 1115232011c942820bba5d033fbd4aa06d4bcbeb6c6Douglas Gregor } 1125232011c942820bba5d033fbd4aa06d4bcbeb6c6Douglas Gregor}; 113