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