1/* 2 * CATCH v1.1 build 1 (master branch) 3 * Generated: 2015-03-27 18:00:16.346230 4 * ---------------------------------------------------------- 5 * This file has been merged from multiple headers. Please don't edit it directly 6 * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. 7 * 8 * Distributed under the Boost Software License, Version 1.0. (See accompanying 9 * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10 */ 11#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED 12#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED 13 14#define TWOBLUECUBES_CATCH_HPP_INCLUDED 15 16// #included from: internal/catch_suppress_warnings.h 17 18#define TWOBLUECUBES_CATCH_SUPPRESS_WARNINGS_H_INCLUDED 19 20#ifdef __clang__ 21# ifdef __ICC // icpc defines the __clang__ macro 22# pragma warning(push) 23# pragma warning(disable: 161 1682) 24# else // __ICC 25# pragma clang diagnostic ignored "-Wglobal-constructors" 26# pragma clang diagnostic ignored "-Wvariadic-macros" 27# pragma clang diagnostic ignored "-Wc99-extensions" 28# pragma clang diagnostic ignored "-Wunused-variable" 29# pragma clang diagnostic push 30# pragma clang diagnostic ignored "-Wpadded" 31# pragma clang diagnostic ignored "-Wc++98-compat" 32# pragma clang diagnostic ignored "-Wc++98-compat-pedantic" 33# endif 34#elif defined __GNUC__ 35# pragma GCC diagnostic ignored "-Wvariadic-macros" 36# pragma GCC diagnostic ignored "-Wunused-variable" 37# pragma GCC diagnostic push 38# pragma GCC diagnostic ignored "-Wpadded" 39#endif 40 41#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) 42# define CATCH_IMPL 43#endif 44 45#ifdef CATCH_IMPL 46# ifndef CLARA_CONFIG_MAIN 47# define CLARA_CONFIG_MAIN_NOT_DEFINED 48# define CLARA_CONFIG_MAIN 49# endif 50#endif 51 52// #included from: internal/catch_notimplemented_exception.h 53#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED 54 55// #included from: catch_common.h 56#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED 57 58#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line 59#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) 60#define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) 61 62#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr 63#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr ) 64 65#include <sstream> 66#include <stdexcept> 67#include <algorithm> 68 69// #included from: catch_compiler_capabilities.h 70#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED 71 72// Much of the following code is based on Boost (1.53) 73 74#ifdef __clang__ 75 76# if __has_feature(cxx_nullptr) 77# define CATCH_CONFIG_CPP11_NULLPTR 78# endif 79 80# if __has_feature(cxx_noexcept) 81# define CATCH_CONFIG_CPP11_NOEXCEPT 82# endif 83 84#endif // __clang__ 85 86//////////////////////////////////////////////////////////////////////////////// 87// Borland 88#ifdef __BORLANDC__ 89 90#if (__BORLANDC__ > 0x582 ) 91//#define CATCH_CONFIG_SFINAE // Not confirmed 92#endif 93 94#endif // __BORLANDC__ 95 96//////////////////////////////////////////////////////////////////////////////// 97// EDG 98#ifdef __EDG_VERSION__ 99 100#if (__EDG_VERSION__ > 238 ) 101//#define CATCH_CONFIG_SFINAE // Not confirmed 102#endif 103 104#endif // __EDG_VERSION__ 105 106//////////////////////////////////////////////////////////////////////////////// 107// Digital Mars 108#ifdef __DMC__ 109 110#if (__DMC__ > 0x840 ) 111//#define CATCH_CONFIG_SFINAE // Not confirmed 112#endif 113 114#endif // __DMC__ 115 116//////////////////////////////////////////////////////////////////////////////// 117// GCC 118#ifdef __GNUC__ 119 120#if __GNUC__ < 3 121 122#if (__GNUC_MINOR__ >= 96 ) 123//#define CATCH_CONFIG_SFINAE 124#endif 125 126#elif __GNUC__ >= 3 127 128// #define CATCH_CONFIG_SFINAE // Taking this out completely for now 129 130#endif // __GNUC__ < 3 131 132#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) ) 133 134#define CATCH_CONFIG_CPP11_NULLPTR 135#endif 136 137#endif // __GNUC__ 138 139//////////////////////////////////////////////////////////////////////////////// 140// Visual C++ 141#ifdef _MSC_VER 142 143#if (_MSC_VER >= 1600) 144#define CATCH_CONFIG_CPP11_NULLPTR 145#endif 146 147#if (_MSC_VER >= 1310 ) // (VC++ 7.0+) 148//#define CATCH_CONFIG_SFINAE // Not confirmed 149#endif 150 151#endif // _MSC_VER 152 153// Use variadic macros if the compiler supports them 154#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \ 155 ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \ 156 ( defined __GNUC__ && __GNUC__ >= 3 ) || \ 157 ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L ) 158 159#ifndef CATCH_CONFIG_NO_VARIADIC_MACROS 160#define CATCH_CONFIG_VARIADIC_MACROS 161#endif 162 163#endif 164 165//////////////////////////////////////////////////////////////////////////////// 166// C++ language feature support 167 168// detect language version: 169#if (__cplusplus == 201103L) 170# define CATCH_CPP11 171# define CATCH_CPP11_OR_GREATER 172#elif (__cplusplus >= 201103L) 173# define CATCH_CPP11_OR_GREATER 174#endif 175 176// noexcept support: 177#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT) 178# define CATCH_NOEXCEPT noexcept 179# define CATCH_NOEXCEPT_IS(x) noexcept(x) 180#else 181# define CATCH_NOEXCEPT throw() 182# define CATCH_NOEXCEPT_IS(x) 183#endif 184 185namespace Catch { 186 187 class NonCopyable { 188#ifdef CATCH_CPP11_OR_GREATER 189 NonCopyable( NonCopyable const& ) = delete; 190 NonCopyable( NonCopyable && ) = delete; 191 NonCopyable& operator = ( NonCopyable const& ) = delete; 192 NonCopyable& operator = ( NonCopyable && ) = delete; 193#else 194 NonCopyable( NonCopyable const& info ); 195 NonCopyable& operator = ( NonCopyable const& ); 196#endif 197 198 protected: 199 NonCopyable() {} 200 virtual ~NonCopyable(); 201 }; 202 203 class SafeBool { 204 public: 205 typedef void (SafeBool::*type)() const; 206 207 static type makeSafe( bool value ) { 208 return value ? &SafeBool::trueValue : 0; 209 } 210 private: 211 void trueValue() const {} 212 }; 213 214 template<typename ContainerT> 215 inline void deleteAll( ContainerT& container ) { 216 typename ContainerT::const_iterator it = container.begin(); 217 typename ContainerT::const_iterator itEnd = container.end(); 218 for(; it != itEnd; ++it ) 219 delete *it; 220 } 221 template<typename AssociativeContainerT> 222 inline void deleteAllValues( AssociativeContainerT& container ) { 223 typename AssociativeContainerT::const_iterator it = container.begin(); 224 typename AssociativeContainerT::const_iterator itEnd = container.end(); 225 for(; it != itEnd; ++it ) 226 delete it->second; 227 } 228 229 bool startsWith( std::string const& s, std::string const& prefix ); 230 bool endsWith( std::string const& s, std::string const& suffix ); 231 bool contains( std::string const& s, std::string const& infix ); 232 void toLowerInPlace( std::string& s ); 233 std::string toLower( std::string const& s ); 234 std::string trim( std::string const& str ); 235 bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ); 236 237 struct pluralise { 238 pluralise( std::size_t count, std::string const& label ); 239 240 friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ); 241 242 std::size_t m_count; 243 std::string m_label; 244 }; 245 246 struct SourceLineInfo { 247 248 SourceLineInfo(); 249 SourceLineInfo( char const* _file, std::size_t _line ); 250 SourceLineInfo( SourceLineInfo const& other ); 251# ifdef CATCH_CPP11_OR_GREATER 252 SourceLineInfo( SourceLineInfo && ) = default; 253 SourceLineInfo& operator = ( SourceLineInfo const& ) = default; 254 SourceLineInfo& operator = ( SourceLineInfo && ) = default; 255# endif 256 bool empty() const; 257 bool operator == ( SourceLineInfo const& other ) const; 258 bool operator < ( SourceLineInfo const& other ) const; 259 260 std::string file; 261 std::size_t line; 262 }; 263 264 std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); 265 266 // This is just here to avoid compiler warnings with macro constants and boolean literals 267 inline bool isTrue( bool value ){ return value; } 268 inline bool alwaysTrue() { return true; } 269 inline bool alwaysFalse() { return false; } 270 271 void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ); 272 273 // Use this in variadic streaming macros to allow 274 // >> +StreamEndStop 275 // as well as 276 // >> stuff +StreamEndStop 277 struct StreamEndStop { 278 std::string operator+() { 279 return std::string(); 280 } 281 }; 282 template<typename T> 283 T const& operator + ( T const& value, StreamEndStop ) { 284 return value; 285 } 286} 287 288#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) ) 289#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO ); 290 291#include <ostream> 292 293namespace Catch { 294 295 class NotImplementedException : public std::exception 296 { 297 public: 298 NotImplementedException( SourceLineInfo const& lineInfo ); 299 NotImplementedException( NotImplementedException const& ) {} 300 301 virtual ~NotImplementedException() CATCH_NOEXCEPT {} 302 303 virtual const char* what() const CATCH_NOEXCEPT; 304 305 private: 306 std::string m_what; 307 SourceLineInfo m_lineInfo; 308 }; 309 310} // end namespace Catch 311 312/////////////////////////////////////////////////////////////////////////////// 313#define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO ) 314 315// #included from: internal/catch_context.h 316#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED 317 318// #included from: catch_interfaces_generators.h 319#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED 320 321#include <string> 322 323namespace Catch { 324 325 struct IGeneratorInfo { 326 virtual ~IGeneratorInfo(); 327 virtual bool moveNext() = 0; 328 virtual std::size_t getCurrentIndex() const = 0; 329 }; 330 331 struct IGeneratorsForTest { 332 virtual ~IGeneratorsForTest(); 333 334 virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0; 335 virtual bool moveNext() = 0; 336 }; 337 338 IGeneratorsForTest* createGeneratorsForTest(); 339 340} // end namespace Catch 341 342// #included from: catch_ptr.hpp 343#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED 344 345#ifdef __clang__ 346#pragma clang diagnostic push 347#pragma clang diagnostic ignored "-Wpadded" 348#endif 349 350namespace Catch { 351 352 // An intrusive reference counting smart pointer. 353 // T must implement addRef() and release() methods 354 // typically implementing the IShared interface 355 template<typename T> 356 class Ptr { 357 public: 358 Ptr() : m_p( NULL ){} 359 Ptr( T* p ) : m_p( p ){ 360 if( m_p ) 361 m_p->addRef(); 362 } 363 Ptr( Ptr const& other ) : m_p( other.m_p ){ 364 if( m_p ) 365 m_p->addRef(); 366 } 367 ~Ptr(){ 368 if( m_p ) 369 m_p->release(); 370 } 371 void reset() { 372 if( m_p ) 373 m_p->release(); 374 m_p = NULL; 375 } 376 Ptr& operator = ( T* p ){ 377 Ptr temp( p ); 378 swap( temp ); 379 return *this; 380 } 381 Ptr& operator = ( Ptr const& other ){ 382 Ptr temp( other ); 383 swap( temp ); 384 return *this; 385 } 386 void swap( Ptr& other ) { std::swap( m_p, other.m_p ); } 387 T* get() { return m_p; } 388 const T* get() const{ return m_p; } 389 T& operator*() const { return *m_p; } 390 T* operator->() const { return m_p; } 391 bool operator !() const { return m_p == NULL; } 392 operator SafeBool::type() const { return SafeBool::makeSafe( m_p != NULL ); } 393 394 private: 395 T* m_p; 396 }; 397 398 struct IShared : NonCopyable { 399 virtual ~IShared(); 400 virtual void addRef() const = 0; 401 virtual void release() const = 0; 402 }; 403 404 template<typename T = IShared> 405 struct SharedImpl : T { 406 407 SharedImpl() : m_rc( 0 ){} 408 409 virtual void addRef() const { 410 ++m_rc; 411 } 412 virtual void release() const { 413 if( --m_rc == 0 ) 414 delete this; 415 } 416 417 mutable unsigned int m_rc; 418 }; 419 420} // end namespace Catch 421 422#ifdef __clang__ 423#pragma clang diagnostic pop 424#endif 425 426#include <memory> 427#include <vector> 428#include <stdlib.h> 429 430namespace Catch { 431 432 class TestCase; 433 class Stream; 434 struct IResultCapture; 435 struct IRunner; 436 struct IGeneratorsForTest; 437 struct IConfig; 438 439 struct IContext 440 { 441 virtual ~IContext(); 442 443 virtual IResultCapture* getResultCapture() = 0; 444 virtual IRunner* getRunner() = 0; 445 virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0; 446 virtual bool advanceGeneratorsForCurrentTest() = 0; 447 virtual Ptr<IConfig const> getConfig() const = 0; 448 }; 449 450 struct IMutableContext : IContext 451 { 452 virtual ~IMutableContext(); 453 virtual void setResultCapture( IResultCapture* resultCapture ) = 0; 454 virtual void setRunner( IRunner* runner ) = 0; 455 virtual void setConfig( Ptr<IConfig const> const& config ) = 0; 456 }; 457 458 IContext& getCurrentContext(); 459 IMutableContext& getCurrentMutableContext(); 460 void cleanUpContext(); 461 Stream createStream( std::string const& streamName ); 462 463} 464 465// #included from: internal/catch_test_registry.hpp 466#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED 467 468// #included from: catch_interfaces_testcase.h 469#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED 470 471#include <vector> 472 473namespace Catch { 474 475 class TestSpec; 476 477 struct ITestCase : IShared { 478 virtual void invoke () const = 0; 479 protected: 480 virtual ~ITestCase(); 481 }; 482 483 class TestCase; 484 struct IConfig; 485 486 struct ITestCaseRegistry { 487 virtual ~ITestCaseRegistry(); 488 virtual std::vector<TestCase> const& getAllTests() const = 0; 489 virtual void getFilteredTests( TestSpec const& testSpec, IConfig const& config, std::vector<TestCase>& matchingTestCases, bool negated = false ) const = 0; 490 491 }; 492} 493 494namespace Catch { 495 496template<typename C> 497class MethodTestCase : public SharedImpl<ITestCase> { 498 499public: 500 MethodTestCase( void (C::*method)() ) : m_method( method ) {} 501 502 virtual void invoke() const { 503 C obj; 504 (obj.*m_method)(); 505 } 506 507private: 508 virtual ~MethodTestCase() {} 509 510 void (C::*m_method)(); 511}; 512 513typedef void(*TestFunction)(); 514 515struct NameAndDesc { 516 NameAndDesc( const char* _name = "", const char* _description= "" ) 517 : name( _name ), description( _description ) 518 {} 519 520 const char* name; 521 const char* description; 522}; 523 524struct AutoReg { 525 526 AutoReg( TestFunction function, 527 SourceLineInfo const& lineInfo, 528 NameAndDesc const& nameAndDesc ); 529 530 template<typename C> 531 AutoReg( void (C::*method)(), 532 char const* className, 533 NameAndDesc const& nameAndDesc, 534 SourceLineInfo const& lineInfo ) { 535 registerTestCase( new MethodTestCase<C>( method ), 536 className, 537 nameAndDesc, 538 lineInfo ); 539 } 540 541 void registerTestCase( ITestCase* testCase, 542 char const* className, 543 NameAndDesc const& nameAndDesc, 544 SourceLineInfo const& lineInfo ); 545 546 ~AutoReg(); 547 548private: 549 AutoReg( AutoReg const& ); 550 void operator= ( AutoReg const& ); 551}; 552 553} // end namespace Catch 554 555#ifdef CATCH_CONFIG_VARIADIC_MACROS 556 /////////////////////////////////////////////////////////////////////////////// 557 #define INTERNAL_CATCH_TESTCASE( ... ) \ 558 static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \ 559 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\ 560 static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )() 561 562 /////////////////////////////////////////////////////////////////////////////// 563 #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ 564 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); } 565 566 /////////////////////////////////////////////////////////////////////////////// 567 #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... )\ 568 namespace{ \ 569 struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \ 570 void test(); \ 571 }; \ 572 Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \ 573 } \ 574 void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test() 575 576#else 577 /////////////////////////////////////////////////////////////////////////////// 578 #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \ 579 static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \ 580 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\ 581 static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )() 582 583 /////////////////////////////////////////////////////////////////////////////// 584 #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \ 585 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); } 586 587 /////////////////////////////////////////////////////////////////////////////// 588 #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\ 589 namespace{ \ 590 struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \ 591 void test(); \ 592 }; \ 593 Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \ 594 } \ 595 void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test() 596 597#endif 598 599// #included from: internal/catch_capture.hpp 600#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED 601 602// #included from: catch_result_builder.h 603#define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED 604 605// #included from: catch_result_type.h 606#define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED 607 608namespace Catch { 609 610 // ResultWas::OfType enum 611 struct ResultWas { enum OfType { 612 Unknown = -1, 613 Ok = 0, 614 Info = 1, 615 Warning = 2, 616 617 FailureBit = 0x10, 618 619 ExpressionFailed = FailureBit | 1, 620 ExplicitFailure = FailureBit | 2, 621 622 Exception = 0x100 | FailureBit, 623 624 ThrewException = Exception | 1, 625 DidntThrowException = Exception | 2, 626 627 FatalErrorCondition = 0x200 | FailureBit 628 629 }; }; 630 631 inline bool isOk( ResultWas::OfType resultType ) { 632 return ( resultType & ResultWas::FailureBit ) == 0; 633 } 634 inline bool isJustInfo( int flags ) { 635 return flags == ResultWas::Info; 636 } 637 638 // ResultDisposition::Flags enum 639 struct ResultDisposition { enum Flags { 640 Normal = 0x00, 641 642 ContinueOnFailure = 0x01, // Failures fail test, but execution continues 643 FalseTest = 0x02, // Prefix expression with ! 644 SuppressFail = 0x04 // Failures are reported but do not fail the test 645 }; }; 646 647 inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) { 648 return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) ); 649 } 650 651 inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; } 652 inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; } 653 inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; } 654 655} // end namespace Catch 656 657// #included from: catch_assertionresult.h 658#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED 659 660#include <string> 661 662namespace Catch { 663 664 struct AssertionInfo 665 { 666 AssertionInfo() {} 667 AssertionInfo( std::string const& _macroName, 668 SourceLineInfo const& _lineInfo, 669 std::string const& _capturedExpression, 670 ResultDisposition::Flags _resultDisposition ); 671 672 std::string macroName; 673 SourceLineInfo lineInfo; 674 std::string capturedExpression; 675 ResultDisposition::Flags resultDisposition; 676 }; 677 678 struct AssertionResultData 679 { 680 AssertionResultData() : resultType( ResultWas::Unknown ) {} 681 682 std::string reconstructedExpression; 683 std::string message; 684 ResultWas::OfType resultType; 685 }; 686 687 class AssertionResult { 688 public: 689 AssertionResult(); 690 AssertionResult( AssertionInfo const& info, AssertionResultData const& data ); 691 ~AssertionResult(); 692# ifdef CATCH_CPP11_OR_GREATER 693 AssertionResult( AssertionResult const& ) = default; 694 AssertionResult( AssertionResult && ) = default; 695 AssertionResult& operator = ( AssertionResult const& ) = default; 696 AssertionResult& operator = ( AssertionResult && ) = default; 697# endif 698 699 bool isOk() const; 700 bool succeeded() const; 701 ResultWas::OfType getResultType() const; 702 bool hasExpression() const; 703 bool hasMessage() const; 704 std::string getExpression() const; 705 std::string getExpressionInMacro() const; 706 bool hasExpandedExpression() const; 707 std::string getExpandedExpression() const; 708 std::string getMessage() const; 709 SourceLineInfo getSourceInfo() const; 710 std::string getTestMacroName() const; 711 712 protected: 713 AssertionInfo m_info; 714 AssertionResultData m_resultData; 715 }; 716 717} // end namespace Catch 718 719namespace Catch { 720 721 struct TestFailureException{}; 722 723 template<typename T> class ExpressionLhs; 724 725 struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison; 726 727 struct CopyableStream { 728 CopyableStream() {} 729 CopyableStream( CopyableStream const& other ) { 730 oss << other.oss.str(); 731 } 732 CopyableStream& operator=( CopyableStream const& other ) { 733 oss.str(""); 734 oss << other.oss.str(); 735 return *this; 736 } 737 std::ostringstream oss; 738 }; 739 740 class ResultBuilder { 741 public: 742 ResultBuilder( char const* macroName, 743 SourceLineInfo const& lineInfo, 744 char const* capturedExpression, 745 ResultDisposition::Flags resultDisposition ); 746 747 template<typename T> 748 ExpressionLhs<T const&> operator->* ( T const& operand ); 749 ExpressionLhs<bool> operator->* ( bool value ); 750 751 template<typename T> 752 ResultBuilder& operator << ( T const& value ) { 753 m_stream.oss << value; 754 return *this; 755 } 756 757 template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& ); 758 template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& ); 759 760 ResultBuilder& setResultType( ResultWas::OfType result ); 761 ResultBuilder& setResultType( bool result ); 762 ResultBuilder& setLhs( std::string const& lhs ); 763 ResultBuilder& setRhs( std::string const& rhs ); 764 ResultBuilder& setOp( std::string const& op ); 765 766 void endExpression(); 767 768 std::string reconstructExpression() const; 769 AssertionResult build() const; 770 771 void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal ); 772 void captureResult( ResultWas::OfType resultType ); 773 void captureExpression(); 774 void react(); 775 bool shouldDebugBreak() const; 776 bool allowThrows() const; 777 778 private: 779 AssertionInfo m_assertionInfo; 780 AssertionResultData m_data; 781 struct ExprComponents { 782 ExprComponents() : testFalse( false ) {} 783 bool testFalse; 784 std::string lhs, rhs, op; 785 } m_exprComponents; 786 CopyableStream m_stream; 787 788 bool m_shouldDebugBreak; 789 bool m_shouldThrow; 790 }; 791 792} // namespace Catch 793 794// Include after due to circular dependency: 795// #included from: catch_expression_lhs.hpp 796#define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED 797 798// #included from: catch_evaluate.hpp 799#define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED 800 801#ifdef _MSC_VER 802#pragma warning(push) 803#pragma warning(disable:4389) // '==' : signed/unsigned mismatch 804#endif 805 806#include <cstddef> 807 808namespace Catch { 809namespace Internal { 810 811 enum Operator { 812 IsEqualTo, 813 IsNotEqualTo, 814 IsLessThan, 815 IsGreaterThan, 816 IsLessThanOrEqualTo, 817 IsGreaterThanOrEqualTo 818 }; 819 820 template<Operator Op> struct OperatorTraits { static const char* getName(){ return "*error*"; } }; 821 template<> struct OperatorTraits<IsEqualTo> { static const char* getName(){ return "=="; } }; 822 template<> struct OperatorTraits<IsNotEqualTo> { static const char* getName(){ return "!="; } }; 823 template<> struct OperatorTraits<IsLessThan> { static const char* getName(){ return "<"; } }; 824 template<> struct OperatorTraits<IsGreaterThan> { static const char* getName(){ return ">"; } }; 825 template<> struct OperatorTraits<IsLessThanOrEqualTo> { static const char* getName(){ return "<="; } }; 826 template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } }; 827 828 template<typename T> 829 inline T& opCast(T const& t) { return const_cast<T&>(t); } 830 831// nullptr_t support based on pull request #154 from Konstantin Baumann 832#ifdef CATCH_CONFIG_CPP11_NULLPTR 833 inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; } 834#endif // CATCH_CONFIG_CPP11_NULLPTR 835 836 // So the compare overloads can be operator agnostic we convey the operator as a template 837 // enum, which is used to specialise an Evaluator for doing the comparison. 838 template<typename T1, typename T2, Operator Op> 839 class Evaluator{}; 840 841 template<typename T1, typename T2> 842 struct Evaluator<T1, T2, IsEqualTo> { 843 static bool evaluate( T1 const& lhs, T2 const& rhs) { 844 return opCast( lhs ) == opCast( rhs ); 845 } 846 }; 847 template<typename T1, typename T2> 848 struct Evaluator<T1, T2, IsNotEqualTo> { 849 static bool evaluate( T1 const& lhs, T2 const& rhs ) { 850 return opCast( lhs ) != opCast( rhs ); 851 } 852 }; 853 template<typename T1, typename T2> 854 struct Evaluator<T1, T2, IsLessThan> { 855 static bool evaluate( T1 const& lhs, T2 const& rhs ) { 856 return opCast( lhs ) < opCast( rhs ); 857 } 858 }; 859 template<typename T1, typename T2> 860 struct Evaluator<T1, T2, IsGreaterThan> { 861 static bool evaluate( T1 const& lhs, T2 const& rhs ) { 862 return opCast( lhs ) > opCast( rhs ); 863 } 864 }; 865 template<typename T1, typename T2> 866 struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> { 867 static bool evaluate( T1 const& lhs, T2 const& rhs ) { 868 return opCast( lhs ) >= opCast( rhs ); 869 } 870 }; 871 template<typename T1, typename T2> 872 struct Evaluator<T1, T2, IsLessThanOrEqualTo> { 873 static bool evaluate( T1 const& lhs, T2 const& rhs ) { 874 return opCast( lhs ) <= opCast( rhs ); 875 } 876 }; 877 878 template<Operator Op, typename T1, typename T2> 879 bool applyEvaluator( T1 const& lhs, T2 const& rhs ) { 880 return Evaluator<T1, T2, Op>::evaluate( lhs, rhs ); 881 } 882 883 // This level of indirection allows us to specialise for integer types 884 // to avoid signed/ unsigned warnings 885 886 // "base" overload 887 template<Operator Op, typename T1, typename T2> 888 bool compare( T1 const& lhs, T2 const& rhs ) { 889 return Evaluator<T1, T2, Op>::evaluate( lhs, rhs ); 890 } 891 892 // unsigned X to int 893 template<Operator Op> bool compare( unsigned int lhs, int rhs ) { 894 return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) ); 895 } 896 template<Operator Op> bool compare( unsigned long lhs, int rhs ) { 897 return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) ); 898 } 899 template<Operator Op> bool compare( unsigned char lhs, int rhs ) { 900 return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) ); 901 } 902 903 // unsigned X to long 904 template<Operator Op> bool compare( unsigned int lhs, long rhs ) { 905 return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) ); 906 } 907 template<Operator Op> bool compare( unsigned long lhs, long rhs ) { 908 return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) ); 909 } 910 template<Operator Op> bool compare( unsigned char lhs, long rhs ) { 911 return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) ); 912 } 913 914 // int to unsigned X 915 template<Operator Op> bool compare( int lhs, unsigned int rhs ) { 916 return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs ); 917 } 918 template<Operator Op> bool compare( int lhs, unsigned long rhs ) { 919 return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs ); 920 } 921 template<Operator Op> bool compare( int lhs, unsigned char rhs ) { 922 return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs ); 923 } 924 925 // long to unsigned X 926 template<Operator Op> bool compare( long lhs, unsigned int rhs ) { 927 return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs ); 928 } 929 template<Operator Op> bool compare( long lhs, unsigned long rhs ) { 930 return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs ); 931 } 932 template<Operator Op> bool compare( long lhs, unsigned char rhs ) { 933 return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs ); 934 } 935 936 // pointer to long (when comparing against NULL) 937 template<Operator Op, typename T> bool compare( long lhs, T* rhs ) { 938 return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs ); 939 } 940 template<Operator Op, typename T> bool compare( T* lhs, long rhs ) { 941 return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) ); 942 } 943 944 // pointer to int (when comparing against NULL) 945 template<Operator Op, typename T> bool compare( int lhs, T* rhs ) { 946 return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs ); 947 } 948 template<Operator Op, typename T> bool compare( T* lhs, int rhs ) { 949 return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) ); 950 } 951 952#ifdef CATCH_CONFIG_CPP11_NULLPTR 953 // pointer to nullptr_t (when comparing against nullptr) 954 template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) { 955 return Evaluator<T*, T*, Op>::evaluate( NULL, rhs ); 956 } 957 template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) { 958 return Evaluator<T*, T*, Op>::evaluate( lhs, NULL ); 959 } 960#endif // CATCH_CONFIG_CPP11_NULLPTR 961 962} // end of namespace Internal 963} // end of namespace Catch 964 965#ifdef _MSC_VER 966#pragma warning(pop) 967#endif 968 969// #included from: catch_tostring.h 970#define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED 971 972// #included from: catch_sfinae.hpp 973#define TWOBLUECUBES_CATCH_SFINAE_HPP_INCLUDED 974 975// Try to detect if the current compiler supports SFINAE 976 977namespace Catch { 978 979 struct TrueType { 980 static const bool value = true; 981 typedef void Enable; 982 char sizer[1]; 983 }; 984 struct FalseType { 985 static const bool value = false; 986 typedef void Disable; 987 char sizer[2]; 988 }; 989 990#ifdef CATCH_CONFIG_SFINAE 991 992 template<bool> struct NotABooleanExpression; 993 994 template<bool c> struct If : NotABooleanExpression<c> {}; 995 template<> struct If<true> : TrueType {}; 996 template<> struct If<false> : FalseType {}; 997 998 template<int size> struct SizedIf; 999 template<> struct SizedIf<sizeof(TrueType)> : TrueType {}; 1000 template<> struct SizedIf<sizeof(FalseType)> : FalseType {}; 1001 1002#endif // CATCH_CONFIG_SFINAE 1003 1004} // end namespace Catch 1005 1006#include <sstream> 1007#include <iomanip> 1008#include <limits> 1009#include <vector> 1010#include <cstddef> 1011 1012#ifdef __OBJC__ 1013// #included from: catch_objc_arc.hpp 1014#define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED 1015 1016#import <Foundation/Foundation.h> 1017 1018#ifdef __has_feature 1019#define CATCH_ARC_ENABLED __has_feature(objc_arc) 1020#else 1021#define CATCH_ARC_ENABLED 0 1022#endif 1023 1024void arcSafeRelease( NSObject* obj ); 1025id performOptionalSelector( id obj, SEL sel ); 1026 1027#if !CATCH_ARC_ENABLED 1028inline void arcSafeRelease( NSObject* obj ) { 1029 [obj release]; 1030} 1031inline id performOptionalSelector( id obj, SEL sel ) { 1032 if( [obj respondsToSelector: sel] ) 1033 return [obj performSelector: sel]; 1034 return nil; 1035} 1036#define CATCH_UNSAFE_UNRETAINED 1037#define CATCH_ARC_STRONG 1038#else 1039inline void arcSafeRelease( NSObject* ){} 1040inline id performOptionalSelector( id obj, SEL sel ) { 1041#ifdef __clang__ 1042#pragma clang diagnostic push 1043#pragma clang diagnostic ignored "-Warc-performSelector-leaks" 1044#endif 1045 if( [obj respondsToSelector: sel] ) 1046 return [obj performSelector: sel]; 1047#ifdef __clang__ 1048#pragma clang diagnostic pop 1049#endif 1050 return nil; 1051} 1052#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained 1053#define CATCH_ARC_STRONG __strong 1054#endif 1055 1056#endif 1057 1058#ifdef CATCH_CPP11_OR_GREATER 1059#include <tuple> 1060#include <type_traits> 1061#endif 1062 1063namespace Catch { 1064 1065// Why we're here. 1066template<typename T> 1067std::string toString( T const& value ); 1068 1069// Built in overloads 1070 1071std::string toString( std::string const& value ); 1072std::string toString( std::wstring const& value ); 1073std::string toString( const char* const value ); 1074std::string toString( char* const value ); 1075std::string toString( const wchar_t* const value ); 1076std::string toString( wchar_t* const value ); 1077std::string toString( int value ); 1078std::string toString( unsigned long value ); 1079std::string toString( unsigned int value ); 1080std::string toString( const double value ); 1081std::string toString( const float value ); 1082std::string toString( bool value ); 1083std::string toString( char value ); 1084std::string toString( signed char value ); 1085std::string toString( unsigned char value ); 1086 1087#ifdef CATCH_CONFIG_CPP11_NULLPTR 1088std::string toString( std::nullptr_t ); 1089#endif 1090 1091#ifdef __OBJC__ 1092 std::string toString( NSString const * const& nsstring ); 1093 std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ); 1094 std::string toString( NSObject* const& nsObject ); 1095#endif 1096 1097namespace Detail { 1098 1099 extern std::string unprintableString; 1100 1101// SFINAE is currently disabled by default for all compilers. 1102// If the non SFINAE version of IsStreamInsertable is ambiguous for you 1103// and your compiler supports SFINAE, try #defining CATCH_CONFIG_SFINAE 1104#ifdef CATCH_CONFIG_SFINAE 1105 1106 template<typename T> 1107 class IsStreamInsertableHelper { 1108 template<int N> struct TrueIfSizeable : TrueType {}; 1109 1110 template<typename T2> 1111 static TrueIfSizeable<sizeof((*(std::ostream*)0) << *((T2 const*)0))> dummy(T2*); 1112 static FalseType dummy(...); 1113 1114 public: 1115 typedef SizedIf<sizeof(dummy((T*)0))> type; 1116 }; 1117 1118 template<typename T> 1119 struct IsStreamInsertable : IsStreamInsertableHelper<T>::type {}; 1120 1121#else 1122 1123 struct BorgType { 1124 template<typename T> BorgType( T const& ); 1125 }; 1126 1127 TrueType& testStreamable( std::ostream& ); 1128 FalseType testStreamable( FalseType ); 1129 1130 FalseType operator<<( std::ostream const&, BorgType const& ); 1131 1132 template<typename T> 1133 struct IsStreamInsertable { 1134 static std::ostream &s; 1135 static T const&t; 1136 enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) }; 1137 }; 1138 1139#endif 1140 1141#if defined(CATCH_CPP11_OR_GREATER) 1142 template<typename T, 1143 bool IsEnum = std::is_enum<T>::value 1144 > 1145 struct EnumStringMaker 1146 { 1147 static std::string convert( T const& ) { return unprintableString; } 1148 }; 1149 1150 template<typename T> 1151 struct EnumStringMaker<T,true> 1152 { 1153 static std::string convert( T const& v ) 1154 { 1155 return ::Catch::toString( 1156 static_cast<typename std::underlying_type<T>::type>(v) 1157 ); 1158 } 1159 }; 1160#endif 1161 template<bool C> 1162 struct StringMakerBase { 1163#if defined(CATCH_CPP11_OR_GREATER) 1164 template<typename T> 1165 static std::string convert( T const& v ) 1166 { 1167 return EnumStringMaker<T>::convert( v ); 1168 } 1169#else 1170 template<typename T> 1171 static std::string convert( T const& ) { return unprintableString; } 1172#endif 1173 }; 1174 1175 template<> 1176 struct StringMakerBase<true> { 1177 template<typename T> 1178 static std::string convert( T const& _value ) { 1179 std::ostringstream oss; 1180 oss << _value; 1181 return oss.str(); 1182 } 1183 }; 1184 1185 std::string rawMemoryToString( const void *object, std::size_t size ); 1186 1187 template<typename T> 1188 inline std::string rawMemoryToString( const T& object ) { 1189 return rawMemoryToString( &object, sizeof(object) ); 1190 } 1191 1192} // end namespace Detail 1193 1194template<typename T> 1195struct StringMaker : 1196 Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {}; 1197 1198template<typename T> 1199struct StringMaker<T*> { 1200 template<typename U> 1201 static std::string convert( U* p ) { 1202 if( !p ) 1203 return INTERNAL_CATCH_STRINGIFY( NULL ); 1204 else 1205 return Detail::rawMemoryToString( p ); 1206 } 1207}; 1208 1209template<typename R, typename C> 1210struct StringMaker<R C::*> { 1211 static std::string convert( R C::* p ) { 1212 if( !p ) 1213 return INTERNAL_CATCH_STRINGIFY( NULL ); 1214 else 1215 return Detail::rawMemoryToString( p ); 1216 } 1217}; 1218 1219namespace Detail { 1220 template<typename InputIterator> 1221 std::string rangeToString( InputIterator first, InputIterator last ); 1222} 1223 1224//template<typename T, typename Allocator> 1225//struct StringMaker<std::vector<T, Allocator> > { 1226// static std::string convert( std::vector<T,Allocator> const& v ) { 1227// return Detail::rangeToString( v.begin(), v.end() ); 1228// } 1229//}; 1230 1231template<typename T, typename Allocator> 1232std::string toString( std::vector<T,Allocator> const& v ) { 1233 return Detail::rangeToString( v.begin(), v.end() ); 1234} 1235 1236#ifdef CATCH_CPP11_OR_GREATER 1237 1238// toString for tuples 1239namespace TupleDetail { 1240 template< 1241 typename Tuple, 1242 std::size_t N = 0, 1243 bool = (N < std::tuple_size<Tuple>::value) 1244 > 1245 struct ElementPrinter { 1246 static void print( const Tuple& tuple, std::ostream& os ) 1247 { 1248 os << ( N ? ", " : " " ) 1249 << Catch::toString(std::get<N>(tuple)); 1250 ElementPrinter<Tuple,N+1>::print(tuple,os); 1251 } 1252 }; 1253 1254 template< 1255 typename Tuple, 1256 std::size_t N 1257 > 1258 struct ElementPrinter<Tuple,N,false> { 1259 static void print( const Tuple&, std::ostream& ) {} 1260 }; 1261 1262} 1263 1264template<typename ...Types> 1265struct StringMaker<std::tuple<Types...>> { 1266 1267 static std::string convert( const std::tuple<Types...>& tuple ) 1268 { 1269 std::ostringstream os; 1270 os << '{'; 1271 TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os ); 1272 os << " }"; 1273 return os.str(); 1274 } 1275}; 1276#endif 1277 1278namespace Detail { 1279 template<typename T> 1280 std::string makeString( T const& value ) { 1281 return StringMaker<T>::convert( value ); 1282 } 1283} // end namespace Detail 1284 1285/// \brief converts any type to a string 1286/// 1287/// The default template forwards on to ostringstream - except when an 1288/// ostringstream overload does not exist - in which case it attempts to detect 1289/// that and writes {?}. 1290/// Overload (not specialise) this template for custom typs that you don't want 1291/// to provide an ostream overload for. 1292template<typename T> 1293std::string toString( T const& value ) { 1294 return StringMaker<T>::convert( value ); 1295} 1296 1297 namespace Detail { 1298 template<typename InputIterator> 1299 std::string rangeToString( InputIterator first, InputIterator last ) { 1300 std::ostringstream oss; 1301 oss << "{ "; 1302 if( first != last ) { 1303 oss << Catch::toString( *first ); 1304 for( ++first ; first != last ; ++first ) 1305 oss << ", " << Catch::toString( *first ); 1306 } 1307 oss << " }"; 1308 return oss.str(); 1309 } 1310} 1311 1312} // end namespace Catch 1313 1314namespace Catch { 1315 1316// Wraps the LHS of an expression and captures the operator and RHS (if any) - 1317// wrapping them all in a ResultBuilder object 1318template<typename T> 1319class ExpressionLhs { 1320 ExpressionLhs& operator = ( ExpressionLhs const& ); 1321# ifdef CATCH_CPP11_OR_GREATER 1322 ExpressionLhs& operator = ( ExpressionLhs && ) = delete; 1323# endif 1324 1325public: 1326 ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {} 1327# ifdef CATCH_CPP11_OR_GREATER 1328 ExpressionLhs( ExpressionLhs const& ) = default; 1329 ExpressionLhs( ExpressionLhs && ) = default; 1330# endif 1331 1332 template<typename RhsT> 1333 ResultBuilder& operator == ( RhsT const& rhs ) { 1334 return captureExpression<Internal::IsEqualTo>( rhs ); 1335 } 1336 1337 template<typename RhsT> 1338 ResultBuilder& operator != ( RhsT const& rhs ) { 1339 return captureExpression<Internal::IsNotEqualTo>( rhs ); 1340 } 1341 1342 template<typename RhsT> 1343 ResultBuilder& operator < ( RhsT const& rhs ) { 1344 return captureExpression<Internal::IsLessThan>( rhs ); 1345 } 1346 1347 template<typename RhsT> 1348 ResultBuilder& operator > ( RhsT const& rhs ) { 1349 return captureExpression<Internal::IsGreaterThan>( rhs ); 1350 } 1351 1352 template<typename RhsT> 1353 ResultBuilder& operator <= ( RhsT const& rhs ) { 1354 return captureExpression<Internal::IsLessThanOrEqualTo>( rhs ); 1355 } 1356 1357 template<typename RhsT> 1358 ResultBuilder& operator >= ( RhsT const& rhs ) { 1359 return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs ); 1360 } 1361 1362 ResultBuilder& operator == ( bool rhs ) { 1363 return captureExpression<Internal::IsEqualTo>( rhs ); 1364 } 1365 1366 ResultBuilder& operator != ( bool rhs ) { 1367 return captureExpression<Internal::IsNotEqualTo>( rhs ); 1368 } 1369 1370 void endExpression() { 1371 bool value = m_lhs ? true : false; 1372 m_rb 1373 .setLhs( Catch::toString( value ) ) 1374 .setResultType( value ) 1375 .endExpression(); 1376 } 1377 1378 // Only simple binary expressions are allowed on the LHS. 1379 // If more complex compositions are required then place the sub expression in parentheses 1380 template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& ); 1381 template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& ); 1382 template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& ); 1383 template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& ); 1384 template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& ); 1385 template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& ); 1386 1387private: 1388 template<Internal::Operator Op, typename RhsT> 1389 ResultBuilder& captureExpression( RhsT const& rhs ) { 1390 return m_rb 1391 .setResultType( Internal::compare<Op>( m_lhs, rhs ) ) 1392 .setLhs( Catch::toString( m_lhs ) ) 1393 .setRhs( Catch::toString( rhs ) ) 1394 .setOp( Internal::OperatorTraits<Op>::getName() ); 1395 } 1396 1397private: 1398 ResultBuilder& m_rb; 1399 T m_lhs; 1400}; 1401 1402} // end namespace Catch 1403 1404 1405namespace Catch { 1406 1407 template<typename T> 1408 inline ExpressionLhs<T const&> ResultBuilder::operator->* ( T const& operand ) { 1409 return ExpressionLhs<T const&>( *this, operand ); 1410 } 1411 1412 inline ExpressionLhs<bool> ResultBuilder::operator->* ( bool value ) { 1413 return ExpressionLhs<bool>( *this, value ); 1414 } 1415 1416} // namespace Catch 1417 1418// #included from: catch_message.h 1419#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED 1420 1421#include <string> 1422 1423namespace Catch { 1424 1425 struct MessageInfo { 1426 MessageInfo( std::string const& _macroName, 1427 SourceLineInfo const& _lineInfo, 1428 ResultWas::OfType _type ); 1429 1430 std::string macroName; 1431 SourceLineInfo lineInfo; 1432 ResultWas::OfType type; 1433 std::string message; 1434 unsigned int sequence; 1435 1436 bool operator == ( MessageInfo const& other ) const { 1437 return sequence == other.sequence; 1438 } 1439 bool operator < ( MessageInfo const& other ) const { 1440 return sequence < other.sequence; 1441 } 1442 private: 1443 static unsigned int globalCount; 1444 }; 1445 1446 struct MessageBuilder { 1447 MessageBuilder( std::string const& macroName, 1448 SourceLineInfo const& lineInfo, 1449 ResultWas::OfType type ) 1450 : m_info( macroName, lineInfo, type ) 1451 {} 1452 1453 template<typename T> 1454 MessageBuilder& operator << ( T const& value ) { 1455 m_stream << value; 1456 return *this; 1457 } 1458 1459 MessageInfo m_info; 1460 std::ostringstream m_stream; 1461 }; 1462 1463 class ScopedMessage { 1464 public: 1465 ScopedMessage( MessageBuilder const& builder ); 1466 ScopedMessage( ScopedMessage const& other ); 1467 ~ScopedMessage(); 1468 1469 MessageInfo m_info; 1470 }; 1471 1472} // end namespace Catch 1473 1474// #included from: catch_interfaces_capture.h 1475#define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED 1476 1477#include <string> 1478 1479namespace Catch { 1480 1481 class TestCase; 1482 class AssertionResult; 1483 struct AssertionInfo; 1484 struct SectionInfo; 1485 struct MessageInfo; 1486 class ScopedMessageBuilder; 1487 struct Counts; 1488 1489 struct IResultCapture { 1490 1491 virtual ~IResultCapture(); 1492 1493 virtual void assertionEnded( AssertionResult const& result ) = 0; 1494 virtual bool sectionStarted( SectionInfo const& sectionInfo, 1495 Counts& assertions ) = 0; 1496 virtual void sectionEnded( SectionInfo const& name, Counts const& assertions, double _durationInSeconds ) = 0; 1497 virtual void pushScopedMessage( MessageInfo const& message ) = 0; 1498 virtual void popScopedMessage( MessageInfo const& message ) = 0; 1499 1500 virtual std::string getCurrentTestName() const = 0; 1501 virtual const AssertionResult* getLastResult() const = 0; 1502 1503 virtual void handleFatalErrorCondition( std::string const& message ) = 0; 1504 }; 1505 1506 IResultCapture& getResultCapture(); 1507} 1508 1509// #included from: catch_debugger.h 1510#define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED 1511 1512// #included from: catch_platform.h 1513#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED 1514 1515#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) 1516#define CATCH_PLATFORM_MAC 1517#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) 1518#define CATCH_PLATFORM_IPHONE 1519#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) 1520#define CATCH_PLATFORM_WINDOWS 1521#endif 1522 1523#include <string> 1524 1525namespace Catch{ 1526 1527 bool isDebuggerActive(); 1528 void writeToDebugConsole( std::string const& text ); 1529} 1530 1531#ifdef CATCH_PLATFORM_MAC 1532 1533 // The following code snippet based on: 1534 // http://cocoawithlove.com/2008/03/break-into-debugger.html 1535 #ifdef DEBUG 1536 #if defined(__ppc64__) || defined(__ppc__) 1537 #define CATCH_BREAK_INTO_DEBUGGER() \ 1538 if( Catch::isDebuggerActive() ) { \ 1539 __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \ 1540 : : : "memory","r0","r3","r4" ); \ 1541 } 1542 #else 1543 #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );} 1544 #endif 1545 #endif 1546 1547#elif defined(_MSC_VER) 1548 #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); } 1549#elif defined(__MINGW32__) 1550 extern "C" __declspec(dllimport) void __stdcall DebugBreak(); 1551 #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); } 1552#endif 1553 1554#ifndef CATCH_BREAK_INTO_DEBUGGER 1555#define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue(); 1556#endif 1557 1558// #included from: catch_interfaces_runner.h 1559#define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED 1560 1561namespace Catch { 1562 class TestCase; 1563 1564 struct IRunner { 1565 virtual ~IRunner(); 1566 virtual bool aborting() const = 0; 1567 }; 1568} 1569 1570/////////////////////////////////////////////////////////////////////////////// 1571// In the event of a failure works out if the debugger needs to be invoked 1572// and/or an exception thrown and takes appropriate action. 1573// This needs to be done as a macro so the debugger will stop in the user 1574// source code rather than in Catch library code 1575#define INTERNAL_CATCH_REACT( resultBuilder ) \ 1576 if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \ 1577 resultBuilder.react(); 1578 1579/////////////////////////////////////////////////////////////////////////////// 1580#define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \ 1581 do { \ 1582 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ 1583 try { \ 1584 ( __catchResult->*expr ).endExpression(); \ 1585 } \ 1586 catch( ... ) { \ 1587 __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \ 1588 } \ 1589 INTERNAL_CATCH_REACT( __catchResult ) \ 1590 } while( Catch::isTrue( false && (expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look 1591 1592/////////////////////////////////////////////////////////////////////////////// 1593#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \ 1594 INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \ 1595 if( Catch::getResultCapture().getLastResult()->succeeded() ) 1596 1597/////////////////////////////////////////////////////////////////////////////// 1598#define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \ 1599 INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \ 1600 if( !Catch::getResultCapture().getLastResult()->succeeded() ) 1601 1602/////////////////////////////////////////////////////////////////////////////// 1603#define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \ 1604 do { \ 1605 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ 1606 try { \ 1607 expr; \ 1608 __catchResult.captureResult( Catch::ResultWas::Ok ); \ 1609 } \ 1610 catch( ... ) { \ 1611 __catchResult.useActiveException( resultDisposition ); \ 1612 } \ 1613 INTERNAL_CATCH_REACT( __catchResult ) \ 1614 } while( Catch::alwaysFalse() ) 1615 1616/////////////////////////////////////////////////////////////////////////////// 1617#define INTERNAL_CATCH_THROWS( expr, resultDisposition, macroName ) \ 1618 do { \ 1619 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ 1620 if( __catchResult.allowThrows() ) \ 1621 try { \ 1622 expr; \ 1623 __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ 1624 } \ 1625 catch( ... ) { \ 1626 __catchResult.captureResult( Catch::ResultWas::Ok ); \ 1627 } \ 1628 else \ 1629 __catchResult.captureResult( Catch::ResultWas::Ok ); \ 1630 INTERNAL_CATCH_REACT( __catchResult ) \ 1631 } while( Catch::alwaysFalse() ) 1632 1633/////////////////////////////////////////////////////////////////////////////// 1634#define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \ 1635 do { \ 1636 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ 1637 if( __catchResult.allowThrows() ) \ 1638 try { \ 1639 expr; \ 1640 __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ 1641 } \ 1642 catch( exceptionType ) { \ 1643 __catchResult.captureResult( Catch::ResultWas::Ok ); \ 1644 } \ 1645 catch( ... ) { \ 1646 __catchResult.useActiveException( resultDisposition ); \ 1647 } \ 1648 else \ 1649 __catchResult.captureResult( Catch::ResultWas::Ok ); \ 1650 INTERNAL_CATCH_REACT( __catchResult ) \ 1651 } while( Catch::alwaysFalse() ) 1652 1653/////////////////////////////////////////////////////////////////////////////// 1654#ifdef CATCH_CONFIG_VARIADIC_MACROS 1655 #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \ 1656 do { \ 1657 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ 1658 __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \ 1659 __catchResult.captureResult( messageType ); \ 1660 INTERNAL_CATCH_REACT( __catchResult ) \ 1661 } while( Catch::alwaysFalse() ) 1662#else 1663 #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \ 1664 do { \ 1665 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ 1666 __catchResult << log + ::Catch::StreamEndStop(); \ 1667 __catchResult.captureResult( messageType ); \ 1668 INTERNAL_CATCH_REACT( __catchResult ) \ 1669 } while( Catch::alwaysFalse() ) 1670#endif 1671 1672/////////////////////////////////////////////////////////////////////////////// 1673#define INTERNAL_CATCH_INFO( log, macroName ) \ 1674 Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log; 1675 1676/////////////////////////////////////////////////////////////////////////////// 1677#define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \ 1678 do { \ 1679 Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg " " #matcher, resultDisposition ); \ 1680 try { \ 1681 std::string matcherAsString = ::Catch::Matchers::matcher.toString(); \ 1682 __catchResult \ 1683 .setLhs( Catch::toString( arg ) ) \ 1684 .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \ 1685 .setOp( "matches" ) \ 1686 .setResultType( ::Catch::Matchers::matcher.match( arg ) ); \ 1687 __catchResult.captureExpression(); \ 1688 } catch( ... ) { \ 1689 __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \ 1690 } \ 1691 INTERNAL_CATCH_REACT( __catchResult ) \ 1692 } while( Catch::alwaysFalse() ) 1693 1694// #included from: internal/catch_section.h 1695#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED 1696 1697// #included from: catch_section_info.h 1698#define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED 1699 1700namespace Catch { 1701 1702 struct SectionInfo { 1703 SectionInfo 1704 ( SourceLineInfo const& _lineInfo, 1705 std::string const& _name, 1706 std::string const& _description = std::string() ); 1707 1708 std::string name; 1709 std::string description; 1710 SourceLineInfo lineInfo; 1711 }; 1712 1713} // end namespace Catch 1714 1715// #included from: catch_totals.hpp 1716#define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED 1717 1718#include <cstddef> 1719 1720namespace Catch { 1721 1722 struct Counts { 1723 Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {} 1724 1725 Counts operator - ( Counts const& other ) const { 1726 Counts diff; 1727 diff.passed = passed - other.passed; 1728 diff.failed = failed - other.failed; 1729 diff.failedButOk = failedButOk - other.failedButOk; 1730 return diff; 1731 } 1732 Counts& operator += ( Counts const& other ) { 1733 passed += other.passed; 1734 failed += other.failed; 1735 failedButOk += other.failedButOk; 1736 return *this; 1737 } 1738 1739 std::size_t total() const { 1740 return passed + failed + failedButOk; 1741 } 1742 bool allPassed() const { 1743 return failed == 0 && failedButOk == 0; 1744 } 1745 bool allOk() const { 1746 return failed == 0; 1747 } 1748 1749 std::size_t passed; 1750 std::size_t failed; 1751 std::size_t failedButOk; 1752 }; 1753 1754 struct Totals { 1755 1756 Totals operator - ( Totals const& other ) const { 1757 Totals diff; 1758 diff.assertions = assertions - other.assertions; 1759 diff.testCases = testCases - other.testCases; 1760 return diff; 1761 } 1762 1763 Totals delta( Totals const& prevTotals ) const { 1764 Totals diff = *this - prevTotals; 1765 if( diff.assertions.failed > 0 ) 1766 ++diff.testCases.failed; 1767 else if( diff.assertions.failedButOk > 0 ) 1768 ++diff.testCases.failedButOk; 1769 else 1770 ++diff.testCases.passed; 1771 return diff; 1772 } 1773 1774 Totals& operator += ( Totals const& other ) { 1775 assertions += other.assertions; 1776 testCases += other.testCases; 1777 return *this; 1778 } 1779 1780 Counts assertions; 1781 Counts testCases; 1782 }; 1783} 1784 1785// #included from: catch_timer.h 1786#define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED 1787 1788#ifdef CATCH_PLATFORM_WINDOWS 1789typedef unsigned long long uint64_t; 1790#else 1791#include <stdint.h> 1792#endif 1793 1794namespace Catch { 1795 1796 class Timer { 1797 public: 1798 Timer() : m_ticks( 0 ) {} 1799 void start(); 1800 unsigned int getElapsedMicroseconds() const; 1801 unsigned int getElapsedMilliseconds() const; 1802 double getElapsedSeconds() const; 1803 1804 private: 1805 uint64_t m_ticks; 1806 }; 1807 1808} // namespace Catch 1809 1810#include <string> 1811 1812namespace Catch { 1813 1814 class Section : NonCopyable { 1815 public: 1816 Section( SectionInfo const& info ); 1817 ~Section(); 1818 1819 // This indicates whether the section should be executed or not 1820 operator bool() const; 1821 1822 private: 1823 SectionInfo m_info; 1824 1825 std::string m_name; 1826 Counts m_assertions; 1827 bool m_sectionIncluded; 1828 Timer m_timer; 1829 }; 1830 1831} // end namespace Catch 1832 1833#ifdef CATCH_CONFIG_VARIADIC_MACROS 1834 #define INTERNAL_CATCH_SECTION( ... ) \ 1835 if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) 1836#else 1837 #define INTERNAL_CATCH_SECTION( name, desc ) \ 1838 if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) ) 1839#endif 1840 1841// #included from: internal/catch_generators.hpp 1842#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED 1843 1844#include <iterator> 1845#include <vector> 1846#include <string> 1847#include <stdlib.h> 1848 1849namespace Catch { 1850 1851template<typename T> 1852struct IGenerator { 1853 virtual ~IGenerator() {} 1854 virtual T getValue( std::size_t index ) const = 0; 1855 virtual std::size_t size () const = 0; 1856}; 1857 1858template<typename T> 1859class BetweenGenerator : public IGenerator<T> { 1860public: 1861 BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){} 1862 1863 virtual T getValue( std::size_t index ) const { 1864 return m_from+static_cast<int>( index ); 1865 } 1866 1867 virtual std::size_t size() const { 1868 return static_cast<std::size_t>( 1+m_to-m_from ); 1869 } 1870 1871private: 1872 1873 T m_from; 1874 T m_to; 1875}; 1876 1877template<typename T> 1878class ValuesGenerator : public IGenerator<T> { 1879public: 1880 ValuesGenerator(){} 1881 1882 void add( T value ) { 1883 m_values.push_back( value ); 1884 } 1885 1886 virtual T getValue( std::size_t index ) const { 1887 return m_values[index]; 1888 } 1889 1890 virtual std::size_t size() const { 1891 return m_values.size(); 1892 } 1893 1894private: 1895 std::vector<T> m_values; 1896}; 1897 1898template<typename T> 1899class CompositeGenerator { 1900public: 1901 CompositeGenerator() : m_totalSize( 0 ) {} 1902 1903 // *** Move semantics, similar to auto_ptr *** 1904 CompositeGenerator( CompositeGenerator& other ) 1905 : m_fileInfo( other.m_fileInfo ), 1906 m_totalSize( 0 ) 1907 { 1908 move( other ); 1909 } 1910 1911 CompositeGenerator& setFileInfo( const char* fileInfo ) { 1912 m_fileInfo = fileInfo; 1913 return *this; 1914 } 1915 1916 ~CompositeGenerator() { 1917 deleteAll( m_composed ); 1918 } 1919 1920 operator T () const { 1921 size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize ); 1922 1923 typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin(); 1924 typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end(); 1925 for( size_t index = 0; it != itEnd; ++it ) 1926 { 1927 const IGenerator<T>* generator = *it; 1928 if( overallIndex >= index && overallIndex < index + generator->size() ) 1929 { 1930 return generator->getValue( overallIndex-index ); 1931 } 1932 index += generator->size(); 1933 } 1934 CATCH_INTERNAL_ERROR( "Indexed past end of generated range" ); 1935 return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so 1936 } 1937 1938 void add( const IGenerator<T>* generator ) { 1939 m_totalSize += generator->size(); 1940 m_composed.push_back( generator ); 1941 } 1942 1943 CompositeGenerator& then( CompositeGenerator& other ) { 1944 move( other ); 1945 return *this; 1946 } 1947 1948 CompositeGenerator& then( T value ) { 1949 ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>(); 1950 valuesGen->add( value ); 1951 add( valuesGen ); 1952 return *this; 1953 } 1954 1955private: 1956 1957 void move( CompositeGenerator& other ) { 1958 std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) ); 1959 m_totalSize += other.m_totalSize; 1960 other.m_composed.clear(); 1961 } 1962 1963 std::vector<const IGenerator<T>*> m_composed; 1964 std::string m_fileInfo; 1965 size_t m_totalSize; 1966}; 1967 1968namespace Generators 1969{ 1970 template<typename T> 1971 CompositeGenerator<T> between( T from, T to ) { 1972 CompositeGenerator<T> generators; 1973 generators.add( new BetweenGenerator<T>( from, to ) ); 1974 return generators; 1975 } 1976 1977 template<typename T> 1978 CompositeGenerator<T> values( T val1, T val2 ) { 1979 CompositeGenerator<T> generators; 1980 ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>(); 1981 valuesGen->add( val1 ); 1982 valuesGen->add( val2 ); 1983 generators.add( valuesGen ); 1984 return generators; 1985 } 1986 1987 template<typename T> 1988 CompositeGenerator<T> values( T val1, T val2, T val3 ){ 1989 CompositeGenerator<T> generators; 1990 ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>(); 1991 valuesGen->add( val1 ); 1992 valuesGen->add( val2 ); 1993 valuesGen->add( val3 ); 1994 generators.add( valuesGen ); 1995 return generators; 1996 } 1997 1998 template<typename T> 1999 CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) { 2000 CompositeGenerator<T> generators; 2001 ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>(); 2002 valuesGen->add( val1 ); 2003 valuesGen->add( val2 ); 2004 valuesGen->add( val3 ); 2005 valuesGen->add( val4 ); 2006 generators.add( valuesGen ); 2007 return generators; 2008 } 2009 2010} // end namespace Generators 2011 2012using namespace Generators; 2013 2014} // end namespace Catch 2015 2016#define INTERNAL_CATCH_LINESTR2( line ) #line 2017#define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line ) 2018 2019#define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" ) 2020 2021// #included from: internal/catch_interfaces_exception.h 2022#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED 2023 2024#include <string> 2025// #included from: catch_interfaces_registry_hub.h 2026#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED 2027 2028#include <string> 2029 2030namespace Catch { 2031 2032 class TestCase; 2033 struct ITestCaseRegistry; 2034 struct IExceptionTranslatorRegistry; 2035 struct IExceptionTranslator; 2036 struct IReporterRegistry; 2037 struct IReporterFactory; 2038 2039 struct IRegistryHub { 2040 virtual ~IRegistryHub(); 2041 2042 virtual IReporterRegistry const& getReporterRegistry() const = 0; 2043 virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0; 2044 virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0; 2045 }; 2046 2047 struct IMutableRegistryHub { 2048 virtual ~IMutableRegistryHub(); 2049 virtual void registerReporter( std::string const& name, IReporterFactory* factory ) = 0; 2050 virtual void registerTest( TestCase const& testInfo ) = 0; 2051 virtual void registerTranslator( const IExceptionTranslator* translator ) = 0; 2052 }; 2053 2054 IRegistryHub& getRegistryHub(); 2055 IMutableRegistryHub& getMutableRegistryHub(); 2056 void cleanUp(); 2057 std::string translateActiveException(); 2058 2059} 2060 2061 2062namespace Catch { 2063 2064 typedef std::string(*exceptionTranslateFunction)(); 2065 2066 struct IExceptionTranslator { 2067 virtual ~IExceptionTranslator(); 2068 virtual std::string translate() const = 0; 2069 }; 2070 2071 struct IExceptionTranslatorRegistry { 2072 virtual ~IExceptionTranslatorRegistry(); 2073 2074 virtual std::string translateActiveException() const = 0; 2075 }; 2076 2077 class ExceptionTranslatorRegistrar { 2078 template<typename T> 2079 class ExceptionTranslator : public IExceptionTranslator { 2080 public: 2081 2082 ExceptionTranslator( std::string(*translateFunction)( T& ) ) 2083 : m_translateFunction( translateFunction ) 2084 {} 2085 2086 virtual std::string translate() const { 2087 try { 2088 throw; 2089 } 2090 catch( T& ex ) { 2091 return m_translateFunction( ex ); 2092 } 2093 } 2094 2095 protected: 2096 std::string(*m_translateFunction)( T& ); 2097 }; 2098 2099 public: 2100 template<typename T> 2101 ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) { 2102 getMutableRegistryHub().registerTranslator 2103 ( new ExceptionTranslator<T>( translateFunction ) ); 2104 } 2105 }; 2106} 2107 2108/////////////////////////////////////////////////////////////////////////////// 2109#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) \ 2110 static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ); \ 2111 namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ) ); }\ 2112 static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ) 2113 2114// #included from: internal/catch_approx.hpp 2115#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED 2116 2117#include <cmath> 2118#include <limits> 2119 2120namespace Catch { 2121namespace Detail { 2122 2123 class Approx { 2124 public: 2125 explicit Approx ( double value ) 2126 : m_epsilon( std::numeric_limits<float>::epsilon()*100 ), 2127 m_scale( 1.0 ), 2128 m_value( value ) 2129 {} 2130 2131 Approx( Approx const& other ) 2132 : m_epsilon( other.m_epsilon ), 2133 m_scale( other.m_scale ), 2134 m_value( other.m_value ) 2135 {} 2136 2137 static Approx custom() { 2138 return Approx( 0 ); 2139 } 2140 2141 Approx operator()( double value ) { 2142 Approx approx( value ); 2143 approx.epsilon( m_epsilon ); 2144 approx.scale( m_scale ); 2145 return approx; 2146 } 2147 2148 friend bool operator == ( double lhs, Approx const& rhs ) { 2149 // Thanks to Richard Harris for his help refining this formula 2150 return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) ); 2151 } 2152 2153 friend bool operator == ( Approx const& lhs, double rhs ) { 2154 return operator==( rhs, lhs ); 2155 } 2156 2157 friend bool operator != ( double lhs, Approx const& rhs ) { 2158 return !operator==( lhs, rhs ); 2159 } 2160 2161 friend bool operator != ( Approx const& lhs, double rhs ) { 2162 return !operator==( rhs, lhs ); 2163 } 2164 2165 Approx& epsilon( double newEpsilon ) { 2166 m_epsilon = newEpsilon; 2167 return *this; 2168 } 2169 2170 Approx& scale( double newScale ) { 2171 m_scale = newScale; 2172 return *this; 2173 } 2174 2175 std::string toString() const { 2176 std::ostringstream oss; 2177 oss << "Approx( " << Catch::toString( m_value ) << " )"; 2178 return oss.str(); 2179 } 2180 2181 private: 2182 double m_epsilon; 2183 double m_scale; 2184 double m_value; 2185 }; 2186} 2187 2188template<> 2189inline std::string toString<Detail::Approx>( Detail::Approx const& value ) { 2190 return value.toString(); 2191} 2192 2193} // end namespace Catch 2194 2195// #included from: internal/catch_matchers.hpp 2196#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED 2197 2198namespace Catch { 2199namespace Matchers { 2200 namespace Impl { 2201 2202 template<typename ExpressionT> 2203 struct Matcher : SharedImpl<IShared> 2204 { 2205 typedef ExpressionT ExpressionType; 2206 2207 virtual ~Matcher() {} 2208 virtual Ptr<Matcher> clone() const = 0; 2209 virtual bool match( ExpressionT const& expr ) const = 0; 2210 virtual std::string toString() const = 0; 2211 }; 2212 2213 template<typename DerivedT, typename ExpressionT> 2214 struct MatcherImpl : Matcher<ExpressionT> { 2215 2216 virtual Ptr<Matcher<ExpressionT> > clone() const { 2217 return Ptr<Matcher<ExpressionT> >( new DerivedT( static_cast<DerivedT const&>( *this ) ) ); 2218 } 2219 }; 2220 2221 namespace Generic { 2222 2223 template<typename ExpressionT> 2224 class AllOf : public MatcherImpl<AllOf<ExpressionT>, ExpressionT> { 2225 public: 2226 2227 AllOf() {} 2228 AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {} 2229 2230 AllOf& add( Matcher<ExpressionT> const& matcher ) { 2231 m_matchers.push_back( matcher.clone() ); 2232 return *this; 2233 } 2234 virtual bool match( ExpressionT const& expr ) const 2235 { 2236 for( std::size_t i = 0; i < m_matchers.size(); ++i ) 2237 if( !m_matchers[i]->match( expr ) ) 2238 return false; 2239 return true; 2240 } 2241 virtual std::string toString() const { 2242 std::ostringstream oss; 2243 oss << "( "; 2244 for( std::size_t i = 0; i < m_matchers.size(); ++i ) { 2245 if( i != 0 ) 2246 oss << " and "; 2247 oss << m_matchers[i]->toString(); 2248 } 2249 oss << " )"; 2250 return oss.str(); 2251 } 2252 2253 private: 2254 std::vector<Ptr<Matcher<ExpressionT> > > m_matchers; 2255 }; 2256 2257 template<typename ExpressionT> 2258 class AnyOf : public MatcherImpl<AnyOf<ExpressionT>, ExpressionT> { 2259 public: 2260 2261 AnyOf() {} 2262 AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {} 2263 2264 AnyOf& add( Matcher<ExpressionT> const& matcher ) { 2265 m_matchers.push_back( matcher.clone() ); 2266 return *this; 2267 } 2268 virtual bool match( ExpressionT const& expr ) const 2269 { 2270 for( std::size_t i = 0; i < m_matchers.size(); ++i ) 2271 if( m_matchers[i]->match( expr ) ) 2272 return true; 2273 return false; 2274 } 2275 virtual std::string toString() const { 2276 std::ostringstream oss; 2277 oss << "( "; 2278 for( std::size_t i = 0; i < m_matchers.size(); ++i ) { 2279 if( i != 0 ) 2280 oss << " or "; 2281 oss << m_matchers[i]->toString(); 2282 } 2283 oss << " )"; 2284 return oss.str(); 2285 } 2286 2287 private: 2288 std::vector<Ptr<Matcher<ExpressionT> > > m_matchers; 2289 }; 2290 2291 } 2292 2293 namespace StdString { 2294 2295 inline std::string makeString( std::string const& str ) { return str; } 2296 inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); } 2297 2298 struct Equals : MatcherImpl<Equals, std::string> { 2299 Equals( std::string const& str ) : m_str( str ){} 2300 Equals( Equals const& other ) : m_str( other.m_str ){} 2301 2302 virtual ~Equals(); 2303 2304 virtual bool match( std::string const& expr ) const { 2305 return m_str == expr; 2306 } 2307 virtual std::string toString() const { 2308 return "equals: \"" + m_str + "\""; 2309 } 2310 2311 std::string m_str; 2312 }; 2313 2314 struct Contains : MatcherImpl<Contains, std::string> { 2315 Contains( std::string const& substr ) : m_substr( substr ){} 2316 Contains( Contains const& other ) : m_substr( other.m_substr ){} 2317 2318 virtual ~Contains(); 2319 2320 virtual bool match( std::string const& expr ) const { 2321 return expr.find( m_substr ) != std::string::npos; 2322 } 2323 virtual std::string toString() const { 2324 return "contains: \"" + m_substr + "\""; 2325 } 2326 2327 std::string m_substr; 2328 }; 2329 2330 struct StartsWith : MatcherImpl<StartsWith, std::string> { 2331 StartsWith( std::string const& substr ) : m_substr( substr ){} 2332 StartsWith( StartsWith const& other ) : m_substr( other.m_substr ){} 2333 2334 virtual ~StartsWith(); 2335 2336 virtual bool match( std::string const& expr ) const { 2337 return expr.find( m_substr ) == 0; 2338 } 2339 virtual std::string toString() const { 2340 return "starts with: \"" + m_substr + "\""; 2341 } 2342 2343 std::string m_substr; 2344 }; 2345 2346 struct EndsWith : MatcherImpl<EndsWith, std::string> { 2347 EndsWith( std::string const& substr ) : m_substr( substr ){} 2348 EndsWith( EndsWith const& other ) : m_substr( other.m_substr ){} 2349 2350 virtual ~EndsWith(); 2351 2352 virtual bool match( std::string const& expr ) const { 2353 return expr.find( m_substr ) == expr.size() - m_substr.size(); 2354 } 2355 virtual std::string toString() const { 2356 return "ends with: \"" + m_substr + "\""; 2357 } 2358 2359 std::string m_substr; 2360 }; 2361 } // namespace StdString 2362 } // namespace Impl 2363 2364 // The following functions create the actual matcher objects. 2365 // This allows the types to be inferred 2366 template<typename ExpressionT> 2367 inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1, 2368 Impl::Matcher<ExpressionT> const& m2 ) { 2369 return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ); 2370 } 2371 template<typename ExpressionT> 2372 inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1, 2373 Impl::Matcher<ExpressionT> const& m2, 2374 Impl::Matcher<ExpressionT> const& m3 ) { 2375 return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 ); 2376 } 2377 template<typename ExpressionT> 2378 inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1, 2379 Impl::Matcher<ExpressionT> const& m2 ) { 2380 return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ); 2381 } 2382 template<typename ExpressionT> 2383 inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1, 2384 Impl::Matcher<ExpressionT> const& m2, 2385 Impl::Matcher<ExpressionT> const& m3 ) { 2386 return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 ); 2387 } 2388 2389 inline Impl::StdString::Equals Equals( std::string const& str ) { 2390 return Impl::StdString::Equals( str ); 2391 } 2392 inline Impl::StdString::Equals Equals( const char* str ) { 2393 return Impl::StdString::Equals( Impl::StdString::makeString( str ) ); 2394 } 2395 inline Impl::StdString::Contains Contains( std::string const& substr ) { 2396 return Impl::StdString::Contains( substr ); 2397 } 2398 inline Impl::StdString::Contains Contains( const char* substr ) { 2399 return Impl::StdString::Contains( Impl::StdString::makeString( substr ) ); 2400 } 2401 inline Impl::StdString::StartsWith StartsWith( std::string const& substr ) { 2402 return Impl::StdString::StartsWith( substr ); 2403 } 2404 inline Impl::StdString::StartsWith StartsWith( const char* substr ) { 2405 return Impl::StdString::StartsWith( Impl::StdString::makeString( substr ) ); 2406 } 2407 inline Impl::StdString::EndsWith EndsWith( std::string const& substr ) { 2408 return Impl::StdString::EndsWith( substr ); 2409 } 2410 inline Impl::StdString::EndsWith EndsWith( const char* substr ) { 2411 return Impl::StdString::EndsWith( Impl::StdString::makeString( substr ) ); 2412 } 2413 2414} // namespace Matchers 2415 2416using namespace Matchers; 2417 2418} // namespace Catch 2419 2420// #included from: internal/catch_interfaces_tag_alias_registry.h 2421#define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED 2422 2423// #included from: catch_tag_alias.h 2424#define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED 2425 2426#include <string> 2427 2428namespace Catch { 2429 2430 struct TagAlias { 2431 TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {} 2432 2433 std::string tag; 2434 SourceLineInfo lineInfo; 2435 }; 2436 2437 struct RegistrarForTagAliases { 2438 RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); 2439 }; 2440 2441} // end namespace Catch 2442 2443#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } 2444// #included from: catch_option.hpp 2445#define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED 2446 2447namespace Catch { 2448 2449 // An optional type 2450 template<typename T> 2451 class Option { 2452 public: 2453 Option() : nullableValue( NULL ) {} 2454 Option( T const& _value ) 2455 : nullableValue( new( storage ) T( _value ) ) 2456 {} 2457 Option( Option const& _other ) 2458 : nullableValue( _other ? new( storage ) T( *_other ) : NULL ) 2459 {} 2460 2461 ~Option() { 2462 reset(); 2463 } 2464 2465 Option& operator= ( Option const& _other ) { 2466 if( &_other != this ) { 2467 reset(); 2468 if( _other ) 2469 nullableValue = new( storage ) T( *_other ); 2470 } 2471 return *this; 2472 } 2473 Option& operator = ( T const& _value ) { 2474 reset(); 2475 nullableValue = new( storage ) T( _value ); 2476 return *this; 2477 } 2478 2479 void reset() { 2480 if( nullableValue ) 2481 nullableValue->~T(); 2482 nullableValue = NULL; 2483 } 2484 2485 T& operator*() { return *nullableValue; } 2486 T const& operator*() const { return *nullableValue; } 2487 T* operator->() { return nullableValue; } 2488 const T* operator->() const { return nullableValue; } 2489 2490 T valueOr( T const& defaultValue ) const { 2491 return nullableValue ? *nullableValue : defaultValue; 2492 } 2493 2494 bool some() const { return nullableValue != NULL; } 2495 bool none() const { return nullableValue == NULL; } 2496 2497 bool operator !() const { return nullableValue == NULL; } 2498 operator SafeBool::type() const { 2499 return SafeBool::makeSafe( some() ); 2500 } 2501 2502 private: 2503 T* nullableValue; 2504 char storage[sizeof(T)]; 2505 }; 2506 2507} // end namespace Catch 2508 2509namespace Catch { 2510 2511 struct ITagAliasRegistry { 2512 virtual ~ITagAliasRegistry(); 2513 virtual Option<TagAlias> find( std::string const& alias ) const = 0; 2514 virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0; 2515 2516 static ITagAliasRegistry const& get(); 2517 }; 2518 2519} // end namespace Catch 2520 2521// These files are included here so the single_include script doesn't put them 2522// in the conditionally compiled sections 2523// #included from: internal/catch_test_case_info.h 2524#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED 2525 2526#include <string> 2527#include <set> 2528 2529#ifdef __clang__ 2530#pragma clang diagnostic push 2531#pragma clang diagnostic ignored "-Wpadded" 2532#endif 2533 2534namespace Catch { 2535 2536 struct ITestCase; 2537 2538 struct TestCaseInfo { 2539 enum SpecialProperties{ 2540 None = 0, 2541 IsHidden = 1 << 1, 2542 ShouldFail = 1 << 2, 2543 MayFail = 1 << 3, 2544 Throws = 1 << 4 2545 }; 2546 2547 TestCaseInfo( std::string const& _name, 2548 std::string const& _className, 2549 std::string const& _description, 2550 std::set<std::string> const& _tags, 2551 SourceLineInfo const& _lineInfo ); 2552 2553 TestCaseInfo( TestCaseInfo const& other ); 2554 2555 bool isHidden() const; 2556 bool throws() const; 2557 bool okToFail() const; 2558 bool expectedToFail() const; 2559 2560 std::string name; 2561 std::string className; 2562 std::string description; 2563 std::set<std::string> tags; 2564 std::set<std::string> lcaseTags; 2565 std::string tagsAsString; 2566 SourceLineInfo lineInfo; 2567 SpecialProperties properties; 2568 }; 2569 2570 class TestCase : public TestCaseInfo { 2571 public: 2572 2573 TestCase( ITestCase* testCase, TestCaseInfo const& info ); 2574 TestCase( TestCase const& other ); 2575 2576 TestCase withName( std::string const& _newName ) const; 2577 2578 void invoke() const; 2579 2580 TestCaseInfo const& getTestCaseInfo() const; 2581 2582 void swap( TestCase& other ); 2583 bool operator == ( TestCase const& other ) const; 2584 bool operator < ( TestCase const& other ) const; 2585 TestCase& operator = ( TestCase const& other ); 2586 2587 private: 2588 Ptr<ITestCase> test; 2589 }; 2590 2591 TestCase makeTestCase( ITestCase* testCase, 2592 std::string const& className, 2593 std::string const& name, 2594 std::string const& description, 2595 SourceLineInfo const& lineInfo ); 2596} 2597 2598#ifdef __clang__ 2599#pragma clang diagnostic pop 2600#endif 2601 2602 2603#ifdef __OBJC__ 2604// #included from: internal/catch_objc.hpp 2605#define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED 2606 2607#import <objc/runtime.h> 2608 2609#include <string> 2610 2611// NB. Any general catch headers included here must be included 2612// in catch.hpp first to make sure they are included by the single 2613// header for non obj-usage 2614 2615/////////////////////////////////////////////////////////////////////////////// 2616// This protocol is really only here for (self) documenting purposes, since 2617// all its methods are optional. 2618@protocol OcFixture 2619 2620@optional 2621 2622-(void) setUp; 2623-(void) tearDown; 2624 2625@end 2626 2627namespace Catch { 2628 2629 class OcMethod : public SharedImpl<ITestCase> { 2630 2631 public: 2632 OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {} 2633 2634 virtual void invoke() const { 2635 id obj = [[m_cls alloc] init]; 2636 2637 performOptionalSelector( obj, @selector(setUp) ); 2638 performOptionalSelector( obj, m_sel ); 2639 performOptionalSelector( obj, @selector(tearDown) ); 2640 2641 arcSafeRelease( obj ); 2642 } 2643 private: 2644 virtual ~OcMethod() {} 2645 2646 Class m_cls; 2647 SEL m_sel; 2648 }; 2649 2650 namespace Detail{ 2651 2652 inline std::string getAnnotation( Class cls, 2653 std::string const& annotationName, 2654 std::string const& testCaseName ) { 2655 NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()]; 2656 SEL sel = NSSelectorFromString( selStr ); 2657 arcSafeRelease( selStr ); 2658 id value = performOptionalSelector( cls, sel ); 2659 if( value ) 2660 return [(NSString*)value UTF8String]; 2661 return ""; 2662 } 2663 } 2664 2665 inline size_t registerTestMethods() { 2666 size_t noTestMethods = 0; 2667 int noClasses = objc_getClassList( NULL, 0 ); 2668 2669 Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses); 2670 objc_getClassList( classes, noClasses ); 2671 2672 for( int c = 0; c < noClasses; c++ ) { 2673 Class cls = classes[c]; 2674 { 2675 u_int count; 2676 Method* methods = class_copyMethodList( cls, &count ); 2677 for( u_int m = 0; m < count ; m++ ) { 2678 SEL selector = method_getName(methods[m]); 2679 std::string methodName = sel_getName(selector); 2680 if( startsWith( methodName, "Catch_TestCase_" ) ) { 2681 std::string testCaseName = methodName.substr( 15 ); 2682 std::string name = Detail::getAnnotation( cls, "Name", testCaseName ); 2683 std::string desc = Detail::getAnnotation( cls, "Description", testCaseName ); 2684 const char* className = class_getName( cls ); 2685 2686 getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) ); 2687 noTestMethods++; 2688 } 2689 } 2690 free(methods); 2691 } 2692 } 2693 return noTestMethods; 2694 } 2695 2696 namespace Matchers { 2697 namespace Impl { 2698 namespace NSStringMatchers { 2699 2700 template<typename MatcherT> 2701 struct StringHolder : MatcherImpl<MatcherT, NSString*>{ 2702 StringHolder( NSString* substr ) : m_substr( [substr copy] ){} 2703 StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){} 2704 StringHolder() { 2705 arcSafeRelease( m_substr ); 2706 } 2707 2708 NSString* m_substr; 2709 }; 2710 2711 struct Equals : StringHolder<Equals> { 2712 Equals( NSString* substr ) : StringHolder( substr ){} 2713 2714 virtual bool match( ExpressionType const& str ) const { 2715 return (str != nil || m_substr == nil ) && 2716 [str isEqualToString:m_substr]; 2717 } 2718 2719 virtual std::string toString() const { 2720 return "equals string: " + Catch::toString( m_substr ); 2721 } 2722 }; 2723 2724 struct Contains : StringHolder<Contains> { 2725 Contains( NSString* substr ) : StringHolder( substr ){} 2726 2727 virtual bool match( ExpressionType const& str ) const { 2728 return (str != nil || m_substr == nil ) && 2729 [str rangeOfString:m_substr].location != NSNotFound; 2730 } 2731 2732 virtual std::string toString() const { 2733 return "contains string: " + Catch::toString( m_substr ); 2734 } 2735 }; 2736 2737 struct StartsWith : StringHolder<StartsWith> { 2738 StartsWith( NSString* substr ) : StringHolder( substr ){} 2739 2740 virtual bool match( ExpressionType const& str ) const { 2741 return (str != nil || m_substr == nil ) && 2742 [str rangeOfString:m_substr].location == 0; 2743 } 2744 2745 virtual std::string toString() const { 2746 return "starts with: " + Catch::toString( m_substr ); 2747 } 2748 }; 2749 struct EndsWith : StringHolder<EndsWith> { 2750 EndsWith( NSString* substr ) : StringHolder( substr ){} 2751 2752 virtual bool match( ExpressionType const& str ) const { 2753 return (str != nil || m_substr == nil ) && 2754 [str rangeOfString:m_substr].location == [str length] - [m_substr length]; 2755 } 2756 2757 virtual std::string toString() const { 2758 return "ends with: " + Catch::toString( m_substr ); 2759 } 2760 }; 2761 2762 } // namespace NSStringMatchers 2763 } // namespace Impl 2764 2765 inline Impl::NSStringMatchers::Equals 2766 Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); } 2767 2768 inline Impl::NSStringMatchers::Contains 2769 Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); } 2770 2771 inline Impl::NSStringMatchers::StartsWith 2772 StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); } 2773 2774 inline Impl::NSStringMatchers::EndsWith 2775 EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); } 2776 2777 } // namespace Matchers 2778 2779 using namespace Matchers; 2780 2781} // namespace Catch 2782 2783/////////////////////////////////////////////////////////////////////////////// 2784#define OC_TEST_CASE( name, desc )\ 2785+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \ 2786{\ 2787return @ name; \ 2788}\ 2789+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \ 2790{ \ 2791return @ desc; \ 2792} \ 2793-(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test ) 2794 2795#endif 2796 2797#ifdef CATCH_IMPL 2798// #included from: internal/catch_impl.hpp 2799#define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED 2800 2801// Collect all the implementation files together here 2802// These are the equivalent of what would usually be cpp files 2803 2804#ifdef __clang__ 2805#pragma clang diagnostic push 2806#pragma clang diagnostic ignored "-Wweak-vtables" 2807#endif 2808 2809// #included from: ../catch_runner.hpp 2810#define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED 2811 2812// #included from: internal/catch_commandline.hpp 2813#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED 2814 2815// #included from: catch_config.hpp 2816#define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED 2817 2818// #included from: catch_test_spec_parser.hpp 2819#define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED 2820 2821#ifdef __clang__ 2822#pragma clang diagnostic push 2823#pragma clang diagnostic ignored "-Wpadded" 2824#endif 2825 2826// #included from: catch_test_spec.hpp 2827#define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED 2828 2829#ifdef __clang__ 2830#pragma clang diagnostic push 2831#pragma clang diagnostic ignored "-Wpadded" 2832#endif 2833 2834#include <string> 2835#include <vector> 2836 2837namespace Catch { 2838 2839 class TestSpec { 2840 struct Pattern : SharedImpl<> { 2841 virtual ~Pattern(); 2842 virtual bool matches( TestCaseInfo const& testCase ) const = 0; 2843 }; 2844 class NamePattern : public Pattern { 2845 enum WildcardPosition { 2846 NoWildcard = 0, 2847 WildcardAtStart = 1, 2848 WildcardAtEnd = 2, 2849 WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd 2850 }; 2851 2852 public: 2853 NamePattern( std::string const& name ) : m_name( toLower( name ) ), m_wildcard( NoWildcard ) { 2854 if( startsWith( m_name, "*" ) ) { 2855 m_name = m_name.substr( 1 ); 2856 m_wildcard = WildcardAtStart; 2857 } 2858 if( endsWith( m_name, "*" ) ) { 2859 m_name = m_name.substr( 0, m_name.size()-1 ); 2860 m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd ); 2861 } 2862 } 2863 virtual ~NamePattern(); 2864 virtual bool matches( TestCaseInfo const& testCase ) const { 2865 switch( m_wildcard ) { 2866 case NoWildcard: 2867 return m_name == toLower( testCase.name ); 2868 case WildcardAtStart: 2869 return endsWith( toLower( testCase.name ), m_name ); 2870 case WildcardAtEnd: 2871 return startsWith( toLower( testCase.name ), m_name ); 2872 case WildcardAtBothEnds: 2873 return contains( toLower( testCase.name ), m_name ); 2874 } 2875 2876#ifdef __clang__ 2877#pragma clang diagnostic push 2878#pragma clang diagnostic ignored "-Wunreachable-code" 2879#endif 2880 throw std::logic_error( "Unknown enum" ); 2881#ifdef __clang__ 2882#pragma clang diagnostic pop 2883#endif 2884 } 2885 private: 2886 std::string m_name; 2887 WildcardPosition m_wildcard; 2888 }; 2889 class TagPattern : public Pattern { 2890 public: 2891 TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {} 2892 virtual ~TagPattern(); 2893 virtual bool matches( TestCaseInfo const& testCase ) const { 2894 return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end(); 2895 } 2896 private: 2897 std::string m_tag; 2898 }; 2899 class ExcludedPattern : public Pattern { 2900 public: 2901 ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {} 2902 virtual ~ExcludedPattern(); 2903 virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); } 2904 private: 2905 Ptr<Pattern> m_underlyingPattern; 2906 }; 2907 2908 struct Filter { 2909 std::vector<Ptr<Pattern> > m_patterns; 2910 2911 bool matches( TestCaseInfo const& testCase ) const { 2912 // All patterns in a filter must match for the filter to be a match 2913 for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it ) 2914 if( !(*it)->matches( testCase ) ) 2915 return false; 2916 return true; 2917 } 2918 }; 2919 2920 public: 2921 bool hasFilters() const { 2922 return !m_filters.empty(); 2923 } 2924 bool matches( TestCaseInfo const& testCase ) const { 2925 // A TestSpec matches if any filter matches 2926 for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it ) 2927 if( it->matches( testCase ) ) 2928 return true; 2929 return false; 2930 } 2931 2932 private: 2933 std::vector<Filter> m_filters; 2934 2935 friend class TestSpecParser; 2936 }; 2937} 2938 2939#ifdef __clang__ 2940#pragma clang diagnostic pop 2941#endif 2942 2943namespace Catch { 2944 2945 class TestSpecParser { 2946 enum Mode{ None, Name, QuotedName, Tag }; 2947 Mode m_mode; 2948 bool m_exclusion; 2949 std::size_t m_start, m_pos; 2950 std::string m_arg; 2951 TestSpec::Filter m_currentFilter; 2952 TestSpec m_testSpec; 2953 ITagAliasRegistry const* m_tagAliases; 2954 2955 public: 2956 TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {} 2957 2958 TestSpecParser& parse( std::string const& arg ) { 2959 m_mode = None; 2960 m_exclusion = false; 2961 m_start = std::string::npos; 2962 m_arg = m_tagAliases->expandAliases( arg ); 2963 for( m_pos = 0; m_pos < m_arg.size(); ++m_pos ) 2964 visitChar( m_arg[m_pos] ); 2965 if( m_mode == Name ) 2966 addPattern<TestSpec::NamePattern>(); 2967 return *this; 2968 } 2969 TestSpec testSpec() { 2970 addFilter(); 2971 return m_testSpec; 2972 } 2973 private: 2974 void visitChar( char c ) { 2975 if( m_mode == None ) { 2976 switch( c ) { 2977 case ' ': return; 2978 case '~': m_exclusion = true; return; 2979 case '[': return startNewMode( Tag, ++m_pos ); 2980 case '"': return startNewMode( QuotedName, ++m_pos ); 2981 default: startNewMode( Name, m_pos ); break; 2982 } 2983 } 2984 if( m_mode == Name ) { 2985 if( c == ',' ) { 2986 addPattern<TestSpec::NamePattern>(); 2987 addFilter(); 2988 } 2989 else if( c == '[' ) { 2990 if( subString() == "exclude:" ) 2991 m_exclusion = true; 2992 else 2993 addPattern<TestSpec::NamePattern>(); 2994 startNewMode( Tag, ++m_pos ); 2995 } 2996 } 2997 else if( m_mode == QuotedName && c == '"' ) 2998 addPattern<TestSpec::NamePattern>(); 2999 else if( m_mode == Tag && c == ']' ) 3000 addPattern<TestSpec::TagPattern>(); 3001 } 3002 void startNewMode( Mode mode, std::size_t start ) { 3003 m_mode = mode; 3004 m_start = start; 3005 } 3006 std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); } 3007 template<typename T> 3008 void addPattern() { 3009 std::string token = subString(); 3010 if( startsWith( token, "exclude:" ) ) { 3011 m_exclusion = true; 3012 token = token.substr( 8 ); 3013 } 3014 if( !token.empty() ) { 3015 Ptr<TestSpec::Pattern> pattern = new T( token ); 3016 if( m_exclusion ) 3017 pattern = new TestSpec::ExcludedPattern( pattern ); 3018 m_currentFilter.m_patterns.push_back( pattern ); 3019 } 3020 m_exclusion = false; 3021 m_mode = None; 3022 } 3023 void addFilter() { 3024 if( !m_currentFilter.m_patterns.empty() ) { 3025 m_testSpec.m_filters.push_back( m_currentFilter ); 3026 m_currentFilter = TestSpec::Filter(); 3027 } 3028 } 3029 }; 3030 inline TestSpec parseTestSpec( std::string const& arg ) { 3031 return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec(); 3032 } 3033 3034} // namespace Catch 3035 3036#ifdef __clang__ 3037#pragma clang diagnostic pop 3038#endif 3039 3040// #included from: catch_interfaces_config.h 3041#define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED 3042 3043#include <iostream> 3044#include <string> 3045#include <vector> 3046 3047namespace Catch { 3048 3049 struct Verbosity { enum Level { 3050 NoOutput = 0, 3051 Quiet, 3052 Normal 3053 }; }; 3054 3055 struct WarnAbout { enum What { 3056 Nothing = 0x00, 3057 NoAssertions = 0x01 3058 }; }; 3059 3060 struct ShowDurations { enum OrNot { 3061 DefaultForReporter, 3062 Always, 3063 Never 3064 }; }; 3065 struct RunTests { enum InWhatOrder { 3066 InDeclarationOrder, 3067 InLexicographicalOrder, 3068 InRandomOrder 3069 }; }; 3070 3071 class TestSpec; 3072 3073 struct IConfig : IShared { 3074 3075 virtual ~IConfig(); 3076 3077 virtual bool allowThrows() const = 0; 3078 virtual std::ostream& stream() const = 0; 3079 virtual std::string name() const = 0; 3080 virtual bool includeSuccessfulResults() const = 0; 3081 virtual bool shouldDebugBreak() const = 0; 3082 virtual bool warnAboutMissingAssertions() const = 0; 3083 virtual int abortAfter() const = 0; 3084 virtual bool showInvisibles() const = 0; 3085 virtual ShowDurations::OrNot showDurations() const = 0; 3086 virtual TestSpec const& testSpec() const = 0; 3087 virtual RunTests::InWhatOrder runOrder() const = 0; 3088 virtual unsigned int rngSeed() const = 0; 3089 virtual bool forceColour() const = 0; 3090 }; 3091} 3092 3093// #included from: catch_stream.h 3094#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED 3095 3096#include <streambuf> 3097 3098#ifdef __clang__ 3099#pragma clang diagnostic ignored "-Wpadded" 3100#endif 3101 3102namespace Catch { 3103 3104 class Stream { 3105 public: 3106 Stream(); 3107 Stream( std::streambuf* _streamBuf, bool _isOwned ); 3108 void release(); 3109 3110 std::streambuf* streamBuf; 3111 3112 private: 3113 bool isOwned; 3114 }; 3115 3116 std::ostream& cout(); 3117 std::ostream& cerr(); 3118} 3119 3120#include <memory> 3121#include <vector> 3122#include <string> 3123#include <iostream> 3124#include <ctime> 3125 3126#ifndef CATCH_CONFIG_CONSOLE_WIDTH 3127#define CATCH_CONFIG_CONSOLE_WIDTH 80 3128#endif 3129 3130namespace Catch { 3131 3132 struct ConfigData { 3133 3134 ConfigData() 3135 : listTests( false ), 3136 listTags( false ), 3137 listReporters( false ), 3138 listTestNamesOnly( false ), 3139 showSuccessfulTests( false ), 3140 shouldDebugBreak( false ), 3141 noThrow( false ), 3142 showHelp( false ), 3143 showInvisibles( false ), 3144 forceColour( false ), 3145 abortAfter( -1 ), 3146 rngSeed( 0 ), 3147 verbosity( Verbosity::Normal ), 3148 warnings( WarnAbout::Nothing ), 3149 showDurations( ShowDurations::DefaultForReporter ), 3150 runOrder( RunTests::InDeclarationOrder ) 3151 {} 3152 3153 bool listTests; 3154 bool listTags; 3155 bool listReporters; 3156 bool listTestNamesOnly; 3157 3158 bool showSuccessfulTests; 3159 bool shouldDebugBreak; 3160 bool noThrow; 3161 bool showHelp; 3162 bool showInvisibles; 3163 bool forceColour; 3164 3165 int abortAfter; 3166 unsigned int rngSeed; 3167 3168 Verbosity::Level verbosity; 3169 WarnAbout::What warnings; 3170 ShowDurations::OrNot showDurations; 3171 RunTests::InWhatOrder runOrder; 3172 3173 std::string reporterName; 3174 std::string outputFilename; 3175 std::string name; 3176 std::string processName; 3177 3178 std::vector<std::string> testsOrTags; 3179 }; 3180 3181 class Config : public SharedImpl<IConfig> { 3182 private: 3183 Config( Config const& other ); 3184 Config& operator = ( Config const& other ); 3185 virtual void dummy(); 3186 public: 3187 3188 Config() 3189 : m_os( Catch::cout().rdbuf() ) 3190 {} 3191 3192 Config( ConfigData const& data ) 3193 : m_data( data ), 3194 m_os( Catch::cout().rdbuf() ) 3195 { 3196 if( !data.testsOrTags.empty() ) { 3197 TestSpecParser parser( ITagAliasRegistry::get() ); 3198 for( std::size_t i = 0; i < data.testsOrTags.size(); ++i ) 3199 parser.parse( data.testsOrTags[i] ); 3200 m_testSpec = parser.testSpec(); 3201 } 3202 } 3203 3204 virtual ~Config() { 3205 m_os.rdbuf( Catch::cout().rdbuf() ); 3206 m_stream.release(); 3207 } 3208 3209 void setFilename( std::string const& filename ) { 3210 m_data.outputFilename = filename; 3211 } 3212 3213 std::string const& getFilename() const { 3214 return m_data.outputFilename ; 3215 } 3216 3217 bool listTests() const { return m_data.listTests; } 3218 bool listTestNamesOnly() const { return m_data.listTestNamesOnly; } 3219 bool listTags() const { return m_data.listTags; } 3220 bool listReporters() const { return m_data.listReporters; } 3221 3222 std::string getProcessName() const { return m_data.processName; } 3223 3224 bool shouldDebugBreak() const { return m_data.shouldDebugBreak; } 3225 3226 void setStreamBuf( std::streambuf* buf ) { 3227 m_os.rdbuf( buf ? buf : Catch::cout().rdbuf() ); 3228 } 3229 3230 void useStream( std::string const& streamName ) { 3231 Stream stream = createStream( streamName ); 3232 setStreamBuf( stream.streamBuf ); 3233 m_stream.release(); 3234 m_stream = stream; 3235 } 3236 3237 std::string getReporterName() const { return m_data.reporterName; } 3238 3239 int abortAfter() const { return m_data.abortAfter; } 3240 3241 TestSpec const& testSpec() const { return m_testSpec; } 3242 3243 bool showHelp() const { return m_data.showHelp; } 3244 bool showInvisibles() const { return m_data.showInvisibles; } 3245 3246 // IConfig interface 3247 virtual bool allowThrows() const { return !m_data.noThrow; } 3248 virtual std::ostream& stream() const { return m_os; } 3249 virtual std::string name() const { return m_data.name.empty() ? m_data.processName : m_data.name; } 3250 virtual bool includeSuccessfulResults() const { return m_data.showSuccessfulTests; } 3251 virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; } 3252 virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; } 3253 virtual RunTests::InWhatOrder runOrder() const { return m_data.runOrder; } 3254 virtual unsigned int rngSeed() const { return m_data.rngSeed; } 3255 virtual bool forceColour() const { return m_data.forceColour; } 3256 3257 private: 3258 ConfigData m_data; 3259 3260 Stream m_stream; 3261 mutable std::ostream m_os; 3262 TestSpec m_testSpec; 3263 }; 3264 3265} // end namespace Catch 3266 3267// #included from: catch_clara.h 3268#define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED 3269 3270// Use Catch's value for console width (store Clara's off to the side, if present) 3271#ifdef CLARA_CONFIG_CONSOLE_WIDTH 3272#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH 3273#undef CLARA_CONFIG_CONSOLE_WIDTH 3274#endif 3275#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH 3276 3277// Declare Clara inside the Catch namespace 3278#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch { 3279// #included from: ../external/clara.h 3280 3281// Only use header guard if we are not using an outer namespace 3282#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE) 3283 3284#ifndef STITCH_CLARA_OPEN_NAMESPACE 3285#define TWOBLUECUBES_CLARA_H_INCLUDED 3286#define STITCH_CLARA_OPEN_NAMESPACE 3287#define STITCH_CLARA_CLOSE_NAMESPACE 3288#else 3289#define STITCH_CLARA_CLOSE_NAMESPACE } 3290#endif 3291 3292#define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE 3293 3294// ----------- #included from tbc_text_format.h ----------- 3295 3296// Only use header guard if we are not using an outer namespace 3297#if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE) 3298#ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE 3299#define TBC_TEXT_FORMAT_H_INCLUDED 3300#endif 3301 3302#include <string> 3303#include <vector> 3304#include <sstream> 3305 3306// Use optional outer namespace 3307#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE 3308namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE { 3309#endif 3310 3311namespace Tbc { 3312 3313#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH 3314 const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH; 3315#else 3316 const unsigned int consoleWidth = 80; 3317#endif 3318 3319 struct TextAttributes { 3320 TextAttributes() 3321 : initialIndent( std::string::npos ), 3322 indent( 0 ), 3323 width( consoleWidth-1 ), 3324 tabChar( '\t' ) 3325 {} 3326 3327 TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; } 3328 TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; } 3329 TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; } 3330 TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; } 3331 3332 std::size_t initialIndent; // indent of first line, or npos 3333 std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos 3334 std::size_t width; // maximum width of text, including indent. Longer text will wrap 3335 char tabChar; // If this char is seen the indent is changed to current pos 3336 }; 3337 3338 class Text { 3339 public: 3340 Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() ) 3341 : attr( _attr ) 3342 { 3343 std::string wrappableChars = " [({.,/|\\-"; 3344 std::size_t indent = _attr.initialIndent != std::string::npos 3345 ? _attr.initialIndent 3346 : _attr.indent; 3347 std::string remainder = _str; 3348 3349 while( !remainder.empty() ) { 3350 if( lines.size() >= 1000 ) { 3351 lines.push_back( "... message truncated due to excessive size" ); 3352 return; 3353 } 3354 std::size_t tabPos = std::string::npos; 3355 std::size_t width = (std::min)( remainder.size(), _attr.width - indent ); 3356 std::size_t pos = remainder.find_first_of( '\n' ); 3357 if( pos <= width ) { 3358 width = pos; 3359 } 3360 pos = remainder.find_last_of( _attr.tabChar, width ); 3361 if( pos != std::string::npos ) { 3362 tabPos = pos; 3363 if( remainder[width] == '\n' ) 3364 width--; 3365 remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 ); 3366 } 3367 3368 if( width == remainder.size() ) { 3369 spliceLine( indent, remainder, width ); 3370 } 3371 else if( remainder[width] == '\n' ) { 3372 spliceLine( indent, remainder, width ); 3373 if( width <= 1 || remainder.size() != 1 ) 3374 remainder = remainder.substr( 1 ); 3375 indent = _attr.indent; 3376 } 3377 else { 3378 pos = remainder.find_last_of( wrappableChars, width ); 3379 if( pos != std::string::npos && pos > 0 ) { 3380 spliceLine( indent, remainder, pos ); 3381 if( remainder[0] == ' ' ) 3382 remainder = remainder.substr( 1 ); 3383 } 3384 else { 3385 spliceLine( indent, remainder, width-1 ); 3386 lines.back() += "-"; 3387 } 3388 if( lines.size() == 1 ) 3389 indent = _attr.indent; 3390 if( tabPos != std::string::npos ) 3391 indent += tabPos; 3392 } 3393 } 3394 } 3395 3396 void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) { 3397 lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) ); 3398 _remainder = _remainder.substr( _pos ); 3399 } 3400 3401 typedef std::vector<std::string>::const_iterator const_iterator; 3402 3403 const_iterator begin() const { return lines.begin(); } 3404 const_iterator end() const { return lines.end(); } 3405 std::string const& last() const { return lines.back(); } 3406 std::size_t size() const { return lines.size(); } 3407 std::string const& operator[]( std::size_t _index ) const { return lines[_index]; } 3408 std::string toString() const { 3409 std::ostringstream oss; 3410 oss << *this; 3411 return oss.str(); 3412 } 3413 3414 inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) { 3415 for( Text::const_iterator it = _text.begin(), itEnd = _text.end(); 3416 it != itEnd; ++it ) { 3417 if( it != _text.begin() ) 3418 _stream << "\n"; 3419 _stream << *it; 3420 } 3421 return _stream; 3422 } 3423 3424 private: 3425 std::string str; 3426 TextAttributes attr; 3427 std::vector<std::string> lines; 3428 }; 3429 3430} // end namespace Tbc 3431 3432#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE 3433} // end outer namespace 3434#endif 3435 3436#endif // TBC_TEXT_FORMAT_H_INCLUDED 3437 3438// ----------- end of #include from tbc_text_format.h ----------- 3439// ........... back in /Users/philnash/Dev/OSS/Clara/srcs/clara.h 3440 3441#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE 3442 3443#include <map> 3444#include <algorithm> 3445#include <stdexcept> 3446#include <memory> 3447 3448// Use optional outer namespace 3449#ifdef STITCH_CLARA_OPEN_NAMESPACE 3450STITCH_CLARA_OPEN_NAMESPACE 3451#endif 3452 3453namespace Clara { 3454 3455 struct UnpositionalTag {}; 3456 3457 extern UnpositionalTag _; 3458 3459#ifdef CLARA_CONFIG_MAIN 3460 UnpositionalTag _; 3461#endif 3462 3463 namespace Detail { 3464 3465#ifdef CLARA_CONSOLE_WIDTH 3466 const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH; 3467#else 3468 const unsigned int consoleWidth = 80; 3469#endif 3470 3471 using namespace Tbc; 3472 3473 inline bool startsWith( std::string const& str, std::string const& prefix ) { 3474 return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix; 3475 } 3476 3477 template<typename T> struct RemoveConstRef{ typedef T type; }; 3478 template<typename T> struct RemoveConstRef<T&>{ typedef T type; }; 3479 template<typename T> struct RemoveConstRef<T const&>{ typedef T type; }; 3480 template<typename T> struct RemoveConstRef<T const>{ typedef T type; }; 3481 3482 template<typename T> struct IsBool { static const bool value = false; }; 3483 template<> struct IsBool<bool> { static const bool value = true; }; 3484 3485 template<typename T> 3486 void convertInto( std::string const& _source, T& _dest ) { 3487 std::stringstream ss; 3488 ss << _source; 3489 ss >> _dest; 3490 if( ss.fail() ) 3491 throw std::runtime_error( "Unable to convert " + _source + " to destination type" ); 3492 } 3493 inline void convertInto( std::string const& _source, std::string& _dest ) { 3494 _dest = _source; 3495 } 3496 inline void convertInto( std::string const& _source, bool& _dest ) { 3497 std::string sourceLC = _source; 3498 std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), ::tolower ); 3499 if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" ) 3500 _dest = true; 3501 else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" ) 3502 _dest = false; 3503 else 3504 throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" ); 3505 } 3506 inline void convertInto( bool _source, bool& _dest ) { 3507 _dest = _source; 3508 } 3509 template<typename T> 3510 inline void convertInto( bool, T& ) { 3511 throw std::runtime_error( "Invalid conversion" ); 3512 } 3513 3514 template<typename ConfigT> 3515 struct IArgFunction { 3516 virtual ~IArgFunction() {} 3517# ifdef CATCH_CPP11_OR_GREATER 3518 IArgFunction() = default; 3519 IArgFunction( IArgFunction const& ) = default; 3520# endif 3521 virtual void set( ConfigT& config, std::string const& value ) const = 0; 3522 virtual void setFlag( ConfigT& config ) const = 0; 3523 virtual bool takesArg() const = 0; 3524 virtual IArgFunction* clone() const = 0; 3525 }; 3526 3527 template<typename ConfigT> 3528 class BoundArgFunction { 3529 public: 3530 BoundArgFunction() : functionObj( NULL ) {} 3531 BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {} 3532 BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : NULL ) {} 3533 BoundArgFunction& operator = ( BoundArgFunction const& other ) { 3534 IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : NULL; 3535 delete functionObj; 3536 functionObj = newFunctionObj; 3537 return *this; 3538 } 3539 ~BoundArgFunction() { delete functionObj; } 3540 3541 void set( ConfigT& config, std::string const& value ) const { 3542 functionObj->set( config, value ); 3543 } 3544 void setFlag( ConfigT& config ) const { 3545 functionObj->setFlag( config ); 3546 } 3547 bool takesArg() const { return functionObj->takesArg(); } 3548 3549 bool isSet() const { 3550 return functionObj != NULL; 3551 } 3552 private: 3553 IArgFunction<ConfigT>* functionObj; 3554 }; 3555 3556 template<typename C> 3557 struct NullBinder : IArgFunction<C>{ 3558 virtual void set( C&, std::string const& ) const {} 3559 virtual void setFlag( C& ) const {} 3560 virtual bool takesArg() const { return true; } 3561 virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); } 3562 }; 3563 3564 template<typename C, typename M> 3565 struct BoundDataMember : IArgFunction<C>{ 3566 BoundDataMember( M C::* _member ) : member( _member ) {} 3567 virtual void set( C& p, std::string const& stringValue ) const { 3568 convertInto( stringValue, p.*member ); 3569 } 3570 virtual void setFlag( C& p ) const { 3571 convertInto( true, p.*member ); 3572 } 3573 virtual bool takesArg() const { return !IsBool<M>::value; } 3574 virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); } 3575 M C::* member; 3576 }; 3577 template<typename C, typename M> 3578 struct BoundUnaryMethod : IArgFunction<C>{ 3579 BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {} 3580 virtual void set( C& p, std::string const& stringValue ) const { 3581 typename RemoveConstRef<M>::type value; 3582 convertInto( stringValue, value ); 3583 (p.*member)( value ); 3584 } 3585 virtual void setFlag( C& p ) const { 3586 typename RemoveConstRef<M>::type value; 3587 convertInto( true, value ); 3588 (p.*member)( value ); 3589 } 3590 virtual bool takesArg() const { return !IsBool<M>::value; } 3591 virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); } 3592 void (C::*member)( M ); 3593 }; 3594 template<typename C> 3595 struct BoundNullaryMethod : IArgFunction<C>{ 3596 BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {} 3597 virtual void set( C& p, std::string const& stringValue ) const { 3598 bool value; 3599 convertInto( stringValue, value ); 3600 if( value ) 3601 (p.*member)(); 3602 } 3603 virtual void setFlag( C& p ) const { 3604 (p.*member)(); 3605 } 3606 virtual bool takesArg() const { return false; } 3607 virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); } 3608 void (C::*member)(); 3609 }; 3610 3611 template<typename C> 3612 struct BoundUnaryFunction : IArgFunction<C>{ 3613 BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {} 3614 virtual void set( C& obj, std::string const& stringValue ) const { 3615 bool value; 3616 convertInto( stringValue, value ); 3617 if( value ) 3618 function( obj ); 3619 } 3620 virtual void setFlag( C& p ) const { 3621 function( p ); 3622 } 3623 virtual bool takesArg() const { return false; } 3624 virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); } 3625 void (*function)( C& ); 3626 }; 3627 3628 template<typename C, typename T> 3629 struct BoundBinaryFunction : IArgFunction<C>{ 3630 BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {} 3631 virtual void set( C& obj, std::string const& stringValue ) const { 3632 typename RemoveConstRef<T>::type value; 3633 convertInto( stringValue, value ); 3634 function( obj, value ); 3635 } 3636 virtual void setFlag( C& obj ) const { 3637 typename RemoveConstRef<T>::type value; 3638 convertInto( true, value ); 3639 function( obj, value ); 3640 } 3641 virtual bool takesArg() const { return !IsBool<T>::value; } 3642 virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); } 3643 void (*function)( C&, T ); 3644 }; 3645 3646 } // namespace Detail 3647 3648 struct Parser { 3649 Parser() : separators( " \t=:" ) {} 3650 3651 struct Token { 3652 enum Type { Positional, ShortOpt, LongOpt }; 3653 Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {} 3654 Type type; 3655 std::string data; 3656 }; 3657 3658 void parseIntoTokens( int argc, char const * const * argv, std::vector<Parser::Token>& tokens ) const { 3659 const std::string doubleDash = "--"; 3660 for( int i = 1; i < argc && argv[i] != doubleDash; ++i ) 3661 parseIntoTokens( argv[i] , tokens); 3662 } 3663 void parseIntoTokens( std::string arg, std::vector<Parser::Token>& tokens ) const { 3664 while( !arg.empty() ) { 3665 Parser::Token token( Parser::Token::Positional, arg ); 3666 arg = ""; 3667 if( token.data[0] == '-' ) { 3668 if( token.data.size() > 1 && token.data[1] == '-' ) { 3669 token = Parser::Token( Parser::Token::LongOpt, token.data.substr( 2 ) ); 3670 } 3671 else { 3672 token = Parser::Token( Parser::Token::ShortOpt, token.data.substr( 1 ) ); 3673 if( token.data.size() > 1 && separators.find( token.data[1] ) == std::string::npos ) { 3674 arg = "-" + token.data.substr( 1 ); 3675 token.data = token.data.substr( 0, 1 ); 3676 } 3677 } 3678 } 3679 if( token.type != Parser::Token::Positional ) { 3680 std::size_t pos = token.data.find_first_of( separators ); 3681 if( pos != std::string::npos ) { 3682 arg = token.data.substr( pos+1 ); 3683 token.data = token.data.substr( 0, pos ); 3684 } 3685 } 3686 tokens.push_back( token ); 3687 } 3688 } 3689 std::string separators; 3690 }; 3691 3692 template<typename ConfigT> 3693 struct CommonArgProperties { 3694 CommonArgProperties() {} 3695 CommonArgProperties( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ) {} 3696 3697 Detail::BoundArgFunction<ConfigT> boundField; 3698 std::string description; 3699 std::string detail; 3700 std::string placeholder; // Only value if boundField takes an arg 3701 3702 bool takesArg() const { 3703 return !placeholder.empty(); 3704 } 3705 void validate() const { 3706 if( !boundField.isSet() ) 3707 throw