2013-08-06 09:03:05 +08:00
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
2011-04-15 06:09:26 +08:00
namespace value_range_detail {
template < typename T >
class value_range_iter {
T t ;
public :
value_range_iter ( const T & t ) : t ( t ) { }
T operator * ( ) const { return t ; }
bool operator ! = ( const value_range_iter & o ) const { return t ! = o . t ; }
value_range_iter & operator + + ( ) { + + t ; return * this ; }
} ;
template < typename T >
struct value_range {
value_range ( const T & a , const T & b ) : begin_ ( a ) , end_ ( b ) { }
value_range_iter < T > begin_ , end_ ;
} ;
template < typename T >
value_range_iter < T > begin ( const value_range < T > & r ) { return r . begin_ ; }
template < typename T >
value_range_iter < T > end ( const value_range < T > & r ) { return r . end_ ; }
struct end_t { } ;
template < typename T >
class value_range_step_iter {
T it , step ;
public :
value_range_step_iter ( const T & it , const T & step ) : it ( it ) , step ( step ) { }
T operator * ( ) const { return it ; }
bool operator ! = ( value_range_step_iter end ) const { return it ! = end . it ; }
value_range_step_iter & operator + + ( ) { it + = step ; return * this ; }
} ;
template < typename T >
class value_range_step {
T it , step , end_ ;
public :
value_range_step ( const T & it , const T & end , const T & step ) :
it ( it ) , end_ ( end ) , step ( step ) { }
typedef value_range_step_iter < T > iterator ;
iterator begin ( ) const { return iterator ( it , step ) ; }
iterator end ( ) const { return iterator ( end_ , step ) ; }
} ;
}
template < typename T >
value_range_detail : : value_range < T > range ( const T & a , const T & b ) { return value_range_detail : : value_range < T > ( a , b ) ; }
template < typename T >
value_range_detail : : value_range_step < T > range ( const T & a , const T & b , const T & step ) { return value_range_detail : : value_range_step < T > ( a , b , step ) ; }
namespace map_range {
template < typename T >
class vector {
T storage [ 100 ] ;
decltype ( sizeof ( char ) ) size ;
public :
vector ( ) : size ( ) { }
void push_back ( T t ) { storage [ size + + ] = t ; }
T * begin ( ) { return storage ; }
T * end ( ) { return storage + size ; }
} ;
template < typename T > struct tuple_elem {
T t ;
tuple_elem ( ) { }
tuple_elem ( T t ) : t ( t ) { }
} ;
template < typename . . . A >
struct tuple : tuple_elem < A > . . . {
tuple ( ) : tuple_elem < A > ( ) . . . { }
tuple ( A . . . a ) : tuple_elem < A > ( a ) . . . { }
template < typename B > B & get ( ) { return tuple_elem < B > : : t ; }
} ;
template < typename F , typename I >
class map_iter {
F f ;
I i ;
public :
map_iter ( F f , I i ) : f ( f ) , i ( i ) { }
auto operator * ( ) const - > decltype ( f ( * i ) ) { return f ( * i ) ; }
bool operator ! = ( const map_iter & o ) const { return i ! = o . i ; }
map_iter & operator + + ( ) { + + i ; return * this ; }
} ;
template < typename T >
struct iter_pair {
T begin_ , end_ ;
iter_pair ( T begin , T end ) : begin_ ( begin ) , end_ ( end ) { }
} ;
template < typename T > T begin ( iter_pair < T > p ) { return p . begin_ ; }
template < typename T > T end ( iter_pair < T > p ) { return p . end_ ; }
template < typename . . . > class mem_fun_impl ;
template < typename R , typename T , typename . . . A >
class mem_fun_impl < R ( T : : * ) ( A . . . ) > {
typedef R ( T : : * F ) ( A . . . ) ;
F f ;
public :
mem_fun_impl ( F f ) : f ( f ) { }
R operator ( ) ( T & t , A & & . . . a ) const { return ( t . * f ) ( static_cast < A & & > ( a ) . . . ) ; }
} ;
template < typename F > mem_fun_impl < F > mem_fun ( F f ) { return mem_fun_impl < F > ( f ) ; }
template < typename F , typename T >
auto map ( const F & f , T & t ) - > iter_pair < map_iter < F , decltype ( t . begin ( ) ) > > {
typedef map_iter < F , decltype ( t . begin ( ) ) > iter ;
return iter_pair < iter > ( iter ( f , t . begin ( ) ) , iter ( f , t . end ( ) ) ) ;
}
}
2012-09-20 00:20:17 +08:00
# define assert(b) if (!(b)) { return 1; }
2011-04-15 06:09:26 +08:00
int main ( ) {
int total = 0 ;
for ( auto n : range ( 1 , 5 ) ) {
total + = n ;
}
2012-09-20 00:20:17 +08:00
assert ( total = = 10 ) ;
2011-04-15 06:09:26 +08:00
for ( auto n : range ( 10 , 100 , 10 ) ) {
total + = n ;
}
2012-09-20 00:20:17 +08:00
assert ( total = = 460 ) ;
2011-04-15 06:09:26 +08:00
map_range : : vector < char > chars ;
chars . push_back ( ' a ' ) ;
chars . push_back ( ' b ' ) ;
chars . push_back ( ' c ' ) ;
for ( char c : chars ) {
+ + total ;
}
2012-09-20 00:20:17 +08:00
assert ( total = = 463 ) ;
2011-04-15 06:09:26 +08:00
typedef map_range : : tuple < int , double > T ;
map_range : : vector < T > pairs ;
pairs . push_back ( T ( 42 , 12.9 ) ) ;
pairs . push_back ( T ( 6 , 4.2 ) ) ;
pairs . push_back ( T ( 9 , 1.1 ) ) ;
for ( auto a : map ( map_range : : mem_fun ( & T : : get < int > ) , pairs ) ) {
total + = a ;
}
2012-09-20 00:20:17 +08:00
assert ( total = = 500 ) ;
2011-04-15 06:09:26 +08:00
}
2012-01-27 09:29:43 +08:00
// PR11793
namespace test2 {
class A {
int xs [ 10 ] ; // expected-note {{implicitly declared private here}}
} ;
void test ( A & a ) {
for ( int x : a . xs ) { } // expected-error {{'xs' is a private member of 'test2::A'}}
}
}
2012-02-01 06:45:40 +08:00
namespace test3 {
// Make sure this doesn't crash
struct A { } ;
struct B { ~ B ( ) ; operator bool ( ) ; } ;
struct C { B operator ! = ( const C & ) ; C & operator + + ( ) ; int operator * ( ) ; } ;
C begin ( const A & ) ;
C end ( const A & ) ;
template < typename T > void f ( ) { for ( auto a : A ( ) ) { } }
void g ( ) { f < int > ( ) ; }
}
2012-02-22 04:01:35 +08:00
namespace test4 {
void f ( ) {
int y ;
// Make sure these don't crash. Better diagnostics would be nice.
for ( : { 1 , 2 , 3 } ) { } // expected-error {{expected expression}} expected-error {{expected ';'}}
2014-06-19 19:42:00 +08:00
for ( 1 : { 1 , 2 , 3 } ) { } // expected-error {{must declare a variable}} expected-warning {{result unused}}
for ( + x : { 1 , 2 , 3 } ) { } // expected-error {{undeclared identifier}} expected-error {{expected ';'}}
for ( + y : { 1 , 2 , 3 } ) { } // expected-error {{must declare a variable}} expected-warning {{result unused}}
2012-02-22 04:01:35 +08:00
}
}
2013-08-21 09:40:36 +08:00
namespace test5 {
// Test error-recovery.
void f ( ) {
for ( auto x : undeclared_identifier ) // expected-error {{undeclared identifier}}
for ( auto y : x - > foo )
y - > bar ( ) ;
for ( auto x : 123 ) // expected-error {{no viable 'begin'}}
x - > foo ( ) ;
}
}
2013-10-12 06:16:04 +08:00
namespace test6 {
void foo ( int arr [ ] ) { // expected-note {{declared here}}
for ( auto i : arr ) { }
// expected-error@-1 {{cannot build range expression with array function parameter 'arr' since parameter with array type 'int []' is treated as pointer type 'int *'}}
}
struct vector {
int * begin ( ) { return 0 ; }
int * end ( ) { return 0 ; }
} ;
void foo ( vector arr [ ] ) { // expected-note {{declared here}}
// Don't suggest to dereference arr.
for ( auto i : arr ) { }
// expected-error@-1 {{cannot build range expression with array function parameter 'arr' since parameter with array type 'test6::vector []' is treated as pointer type 'test6::vector *'}}
}
}
2014-06-19 19:42:00 +08:00
namespace test7 {
void f ( ) {
int arr [ 5 ] , b ;
for ( a : arr ) { } // expected-warning {{extension}}
// FIXME: Give a -Wshadow for this by default?
for ( b : arr ) { } // expected-warning {{extension}}
for ( arr : arr ) { } // expected-warning {{extension}}
for ( c alignas ( 8 ) : arr ) { // expected-warning {{extension}}
static_assert ( alignof ( c ) = = 8 , " " ) ; // expected-warning {{extension}}
}
// FIXME: We should reject this, but don't, because we only check the
// attribute before we deduce the 'auto' type.
for ( d alignas ( 1 ) : arr ) { } // expected-warning {{extension}}
for ( e [[deprecated]] : arr ) { e = 0 ; } // expected-warning {{deprecated}} expected-note {{here}} expected-warning {{extension}}
}
}
2014-07-16 13:16:52 +08:00
namespace pr18587 {
class Arg { } ;
struct Cont {
int * begin ( ) ;
int * end ( ) ;
} ;
void AddAllArgs ( Cont & x ) {
for ( auto Arg : x ) {
}
}
}