11 #ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
12 #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
14 #define TWOBLUECUBES_CATCH_HPP_INCLUDED
17 # pragma clang system_header
18 #elif defined __GNUC__
19 # pragma GCC system_header
26 # pragma warning(push)
27 # pragma warning(disable: 161 1682)
29 # pragma clang diagnostic ignored "-Wglobal-constructors"
30 # pragma clang diagnostic ignored "-Wvariadic-macros"
31 # pragma clang diagnostic ignored "-Wc99-extensions"
32 # pragma clang diagnostic ignored "-Wunused-variable"
33 # pragma clang diagnostic push
34 # pragma clang diagnostic ignored "-Wpadded"
35 # pragma clang diagnostic ignored "-Wc++98-compat"
36 # pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
37 # pragma clang diagnostic ignored "-Wswitch-enum"
38 # pragma clang diagnostic ignored "-Wcovered-switch-default"
40 #elif defined __GNUC__
41 # pragma GCC diagnostic ignored "-Wvariadic-macros"
42 # pragma GCC diagnostic ignored "-Wunused-variable"
43 # pragma GCC diagnostic push
44 # pragma GCC diagnostic ignored "-Wpadded"
46 #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
51 # ifndef CLARA_CONFIG_MAIN
52 # define CLARA_CONFIG_MAIN_NOT_DEFINED
53 # define CLARA_CONFIG_MAIN
58 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED
61 #define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
63 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
64 #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
65 #ifdef CATCH_CONFIG_COUNTER
66 # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
68 # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
71 #define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
72 #define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
85 #define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
115 #if defined(__cplusplus) && __cplusplus >= 201103L
116 # define CATCH_CPP11_OR_GREATER
121 # if __has_feature(cxx_nullptr)
122 # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
125 # if __has_feature(cxx_noexcept)
126 # define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
129 # if defined(CATCH_CPP11_OR_GREATER)
130 # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
143 #ifdef __EDG_VERSION__
157 # if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
158 # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
161 # if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) && defined(CATCH_CPP11_OR_GREATER)
162 # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "GCC diagnostic ignored \"-Wparentheses\"" )
174 #if (_MSC_VER >= 1600)
175 # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
176 # define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
179 #if (_MSC_VER >= 1900 )
180 #define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
181 #define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
189 #if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
190 ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
191 ( defined __GNUC__ && __GNUC__ >= 3 ) || \
192 ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
194 #define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
199 #if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \
200 ( defined __GNUC__ && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 ) || \
201 ( defined __clang__ && __clang_major__ >= 3 )
203 #define CATCH_INTERNAL_CONFIG_COUNTER
211 #if defined(CATCH_CPP11_OR_GREATER)
213 # if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR)
214 # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
217 # ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
218 # define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
221 # ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
222 # define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
225 # ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
226 # define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
229 # ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE
230 # define CATCH_INTERNAL_CONFIG_CPP11_TUPLE
233 # ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
234 # define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
237 # if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG)
238 # define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG
241 # if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE)
242 # define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE
244 # if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
245 # define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
251 #if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11)
252 # define CATCH_CONFIG_CPP11_NULLPTR
254 #if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11)
255 # define CATCH_CONFIG_CPP11_NOEXCEPT
257 #if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11)
258 # define CATCH_CONFIG_CPP11_GENERATED_METHODS
260 #if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11)
261 # define CATCH_CONFIG_CPP11_IS_ENUM
263 #if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11)
264 # define CATCH_CONFIG_CPP11_TUPLE
266 #if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS)
267 # define CATCH_CONFIG_VARIADIC_MACROS
269 #if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11)
270 # define CATCH_CONFIG_CPP11_LONG_LONG
272 #if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11)
273 # define CATCH_CONFIG_CPP11_OVERRIDE
275 #if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11)
276 # define CATCH_CONFIG_CPP11_UNIQUE_PTR
278 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
279 # define CATCH_CONFIG_COUNTER
282 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
283 # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
287 #if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)
288 # define CATCH_NOEXCEPT noexcept
289 # define CATCH_NOEXCEPT_IS(x) noexcept(x)
291 # define CATCH_NOEXCEPT throw()
292 # define CATCH_NOEXCEPT_IS(x)
296 #ifdef CATCH_CONFIG_CPP11_NULLPTR
297 # define CATCH_NULL nullptr
299 # define CATCH_NULL NULL
303 #ifdef CATCH_CONFIG_CPP11_OVERRIDE
304 # define CATCH_OVERRIDE override
306 # define CATCH_OVERRIDE
310 #ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR
311 # define CATCH_AUTO_PTR( T ) std::unique_ptr<T>
313 # define CATCH_AUTO_PTR( T ) std::auto_ptr<T>
326 #ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
352 template<
typename ContainerT>
354 typename ContainerT::const_iterator it = container.begin();
355 typename ContainerT::const_iterator itEnd = container.end();
356 for(; it != itEnd; ++it )
359 template<
typename AssociativeContainerT>
361 typename AssociativeContainerT::const_iterator it = container.begin();
362 typename AssociativeContainerT::const_iterator itEnd = container.end();
363 for(; it != itEnd; ++it )
367 bool startsWith( std::string
const& s, std::string
const& prefix );
368 bool endsWith( std::string
const& s, std::string
const& suffix );
369 bool contains( std::string
const& s, std::string
const& infix );
372 std::string
trim( std::string
const& str );
373 bool replaceInPlace( std::string& str, std::string
const& replaceThis, std::string
const& withThis );
376 pluralise( std::size_t count, std::string
const& label );
389 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
405 inline bool isTrue(
bool value ){
return value; }
420 return std::string();
429 #define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
430 #define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
454 #define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )
457 #define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
460 #define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED
484 #define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
487 #pragma clang diagnostic push
488 #pragma clang diagnostic ignored "-Wpadded"
504 Ptr(
Ptr const& other ) : m_p( other.m_p ){
544 template<
typename T = IShared>
563 #pragma clang diagnostic pop
574 struct IResultCapture;
576 struct IGeneratorsForTest;
606 #define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
609 #define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
633 std::vector<TestCase>
filterTests( std::vector<TestCase>
const& testCases, TestSpec
const& testSpec, IConfig
const&
config );
654 void (C::*m_method)();
660 NameAndDesc(
const char* _name =
"",
const char* _description=
"" )
661 : name( _name ), description( _description )
670 char const* className,
683 (
void (C::*method)(),
684 char const* className,
709 #ifdef CATCH_CONFIG_VARIADIC_MACROS
711 #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
712 static void TestName(); \
713 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
714 static void TestName()
715 #define INTERNAL_CATCH_TESTCASE( ... ) \
716 INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
719 #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
720 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
723 #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
725 struct TestName : ClassName{ \
728 Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
730 void TestName::test()
731 #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
732 INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
735 #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
736 Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) );
740 #define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \
741 static void TestName(); \
742 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
743 static void TestName()
744 #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
745 INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc )
748 #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
749 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
752 #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\
754 struct TestCaseName : ClassName{ \
757 Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
759 void TestCaseName::test()
760 #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
761 INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc )
764 #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \
765 Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) );
769 #define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
772 #define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
775 #define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
788 ExpressionFailed = FailureBit | 1,
789 ExplicitFailure = FailureBit | 2,
796 FatalErrorCondition = 0x200 | FailureBit
811 ContinueOnFailure = 0x02,
827 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
838 std::string
const& _capturedExpression,
861 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
889 #define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
896 template<
typename ExpressionT>
class AllOf;
897 template<
typename ExpressionT>
class AnyOf;
898 template<
typename ExpressionT>
class Not;
901 template<
typename ExpressionT>
908 virtual bool match( ExpressionT
const& expr )
const = 0;
916 template<
typename DerivedT,
typename ExpressionT>
925 template<
typename ExpressionT>
929 Not(
Not const& other ) : m_matcher( other.m_matcher ) {}
932 return !m_matcher->match( expr );
936 return "not " + m_matcher->toString();
942 template<
typename ExpressionT>
947 AllOf(
AllOf const& other ) : m_matchers( other.m_matchers ) {}
950 m_matchers.push_back( matcher.
clone() );
953 virtual bool match( ExpressionT
const& expr )
const
955 for( std::size_t i = 0; i < m_matchers.size(); ++i )
956 if( !m_matchers[i]->match( expr ) )
961 std::ostringstream oss;
963 for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
966 oss << m_matchers[i]->toString();
973 AllOf allOfExpr( *
this );
974 allOfExpr.
add( other );
982 template<
typename ExpressionT>
987 AnyOf(
AnyOf const& other ) : m_matchers( other.m_matchers ) {}
990 m_matchers.push_back( matcher.
clone() );
993 virtual bool match( ExpressionT
const& expr )
const
995 for( std::size_t i = 0; i < m_matchers.size(); ++i )
996 if( m_matchers[i]->match( expr ) )
1001 std::ostringstream oss;
1003 for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
1006 oss << m_matchers[i]->toString();
1013 AnyOf anyOfExpr( *
this );
1014 anyOfExpr.
add( other );
1024 template<
typename ExpressionT>
1027 allOfExpr.
add( *
this );
1028 allOfExpr.
add( other );
1032 template<
typename ExpressionT>
1035 anyOfExpr.
add( *
this );
1036 anyOfExpr.
add( other );
1040 template<
typename ExpressionT>
1045 namespace StdString {
1047 inline std::string
makeString( std::string
const& str ) {
return str; }
1048 inline std::string
makeString(
const char* str ) {
return str ? std::string( str ) : std::string(); }
1053 : m_caseSensitivity( caseSensitivity ),
1054 m_str( adjustString( str ) )
1065 ?
" (case insensitive)"
1074 : m_data( str, caseSensitivity )
1080 virtual bool match( std::string
const& expr )
const {
1081 return m_data.m_str == m_data.adjustString( expr );;
1084 return "equals: \"" + m_data.m_str +
"\"" + m_data.toStringSuffix();
1092 : m_data( substr, caseSensitivity ){}
1097 virtual bool match( std::string
const& expr )
const {
1098 return m_data.adjustString( expr ).find( m_data.m_str ) != std::string::npos;
1101 return "contains: \"" + m_data.m_str +
"\"" + m_data.toStringSuffix();
1109 : m_data( substr, caseSensitivity ){}
1115 virtual bool match( std::string
const& expr )
const {
1116 return startsWith( m_data.adjustString( expr ), m_data.m_str );
1119 return "starts with: \"" + m_data.m_str +
"\"" + m_data.toStringSuffix();
1127 : m_data( substr, caseSensitivity ){}
1132 virtual bool match( std::string
const& expr )
const {
1133 return endsWith( m_data.adjustString( expr ), m_data.m_str );
1136 return "ends with: \"" + m_data.m_str +
"\"" + m_data.toStringSuffix();
1146 template<
typename ExpressionT>
1151 template<
typename ExpressionT>
1156 template<
typename ExpressionT>
1162 template<
typename ExpressionT>
1167 template<
typename ExpressionT>
1201 using namespace Matchers;
1211 struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
1216 oss << other.
oss.str();
1220 oss << other.
oss.str();
1230 char const* capturedExpression,
1232 char const* secondArg =
"" );
1234 template<
typename T>
1238 template<
typename T>
1240 m_stream.oss << value;
1244 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT
const& );
1245 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT
const& );
1286 #define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
1289 #define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
1292 #pragma warning(push)
1293 #pragma warning(disable:4389)
1299 namespace Internal {
1318 template<
typename T>
1322 #ifdef CATCH_CONFIG_CPP11_NULLPTR
1328 template<
typename T1,
typename T2, Operator Op>
1331 template<
typename T1,
typename T2>
1337 template<
typename T1,
typename T2>
1343 template<
typename T1,
typename T2>
1349 template<
typename T1,
typename T2>
1355 template<
typename T1,
typename T2>
1361 template<
typename T1,
typename T2>
1368 template<Operator Op,
typename T1,
typename T2>
1377 template<Operator Op,
typename T1,
typename T2>
1383 template<Operator Op>
bool compare(
unsigned int lhs,
int rhs ) {
1384 return applyEvaluator<Op>( lhs,
static_cast<unsigned int>( rhs ) );
1386 template<Operator Op>
bool compare(
unsigned long lhs,
int rhs ) {
1387 return applyEvaluator<Op>( lhs,
static_cast<unsigned int>( rhs ) );
1389 template<Operator Op>
bool compare(
unsigned char lhs,
int rhs ) {
1390 return applyEvaluator<Op>( lhs,
static_cast<unsigned int>( rhs ) );
1394 template<Operator Op>
bool compare(
unsigned int lhs,
long rhs ) {
1395 return applyEvaluator<Op>( lhs,
static_cast<unsigned long>( rhs ) );
1397 template<Operator Op>
bool compare(
unsigned long lhs,
long rhs ) {
1398 return applyEvaluator<Op>( lhs,
static_cast<unsigned long>( rhs ) );
1400 template<Operator Op>
bool compare(
unsigned char lhs,
long rhs ) {
1401 return applyEvaluator<Op>( lhs,
static_cast<unsigned long>( rhs ) );
1405 template<Operator Op>
bool compare(
int lhs,
unsigned int rhs ) {
1406 return applyEvaluator<Op>(
static_cast<unsigned int>( lhs ), rhs );
1408 template<Operator Op>
bool compare(
int lhs,
unsigned long rhs ) {
1409 return applyEvaluator<Op>(
static_cast<unsigned int>( lhs ), rhs );
1411 template<Operator Op>
bool compare(
int lhs,
unsigned char rhs ) {
1412 return applyEvaluator<Op>(
static_cast<unsigned int>( lhs ), rhs );
1416 template<Operator Op>
bool compare(
long lhs,
unsigned int rhs ) {
1417 return applyEvaluator<Op>(
static_cast<unsigned long>( lhs ), rhs );
1419 template<Operator Op>
bool compare(
long lhs,
unsigned long rhs ) {
1420 return applyEvaluator<Op>(
static_cast<unsigned long>( lhs ), rhs );
1422 template<Operator Op>
bool compare(
long lhs,
unsigned char rhs ) {
1423 return applyEvaluator<Op>(
static_cast<unsigned long>( lhs ), rhs );
1427 template<Operator Op,
typename T>
bool compare(
long lhs,
T* rhs ) {
1430 template<Operator Op,
typename T>
bool compare(
T* lhs,
long rhs ) {
1435 template<Operator Op,
typename T>
bool compare(
int lhs,
T* rhs ) {
1438 template<Operator Op,
typename T>
bool compare(
T* lhs,
int rhs ) {
1442 #ifdef CATCH_CONFIG_CPP11_LONG_LONG
1444 template<Operator Op>
bool compare(
long long lhs,
unsigned int rhs ) {
1445 return applyEvaluator<Op>(
static_cast<unsigned long>( lhs ), rhs );
1447 template<Operator Op>
bool compare(
long long lhs,
unsigned long rhs ) {
1448 return applyEvaluator<Op>(
static_cast<unsigned long>( lhs ), rhs );
1450 template<Operator Op>
bool compare(
long long lhs,
unsigned long long rhs ) {
1451 return applyEvaluator<Op>(
static_cast<unsigned long>( lhs ), rhs );
1453 template<Operator Op>
bool compare(
long long lhs,
unsigned char rhs ) {
1454 return applyEvaluator<Op>(
static_cast<unsigned long>( lhs ), rhs );
1458 template<Operator Op>
bool compare(
unsigned long long lhs,
int rhs ) {
1459 return applyEvaluator<Op>(
static_cast<long>( lhs ), rhs );
1461 template<Operator Op>
bool compare(
unsigned long long lhs,
long rhs ) {
1462 return applyEvaluator<Op>(
static_cast<long>( lhs ), rhs );
1464 template<Operator Op>
bool compare(
unsigned long long lhs,
long long rhs ) {
1465 return applyEvaluator<Op>(
static_cast<long>( lhs ), rhs );
1467 template<Operator Op>
bool compare(
unsigned long long lhs,
char rhs ) {
1468 return applyEvaluator<Op>(
static_cast<long>( lhs ), rhs );
1472 template<Operator Op,
typename T>
bool compare(
long long lhs,
T* rhs ) {
1473 return Evaluator<T*, T*, Op>::evaluate(
reinterpret_cast<T*
>( lhs ), rhs );
1475 template<Operator Op,
typename T>
bool compare(
T* lhs,
long long rhs ) {
1476 return Evaluator<T*, T*, Op>::evaluate( lhs,
reinterpret_cast<T*
>( rhs ) );
1480 #ifdef CATCH_CONFIG_CPP11_NULLPTR
1483 return Evaluator<T*, T*, Op>::evaluate(
nullptr, rhs );
1486 return Evaluator<T*, T*, Op>::evaluate( lhs,
nullptr );
1494 #pragma warning(pop)
1498 #define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED
1508 #define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED
1510 #import <Foundation/Foundation.h>
1512 #ifdef __has_feature
1513 #define CATCH_ARC_ENABLED __has_feature(objc_arc)
1515 #define CATCH_ARC_ENABLED 0
1518 void arcSafeRelease( NSObject* obj );
1519 id performOptionalSelector(
id obj,
SEL sel );
1521 #if !CATCH_ARC_ENABLED
1522 inline void arcSafeRelease( NSObject* obj ) {
1525 inline id performOptionalSelector(
id obj,
SEL sel ) {
1526 if( [obj respondsToSelector: sel] )
1527 return [obj performSelector: sel];
1530 #define CATCH_UNSAFE_UNRETAINED
1531 #define CATCH_ARC_STRONG
1533 inline void arcSafeRelease( NSObject* ){}
1534 inline id performOptionalSelector(
id obj,
SEL sel ) {
1536 #pragma clang diagnostic push
1537 #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
1539 if( [obj respondsToSelector: sel] )
1540 return [obj performSelector: sel];
1542 #pragma clang diagnostic pop
1546 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
1547 #define CATCH_ARC_STRONG __strong
1552 #ifdef CATCH_CONFIG_CPP11_TUPLE
1556 #ifdef CATCH_CONFIG_CPP11_IS_ENUM
1557 #include <type_traits>
1563 template<
typename T>
1584 #ifdef CATCH_CONFIG_CPP11_LONG_LONG
1585 std::string
toString(
long long value );
1586 std::string
toString(
unsigned long long value );
1589 #ifdef CATCH_CONFIG_CPP11_NULLPTR
1594 std::string
toString( NSString
const *
const& nsstring );
1595 std::string
toString( NSString * CATCH_ARC_STRONG
const& nsstring );
1596 std::string
toString( NSObject*
const& nsObject );
1615 template<
typename T>
1617 static std::ostream &
s;
1622 #if defined(CATCH_CONFIG_CPP11_IS_ENUM)
1623 template<
typename T,
1624 bool IsEnum = std::is_enum<T>::value
1626 struct EnumStringMaker
1631 template<
typename T>
1632 struct EnumStringMaker<
T,true>
1634 static std::string convert(
T const& v )
1637 static_cast<typename std::underlying_type<T>::type
>(v)
1644 #if defined(CATCH_CONFIG_CPP11_IS_ENUM)
1645 template<
typename T>
1646 static std::string convert(
T const& v )
1648 return EnumStringMaker<T>::convert( v );
1651 template<
typename T>
1658 template<
typename T>
1660 std::ostringstream oss;
1668 template<
typename T>
1675 template<
typename T>
1679 template<
typename T>
1681 template<
typename U>
1690 template<
typename R,
typename C>
1701 template<
typename InputIterator>
1702 std::string
rangeToString( InputIterator first, InputIterator last );
1712 template<
typename T,
typename Allocator>
1713 std::string
toString( std::vector<T,Allocator>
const& v ) {
1717 #ifdef CATCH_CONFIG_CPP11_TUPLE
1720 namespace TupleDetail {
1724 bool = (N < std::tuple_size<Tuple>::value)
1726 struct ElementPrinter {
1727 static void print(
const Tuple& tuple, std::ostream& os )
1729 os << ( N ?
", " :
" " )
1731 ElementPrinter<Tuple,N+1>::print(tuple,os);
1739 struct ElementPrinter<Tuple,N,false> {
1740 static void print(
const Tuple&, std::ostream& ) {}
1745 template<
typename ...Types>
1746 struct StringMaker<
std::tuple<Types...>> {
1748 static std::string convert(
const std::tuple<Types...>& tuple )
1750 std::ostringstream os;
1752 TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os );
1760 template<
typename T>
1773 template<
typename T>
1779 template<
typename InputIterator>
1781 std::ostringstream oss;
1783 if( first != last ) {
1785 for( ++first ; first != last ; ++first )
1799 template<
typename T>
1802 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
1808 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
1813 template<
typename RhsT>
1815 return captureExpression<Internal::IsEqualTo>( rhs );
1818 template<
typename RhsT>
1820 return captureExpression<Internal::IsNotEqualTo>( rhs );
1823 template<
typename RhsT>
1825 return captureExpression<Internal::IsLessThan>( rhs );
1828 template<
typename RhsT>
1830 return captureExpression<Internal::IsGreaterThan>( rhs );
1833 template<
typename RhsT>
1835 return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
1838 template<
typename RhsT>
1840 return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
1844 return captureExpression<Internal::IsEqualTo>( rhs );
1848 return captureExpression<Internal::IsNotEqualTo>( rhs );
1852 bool value = m_lhs ? true :
false;
1855 .setResultType( value )
1861 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison&
operator + ( RhsT
const& );
1862 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison&
operator - ( RhsT
const& );
1863 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison&
operator / ( RhsT
const& );
1864 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison&
operator * ( RhsT
const& );
1865 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT
const& );
1866 template<
typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT
const& );
1869 template<Internal::Operator Op,
typename RhsT>
1888 template<
typename T>
1890 return ExpressionLhs<T const&>( *
this, operand );
1894 return ExpressionLhs<bool>( *
this, value );
1900 #define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
1931 : m_info( macroName, lineInfo, type )
1934 template<
typename T>
1956 #define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
1963 class AssertionResult;
1964 struct AssertionInfo;
1966 struct SectionEndInfo;
1968 class ScopedMessageBuilder;
1977 Counts& assertions ) = 0;
1993 #define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
1996 #define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
1998 #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
1999 #define CATCH_PLATFORM_MAC
2000 #elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
2001 #define CATCH_PLATFORM_IPHONE
2002 #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
2003 #define CATCH_PLATFORM_WINDOWS
2014 #ifdef CATCH_PLATFORM_MAC
2019 #if defined(__ppc64__) || defined(__ppc__)
2020 #define CATCH_BREAK_INTO_DEBUGGER() \
2021 if( Catch::isDebuggerActive() ) { \
2022 __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
2023 : : : "memory","r0","r3","r4" ); \
2026 #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );}
2030 #elif defined(_MSC_VER)
2031 #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); }
2032 #elif defined(__MINGW32__)
2033 extern "C" __declspec(dllimport)
void __stdcall DebugBreak();
2034 #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); }
2037 #ifndef CATCH_BREAK_INTO_DEBUGGER
2038 #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
2042 #define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
2058 #define INTERNAL_CATCH_REACT( resultBuilder ) \
2059 if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
2060 resultBuilder.react();
2063 #define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \
2065 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
2067 CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
2068 ( __catchResult <= expr ).endExpression(); \
2071 __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \
2073 INTERNAL_CATCH_REACT( __catchResult ) \
2074 } while( Catch::isTrue( false && static_cast<bool>(expr) ) )
2077 #define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
2078 INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
2079 if( Catch::getResultCapture().getLastResult()->succeeded() )
2082 #define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \
2083 INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
2084 if( !Catch::getResultCapture().getLastResult()->succeeded() )
2087 #define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \
2089 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
2092 __catchResult.captureResult( Catch::ResultWas::Ok ); \
2095 __catchResult.useActiveException( resultDisposition ); \
2097 INTERNAL_CATCH_REACT( __catchResult ) \
2098 } while( Catch::alwaysFalse() )
2101 #define INTERNAL_CATCH_THROWS( expr, resultDisposition, matcher, macroName ) \
2103 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition, #matcher ); \
2104 if( __catchResult.allowThrows() ) \
2107 __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
2110 __catchResult.captureExpectedException( matcher ); \
2113 __catchResult.captureResult( Catch::ResultWas::Ok ); \
2114 INTERNAL_CATCH_REACT( __catchResult ) \
2115 } while( Catch::alwaysFalse() )
2118 #define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \
2120 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
2121 if( __catchResult.allowThrows() ) \
2124 __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
2126 catch( exceptionType ) { \
2127 __catchResult.captureResult( Catch::ResultWas::Ok ); \
2130 __catchResult.useActiveException( resultDisposition ); \
2133 __catchResult.captureResult( Catch::ResultWas::Ok ); \
2134 INTERNAL_CATCH_REACT( __catchResult ) \
2135 } while( Catch::alwaysFalse() )
2138 #ifdef CATCH_CONFIG_VARIADIC_MACROS
2139 #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \
2141 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
2142 __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \
2143 __catchResult.captureResult( messageType ); \
2144 INTERNAL_CATCH_REACT( __catchResult ) \
2145 } while( Catch::alwaysFalse() )
2147 #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \
2149 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
2150 __catchResult << log + ::Catch::StreamEndStop(); \
2151 __catchResult.captureResult( messageType ); \
2152 INTERNAL_CATCH_REACT( __catchResult ) \
2153 } while( Catch::alwaysFalse() )
2157 #define INTERNAL_CATCH_INFO( log, macroName ) \
2158 Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
2161 #define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \
2163 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \
2165 std::string matcherAsString = (matcher).toString(); \
2167 .setLhs( Catch::toString( arg ) ) \
2168 .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \
2169 .setOp( "matches" ) \
2170 .setResultType( (matcher).match( arg ) ); \
2171 __catchResult.captureExpression(); \
2173 __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
2175 INTERNAL_CATCH_REACT( __catchResult ) \
2176 } while( Catch::alwaysFalse() )
2179 #define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
2182 #define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
2185 #define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED
2192 Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {}
2209 return passed + failed + failedButOk;
2212 return failed == 0 && failedButOk == 0;
2233 Totals diff = *
this - prevTotals;
2259 std::string
const& _name,
2260 std::string
const& _description = std::string() );
2269 : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
2280 #define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED
2282 #ifdef CATCH_PLATFORM_WINDOWS
2283 typedef unsigned long long uint64_t;
2314 operator bool()
const;
2327 #ifdef CATCH_CONFIG_VARIADIC_MACROS
2328 #define INTERNAL_CATCH_SECTION( ... ) \
2329 if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
2331 #define INTERNAL_CATCH_SECTION( name, desc ) \
2332 if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) )
2336 #define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
2345 template<
typename T>
2349 virtual std::size_t
size ()
const = 0;
2352 template<
typename T>
2358 return m_from+
static_cast<int>( index );
2362 return static_cast<std::size_t
>( 1+m_to-m_from );
2371 template<
typename T>
2377 m_values.push_back( value );
2381 return m_values[index];
2385 return m_values.size();
2392 template<
typename T>
2399 : m_fileInfo( other.m_fileInfo ),
2406 m_fileInfo = fileInfo;
2414 operator T ()
const {
2417 typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
2418 typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
2419 for(
size_t index = 0; it != itEnd; ++it )
2422 if( overallIndex >= index && overallIndex < index + generator->
size() )
2424 return generator->getValue( overallIndex-index );
2444 valuesGen->
add( value );
2452 std::copy( other.
m_composed.begin(), other.
m_composed.end(), std::back_inserter( m_composed ) );
2462 namespace Generators
2464 template<
typename T>
2471 template<
typename T>
2475 valuesGen->
add( val1 );
2476 valuesGen->
add( val2 );
2477 generators.
add( valuesGen );
2481 template<
typename T>
2485 valuesGen->
add( val1 );
2486 valuesGen->
add( val2 );
2487 valuesGen->
add( val3 );
2488 generators.
add( valuesGen );
2492 template<
typename T>
2496 valuesGen->
add( val1 );
2497 valuesGen->
add( val2 );
2498 valuesGen->
add( val3 );
2499 valuesGen->
add( val4 );
2500 generators.
add( valuesGen );
2506 using namespace Generators;
2510 #define INTERNAL_CATCH_LINESTR2( line ) #line
2511 #define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )
2513 #define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" )
2516 #define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
2522 #define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
2529 struct ITestCaseRegistry;
2530 struct IExceptionTranslatorRegistry;
2531 struct IExceptionTranslator;
2532 struct IReporterRegistry;
2533 struct IReporterFactory;
2567 virtual std::string
translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd )
const = 0;
2577 template<
typename T>
2582 : m_translateFunction( translateFunction )
2585 virtual std::string
translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd )
const CATCH_OVERRIDE {
2590 return (*it)->translate( it+1, itEnd );
2593 return m_translateFunction( ex );
2598 std::string(*m_translateFunction)(
T& );
2602 template<
typename T>
2611 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
2612 static std::string translatorName( signature ); \
2613 namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\
2614 static std::string translatorName( signature )
2616 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
2619 #define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
2630 : m_epsilon(
std::numeric_limits<float>::epsilon()*100 ),
2636 : m_epsilon( other.m_epsilon ),
2637 m_scale( other.m_scale ),
2638 m_value( other.m_value )
2648 approx.
scale( m_scale );
2670 m_epsilon = newEpsilon;
2680 std::ostringstream oss;
2700 #define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED
2703 #define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED
2722 #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }
2724 #define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
2729 template<
typename T>
2734 : nullableValue(
new( storage )
T( _value ) )
2737 : nullableValue( _other ?
new( storage )
T( *_other ) :
CATCH_NULL )
2745 if( &_other !=
this ) {
2748 nullableValue =
new( storage )
T( *_other );
2754 nullableValue =
new( storage )
T( _value );
2760 nullableValue->~T();
2770 return nullableValue ? *nullableValue : defaultValue;
2783 char storage[
sizeof(
T)];
2793 virtual std::string
expandAliases( std::string
const& unexpandedTestSpec )
const = 0;
2803 #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED
2809 #pragma clang diagnostic push
2810 #pragma clang diagnostic ignored "-Wpadded"
2821 ShouldFail = 1 << 2,
2827 std::string
const& _className,
2828 std::string
const& _description,
2829 std::set<std::string>
const& _tags,
2837 bool throws()
const;
2873 std::string
const& className,
2874 std::string
const& name,
2875 std::string
const& description,
2880 #pragma clang diagnostic pop
2886 #define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
2888 #import <objc/runtime.h>
2910 class OcMethod :
public SharedImpl<ITestCase> {
2913 OcMethod( Class cls,
SEL sel ) : m_cls( cls ), m_sel( sel ) {}
2915 virtual void invoke()
const {
2916 id obj = [[m_cls alloc] init];
2918 performOptionalSelector( obj,
@selector(setUp) );
2919 performOptionalSelector( obj, m_sel );
2920 performOptionalSelector( obj,
@selector(tearDown) );
2922 arcSafeRelease( obj );
2925 virtual ~OcMethod() {}
2933 inline std::string getAnnotation( Class cls,
2934 std::string
const& annotationName,
2935 std::string
const& testCaseName ) {
2936 NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
2937 SEL sel = NSSelectorFromString( selStr );
2938 arcSafeRelease( selStr );
2939 id value = performOptionalSelector( cls, sel );
2941 return [(NSString*)value UTF8String];
2946 inline size_t registerTestMethods() {
2947 size_t noTestMethods = 0;
2948 int noClasses = objc_getClassList(
CATCH_NULL, 0 );
2950 Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc(
sizeof(Class) * noClasses);
2951 objc_getClassList( classes, noClasses );
2953 for(
int c = 0; c < noClasses; c++ ) {
2954 Class cls = classes[c];
2957 Method* methods = class_copyMethodList( cls, &count );
2958 for( u_int m = 0; m < count ; m++ ) {
2959 SEL selector = method_getName(methods[m]);
2960 std::string methodName = sel_getName(selector);
2961 if(
startsWith( methodName,
"Catch_TestCase_" ) ) {
2962 std::string testCaseName = methodName.substr( 15 );
2963 std::string name = Detail::getAnnotation( cls,
"Name", testCaseName );
2964 std::string desc = Detail::getAnnotation( cls,
"Description", testCaseName );
2965 const char* className = class_getName( cls );
2974 return noTestMethods;
2977 namespace Matchers {
2979 namespace NSStringMatchers {
2981 template<
typename MatcherT>
2982 struct StringHolder : MatcherImpl<MatcherT, NSString*>{
2983 StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
2984 StringHolder( StringHolder
const& other ) : m_substr( [other.m_substr copy] ){}
2986 arcSafeRelease( m_substr );
2993 Equals( NSString* substr ) : StringHolder( substr ){}
2995 virtual bool match( ExpressionType
const& str )
const {
2996 return (str != nil || m_substr == nil ) &&
2997 [str isEqualToString:m_substr];
3000 virtual std::string
toString()
const {
3001 return "equals string: " +
Catch::toString( m_substr );
3006 Contains( NSString* substr ) : StringHolder( substr ){}
3008 virtual bool match( ExpressionType
const& str )
const {
3009 return (str != nil || m_substr == nil ) &&
3010 [str rangeOfString:m_substr].location != NSNotFound;
3013 virtual std::string
toString()
const {
3014 return "contains string: " +
Catch::toString( m_substr );
3019 StartsWith( NSString* substr ) : StringHolder( substr ){}
3021 virtual bool match( ExpressionType
const& str )
const {
3022 return (str != nil || m_substr == nil ) &&
3023 [str rangeOfString:m_substr].location == 0;
3026 virtual std::string
toString()
const {
3027 return "starts with: " +
Catch::toString( m_substr );
3031 EndsWith( NSString* substr ) : StringHolder( substr ){}
3033 virtual bool match( ExpressionType
const& str )
const {
3034 return (str != nil || m_substr == nil ) &&
3035 [str rangeOfString:m_substr].location == [str length] - [m_substr length];
3038 virtual std::string
toString()
const {
3039 return "ends with: " +
Catch::toString( m_substr );
3060 using namespace Matchers;
3065 #define OC_TEST_CASE( name, desc )\
3066 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
3070 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
3074 -(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
3080 #define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED
3086 #pragma clang diagnostic push
3087 #pragma clang diagnostic ignored "-Wweak-vtables"
3091 #define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
3094 #define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
3097 #define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
3100 #define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
3103 #pragma clang diagnostic push
3104 #pragma clang diagnostic ignored "-Wpadded"
3108 #define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
3111 #pragma clang diagnostic push
3112 #pragma clang diagnostic ignored "-Wpadded"
3116 #define TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED
3120 class WildcardPattern {
3121 enum WildcardPosition {
3123 WildcardAtStart = 1,
3125 WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
3131 : m_caseSensitivity( caseSensitivity ),
3132 m_wildcard( NoWildcard ),
3133 m_pattern( adjustCase( pattern ) )
3136 m_pattern = m_pattern.substr( 1 );
3137 m_wildcard = WildcardAtStart;
3140 m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
3141 m_wildcard =
static_cast<WildcardPosition
>( m_wildcard | WildcardAtEnd );
3144 virtual ~WildcardPattern();
3145 virtual bool matches( std::string
const& str )
const {
3146 switch( m_wildcard ) {
3148 return m_pattern == adjustCase( str );
3149 case WildcardAtStart:
3150 return endsWith( adjustCase( str ), m_pattern );
3152 return startsWith( adjustCase( str ), m_pattern );
3153 case WildcardAtBothEnds:
3154 return contains( adjustCase( str ), m_pattern );
3158 #pragma clang diagnostic push
3159 #pragma clang diagnostic ignored "-Wunreachable-code"
3161 throw std::logic_error(
"Unknown enum" );
3163 #pragma clang diagnostic pop
3167 std::string adjustCase( std::string
const& str )
const {
3171 WildcardPosition m_wildcard;
3172 std::string m_pattern;
3182 struct Pattern : SharedImpl<> {
3184 virtual bool matches( TestCaseInfo
const& testCase )
const = 0;
3186 class NamePattern :
public Pattern {
3188 NamePattern( std::string
const& name )
3189 : m_wildcardPattern(
toLower( name ), CaseSensitive::
No )
3191 virtual ~NamePattern();
3192 virtual bool matches( TestCaseInfo
const& testCase )
const {
3193 return m_wildcardPattern.matches(
toLower( testCase.name ) );
3196 WildcardPattern m_wildcardPattern;
3199 class TagPattern :
public Pattern {
3201 TagPattern( std::string
const& tag ) : m_tag(
toLower( tag ) ) {}
3202 virtual ~TagPattern();
3203 virtual bool matches( TestCaseInfo
const& testCase )
const {
3204 return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end();
3210 class ExcludedPattern :
public Pattern {
3212 ExcludedPattern( Ptr<Pattern>
const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
3213 virtual ~ExcludedPattern();
3214 virtual bool matches( TestCaseInfo
const& testCase )
const {
return !m_underlyingPattern->matches( testCase ); }
3216 Ptr<Pattern> m_underlyingPattern;
3220 std::vector<Ptr<Pattern> > m_patterns;
3222 bool matches( TestCaseInfo
const& testCase )
const {
3224 for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it )
3225 if( !(*it)->matches( testCase ) )
3232 bool hasFilters()
const {
3233 return !m_filters.empty();
3235 bool matches( TestCaseInfo
const& testCase )
const {
3237 for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it )
3238 if( it->matches( testCase ) )
3244 std::vector<Filter> m_filters;
3246 friend class TestSpecParser;
3251 #pragma clang diagnostic pop
3256 class TestSpecParser {
3257 enum Mode{
None,
Name, QuotedName, Tag };
3260 std::size_t m_start, m_pos;
3262 TestSpec::Filter m_currentFilter;
3263 TestSpec m_testSpec;
3264 ITagAliasRegistry
const* m_tagAliases;
3267 TestSpecParser( ITagAliasRegistry
const& tagAliases ) : m_tagAliases( &tagAliases ) {}
3269 TestSpecParser& parse( std::string
const& arg ) {
3271 m_exclusion =
false;
3272 m_start = std::string::npos;
3273 m_arg = m_tagAliases->expandAliases( arg );
3274 for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
3275 visitChar( m_arg[m_pos] );
3276 if( m_mode ==
Name )
3277 addPattern<TestSpec::NamePattern>();
3280 TestSpec testSpec() {
3285 void visitChar(
char c ) {
3286 if( m_mode ==
None ) {
3289 case '~': m_exclusion =
true;
return;
3290 case '[':
return startNewMode( Tag, ++m_pos );
3291 case '"':
return startNewMode( QuotedName, ++m_pos );
3292 default: startNewMode(
Name, m_pos );
break;
3295 if( m_mode ==
Name ) {
3297 addPattern<TestSpec::NamePattern>();
3300 else if( c ==
'[' ) {
3301 if( subString() ==
"exclude:" )
3304 addPattern<TestSpec::NamePattern>();
3305 startNewMode( Tag, ++m_pos );
3308 else if( m_mode == QuotedName && c ==
'"' )
3309 addPattern<TestSpec::NamePattern>();
3310 else if( m_mode == Tag && c ==
']' )
3311 addPattern<TestSpec::TagPattern>();
3313 void startNewMode( Mode mode, std::size_t
start ) {
3317 std::string subString()
const {
return m_arg.substr( m_start, m_pos - m_start ); }
3318 template<
typename T>
3320 std::string token = subString();
3323 token = token.substr( 8 );
3325 if( !token.empty() ) {
3326 Ptr<TestSpec::Pattern> pattern =
new T( token );
3328 pattern =
new TestSpec::ExcludedPattern( pattern );
3329 m_currentFilter.m_patterns.push_back( pattern );
3331 m_exclusion =
false;
3335 if( !m_currentFilter.m_patterns.empty() ) {
3336 m_testSpec.m_filters.push_back( m_currentFilter );
3337 m_currentFilter = TestSpec::Filter();
3341 inline TestSpec parseTestSpec( std::string
const& arg ) {
3348 #pragma clang diagnostic pop
3352 #define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
3360 struct Verbosity {
enum Level {
3366 struct WarnAbout {
enum What {
3371 struct ShowDurations {
enum OrNot {
3376 struct RunTests {
enum InWhatOrder {
3378 InLexicographicalOrder,
3381 struct UseColour {
enum YesOrNo {
3389 struct IConfig : IShared {
3393 virtual bool allowThrows()
const = 0;
3394 virtual std::ostream& stream()
const = 0;
3395 virtual std::string name()
const = 0;
3396 virtual bool includeSuccessfulResults()
const = 0;
3397 virtual bool shouldDebugBreak()
const = 0;
3398 virtual bool warnAboutMissingAssertions()
const = 0;
3399 virtual int abortAfter()
const = 0;
3400 virtual bool showInvisibles()
const = 0;
3401 virtual ShowDurations::OrNot showDurations()
const = 0;
3402 virtual TestSpec
const& testSpec()
const = 0;
3403 virtual RunTests::InWhatOrder runOrder()
const = 0;
3404 virtual unsigned int rngSeed()
const = 0;
3405 virtual UseColour::YesOrNo useColour()
const = 0;
3410 #define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
3413 #define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED
3415 #include <streambuf>
3419 class StreamBufBase :
public std::streambuf {
3425 #include <streambuf>
3431 std::ostream& cout();
3432 std::ostream& cerr();
3436 virtual
std::ostream& stream() const = 0;
3439 class FileStream : public IStream {
3440 mutable std::ofstream m_ofs;
3442 FileStream( std::string
const& filename );
3448 class CoutStream : public IStream {
3449 mutable std::ostream m_os;
3458 class DebugOutStream : public IStream {
3459 std::auto_ptr<StreamBufBase> m_streamBuf;
3460 mutable std::ostream m_os;
3476 #ifndef CATCH_CONFIG_CONSOLE_WIDTH
3477 #define CATCH_CONFIG_CONSOLE_WIDTH 80
3485 : listTests( false ),
3487 listReporters( false ),
3488 listTestNamesOnly( false ),
3489 showSuccessfulTests( false ),
3490 shouldDebugBreak( false ),
3493 showInvisibles( false ),
3494 filenamesAsTags( false ),
3497 verbosity( Verbosity::
Normal ),
3498 warnings( WarnAbout::Nothing ),
3499 showDurations( ShowDurations::DefaultForReporter ),
3500 runOrder( RunTests::InDeclarationOrder ),
3501 useColour( UseColour::Auto )
3507 bool listTestNamesOnly;
3509 bool showSuccessfulTests;
3510 bool shouldDebugBreak;
3513 bool showInvisibles;
3514 bool filenamesAsTags;
3519 Verbosity::Level verbosity;
3520 WarnAbout::What warnings;
3521 ShowDurations::OrNot showDurations;
3522 RunTests::InWhatOrder runOrder;
3523 UseColour::YesOrNo useColour;
3525 std::string outputFilename;
3527 std::string processName;
3529 std::vector<std::string> reporterNames;
3530 std::vector<std::string> testsOrTags;
3533 class Config :
public SharedImpl<IConfig> {
3535 Config( Config
const& other );
3536 Config& operator = ( Config
const& other );
3537 virtual void dummy();
3543 Config( ConfigData
const&
data )
3545 m_stream( openStream() )
3547 if( !
data.testsOrTags.empty() ) {
3549 for( std::size_t i = 0; i <
data.testsOrTags.size(); ++i )
3550 parser.parse(
data.testsOrTags[i] );
3551 m_testSpec = parser.testSpec();
3558 std::string
const& getFilename()
const {
3559 return m_data.outputFilename ;
3562 bool listTests()
const {
return m_data.listTests; }
3563 bool listTestNamesOnly()
const {
return m_data.listTestNamesOnly; }
3564 bool listTags()
const {
return m_data.listTags; }
3565 bool listReporters()
const {
return m_data.listReporters; }
3567 std::string getProcessName()
const {
return m_data.processName; }
3569 bool shouldDebugBreak()
const {
return m_data.shouldDebugBreak; }
3571 std::vector<std::string> getReporterNames()
const {
return m_data.reporterNames; }
3573 int abortAfter()
const {
return m_data.abortAfter; }
3575 TestSpec
const& testSpec()
const {
return m_testSpec; }
3577 bool showHelp()
const {
return m_data.showHelp; }
3578 bool showInvisibles()
const {
return m_data.showInvisibles; }
3581 virtual bool allowThrows()
const {
return !m_data.noThrow; }
3582 virtual std::ostream& stream()
const {
return m_stream->stream(); }
3583 virtual std::string name()
const {
return m_data.name.empty() ? m_data.processName : m_data.name; }
3584 virtual bool includeSuccessfulResults()
const {
return m_data.showSuccessfulTests; }
3585 virtual bool warnAboutMissingAssertions()
const {
return m_data.warnings & WarnAbout::NoAssertions; }
3586 virtual ShowDurations::OrNot showDurations()
const {
return m_data.showDurations; }
3587 virtual RunTests::InWhatOrder runOrder()
const {
return m_data.runOrder; }
3588 virtual unsigned int rngSeed()
const {
return m_data.rngSeed; }
3589 virtual UseColour::YesOrNo useColour()
const {
return m_data.useColour; }
3593 IStream
const* openStream() {
3594 if( m_data.outputFilename.empty() )
3595 return new CoutStream();
3596 else if( m_data.outputFilename[0] ==
'%' ) {
3597 if( m_data.outputFilename ==
"%debug" )
3598 return new DebugOutStream();
3600 throw std::domain_error(
"Unrecognised stream: " + m_data.outputFilename );
3603 return new FileStream( m_data.outputFilename );
3607 std::auto_ptr<IStream const> m_stream;
3608 TestSpec m_testSpec;
3614 #define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED
3617 #ifdef CLARA_CONFIG_CONSOLE_WIDTH
3618 #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH
3619 #undef CLARA_CONFIG_CONSOLE_WIDTH
3621 #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
3624 #define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {
3630 #if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
3632 #ifndef STITCH_CLARA_OPEN_NAMESPACE
3633 #define TWOBLUECUBES_CLARA_H_INCLUDED
3634 #define STITCH_CLARA_OPEN_NAMESPACE
3635 #define STITCH_CLARA_CLOSE_NAMESPACE
3637 #define STITCH_CLARA_CLOSE_NAMESPACE }
3640 #define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE
3645 #if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE)
3646 #ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
3647 #define TBC_TEXT_FORMAT_H_INCLUDED
3653 #include <algorithm>
3656 #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
3657 namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
3662 #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
3663 const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
3665 const unsigned int consoleWidth = 80;
3668 struct TextAttributes {
3670 : initialIndent(
std::string::npos ),
3672 width( consoleWidth-1 ),
3676 TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value;
return *
this; }
3677 TextAttributes& setIndent( std::size_t _value ) { indent = _value;
return *
this; }
3678 TextAttributes& setWidth( std::size_t _value ) { width = _value;
return *
this; }
3679 TextAttributes& setTabChar(
char _value ) { tabChar = _value;
return *
this; }
3681 std::size_t initialIndent;
3689 Text( std::string
const& _str, TextAttributes
const& _attr = TextAttributes() )
3692 std::string wrappableChars =
" [({.,/|\\-";
3693 std::size_t indent = _attr.initialIndent != std::string::npos
3694 ? _attr.initialIndent
3696 std::string remainder = _str;
3698 while( !remainder.empty() ) {
3699 if( lines.size() >= 1000 ) {
3700 lines.push_back(
"... message truncated due to excessive size" );
3703 std::size_t tabPos = std::string::npos;
3704 std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
3705 std::size_t pos = remainder.find_first_of(
'\n' );
3706 if( pos <= width ) {
3709 pos = remainder.find_last_of( _attr.tabChar, width );
3710 if( pos != std::string::npos ) {
3712 if( remainder[width] ==
'\n' )
3714 remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
3717 if( width == remainder.size() ) {
3718 spliceLine( indent, remainder, width );
3720 else if( remainder[width] ==
'\n' ) {
3721 spliceLine( indent, remainder, width );
3722 if( width <= 1 || remainder.size() != 1 )
3723 remainder = remainder.substr( 1 );
3724 indent = _attr.indent;
3727 pos = remainder.find_last_of( wrappableChars, width );
3728 if( pos != std::string::npos && pos > 0 ) {
3729 spliceLine( indent, remainder, pos );
3730 if( remainder[0] ==
' ' )
3731 remainder = remainder.substr( 1 );
3734 spliceLine( indent, remainder, width-1 );
3735 lines.back() += "-";
3737 if( lines.size() == 1 )
3738 indent = _attr.indent;
3739 if( tabPos != std::string::npos )
3745 void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
3746 lines.push_back( std::string( _indent,
' ' ) + _remainder.substr( 0, _pos ) );
3747 _remainder = _remainder.substr( _pos );
3750 typedef std::vector<std::string>::const_iterator const_iterator;
3752 const_iterator begin()
const {
return lines.begin(); }
3753 const_iterator end()
const {
return lines.end(); }
3754 std::string
const& last()
const {
return lines.back(); }
3755 std::size_t
size()
const {
return lines.size(); }
3756 std::string
const& operator[]( std::size_t _index )
const {
return lines[_index]; }
3758 std::ostringstream oss;
3763 inline friend std::ostream&
operator << ( std::ostream& _stream,
Text const& _text ) {
3764 for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
3765 it != itEnd; ++it ) {
3766 if( it != _text.begin() )
3775 TextAttributes attr;
3776 std::vector<std::string> lines;
3781 #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
3790 #undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE
3794 #ifndef TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
3795 #define TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
3819 #if __has_feature(cxx_nullptr)
3820 #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
3823 #if __has_feature(cxx_noexcept)
3824 #define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
3833 #if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
3834 #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
3846 #if (_MSC_VER >= 1600)
3847 #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
3848 #define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
3851 #if (_MSC_VER >= 1900 )
3852 #define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
3853 #define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
3862 #if defined(__cplusplus) && __cplusplus >= 201103L
3864 #define CLARA_CPP11_OR_GREATER
3866 #if !defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR)
3867 #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
3870 #ifndef CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
3871 #define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
3874 #ifndef CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
3875 #define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
3878 #if !defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE)
3879 #define CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE
3881 #if !defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
3882 #define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
3888 #if defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NO_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_NO_CPP11)
3889 #define CLARA_CONFIG_CPP11_NULLPTR
3891 #if defined(CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_NO_CPP11)
3892 #define CLARA_CONFIG_CPP11_NOEXCEPT
3894 #if defined(CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_NO_CPP11)
3895 #define CLARA_CONFIG_CPP11_GENERATED_METHODS
3897 #if defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_OVERRIDE) && !defined(CLARA_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_CPP11)
3898 #define CLARA_CONFIG_CPP11_OVERRIDE
3900 #if defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_UNIQUE_PTR) && !defined(CLARA_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_CPP11)
3901 #define CLARA_CONFIG_CPP11_UNIQUE_PTR
3905 #if defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_NOEXCEPT)
3906 #define CLARA_NOEXCEPT noexcept
3907 # define CLARA_NOEXCEPT_IS(x) noexcept(x)
3909 #define CLARA_NOEXCEPT throw()
3910 # define CLARA_NOEXCEPT_IS(x)
3914 #ifdef CLARA_CONFIG_CPP11_NULLPTR
3915 #define CLARA_NULL nullptr
3917 #define CLARA_NULL NULL
3921 #ifdef CLARA_CONFIG_CPP11_OVERRIDE
3922 #define CLARA_OVERRIDE override
3924 #define CLARA_OVERRIDE
3928 #ifdef CLARA_CONFIG_CPP11_UNIQUE_PTR
3929 # define CLARA_AUTO_PTR( T ) std::unique_ptr<T>
3931 # define CLARA_AUTO_PTR( T ) std::auto_ptr<T>
3940 #include <stdexcept>
3943 #if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
3944 #define CLARA_PLATFORM_WINDOWS
3948 #ifdef STITCH_CLARA_OPEN_NAMESPACE
3949 STITCH_CLARA_OPEN_NAMESPACE
3954 struct UnpositionalTag {};
3956 extern UnpositionalTag
_;
3958 #ifdef CLARA_CONFIG_MAIN
3964 #ifdef CLARA_CONSOLE_WIDTH
3965 const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
3967 const unsigned int consoleWidth = 80;
3970 using namespace Tbc;
3972 inline bool startsWith( std::string
const& str, std::string
const& prefix ) {
3973 return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;
3976 template<
typename T>
struct RemoveConstRef{
typedef T type; };
3977 template<
typename T>
struct RemoveConstRef<
T&>{
typedef T type; };
3978 template<
typename T>
struct RemoveConstRef<
T const&>{
typedef T type; };
3979 template<
typename T>
struct RemoveConstRef<
T const>{
typedef T type; };
3981 template<
typename T>
struct IsBool {
static const bool value =
false; };
3982 template<>
struct IsBool<bool> {
static const bool value =
true; };
3984 template<
typename T>
3985 void convertInto( std::string
const& _source,
T& _dest ) {
3986 std::stringstream ss;
3990 throw std::runtime_error(
"Unable to convert " + _source +
" to destination type" );
3992 inline void convertInto( std::string
const& _source, std::string& _dest ) {
3995 inline void convertInto( std::string
const& _source,
bool& _dest ) {
3996 std::string sourceLC = _source;
3997 std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), ::tolower );
3998 if( sourceLC ==
"y" || sourceLC ==
"1" || sourceLC ==
"true" || sourceLC ==
"yes" || sourceLC ==
"on" )
4000 else if( sourceLC ==
"n" || sourceLC ==
"0" || sourceLC ==
"false" || sourceLC ==
"no" || sourceLC ==
"off" )
4003 throw std::runtime_error(
"Expected a boolean value but did not recognise:\n '" + _source +
"'" );
4006 template<
typename ConfigT>
4007 struct IArgFunction {
4008 virtual ~IArgFunction() {}
4009 #ifdef CLARA_CONFIG_CPP11_GENERATED_METHODS
4010 IArgFunction() =
default;
4011 IArgFunction( IArgFunction
const& ) =
default;
4013 virtual void set( ConfigT&
config, std::string
const& value )
const = 0;
4014 virtual bool takesArg()
const = 0;
4015 virtual IArgFunction* clone()
const = 0;
4018 template<
typename ConfigT>
4019 class BoundArgFunction {
4021 BoundArgFunction() : functionObj( CLARA_NULL ) {}
4022 BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
4023 BoundArgFunction( BoundArgFunction
const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CLARA_NULL ) {}
4024 BoundArgFunction& operator = ( BoundArgFunction
const& other ) {
4025 IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : CLARA_NULL;
4027 functionObj = newFunctionObj;
4030 ~BoundArgFunction() {
delete functionObj; }
4032 void set( ConfigT&
config, std::string
const& value )
const {
4033 functionObj->set(
config, value );
4035 bool takesArg()
const {
return functionObj->takesArg(); }
4037 bool isSet()
const {
4038 return functionObj != CLARA_NULL;
4041 IArgFunction<ConfigT>* functionObj;
4044 template<
typename C>
4045 struct NullBinder : IArgFunction<C>{
4046 virtual void set( C&, std::string
const& )
const {}
4047 virtual bool takesArg()
const {
return true; }
4048 virtual IArgFunction<C>* clone()
const {
return new NullBinder( *
this ); }
4051 template<
typename C,
typename M>
4052 struct BoundDataMember : IArgFunction<C>{
4053 BoundDataMember( M C::* _member ) : member( _member ) {}
4054 virtual void set( C& p, std::string
const& stringValue )
const {
4055 convertInto( stringValue, p.*member );
4057 virtual bool takesArg()
const {
return !IsBool<M>::value; }
4058 virtual IArgFunction<C>* clone()
const {
return new BoundDataMember( *
this ); }
4061 template<
typename C,
typename M>
4062 struct BoundUnaryMethod : IArgFunction<C>{
4063 BoundUnaryMethod(
void (C::*_member)( M ) ) : member( _member ) {}
4064 virtual void set( C& p, std::string
const& stringValue )
const {
4065 typename RemoveConstRef<M>::type value;
4066 convertInto( stringValue, value );
4067 (p.*member)( value );
4069 virtual bool takesArg()
const {
return !IsBool<M>::value; }
4070 virtual IArgFunction<C>* clone()
const {
return new BoundUnaryMethod( *
this ); }
4071 void (C::*member)( M );
4073 template<
typename C>
4074 struct BoundNullaryMethod : IArgFunction<C>{
4075 BoundNullaryMethod(
void (C::*_member)() ) : member( _member ) {}
4076 virtual void set( C& p, std::string
const& stringValue )
const {
4078 convertInto( stringValue, value );
4082 virtual bool takesArg()
const {
return false; }
4083 virtual IArgFunction<C>* clone()
const {
return new BoundNullaryMethod( *
this ); }
4084 void (C::*member)();
4087 template<
typename C>
4088 struct BoundUnaryFunction : IArgFunction<C>{
4089 BoundUnaryFunction(
void (*_function)( C& ) ) : function( _function ) {}
4090 virtual void set( C& obj, std::string
const& stringValue )
const {
4092 convertInto( stringValue, value );
4096 virtual bool takesArg()
const {
return false; }
4097 virtual IArgFunction<C>* clone()
const {
return new BoundUnaryFunction( *
this ); }
4098 void (*
function)( C& );
4101 template<
typename C,
typename T>
4102 struct BoundBinaryFunction : IArgFunction<C>{
4103 BoundBinaryFunction(
void (*_function)( C&,
T ) ) : function( _function ) {}
4104 virtual void set( C& obj, std::string
const& stringValue )
const {
4105 typename RemoveConstRef<T>::type value;
4106 convertInto( stringValue, value );
4107 function( obj, value );
4109 virtual bool takesArg()
const {
return !IsBool<T>::value; }
4110 virtual IArgFunction<C>* clone()
const {
return new BoundBinaryFunction( *
this ); }
4111 void (*
function)( C&,
T );
4116 inline std::vector<std::string> argsToVector(
int argc,
char const*
const*
const argv ) {
4117 std::vector<std::string> args(
static_cast<std::size_t
>( argc ) );
4118 for( std::size_t i = 0; i < static_cast<std::size_t>( argc ); ++i )
4125 enum Mode {
None, MaybeShortOpt, SlashOpt, ShortOpt, LongOpt, Positional };
4132 enum Type { Positional, ShortOpt, LongOpt };
4133 Token(
Type _type, std::string
const& _data ) : type( _type ),
data( _data ) {}
4138 Parser() : mode(
None ), from( 0 ), inQuotes( false ){}
4140 void parseIntoTokens( std::vector<std::string>
const& args, std::vector<Token>& tokens ) {
4141 const std::string doubleDash =
"--";
4142 for( std::size_t i = 1; i < args.size() && args[i] != doubleDash; ++i )
4143 parseIntoTokens( args[i], tokens);
4146 void parseIntoTokens( std::string
const& arg, std::vector<Token>& tokens ) {
4147 for( std::size_t i = 0; i <= arg.size(); ++i ) {
4150 inQuotes = !inQuotes;
4151 mode = handleMode( i, c, arg, tokens );
4154 Mode handleMode( std::size_t i,
char c, std::string
const& arg, std::vector<Token>& tokens ) {
4156 case None:
return handleNone( i, c );
4157 case MaybeShortOpt:
return handleMaybeShortOpt( i, c );
4160 case SlashOpt:
return handleOpt( i, c, arg, tokens );
4161 case Positional:
return handlePositional( i, c, arg, tokens );
4162 default:
throw std::logic_error(
"Unknown mode" );
4166 Mode handleNone( std::size_t i,
char c ) {
4172 case '-':
return MaybeShortOpt;
4173 #ifdef CLARA_PLATFORM_WINDOWS
4174 case '/': from = i+1;
return SlashOpt;
4176 default: from = i;
return Positional;
4179 Mode handleMaybeShortOpt( std::size_t i,
char c ) {
4181 case '-': from = i+1;
return LongOpt;
4182 default: from = i;
return ShortOpt;
4185 Mode handleOpt( std::size_t i,
char c, std::string
const& arg, std::vector<Token>& tokens ) {
4186 if( std::string(
" \t:=\0", 5 ).
find( c ) == std::string::npos )
4189 std::string optName = arg.substr( from, i-from );
4190 if( mode == ShortOpt )
4191 for( std::size_t j = 0; j < optName.size(); ++j )
4192 tokens.push_back(
Token(
Token::ShortOpt, optName.substr( j, 1 ) ) );
4193 else if( mode == SlashOpt && optName.size() == 1 )
4194 tokens.push_back(
Token( Token::ShortOpt, optName ) );
4196 tokens.push_back(
Token( Token::LongOpt, optName ) );
4199 Mode handlePositional( std::size_t i,
char c, std::string
const& arg, std::vector<Token>& tokens ) {
4200 if( inQuotes || std::string(
" \t\0", 3 ).
find( c ) == std::string::npos )
4203 std::string
data = arg.substr( from, i-from );
4204 tokens.push_back(
Token( Token::Positional,
data ) );
4209 template<
typename ConfigT>
4210 struct CommonArgProperties {
4211 CommonArgProperties() {}
4212 CommonArgProperties( Detail::BoundArgFunction<ConfigT>
const& _boundField ) : boundField( _boundField ) {}
4214 Detail::BoundArgFunction<ConfigT> boundField;
4215 std::string description;
4217 std::string placeholder;
4219 bool takesArg()
const {
4220 return !placeholder.empty();
4222 void validate()
const {
4223 if( !boundField.isSet() )
4224 throw std::logic_error(
"option not bound" );
4227 struct OptionArgProperties {
4228 std::vector<std::string> shortNames;
4229 std::string longName;
4231 bool hasShortName( std::string
const& shortName )
const {
4232 return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end();
4234 bool hasLongName( std::string
const& _longName )
const {
4235 return _longName == longName;
4238 struct PositionalArgProperties {
4239 PositionalArgProperties() : position( -1 ) {}
4242 bool isFixedPositional()
const {
4243 return position != -1;
4247 template<
typename ConfigT>
4250 struct Arg : CommonArgProperties<ConfigT>, OptionArgProperties, PositionalArgProperties {
4252 Arg( Detail::BoundArgFunction<ConfigT>
const& _boundField ) : CommonArgProperties<ConfigT>( _boundField ) {}
4254 using CommonArgProperties<ConfigT>::placeholder;
4256 std::string dbgName()
const {
4257 if( !longName.empty() )
4258 return "--" + longName;
4259 if( !shortNames.empty() )
4260 return "-" + shortNames[0];
4261 return "positional args";
4263 std::string commands()
const {
4264 std::ostringstream oss;
4266 std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();
4267 for(; it != itEnd; ++it ) {
4274 if( !longName.empty() ) {
4277 oss <<
"--" << longName;
4279 if( !placeholder.empty() )
4280 oss <<
" <" << placeholder <<
">";
4285 typedef CLARA_AUTO_PTR( Arg ) ArgAutoPtr;
4287 friend void addOptName( Arg& arg, std::string
const& optName )
4289 if( optName.empty() )
4292 if( !arg.longName.empty() )
4293 throw std::logic_error(
"Only one long opt may be specified. '"
4295 +
"' already specified, now attempting to add '"
4297 arg.longName = optName.substr( 2 );
4300 arg.shortNames.push_back( optName.substr( 1 ) );
4302 throw std::logic_error(
"option must begin with - or --. Option was: '" + optName +
"'" );
4304 friend void setPositionalArg( Arg& arg,
int position )
4306 arg.position = position;
4311 ArgBuilder( Arg* arg ) : m_arg( arg ) {}
4314 template<
typename C,
typename M>
4315 void bind( M C::* field, std::string
const& placeholder ) {
4316 m_arg->boundField =
new Detail::BoundDataMember<C,M>( field );
4317 m_arg->placeholder = placeholder;
4320 template<
typename C>
4321 void bind(
bool C::* field ) {
4322 m_arg->boundField =
new Detail::BoundDataMember<C,bool>( field );
4326 template<
typename C,
typename M>
4327 void bind(
void (C::* unaryMethod)( M ), std::string
const& placeholder ) {
4328 m_arg->boundField =
new Detail::BoundUnaryMethod<C,M>( unaryMethod );
4329 m_arg->placeholder = placeholder;
4333 template<
typename C>
4334 void bind(
void (C::* unaryMethod)(
bool ) ) {
4335 m_arg->boundField =
new Detail::BoundUnaryMethod<C,bool>( unaryMethod );
4339 template<
typename C>
4340 void bind(
void (C::* nullaryMethod)() ) {
4341 m_arg->boundField =
new Detail::BoundNullaryMethod<C>( nullaryMethod );
4345 template<
typename C>
4346 void bind(
void (* unaryFunction)( C& ) ) {
4347 m_arg->boundField =
new Detail::BoundUnaryFunction<C>( unaryFunction );
4351 template<
typename C,
typename T>
4352 void bind(
void (* binaryFunction)( C&,
T ), std::string
const& placeholder ) {
4353 m_arg->boundField =
new Detail::BoundBinaryFunction<C, T>( binaryFunction );
4354 m_arg->placeholder = placeholder;
4357 ArgBuilder& describe( std::string
const& description ) {
4358 m_arg->description = description;
4361 ArgBuilder& detail( std::string
const& detail ) {
4362 m_arg->detail = detail;
4370 class OptBuilder :
public ArgBuilder {
4372 OptBuilder( Arg* arg ) : ArgBuilder( arg ) {}
4373 OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {}
4375 OptBuilder& operator[]( std::string
const& optName ) {
4376 addOptName( *ArgBuilder::m_arg, optName );
4384 : m_boundProcessName(
new Detail::NullBinder<ConfigT>() ),
4385 m_highestSpecifiedArgPosition( 0 ),
4386 m_throwOnUnrecognisedTokens( false )
4388 CommandLine( CommandLine
const& other )
4389 : m_boundProcessName( other.m_boundProcessName ),
4390 m_options ( other.m_options ),
4391 m_positionalArgs( other.m_positionalArgs ),
4392 m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ),
4393 m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens )
4395 if( other.m_floatingArg.get() )
4396 m_floatingArg.reset(
new Arg( *other.m_floatingArg ) );
4399 CommandLine& setThrowOnUnrecognisedTokens(
bool shouldThrow =
true ) {
4400 m_throwOnUnrecognisedTokens = shouldThrow;
4404 OptBuilder operator[]( std::string
const& optName ) {
4405 m_options.push_back( Arg() );
4406 addOptName( m_options.back(), optName );
4407 OptBuilder builder( &m_options.back() );
4411 ArgBuilder operator[](
int position ) {
4412 m_positionalArgs.insert( std::make_pair( position, Arg() ) );
4413 if( position > m_highestSpecifiedArgPosition )
4414 m_highestSpecifiedArgPosition = position;
4415 setPositionalArg( m_positionalArgs[position], position );
4416 ArgBuilder builder( &m_positionalArgs[position] );
4421 ArgBuilder operator[]( UnpositionalTag ) {
4422 if( m_floatingArg.get() )
4423 throw std::logic_error(
"Only one unpositional argument can be added" );
4424 m_floatingArg.reset(
new Arg() );
4425 ArgBuilder builder( m_floatingArg.get() );
4429 template<
typename C,
typename M>
4430 void bindProcessName( M C::* field ) {
4431 m_boundProcessName =
new Detail::BoundDataMember<C,M>( field );
4433 template<
typename C,
typename M>
4434 void bindProcessName(
void (C::*_unaryMethod)( M ) ) {
4435 m_boundProcessName =
new Detail::BoundUnaryMethod<C,M>( _unaryMethod );
4438 void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth )
const {
4439 typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;
4440 std::size_t maxWidth = 0;
4441 for( it = itBegin; it != itEnd; ++it )
4442 maxWidth = (
std::max)( maxWidth, it->commands().size() );
4444 for( it = itBegin; it != itEnd; ++it ) {
4445 Detail::Text usage( it->commands(), Detail::TextAttributes()
4446 .setWidth( maxWidth+indent )
4447 .setIndent( indent ) );
4448 Detail::Text desc( it->description, Detail::TextAttributes()
4449 .setWidth( width - maxWidth - 3 ) );
4451 for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) {
4452 std::string usageCol = i < usage.size() ? usage[i] :
"";
4455 if( i < desc.size() && !desc[i].empty() )
4456 os << std::string( indent + 2 + maxWidth - usageCol.size(),
' ' )
4462 std::string optUsage()
const {
4463 std::ostringstream oss;
4468 void argSynopsis( std::ostream& os )
const {
4469 for(
int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {
4472 typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
4473 if( it != m_positionalArgs.end() )
4474 os <<
"<" << it->second.placeholder <<
">";
4475 else if( m_floatingArg.get() )
4476 os <<
"<" << m_floatingArg->placeholder <<
">";
4478 throw std::logic_error(
"non consecutive positional arguments with no floating args" );
4481 if( m_floatingArg.get() ) {
4482 if( m_highestSpecifiedArgPosition > 1 )
4484 os <<
"[<" << m_floatingArg->placeholder <<
"> ...]";
4487 std::string argSynopsis()
const {
4488 std::ostringstream oss;
4493 void usage( std::ostream& os, std::string
const& procName )
const {
4495 os <<
"usage:\n " << procName <<
" ";
4497 if( !m_options.empty() ) {
4498 os <<
" [options]\n\nwhere options are: \n";
4503 std::string usage( std::string
const& procName )
const {
4504 std::ostringstream oss;
4505 usage( oss, procName );
4509 ConfigT parse( std::vector<std::string>
const& args )
const {
4511 parseInto( args,
config );
4515 std::vector<Parser::Token> parseInto( std::vector<std::string>
const& args, ConfigT&
config )
const {
4516 std::string processName = args[0];
4517 std::size_t lastSlash = processName.find_last_of(
"/\\" );
4518 if( lastSlash != std::string::npos )
4519 processName = processName.substr( lastSlash+1 );
4520 m_boundProcessName.set(
config, processName );
4521 std::vector<Parser::Token> tokens;
4523 parser.parseIntoTokens( args, tokens );
4524 return populate( tokens,
config );
4527 std::vector<Parser::Token> populate( std::vector<Parser::Token>
const& tokens, ConfigT&
config )
const {
4529 std::vector<Parser::Token> unusedTokens = populateOptions( tokens,
config );
4530 unusedTokens = populateFixedArgs( unusedTokens,
config );
4531 unusedTokens = populateFloatingArgs( unusedTokens,
config );
4532 return unusedTokens;
4535 std::vector<Parser::Token> populateOptions( std::vector<Parser::Token>
const& tokens, ConfigT&
config )
const {
4536 std::vector<Parser::Token> unusedTokens;
4537 std::vector<std::string> errors;
4538 for( std::size_t i = 0; i < tokens.size(); ++i ) {
4539 Parser::Token
const& token = tokens[i];
4540 typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();
4541 for(; it != itEnd; ++it ) {
4542 Arg const& arg = *it;
4545 if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||
4546 ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {
4547 if( arg.takesArg() ) {
4548 if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional )
4549 errors.push_back(
"Expected argument to option: " + token.data );
4551 arg.boundField.set( config, tokens[++i].data );
4554 arg.boundField.set( config,
"true" );
4559 catch( std::exception& ex ) {
4560 errors.push_back( std::string( ex.what() ) +
"\n- while parsing: (" + arg.commands() +
")" );
4564 if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens )
4565 unusedTokens.push_back( token );
4566 else if( errors.empty() && m_throwOnUnrecognisedTokens )
4567 errors.push_back(
"unrecognised option: " + token.data );
4570 if( !errors.empty() ) {
4571 std::ostringstream oss;
4572 for( std::vector<std::string>::const_iterator it = errors.begin(), itEnd = errors.end();
4575 if( it != errors.begin() )
4579 throw std::runtime_error( oss.str() );
4581 return unusedTokens;
4583 std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token>
const& tokens, ConfigT&
config )
const {
4584 std::vector<Parser::Token> unusedTokens;
4586 for( std::size_t i = 0; i < tokens.size(); ++i ) {
4587 Parser::Token
const& token = tokens[i];
4588 typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );
4589 if( it != m_positionalArgs.end() )
4590 it->second.boundField.set(
config, token.data );
4592 unusedTokens.push_back( token );
4593 if( token.type == Parser::Token::Positional )
4596 return unusedTokens;
4598 std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token>
const& tokens, ConfigT&
config )
const {
4599 if( !m_floatingArg.get() )
4601 std::vector<Parser::Token> unusedTokens;
4602 for( std::size_t i = 0; i < tokens.size(); ++i ) {
4603 Parser::Token
const& token = tokens[i];
4604 if( token.type == Parser::Token::Positional )
4605 m_floatingArg->boundField.set(
config, token.data );
4607 unusedTokens.push_back( token );
4609 return unusedTokens;
4612 void validate()
const
4614 if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() )
4615 throw std::logic_error(
"No options or arguments specified" );
4617 for(
typename std::vector<Arg>::const_iterator it = m_options.begin(),
4618 itEnd = m_options.end();
4624 Detail::BoundArgFunction<ConfigT> m_boundProcessName;
4625 std::vector<Arg> m_options;
4626 std::map<int, Arg> m_positionalArgs;
4627 ArgAutoPtr m_floatingArg;
4628 int m_highestSpecifiedArgPosition;
4629 bool m_throwOnUnrecognisedTokens;
4634 STITCH_CLARA_CLOSE_NAMESPACE
4635 #undef STITCH_CLARA_OPEN_NAMESPACE
4636 #undef STITCH_CLARA_CLOSE_NAMESPACE
4639 #undef STITCH_CLARA_OPEN_NAMESPACE
4642 #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
4643 #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
4644 #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
4651 inline void abortAfterFirst( ConfigData&
config ) {
config.abortAfter = 1; }
4652 inline void abortAfterX( ConfigData&
config,
int x ) {
4654 throw std::runtime_error(
"Value after -x or --abortAfter must be greater than zero" );
4657 inline void addTestOrTags( ConfigData&
config, std::string
const& _testSpec ) {
config.testsOrTags.push_back( _testSpec ); }
4658 inline void addReporterName( ConfigData&
config, std::string
const& _reporterName ) {
config.reporterNames.push_back( _reporterName ); }
4660 inline void addWarning( ConfigData&
config, std::string
const& _warning ) {
4661 if( _warning ==
"NoAssertions" )
4662 config.warnings =
static_cast<WarnAbout::What
>(
config.warnings | WarnAbout::NoAssertions );
4664 throw std::runtime_error(
"Unrecognised warning: '" + _warning +
"'" );
4666 inline void setOrder( ConfigData&
config, std::string
const& order ) {
4668 config.runOrder = RunTests::InDeclarationOrder;
4670 config.runOrder = RunTests::InLexicographicalOrder;
4672 config.runOrder = RunTests::InRandomOrder;
4674 throw std::runtime_error(
"Unrecognised ordering: '" + order +
"'" );
4676 inline void setRngSeed( ConfigData&
config, std::string
const& seed ) {
4677 if( seed ==
"time" ) {
4678 config.rngSeed =
static_cast<unsigned int>( std::time(0) );
4681 std::stringstream ss;
4685 throw std::runtime_error(
"Argment to --rng-seed should be the word 'time' or a number" );
4688 inline void setVerbosity( ConfigData&
config,
int level ) {
4690 config.verbosity =
static_cast<Verbosity::Level
>( level );
4692 inline void setShowDurations( ConfigData&
config,
bool _showDurations ) {
4693 config.showDurations = _showDurations
4694 ? ShowDurations::Always
4695 : ShowDurations::Never;
4697 inline void setUseColour( ConfigData&
config, std::string
const& value ) {
4698 std::string mode =
toLower( value );
4701 config.useColour = UseColour::Yes;
4702 else if( mode ==
"no" )
4704 else if( mode ==
"auto" )
4705 config.useColour = UseColour::Auto;
4707 throw std::runtime_error(
"colour mode must be one of: auto, yes or no" );
4709 inline void forceColour( ConfigData&
config ) {
4710 config.useColour = UseColour::Yes;
4712 inline void loadTestNamesFromFile( ConfigData&
config, std::string
const& _filename ) {
4713 std::ifstream f( _filename.c_str() );
4715 throw std::domain_error(
"Unable to load input file: " + _filename );
4718 while( std::getline( f, line ) ) {
4720 if( !line.empty() && !
startsWith( line,
"#" ) )
4721 addTestOrTags(
config,
"\"" + line +
"\"," );
4725 inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
4727 using namespace Clara;
4728 CommandLine<ConfigData> cli;
4730 cli.bindProcessName( &ConfigData::processName );
4732 cli["-?"]["-h"]["--help"]
4733 .describe(
"display usage information" )
4734 .bind( &ConfigData::showHelp );
4736 cli["-l"]["--list-tests"]
4737 .describe(
"list all/matching test cases" )
4738 .bind( &ConfigData::listTests );
4740 cli["-t"]["--list-tags"]
4741 .describe(
"list all/matching tags" )
4742 .bind( &ConfigData::listTags );
4744 cli["-s"]["--success"]
4745 .describe(
"include successful tests in output" )
4746 .bind( &ConfigData::showSuccessfulTests );
4748 cli["-b"]["--break"]
4749 .describe(
"break into debugger on failure" )
4750 .bind( &ConfigData::shouldDebugBreak );
4752 cli["-e"]["--nothrow"]
4753 .describe(
"skip exception tests" )
4754 .bind( &ConfigData::noThrow );
4756 cli["-i"]["--invisibles"]
4757 .describe(
"show invisibles (tabs, newlines)" )
4758 .bind( &ConfigData::showInvisibles );
4761 .describe(
"output filename" )
4762 .bind( &ConfigData::outputFilename,
"filename" );
4764 cli["-r"]["--reporter"]
4766 .describe(
"reporter to use (defaults to console)" )
4767 .bind( &addReporterName,
"name" );
4770 .describe(
"suite name" )
4771 .bind( &ConfigData::name,
"name" );
4773 cli["-a"]["--abort"]
4774 .describe(
"abort at first failure" )
4775 .bind( &abortAfterFirst );
4777 cli["-x"]["--abortx"]
4778 .describe(
"abort after x failures" )
4779 .bind( &abortAfterX,
"no. failures" );
4782 .describe(
"enable warnings" )
4783 .bind( &addWarning,
"warning name" );
4793 .describe(
"which test or tests to use" )
4794 .bind( &addTestOrTags,
"test name, pattern or tags" );
4796 cli["-d"]["--durations"]
4797 .describe(
"show test durations" )
4798 .bind( &setShowDurations,
"yes|no" );
4800 cli["-f"]["--input-file"]
4801 .describe(
"load test names to run from a file" )
4802 .bind( &loadTestNamesFromFile,
"filename" );
4804 cli["-#"]["--filenames-as-tags"]
4805 .describe(
"adds a tag for the filename" )
4806 .bind( &ConfigData::filenamesAsTags );
4809 cli["--list-test-names-only"]
4810 .describe(
"list all/matching test cases names only" )
4811 .bind( &ConfigData::listTestNamesOnly );
4813 cli["--list-reporters"]
4814 .describe(
"list all reporters" )
4815 .bind( &ConfigData::listReporters );
4818 .describe(
"test case order (defaults to decl)" )
4819 .bind( &setOrder,
"decl|lex|rand" );
4822 .describe(
"set a specific seed for random numbers" )
4823 .bind( &setRngSeed,
"'time'|number" );
4825 cli["--force-colour"]
4826 .describe(
"force colourised output (deprecated)" )
4827 .bind( &forceColour );
4830 .describe(
"should output be colourised" )
4831 .bind( &setUseColour,
"yes|no" );
4839 #define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED
4842 #define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED
4844 #define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
4846 #define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch
4849 #ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
4850 # ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
4851 # ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
4852 # define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
4855 # define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
4858 #ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
4864 #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
4865 namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
4870 #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
4871 const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
4873 const unsigned int consoleWidth = 80;
4876 struct TextAttributes {
4878 : initialIndent(
std::string::npos ),
4880 width( consoleWidth-1 ),
4884 TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value;
return *
this; }
4885 TextAttributes& setIndent( std::size_t _value ) { indent = _value;
return *
this; }
4886 TextAttributes& setWidth( std::size_t _value ) { width = _value;
return *
this; }
4887 TextAttributes& setTabChar(
char _value ) { tabChar = _value;
return *
this; }
4889 std::size_t initialIndent;
4897 Text( std::string
const& _str, TextAttributes
const& _attr = TextAttributes() )
4900 std::string wrappableChars =
" [({.,/|\\-";
4901 std::size_t indent = _attr.initialIndent != std::string::npos
4902 ? _attr.initialIndent
4904 std::string remainder = _str;
4906 while( !remainder.empty() ) {
4907 if( lines.size() >= 1000 ) {
4908 lines.push_back(
"... message truncated due to excessive size" );
4911 std::size_t tabPos = std::string::npos;
4912 std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
4913 std::size_t pos = remainder.find_first_of(
'\n' );
4914 if( pos <= width ) {
4917 pos = remainder.find_last_of( _attr.tabChar, width );
4918 if( pos != std::string::npos ) {
4920 if( remainder[width] ==
'\n' )
4922 remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
4925 if( width == remainder.size() ) {
4926 spliceLine( indent, remainder, width );
4928 else if( remainder[width] ==
'\n' ) {
4929 spliceLine( indent, remainder, width );
4930 if( width <= 1 || remainder.size() != 1 )
4931 remainder = remainder.substr( 1 );
4932 indent = _attr.indent;
4935 pos = remainder.find_last_of( wrappableChars, width );
4936 if( pos != std::string::npos && pos > 0 ) {
4937 spliceLine( indent, remainder, pos );
4938 if( remainder[0] ==
' ' )
4939 remainder = remainder.substr( 1 );
4942 spliceLine( indent, remainder, width-1 );
4943 lines.back() += "-";
4945 if( lines.size() == 1 )
4946 indent = _attr.indent;
4947 if( tabPos != std::string::npos )
4953 void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
4954 lines.push_back( std::string( _indent,
' ' ) + _remainder.substr( 0, _pos ) );
4955 _remainder = _remainder.substr( _pos );
4958 typedef std::vector<std::string>::const_iterator const_iterator;
4960 const_iterator begin()
const {
return lines.begin(); }
4961 const_iterator end()
const {
return lines.end(); }
4962 std::string
const& last()
const {
return lines.back(); }
4963 std::size_t
size()
const {
return lines.size(); }
4964 std::string
const& operator[]( std::size_t _index )
const {
return lines[_index]; }
4966 std::ostringstream oss;
4971 inline friend std::ostream&
operator << ( std::ostream& _stream,
Text const& _text ) {
4972 for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
4973 it != itEnd; ++it ) {
4974 if( it != _text.begin() )
4983 TextAttributes attr;
4984 std::vector<std::string> lines;
4989 #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
4994 #undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
4998 using Tbc::TextAttributes;
5002 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED
5030 ResultExpectedFailure = Warning,
5035 OriginalExpression =
Cyan,
5036 ReconstructedExpression =
Yellow,
5043 Colour( Code _colourCode );
5044 Colour( Colour
const& other );
5048 static void use( Code _colourCode );
5054 inline std::ostream&
operator << ( std::ostream& os, Colour
const& ) {
return os; }
5059 #define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
5068 struct ReporterConfig {
5069 explicit ReporterConfig( Ptr<IConfig const>
const& _fullConfig )
5070 : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
5072 ReporterConfig( Ptr<IConfig const>
const& _fullConfig, std::ostream& _stream )
5073 : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
5075 std::ostream& stream()
const {
return *m_stream; }
5076 Ptr<IConfig const> fullConfig()
const {
return m_fullConfig; }
5079 std::ostream* m_stream;
5080 Ptr<IConfig const> m_fullConfig;
5083 struct ReporterPreferences {
5084 ReporterPreferences()
5085 : shouldRedirectStdOut( false )
5088 bool shouldRedirectStdOut;
5091 template<
typename T>
5092 struct LazyStat : Option<
T> {
5093 LazyStat() : used( false ) {}
5094 LazyStat& operator=(
T const& _value ) {
5106 struct TestRunInfo {
5107 TestRunInfo( std::string
const& _name ) : name( _name ) {}
5112 std::size_t _groupIndex,
5113 std::size_t _groupsCount )
5115 groupIndex( _groupIndex ),
5116 groupsCounts( _groupsCount )
5120 std::size_t groupIndex;
5121 std::size_t groupsCounts;
5124 struct AssertionStats {
5125 AssertionStats( AssertionResult
const& _assertionResult,
5126 std::vector<MessageInfo>
const& _infoMessages,
5127 Totals
const& _totals )
5128 : assertionResult( _assertionResult ),
5129 infoMessages( _infoMessages ),
5132 if( assertionResult.hasMessage() ) {
5135 MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
5136 builder << assertionResult.getMessage();
5137 builder.m_info.message = builder.m_stream.str();
5139 infoMessages.push_back( builder.m_info );
5142 virtual ~AssertionStats();
5144 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
5145 AssertionStats( AssertionStats
const& ) =
default;
5146 AssertionStats( AssertionStats && ) =
default;
5147 AssertionStats& operator = ( AssertionStats
const& ) =
default;
5148 AssertionStats& operator = ( AssertionStats && ) =
default;
5151 AssertionResult assertionResult;
5152 std::vector<MessageInfo> infoMessages;
5156 struct SectionStats {
5157 SectionStats( SectionInfo
const& _sectionInfo,
5158 Counts
const& _assertions,
5159 double _durationInSeconds,
5160 bool _missingAssertions )
5161 : sectionInfo( _sectionInfo ),
5162 assertions( _assertions ),
5163 durationInSeconds( _durationInSeconds ),
5164 missingAssertions( _missingAssertions )
5166 virtual ~SectionStats();
5167 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
5168 SectionStats( SectionStats
const& ) =
default;
5169 SectionStats( SectionStats && ) =
default;
5170 SectionStats& operator = ( SectionStats
const& ) =
default;
5171 SectionStats& operator = ( SectionStats && ) =
default;
5174 SectionInfo sectionInfo;
5176 double durationInSeconds;
5177 bool missingAssertions;
5180 struct TestCaseStats {
5181 TestCaseStats( TestCaseInfo
const& _testInfo,
5182 Totals
const& _totals,
5183 std::string
const& _stdOut,
5184 std::string
const& _stdErr,
5190 aborting( _aborting )
5192 virtual ~TestCaseStats();
5194 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
5195 TestCaseStats( TestCaseStats
const& ) =
default;
5196 TestCaseStats( TestCaseStats && ) =
default;
5197 TestCaseStats& operator = ( TestCaseStats
const& ) =
default;
5198 TestCaseStats& operator = ( TestCaseStats && ) =
default;
5208 struct TestGroupStats {
5209 TestGroupStats(
GroupInfo const& _groupInfo,
5210 Totals
const& _totals,
5212 : groupInfo( _groupInfo ),
5214 aborting( _aborting )
5216 TestGroupStats(
GroupInfo const& _groupInfo )
5217 : groupInfo( _groupInfo ),
5220 virtual ~TestGroupStats();
5222 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
5223 TestGroupStats( TestGroupStats
const& ) =
default;
5224 TestGroupStats( TestGroupStats && ) =
default;
5225 TestGroupStats& operator = ( TestGroupStats
const& ) =
default;
5226 TestGroupStats& operator = ( TestGroupStats && ) =
default;
5234 struct TestRunStats {
5235 TestRunStats( TestRunInfo
const& _runInfo,
5236 Totals
const& _totals,
5238 : runInfo( _runInfo ),
5240 aborting( _aborting )
5242 virtual ~TestRunStats();
5244 # ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS
5245 TestRunStats( TestRunStats
const& _other )
5246 : runInfo( _other.runInfo ),
5247 totals( _other.totals ),
5248 aborting( _other.aborting )
5251 TestRunStats( TestRunStats
const& ) =
default;
5252 TestRunStats( TestRunStats && ) =
default;
5253 TestRunStats& operator = ( TestRunStats
const& ) =
default;
5254 TestRunStats& operator = ( TestRunStats && ) =
default;
5257 TestRunInfo runInfo;
5262 class MultipleReporters;
5264 struct IStreamingReporter : IShared {
5265 virtual ~IStreamingReporter();
5270 virtual ReporterPreferences getPreferences()
const = 0;
5272 virtual void noMatchingTestCases( std::string
const& spec ) = 0;
5274 virtual void testRunStarting( TestRunInfo
const& testRunInfo ) = 0;
5275 virtual void testGroupStarting(
GroupInfo const& groupInfo ) = 0;
5277 virtual void testCaseStarting( TestCaseInfo
const&
testInfo ) = 0;
5278 virtual void sectionStarting( SectionInfo
const& sectionInfo ) = 0;
5280 virtual void assertionStarting( AssertionInfo
const& assertionInfo ) = 0;
5283 virtual bool assertionEnded( AssertionStats
const& assertionStats ) = 0;
5285 virtual void sectionEnded( SectionStats
const& sectionStats ) = 0;
5286 virtual void testCaseEnded( TestCaseStats
const& testCaseStats ) = 0;
5287 virtual void testGroupEnded( TestGroupStats
const& testGroupStats ) = 0;
5288 virtual void testRunEnded( TestRunStats
const& testRunStats ) = 0;
5290 virtual void skipTest( TestCaseInfo
const&
testInfo ) = 0;
5292 virtual MultipleReporters* tryAsMulti() {
return CATCH_NULL; }
5295 struct IReporterFactory : IShared {
5296 virtual ~IReporterFactory();
5297 virtual IStreamingReporter* create( ReporterConfig
const&
config )
const = 0;
5298 virtual std::string getDescription()
const = 0;
5301 struct IReporterRegistry {
5302 typedef std::map<std::string, Ptr<IReporterFactory> > FactoryMap;
5303 typedef std::vector<Ptr<IReporterFactory> > Listeners;
5305 virtual ~IReporterRegistry();
5306 virtual IStreamingReporter* create( std::string
const& name, Ptr<IConfig const>
const&
config )
const = 0;
5307 virtual FactoryMap
const& getFactories()
const = 0;
5308 virtual Listeners
const& getListeners()
const = 0;
5311 Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter>
const& existingReporter, Ptr<IStreamingReporter>
const& additionalReporter );
5316 #include <algorithm>
5320 inline std::size_t listTests( Config
const&
config ) {
5322 TestSpec testSpec =
config.testSpec();
5323 if(
config.testSpec().hasFilters() )
5324 Catch::cout() <<
"Matching test cases:\n";
5326 Catch::cout() <<
"All available test cases:\n";
5330 std::size_t matchedTests = 0;
5331 TextAttributes nameAttr, tagsAttr;
5332 nameAttr.setInitialIndent( 2 ).setIndent( 4 );
5333 tagsAttr.setIndent( 6 );
5336 for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
5340 TestCaseInfo
const& testCaseInfo = it->getTestCaseInfo();
5341 Colour::Code colour = testCaseInfo.isHidden()
5342 ? Colour::SecondaryText
5344 Colour colourGuard( colour );
5346 Catch::cout() <<
Text( testCaseInfo.name, nameAttr ) << std::endl;
5347 if( !testCaseInfo.tags.empty() )
5348 Catch::cout() <<
Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl;
5351 if( !
config.testSpec().hasFilters() )
5352 Catch::cout() << pluralise( matchedTests,
"test case" ) <<
"\n" << std::endl;
5354 Catch::cout() << pluralise( matchedTests,
"matching test case" ) <<
"\n" << std::endl;
5355 return matchedTests;
5358 inline std::size_t listTestsNamesOnly( Config
const&
config ) {
5359 TestSpec testSpec =
config.testSpec();
5360 if( !
config.testSpec().hasFilters() )
5362 std::size_t matchedTests = 0;
5364 for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
5368 TestCaseInfo
const& testCaseInfo = it->getTestCaseInfo();
5369 Catch::cout() << testCaseInfo.name << std::endl;
5371 return matchedTests;
5375 TagInfo() : count ( 0 ) {}
5376 void add( std::string
const& spelling ) {
5378 spellings.insert( spelling );
5380 std::string all()
const {
5382 for( std::set<std::string>::const_iterator it = spellings.begin(), itEnd = spellings.end();
5385 out += "[" + *it + "]";
5388 std::set<std::string> spellings;
5392 inline std::size_t listTags( Config
const&
config ) {
5393 TestSpec testSpec =
config.testSpec();
5394 if(
config.testSpec().hasFilters() )
5395 Catch::cout() <<
"Tags for matching test cases:\n";
5397 Catch::cout() <<
"All available tags:\n";
5401 std::map<std::string, TagInfo> tagCounts;
5404 for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
5407 for( std::set<std::string>::const_iterator tagIt = it->getTestCaseInfo().tags.begin(),
5408 tagItEnd = it->getTestCaseInfo().tags.end();
5411 std::string tagName = *tagIt;
5412 std::string lcaseTagName =
toLower( tagName );
5413 std::map<std::string, TagInfo>::iterator countIt = tagCounts.find( lcaseTagName );
5414 if( countIt == tagCounts.end() )
5415 countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
5416 countIt->second.add( tagName );
5420 for( std::map<std::string, TagInfo>::const_iterator countIt = tagCounts.begin(),
5421 countItEnd = tagCounts.end();
5422 countIt != countItEnd;
5424 std::ostringstream oss;
5425 oss <<
" " << std::setw(2) << countIt->second.count <<
" ";
5426 Text wrapper( countIt->second.all(), TextAttributes()
5427 .setInitialIndent( 0 )
5428 .setIndent( oss.str().size() )
5429 .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) );
5430 Catch::cout() << oss.str() << wrapper <<
"\n";
5432 Catch::cout() << pluralise( tagCounts.size(),
"tag" ) <<
"\n" << std::endl;
5433 return tagCounts.size();
5436 inline std::size_t listReporters( Config
const& ) {
5437 Catch::cout() <<
"Available reporters:\n";
5439 IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;
5440 std::size_t maxNameLen = 0;
5441 for(it = itBegin; it != itEnd; ++it )
5442 maxNameLen = (
std::max)( maxNameLen, it->first.
size() );
5444 for(it = itBegin; it != itEnd; ++it ) {
5445 Text wrapper( it->second->getDescription(), TextAttributes()
5446 .setInitialIndent( 0 )
5447 .setIndent( 7+maxNameLen )
5448 .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );
5449 Catch::cout() <<
" "
5452 << std::string( maxNameLen - it->first.size() + 2,
' ' )
5455 Catch::cout() << std::endl;
5456 return factories.size();
5459 inline Option<std::size_t> list( Config
const&
config ) {
5460 Option<std::size_t> listedCount;
5462 listedCount = listedCount.valueOr(0) + listTests(
config );
5463 if(
config.listTestNamesOnly() )
5464 listedCount = listedCount.valueOr(0) + listTestsNamesOnly(
config );
5466 listedCount = listedCount.valueOr(0) + listTags(
config );
5467 if(
config.listReporters() )
5468 listedCount = listedCount.valueOr(0) + listReporters(
config );
5475 #define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
5478 #define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
5486 namespace TestCaseTracking {
5488 struct ITracker : SharedImpl<> {
5489 virtual ~ITracker();
5492 virtual std::string name()
const = 0;
5495 virtual bool isComplete()
const = 0;
5496 virtual bool isSuccessfullyCompleted()
const = 0;
5497 virtual bool isOpen()
const = 0;
5498 virtual bool hasChildren()
const = 0;
5500 virtual ITracker& parent() = 0;
5503 virtual void close() = 0;
5504 virtual void fail() = 0;
5505 virtual void markAsNeedingAnotherRun() = 0;
5507 virtual void addChild( Ptr<ITracker>
const& child ) = 0;
5508 virtual ITracker* findChild( std::string
const& name ) = 0;
5509 virtual void openChild() = 0;
5512 virtual bool isSectionTracker()
const = 0;
5513 virtual bool isIndexTracker()
const = 0;
5516 class TrackerContext {
5524 Ptr<ITracker> m_rootTracker;
5525 ITracker* m_currentTracker;
5526 RunState m_runState;
5530 static TrackerContext& instance() {
5531 static TrackerContext s_instance;
5537 m_runState( NotStarted )
5540 ITracker& startRun();
5543 m_rootTracker.reset();
5545 m_runState = NotStarted;
5549 m_currentTracker = m_rootTracker.get();
5550 m_runState = Executing;
5552 void completeCycle() {
5553 m_runState = CompletedCycle;
5556 bool completedCycle()
const {
5557 return m_runState == CompletedCycle;
5559 ITracker& currentTracker() {
5560 return *m_currentTracker;
5562 void setCurrentTracker( ITracker* tracker ) {
5563 m_currentTracker = tracker;
5567 class TrackerBase :
public ITracker {
5574 CompletedSuccessfully,
5577 class TrackerHasName {
5580 TrackerHasName( std::string
const& name ) : m_name( name ) {}
5581 bool operator ()( Ptr<ITracker>
const& tracker ) {
5582 return tracker->name() == m_name;
5585 typedef std::vector<Ptr<ITracker> > Children;
5587 TrackerContext& m_ctx;
5589 Children m_children;
5590 CycleState m_runState;
5592 TrackerBase( std::string
const& name, TrackerContext& ctx, ITracker* parent )
5596 m_runState( NotStarted )
5598 virtual ~TrackerBase();
5604 return m_runState == CompletedSuccessfully || m_runState == Failed;
5607 return m_runState == CompletedSuccessfully;
5610 return m_runState != NotStarted && !isComplete();
5613 return !m_children.empty();
5616 virtual void addChild( Ptr<ITracker>
const& child )
CATCH_OVERRIDE {
5617 m_children.push_back( child );
5620 virtual ITracker* findChild( std::string
const& name )
CATCH_OVERRIDE {
5621 Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( name ) );
5622 return( it != m_children.end() )
5632 if( m_runState != ExecutingChildren ) {
5633 m_runState = ExecutingChildren;
5635 m_parent->openChild();
5639 virtual bool isSectionTracker() const
CATCH_OVERRIDE {
return false; }
5640 virtual bool isIndexTracker() const
CATCH_OVERRIDE {
return false; }
5643 m_runState = Executing;
5646 m_parent->openChild();
5652 while( &m_ctx.currentTracker() !=
this )
5653 m_ctx.currentTracker().close();
5655 switch( m_runState ) {
5657 case CompletedSuccessfully:
5659 throw std::logic_error(
"Illogical state" );
5661 case NeedsAnotherRun:
5665 m_runState = CompletedSuccessfully;
5667 case ExecutingChildren:
5668 if( m_children.empty() || m_children.back()->isComplete() )
5669 m_runState = CompletedSuccessfully;
5673 throw std::logic_error(
"Unexpected state" );
5676 m_ctx.completeCycle();
5679 m_runState = Failed;
5681 m_parent->markAsNeedingAnotherRun();
5683 m_ctx.completeCycle();
5686 m_runState = NeedsAnotherRun;
5689 void moveToParent() {
5691 m_ctx.setCurrentTracker( m_parent );
5694 m_ctx.setCurrentTracker(
this );
5698 class SectionTracker :
public TrackerBase {
5700 SectionTracker( std::string
const& name, TrackerContext& ctx, ITracker* parent )
5701 : TrackerBase( name, ctx, parent )
5703 virtual ~SectionTracker();
5705 virtual bool isSectionTracker() const
CATCH_OVERRIDE {
return true; }
5707 static SectionTracker& acquire( TrackerContext& ctx, std::string
const& name ) {
5710 ITracker& currentTracker = ctx.currentTracker();
5711 if( ITracker* childTracker = currentTracker.findChild( name ) ) {
5712 assert( childTracker );
5713 assert( childTracker->isSectionTracker() );
5714 section =
static_cast<SectionTracker*
>( childTracker );
5717 section =
new SectionTracker( name, ctx, ¤tTracker );
5718 currentTracker.addChild( section );
5720 if( !ctx.completedCycle() && !section->isComplete() ) {
5728 class IndexTracker :
public TrackerBase {
5732 IndexTracker( std::string
const& name, TrackerContext& ctx, ITracker* parent,
int size )
5733 : TrackerBase( name, ctx, parent ),
5737 virtual ~IndexTracker();
5739 virtual bool isIndexTracker() const
CATCH_OVERRIDE {
return true; }
5741 static IndexTracker& acquire( TrackerContext& ctx, std::string
const& name,
int size ) {
5744 ITracker& currentTracker = ctx.currentTracker();
5745 if( ITracker* childTracker = currentTracker.findChild( name ) ) {
5746 assert( childTracker );
5747 assert( childTracker->isIndexTracker() );
5748 tracker =
static_cast<IndexTracker*
>( childTracker );
5751 tracker =
new IndexTracker( name, ctx, ¤tTracker,
size );
5752 currentTracker.addChild( tracker );
5755 if( !ctx.completedCycle() && !tracker->isComplete() ) {
5756 if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
5757 tracker->moveNext();
5764 int index()
const {
return m_index; }
5773 if( m_runState == CompletedSuccessfully && m_index < m_size-1 )
5774 m_runState = Executing;
5778 inline ITracker& TrackerContext::startRun() {
5779 m_rootTracker =
new SectionTracker(
"{root}", *
this,
CATCH_NULL );
5781 m_runState = Executing;
5782 return *m_rootTracker;