Home | History | Annotate | Download | only in SemaCXX
      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