2010-07-13 16:18:22 +08:00
// RUN: %clang_cc1 -fsyntax-only -verify %s
2009-11-12 07:06:43 +08:00
// Template argument deduction with template template parameters.
template < typename T , template < T > class A >
struct X0 {
static const unsigned value = 0 ;
} ;
template < template < int > class A >
struct X0 < int , A > {
static const unsigned value = 1 ;
} ;
template < int > struct X0i ;
template < long > struct X0l ;
int array_x0a [ X0 < long , X0l > : : value = = 0 ? 1 : - 1 ] ;
int array_x0b [ X0 < int , X0i > : : value = = 1 ? 1 : - 1 ] ;
template < typename T , typename U >
struct is_same {
static const bool value = false ;
} ;
template < typename T >
struct is_same < T , T > {
static const bool value = true ;
} ;
template < typename T > struct allocator { } ;
template < typename T , typename Alloc = allocator < T > > struct vector { } ;
// Fun with meta-lambdas!
struct _1 { } ;
struct _2 { } ;
// Replaces all occurrences of _1 with Arg1 and _2 with Arg2 in T.
template < typename T , typename Arg1 , typename Arg2 >
struct Replace {
typedef T type ;
} ;
// Replacement of the whole type.
template < typename Arg1 , typename Arg2 >
struct Replace < _1 , Arg1 , Arg2 > {
typedef Arg1 type ;
} ;
template < typename Arg1 , typename Arg2 >
struct Replace < _2 , Arg1 , Arg2 > {
typedef Arg2 type ;
} ;
// Replacement through cv-qualifiers
template < typename T , typename Arg1 , typename Arg2 >
struct Replace < const T , Arg1 , Arg2 > {
typedef typename Replace < T , Arg1 , Arg2 > : : type const type ;
} ;
// Replacement of templates
template < template < typename > class TT , typename T1 , typename Arg1 , typename Arg2 >
struct Replace < TT < T1 > , Arg1 , Arg2 > {
typedef TT < typename Replace < T1 , Arg1 , Arg2 > : : type > type ;
} ;
template < template < typename , typename > class TT , typename T1 , typename T2 ,
typename Arg1 , typename Arg2 >
struct Replace < TT < T1 , T2 > , Arg1 , Arg2 > {
typedef TT < typename Replace < T1 , Arg1 , Arg2 > : : type ,
typename Replace < T2 , Arg1 , Arg2 > : : type > type ;
} ;
// Just for kicks...
template < template < typename , typename > class TT , typename T1 ,
typename Arg1 , typename Arg2 >
struct Replace < TT < T1 , _2 > , Arg1 , Arg2 > {
typedef TT < typename Replace < T1 , Arg1 , Arg2 > : : type , Arg2 > type ;
} ;
int array0 [ is_same < Replace < _1 , int , float > : : type , int > : : value ? 1 : - 1 ] ;
int array1 [ is_same < Replace < const _1 , int , float > : : type , const int > : : value ? 1 : - 1 ] ;
int array2 [ is_same < Replace < vector < _1 > , int , float > : : type , vector < int > > : : value ? 1 : - 1 ] ;
int array3 [ is_same < Replace < vector < const _1 > , int , float > : : type , vector < const int > > : : value ? 1 : - 1 ] ;
int array4 [ is_same < Replace < vector < int , _2 > , double , float > : : type , vector < int , float > > : : value ? 1 : - 1 ] ;
2009-12-30 12:10:01 +08:00
// PR5911
template < typename T , int N > void f ( const T ( & a ) [ N ] ) ;
int iarr [ ] = { 1 } ;
void test_PR5911 ( ) { f ( iarr ) ; }
2010-02-08 05:33:28 +08:00
// Must not examine base classes of incomplete type during template argument
// deduction.
namespace PR6257 {
template < typename T > struct X {
template < typename U > X ( const X < U > & u ) ;
} ;
struct A ;
void f ( A & a ) ;
void f ( const X < A > & a ) ;
void test ( A & a ) { ( void ) f ( a ) ; }
}
2010-07-13 16:18:22 +08:00
// PR7463
namespace PR7463 {
2010-07-14 14:36:18 +08:00
const int f ( ) ;
2010-07-13 16:18:22 +08:00
template < typename T_ > void g ( T_ & ) ; // expected-note{{T_ = int}}
void h ( void ) { g ( f ( ) ) ; } // expected-error{{no matching function for call}}
}
2010-08-05 17:05:08 +08:00
namespace test0 {
2011-02-17 14:52:25 +08:00
template < class T > void make ( const T * ( * fn ) ( ) ) ; // expected-note {{candidate template ignored: can't deduce a type for 'T' which would make 'const T' equal 'char'}}
2010-08-05 17:05:08 +08:00
char * char_maker ( ) ;
void test ( ) {
make ( char_maker ) ; // expected-error {{no matching function for call to 'make'}}
}
}
2010-08-19 08:20:19 +08:00
namespace test1 {
template < typename T > void foo ( const T a [ 3 ] [ 3 ] ) ;
void test ( ) {
int a [ 3 ] [ 3 ] ;
foo ( a ) ;
}
}
2010-08-29 06:14:41 +08:00
// PR7708
namespace test2 {
template < typename T > struct Const { typedef void const type ; } ;
template < typename T > void f ( T , typename Const < T > : : type * ) ;
template < typename T > void f ( T , void const * ) ;
void test ( ) {
void * p = 0 ;
f ( 0 , p ) ;
}
}
2010-10-13 03:40:14 +08:00
// rdar://problem/8537391
namespace test3 {
struct Foo {
template < void F ( char ) > static inline void foo ( ) ;
} ;
class Bar {
template < typename T > static inline void wobble ( T ch ) ;
public :
static void madness ( ) {
Foo : : foo < wobble < char > > ( ) ;
}
} ;
}
2011-07-15 15:47:58 +08:00
// Verify that we can deduce enum-typed arguments correctly.
namespace test14 {
enum E { E0 , E1 } ;
template < E > struct A { } ;
template < E e > void foo ( const A < e > & a ) { }
void test ( ) {
A < E0 > a ;
foo ( a ) ;
}
}