2011-10-14 06:29:44 +08:00
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
2011-01-22 01:06:29 +08:00
template < typename T >
class unique_ptr {
T * ptr ;
2013-12-19 07:30:06 +08:00
unique_ptr ( const unique_ptr & ) = delete ; // expected-note 3{{'unique_ptr' has been explicitly marked deleted here}}
2011-01-22 01:06:29 +08:00
unique_ptr & operator = ( const unique_ptr & ) = delete ; // expected-note{{candidate function has been explicitly deleted}}
public :
unique_ptr ( ) : ptr ( 0 ) { }
unique_ptr ( unique_ptr & & other ) : ptr ( other . ptr ) { other . ptr = 0 ; }
explicit unique_ptr ( T * ptr ) : ptr ( ptr ) { }
~ unique_ptr ( ) { delete ptr ; }
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}}
if ( this = = & other )
return * this ;
delete ptr ;
ptr = other . ptr ;
other . ptr = 0 ;
return * this ;
}
} ;
template < typename T >
struct remove_reference {
typedef T type ;
} ;
template < typename T >
struct remove_reference < T & > {
typedef T type ;
} ;
template < typename T >
struct remove_reference < T & & > {
typedef T type ;
} ;
template < class T > typename remove_reference < T > : : type & & move ( T & & t ) {
return static_cast < typename remove_reference < T > : : type & & > ( t ) ;
}
template < class T > T & & forward ( typename remove_reference < T > : : type & t ) {
return static_cast < T & & > ( t ) ;
}
template < class T > T & & forward ( typename remove_reference < T > : : type & & t ) {
return static_cast < T & & > ( t ) ;
}
template < typename T , typename . . . Args >
unique_ptr < T > make_unique_ptr ( Args & & . . . args ) {
return unique_ptr < T > ( new T ( forward < Args > ( args ) . . . ) ) ;
}
template < typename T > void accept_unique_ptr ( unique_ptr < T > ) ; // expected-note{{passing argument to parameter here}}
2011-01-22 03:38:21 +08:00
unique_ptr < int > test_unique_ptr ( ) {
2011-01-22 01:06:29 +08:00
// Simple construction
unique_ptr < int > p ;
unique_ptr < int > p1 ( new int ) ;
// Move construction
unique_ptr < int > p2 ( make_unique_ptr < int > ( 17 ) ) ;
unique_ptr < int > p3 = make_unique_ptr < int > ( 17 ) ;
// Copy construction (failures)
unique_ptr < int > p4 ( p ) ; // expected-error{{call to deleted constructor of 'unique_ptr<int>'}}
unique_ptr < int > p5 = p ; // expected-error{{call to deleted constructor of 'unique_ptr<int>'}}
// Move assignment
p2 = move ( p ) ;
p2 = make_unique_ptr < int > ( 0 ) ;
// Copy assignment (failures);
p2 = p3 ; // expected-error{{overload resolution selected deleted operator '='}}
// Implicit copies
accept_unique_ptr ( make_unique_ptr < double > ( 0.0 ) ) ;
accept_unique_ptr ( move ( p2 ) ) ;
// Implicit copies (failures);
accept_unique_ptr ( p ) ; // expected-error{{call to deleted constructor of 'unique_ptr<int>'}}
2011-01-22 03:38:21 +08:00
return p ;
2011-01-22 01:06:29 +08:00
}
2011-01-22 06:52:47 +08:00
namespace perfect_forwarding {
struct A { } ;
struct F0 {
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}}
} ;
template < typename F , typename . . . Args >
void forward ( F f , Args & & . . . args ) {
f ( static_cast < Args & & > ( args ) . . . ) ; // expected-error{{no matching function for call to object of type 'perfect_forwarding::F0'}}
}
template < typename T > T get ( ) ;
void test_forward ( ) {
forward ( F0 ( ) , get < A & > ( ) , get < A const & > ( ) , get < A > ( ) , get < const A > ( ) ,
get < A & & > ( ) , get < const A & & > ( ) ) ;
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}}
get < const A & & > ( ) , get < const A & & > ( ) ) ;
}
} ;