@ -86,71 +86,73 @@ struct FlipFlop {
int member ;
} ;
// CallMaybeWithArg(f) resolves either to Invoke(f) or I nvoke(f, 42), depending
// CallMaybeWithArg(f) resolves either to invoke(f) or i nvoke(f, 42), depending
// on which one is valid.
template < typename F >
decltype ( Invoke ( std : : declval < const F & > ( ) ) ) CallMaybeWithArg ( const F & f ) {
return Invoke ( f ) ;
decltype ( base_internal : : invoke ( std : : declval < const F & > ( ) ) ) CallMaybeWithArg (
const F & f ) {
return base_internal : : invoke ( f ) ;
}
template < typename F >
decltype ( Invoke ( std : : declval < const F & > ( ) , 42 ) ) CallMaybeWithArg ( const F & f ) {
return Invoke ( f , 42 ) ;
decltype ( base_internal : : invoke ( std : : declval < const F & > ( ) , 42 ) ) CallMaybeWithArg (
const F & f ) {
return base_internal : : invoke ( f , 42 ) ;
}
TEST ( InvokeTest , Function ) {
EXPECT_EQ ( 1 , I nvoke( Function , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , I nvoke( & Function , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : i nvoke( Function , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : i nvoke( & Function , 3 , 2 ) ) ;
}
TEST ( InvokeTest , NonCopyableArgument ) {
EXPECT_EQ ( 42 , I nvoke( Sink , make_unique < int > ( 42 ) ) ) ;
EXPECT_EQ ( 42 , base_internal : : i nvoke( Sink , make_unique < int > ( 42 ) ) ) ;
}
TEST ( InvokeTest , NonCopyableResult ) {
EXPECT_THAT ( I nvoke( Factory , 42 ) , : : testing : : Pointee ( 42 ) ) ;
EXPECT_THAT ( base_internal : : i nvoke( Factory , 42 ) , : : testing : : Pointee ( 42 ) ) ;
}
TEST ( InvokeTest , VoidResult ) {
Invoke ( NoOp ) ;
}
TEST ( InvokeTest , VoidResult ) { base_internal : : invoke ( NoOp ) ; }
TEST ( InvokeTest , ConstFunctor ) {
EXPECT_EQ ( 1 , I nvoke( ConstFunctor ( ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : i nvoke( ConstFunctor ( ) , 3 , 2 ) ) ;
}
TEST ( InvokeTest , MutableFunctor ) {
MutableFunctor f ;
EXPECT_EQ ( 1 , I nvoke( f , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , I nvoke( MutableFunctor ( ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : i nvoke( f , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : i nvoke( MutableFunctor ( ) , 3 , 2 ) ) ;
}
TEST ( InvokeTest , EphemeralFunctor ) {
EphemeralFunctor f ;
EXPECT_EQ ( 1 , I nvoke( std : : move ( f ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , I nvoke( EphemeralFunctor ( ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : i nvoke( std : : move ( f ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : i nvoke( EphemeralFunctor ( ) , 3 , 2 ) ) ;
}
TEST ( InvokeTest , OverloadedFunctor ) {
OverloadedFunctor f ;
const OverloadedFunctor & cf = f ;
EXPECT_EQ ( " & " , Invoke ( f ) ) ;
EXPECT_EQ ( " & 42 " , Invoke ( f , " 42 " ) ) ;
EXPECT_EQ ( " & " , base_internal : : invoke ( f ) ) ;
EXPECT_EQ ( " & 42 " , base_internal : : invoke ( f , " 42 " ) ) ;
EXPECT_EQ ( " const& " , base_internal : : invoke ( cf ) ) ;
EXPECT_EQ ( " const& 42 " , base_internal : : invoke ( cf , " 42 " ) ) ;
EXPECT_EQ ( " const& " , Invoke ( cf ) ) ;
EXPECT_EQ ( " const& 42 " , Invoke ( cf , " 42 " ) ) ;
EXPECT_EQ ( " && " , base_internal : : invoke ( std : : move ( f ) ) ) ;
EXPECT_EQ ( " && " , Invoke ( std : : move ( f ) ) ) ;
EXPECT_EQ ( " && 42 " , I nvoke( std : : move ( f ) , " 42 " ) ) ;
OverloadedFunctor f2 ;
EXPECT_EQ ( " && 42 " , base_internal : : i nvoke( std : : move ( f2 ) , " 42 " ) ) ;
}
TEST ( InvokeTest , ReferenceWrapper ) {
ConstFunctor cf ;
MutableFunctor mf ;
EXPECT_EQ ( 1 , I nvoke( std : : cref ( cf ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , I nvoke( std : : ref ( cf ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , I nvoke( std : : ref ( mf ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : i nvoke( std : : cref ( cf ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : i nvoke( std : : ref ( cf ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : i nvoke( std : : ref ( mf ) , 3 , 2 ) ) ;
}
TEST ( InvokeTest , MemberFunction ) {
@ -158,58 +160,62 @@ TEST(InvokeTest, MemberFunction) {
std : : unique_ptr < const Class > cp ( new Class ) ;
std : : unique_ptr < volatile Class > vp ( new Class ) ;
EXPECT_EQ ( 1 , Invoke ( & Class : : Method , p , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , Invoke ( & Class : : Method , p . get ( ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , Invoke ( & Class : : Method , * p , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , Invoke ( & Class : : RefMethod , p , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , Invoke ( & Class : : RefMethod , p . get ( ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , Invoke ( & Class : : RefMethod , * p , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , Invoke ( & Class : : RefRefMethod , std : : move ( * p ) , 3 , 2 ) ) ; // NOLINT
EXPECT_EQ ( 1 , Invoke ( & Class : : NoExceptMethod , p , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , Invoke ( & Class : : NoExceptMethod , p . get ( ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , Invoke ( & Class : : NoExceptMethod , * p , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , Invoke ( & Class : : ConstMethod , p , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , Invoke ( & Class : : ConstMethod , p . get ( ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , Invoke ( & Class : : ConstMethod , * p , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , Invoke ( & Class : : ConstMethod , cp , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , Invoke ( & Class : : ConstMethod , cp . get ( ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , Invoke ( & Class : : ConstMethod , * cp , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , Invoke ( & Class : : VolatileMethod , p , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , Invoke ( & Class : : VolatileMethod , p . get ( ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , Invoke ( & Class : : VolatileMethod , * p , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , Invoke ( & Class : : VolatileMethod , vp , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , Invoke ( & Class : : VolatileMethod , vp . get ( ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , Invoke ( & Class : : VolatileMethod , * vp , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , Invoke ( & Class : : Method , make_unique < Class > ( ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , Invoke ( & Class : : ConstMethod , make_unique < Class > ( ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , Invoke ( & Class : : ConstMethod , make_unique < const Class > ( ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : invoke ( & Class : : Method , p , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : invoke ( & Class : : Method , p . get ( ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : invoke ( & Class : : Method , * p , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : invoke ( & Class : : RefMethod , p , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : invoke ( & Class : : RefMethod , p . get ( ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : invoke ( & Class : : RefMethod , * p , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : invoke ( & Class : : RefRefMethod , std : : move ( * p ) , 3 ,
2 ) ) ; // NOLINT
EXPECT_EQ ( 1 , base_internal : : invoke ( & Class : : NoExceptMethod , p , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : invoke ( & Class : : NoExceptMethod , p . get ( ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : invoke ( & Class : : NoExceptMethod , * p , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : invoke ( & Class : : ConstMethod , p , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : invoke ( & Class : : ConstMethod , p . get ( ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : invoke ( & Class : : ConstMethod , * p , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : invoke ( & Class : : ConstMethod , cp , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : invoke ( & Class : : ConstMethod , cp . get ( ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : invoke ( & Class : : ConstMethod , * cp , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : invoke ( & Class : : VolatileMethod , p , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : invoke ( & Class : : VolatileMethod , p . get ( ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : invoke ( & Class : : VolatileMethod , * p , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : invoke ( & Class : : VolatileMethod , vp , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : invoke ( & Class : : VolatileMethod , vp . get ( ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : invoke ( & Class : : VolatileMethod , * vp , 3 , 2 ) ) ;
EXPECT_EQ ( 1 ,
base_internal : : invoke ( & Class : : Method , make_unique < Class > ( ) , 3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : invoke ( & Class : : ConstMethod , make_unique < Class > ( ) ,
3 , 2 ) ) ;
EXPECT_EQ ( 1 , base_internal : : invoke ( & Class : : ConstMethod ,
make_unique < const Class > ( ) , 3 , 2 ) ) ;
}
TEST ( InvokeTest , DataMember ) {
std : : unique_ptr < Class > p ( new Class { 42 } ) ;
std : : unique_ptr < const Class > cp ( new Class { 42 } ) ;
EXPECT_EQ ( 42 , I nvoke( & Class : : member , p ) ) ;
EXPECT_EQ ( 42 , I nvoke( & Class : : member , * p ) ) ;
EXPECT_EQ ( 42 , I nvoke( & Class : : member , p . get ( ) ) ) ;
EXPECT_EQ ( 42 , base_internal : : i nvoke( & Class : : member , p ) ) ;
EXPECT_EQ ( 42 , base_internal : : i nvoke( & Class : : member , * p ) ) ;
EXPECT_EQ ( 42 , base_internal : : i nvoke( & Class : : member , p . get ( ) ) ) ;
I nvoke( & Class : : member , p ) = 42 ;
I nvoke( & Class : : member , p . get ( ) ) = 42 ;
base_internal : : i nvoke( & Class : : member , p ) = 42 ;
base_internal : : i nvoke( & Class : : member , p . get ( ) ) = 42 ;
EXPECT_EQ ( 42 , I nvoke( & Class : : member , cp ) ) ;
EXPECT_EQ ( 42 , I nvoke( & Class : : member , * cp ) ) ;
EXPECT_EQ ( 42 , I nvoke( & Class : : member , cp . get ( ) ) ) ;
EXPECT_EQ ( 42 , base_internal : : i nvoke( & Class : : member , cp ) ) ;
EXPECT_EQ ( 42 , base_internal : : i nvoke( & Class : : member , * cp ) ) ;
EXPECT_EQ ( 42 , base_internal : : i nvoke( & Class : : member , cp . get ( ) ) ) ;
}
TEST ( InvokeTest , FlipFlop ) {
FlipFlop obj = { 42 } ;
// This call could resolve to (obj.*&FlipFlop::ConstMethod)() or
// ((*obj).*&FlipFlop::ConstMethod)(). We verify that it's the former.
EXPECT_EQ ( 42 , I nvoke( & FlipFlop : : ConstMethod , obj ) ) ;
EXPECT_EQ ( 42 , I nvoke( & FlipFlop : : member , obj ) ) ;
EXPECT_EQ ( 42 , base_internal : : i nvoke( & FlipFlop : : ConstMethod , obj ) ) ;
EXPECT_EQ ( 42 , base_internal : : i nvoke( & FlipFlop : : member , obj ) ) ;
}
TEST ( InvokeTest , SfinaeFriendly ) {