From 3dde25be7d05ae63569557b2c92cc19f813a82d5 Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Mon, 20 May 2013 18:40:51 +0100 Subject: [PATCH] Clara: support for binary functions --- projects/SelfTest/CmdLineTests.cpp | 45 ++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/projects/SelfTest/CmdLineTests.cpp b/projects/SelfTest/CmdLineTests.cpp index b65d9b19..6624e8cd 100644 --- a/projects/SelfTest/CmdLineTests.cpp +++ b/projects/SelfTest/CmdLineTests.cpp @@ -149,6 +149,24 @@ namespace Clara { void (*function)( C& ); }; + template + struct BoundBinaryFunction : IArgFunction{ + BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {} + virtual void set( C& obj, std::string const& stringValue ) const { + typename RemoveConstRef::type value; + convertInto( stringValue, value ); + function( obj, value ); + } + virtual void setFlag( C& obj ) const { + typename RemoveConstRef::type value; + convertInto( true, value ); + function( obj, value ); + } + virtual bool takesArg() const { return !IsBool::value; } + virtual IArgFunction* clone() const { return new BoundBinaryFunction( *this ); } + void (*function)( C&, T ); + }; + template BoundArgFunction makeBoundField( M C::* _member ) { return BoundArgFunction( new BoundDataMember( _member ) ); @@ -165,6 +183,10 @@ namespace Clara { BoundArgFunction makeBoundField( void (*_function)( C& ) ) { return BoundArgFunction( new BoundUnaryFunction( _function ) ); } + template + BoundArgFunction makeBoundField( void (*_function)( C&, T ) ) { + return BoundArgFunction( new BoundBinaryFunction( _function ) ); + } } // namespace Detail struct Parser { @@ -564,12 +586,15 @@ struct Config { std::vector testsOrTags; // void abortAfterFirst() { abortAfter = 1; } - void abortAfterX( int x ) { abortAfter = x; } - void addWarning( std::string const& _warning ) { warnings.push_back( _warning ); } - void addTestOrTags( std::string const& _testSpec ) { testsOrTags.push_back( _testSpec ); } +// void abortAfterX( int x ) { abortAfter = x; } +// void addWarning( std::string const& _warning ) { warnings.push_back( _warning ); } +// void addTestOrTags( std::string const& _testSpec ) { testsOrTags.push_back( _testSpec ); } }; inline void abortAfterFirst( Config& config ) { config.abortAfter = 1; } +inline void abortAfterX( Config& config, int x ) { config.abortAfter = x; } +inline void addWarning( Config& config, std::string const& _warning ) { config.warnings.push_back( _warning ); } +inline void addTestOrTags( Config& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); } SCENARIO( "New Catch commandline interface", "[cli]" ) { @@ -631,19 +656,19 @@ SCENARIO( "New Catch commandline interface", "[cli]" ) { .shortOpt( "a") .longOpt( "abort" ); - cli.bind( &Config::abortAfterX ) + cli.bind( &abortAfterX ) .describe( "abort after x failures" ) .shortOpt( "x") .longOpt( "abortx" ) .argName( "number of failures" ); - cli.bind( &Config::addWarning ) + cli.bind( &addWarning ) .describe( "enables warnings" ) .shortOpt( "w") .longOpt( "warn" ) .argName( "warning name" ); - cli.bind( &Config::addTestOrTags ) + cli.bind( &addTestOrTags ) .describe( "which test or tests to use" ) .argName( "test name, pattern or tags" ); @@ -676,6 +701,14 @@ SCENARIO( "New Catch commandline interface", "[cli]" ) { REQUIRE( config.abortAfter == 1 ); } + WHEN( "A flag is set via a unary method" ) { + CHECK( config.abortAfter == 0 ); + + const char* argv[] = { "test", "-x", "2" }; + parseInto( cli, argv, config ); + + REQUIRE( config.abortAfter == 2 ); + } } }