/ unit_tests / catch.hpp
catch.hpp
    1  /*
    2   *  Catch v2.7.2
    3   *  Generated: 2019-04-22 23:13:14.687465
    4   *  ----------------------------------------------------------
    5   *  This file has been merged from multiple headers. Please don't edit it directly
    6   *  Copyright (c) 2019 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  // start catch.hpp
   14  
   15  
   16  #define CATCH_VERSION_MAJOR 2
   17  #define CATCH_VERSION_MINOR 7
   18  #define CATCH_VERSION_PATCH 2
   19  
   20  #ifdef __clang__
   21  #    pragma clang system_header
   22  #elif defined __GNUC__
   23  #    pragma GCC system_header
   24  #endif
   25  
   26  // start catch_suppress_warnings.h
   27  
   28  #ifdef __clang__
   29  #   ifdef __ICC // icpc defines the __clang__ macro
   30  #       pragma warning(push)
   31  #       pragma warning(disable: 161 1682)
   32  #   else // __ICC
   33  #       pragma clang diagnostic push
   34  #       pragma clang diagnostic ignored "-Wpadded"
   35  #       pragma clang diagnostic ignored "-Wswitch-enum"
   36  #       pragma clang diagnostic ignored "-Wcovered-switch-default"
   37  #    endif
   38  #elif defined __GNUC__
   39       // Because REQUIREs trigger GCC's -Wparentheses, and because still
   40       // supported version of g++ have only buggy support for _Pragmas,
   41       // Wparentheses have to be suppressed globally.
   42  #    pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details
   43  
   44  #    pragma GCC diagnostic push
   45  #    pragma GCC diagnostic ignored "-Wunused-variable"
   46  #    pragma GCC diagnostic ignored "-Wpadded"
   47  #endif
   48  // end catch_suppress_warnings.h
   49  #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
   50  #  define CATCH_IMPL
   51  #  define CATCH_CONFIG_ALL_PARTS
   52  #endif
   53  
   54  // In the impl file, we want to have access to all parts of the headers
   55  // Can also be used to sanely support PCHs
   56  #if defined(CATCH_CONFIG_ALL_PARTS)
   57  #  define CATCH_CONFIG_EXTERNAL_INTERFACES
   58  #  if defined(CATCH_CONFIG_DISABLE_MATCHERS)
   59  #    undef CATCH_CONFIG_DISABLE_MATCHERS
   60  #  endif
   61  #  if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
   62  #    define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
   63  #  endif
   64  #endif
   65  
   66  #if !defined(CATCH_CONFIG_IMPL_ONLY)
   67  // start catch_platform.h
   68  
   69  #ifdef __APPLE__
   70  # include <TargetConditionals.h>
   71  # if TARGET_OS_OSX == 1
   72  #  define CATCH_PLATFORM_MAC
   73  # elif TARGET_OS_IPHONE == 1
   74  #  define CATCH_PLATFORM_IPHONE
   75  # endif
   76  
   77  #elif defined(linux) || defined(__linux) || defined(__linux__)
   78  #  define CATCH_PLATFORM_LINUX
   79  
   80  #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
   81  #  define CATCH_PLATFORM_WINDOWS
   82  #endif
   83  
   84  // end catch_platform.h
   85  
   86  #ifdef CATCH_IMPL
   87  #  ifndef CLARA_CONFIG_MAIN
   88  #    define CLARA_CONFIG_MAIN_NOT_DEFINED
   89  #    define CLARA_CONFIG_MAIN
   90  #  endif
   91  #endif
   92  
   93  // start catch_user_interfaces.h
   94  
   95  namespace Catch {
   96      unsigned int rngSeed();
   97  }
   98  
   99  // end catch_user_interfaces.h
  100  // start catch_tag_alias_autoregistrar.h
  101  
  102  // start catch_common.h
  103  
  104  // start catch_compiler_capabilities.h
  105  
  106  // Detect a number of compiler features - by compiler
  107  // The following features are defined:
  108  //
  109  // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
  110  // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
  111  // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
  112  // CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
  113  // ****************
  114  // Note to maintainers: if new toggles are added please document them
  115  // in configuration.md, too
  116  // ****************
  117  
  118  // In general each macro has a _NO_<feature name> form
  119  // (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
  120  // Many features, at point of detection, define an _INTERNAL_ macro, so they
  121  // can be combined, en-mass, with the _NO_ forms later.
  122  
  123  #ifdef __cplusplus
  124  
  125  #  if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
  126  #    define CATCH_CPP14_OR_GREATER
  127  #  endif
  128  
  129  #  if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
  130  #    define CATCH_CPP17_OR_GREATER
  131  #  endif
  132  
  133  #endif
  134  
  135  #if defined(CATCH_CPP17_OR_GREATER)
  136  #  define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
  137  #endif
  138  
  139  #ifdef __clang__
  140  
  141  #       define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  142              _Pragma( "clang diagnostic push" ) \
  143              _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
  144              _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
  145  #       define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  146              _Pragma( "clang diagnostic pop" )
  147  
  148  #       define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
  149              _Pragma( "clang diagnostic push" ) \
  150              _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
  151  #       define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
  152              _Pragma( "clang diagnostic pop" )
  153  
  154  #       define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
  155              _Pragma( "clang diagnostic push" ) \
  156              _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
  157  #       define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS \
  158              _Pragma( "clang diagnostic pop" )
  159  
  160  #endif // __clang__
  161  
  162  ////////////////////////////////////////////////////////////////////////////////
  163  // Assume that non-Windows platforms support posix signals by default
  164  #if !defined(CATCH_PLATFORM_WINDOWS)
  165      #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
  166  #endif
  167  
  168  ////////////////////////////////////////////////////////////////////////////////
  169  // We know some environments not to support full POSIX signals
  170  #if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
  171      #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
  172  #endif
  173  
  174  #ifdef __OS400__
  175  #       define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
  176  #       define CATCH_CONFIG_COLOUR_NONE
  177  #endif
  178  
  179  ////////////////////////////////////////////////////////////////////////////////
  180  // Android somehow still does not support std::to_string
  181  #if defined(__ANDROID__)
  182  #    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
  183  #endif
  184  
  185  ////////////////////////////////////////////////////////////////////////////////
  186  // Not all Windows environments support SEH properly
  187  #if defined(__MINGW32__)
  188  #    define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
  189  #endif
  190  
  191  ////////////////////////////////////////////////////////////////////////////////
  192  // PS4
  193  #if defined(__ORBIS__)
  194  #    define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
  195  #endif
  196  
  197  ////////////////////////////////////////////////////////////////////////////////
  198  // Cygwin
  199  #ifdef __CYGWIN__
  200  
  201  // Required for some versions of Cygwin to declare gettimeofday
  202  // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
  203  #   define _BSD_SOURCE
  204  // some versions of cygwin (most) do not support std::to_string. Use the libstd check.
  205  // https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
  206  # if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
  207  	       && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
  208  
  209  #	define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
  210  
  211  # endif
  212  #endif // __CYGWIN__
  213  
  214  ////////////////////////////////////////////////////////////////////////////////
  215  // Visual C++
  216  #ifdef _MSC_VER
  217  
  218  #  if _MSC_VER >= 1900 // Visual Studio 2015 or newer
  219  #    define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
  220  #  endif
  221  
  222  // Universal Windows platform does not support SEH
  223  // Or console colours (or console at all...)
  224  #  if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
  225  #    define CATCH_CONFIG_COLOUR_NONE
  226  #  else
  227  #    define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
  228  #  endif
  229  
  230  // MSVC traditional preprocessor needs some workaround for __VA_ARGS__
  231  // _MSVC_TRADITIONAL == 0 means new conformant preprocessor
  232  // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
  233  #  if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
  234  #    define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  235  #  endif
  236  
  237  #endif // _MSC_VER
  238  
  239  ////////////////////////////////////////////////////////////////////////////////
  240  // Check if we are compiled with -fno-exceptions or equivalent
  241  #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
  242  #  define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
  243  #endif
  244  
  245  ////////////////////////////////////////////////////////////////////////////////
  246  // DJGPP
  247  #ifdef __DJGPP__
  248  #  define CATCH_INTERNAL_CONFIG_NO_WCHAR
  249  #endif // __DJGPP__
  250  
  251  ////////////////////////////////////////////////////////////////////////////////
  252  // Embarcadero C++Build
  253  #if defined(__BORLANDC__)
  254      #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN
  255  #endif
  256  
  257  ////////////////////////////////////////////////////////////////////////////////
  258  
  259  // Use of __COUNTER__ is suppressed during code analysis in
  260  // CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
  261  // handled by it.
  262  // Otherwise all supported compilers support COUNTER macro,
  263  // but user still might want to turn it off
  264  #if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
  265      #define CATCH_INTERNAL_CONFIG_COUNTER
  266  #endif
  267  
  268  ////////////////////////////////////////////////////////////////////////////////
  269  // Check if string_view is available and usable
  270  // The check is split apart to work around v140 (VS2015) preprocessor issue...
  271  #if defined(__has_include)
  272  #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
  273  #    define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
  274  #endif
  275  #endif
  276  
  277  ////////////////////////////////////////////////////////////////////////////////
  278  // Check if optional is available and usable
  279  #if defined(__has_include)
  280  #  if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
  281  #    define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
  282  #  endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
  283  #endif // __has_include
  284  
  285  ////////////////////////////////////////////////////////////////////////////////
  286  // Check if variant is available and usable
  287  #if defined(__has_include)
  288  #  if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
  289  #    if defined(__clang__) && (__clang_major__ < 8)
  290         // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
  291         // fix should be in clang 8, workaround in libstdc++ 8.2
  292  #      include <ciso646>
  293  #      if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
  294  #        define CATCH_CONFIG_NO_CPP17_VARIANT
  295  #      else
  296  #        define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
  297  #      endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
  298  #    else
  299  #      define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
  300  #    endif // defined(__clang__) && (__clang_major__ < 8)
  301  #  endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
  302  #endif // __has_include
  303  
  304  #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
  305  #   define CATCH_CONFIG_COUNTER
  306  #endif
  307  #if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH)
  308  #   define CATCH_CONFIG_WINDOWS_SEH
  309  #endif
  310  // This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
  311  #if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
  312  #   define CATCH_CONFIG_POSIX_SIGNALS
  313  #endif
  314  // This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.
  315  #if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
  316  #   define CATCH_CONFIG_WCHAR
  317  #endif
  318  
  319  #if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
  320  #    define CATCH_CONFIG_CPP11_TO_STRING
  321  #endif
  322  
  323  #if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL)
  324  #  define CATCH_CONFIG_CPP17_OPTIONAL
  325  #endif
  326  
  327  #if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
  328  #  define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
  329  #endif
  330  
  331  #if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
  332  #  define CATCH_CONFIG_CPP17_STRING_VIEW
  333  #endif
  334  
  335  #if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
  336  #  define CATCH_CONFIG_CPP17_VARIANT
  337  #endif
  338  
  339  #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
  340  #  define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
  341  #endif
  342  
  343  #if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE)
  344  #  define CATCH_CONFIG_NEW_CAPTURE
  345  #endif
  346  
  347  #if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  348  #  define CATCH_CONFIG_DISABLE_EXCEPTIONS
  349  #endif
  350  
  351  #if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN)
  352  #  define CATCH_CONFIG_POLYFILL_ISNAN
  353  #endif
  354  
  355  #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
  356  #   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
  357  #   define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
  358  #endif
  359  #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
  360  #   define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
  361  #   define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  362  #endif
  363  #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
  364  #   define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
  365  #   define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
  366  #endif
  367  
  368  #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  369  #define CATCH_TRY if ((true))
  370  #define CATCH_CATCH_ALL if ((false))
  371  #define CATCH_CATCH_ANON(type) if ((false))
  372  #else
  373  #define CATCH_TRY try
  374  #define CATCH_CATCH_ALL catch (...)
  375  #define CATCH_CATCH_ANON(type) catch (type)
  376  #endif
  377  
  378  #if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)
  379  #define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  380  #endif
  381  
  382  // end catch_compiler_capabilities.h
  383  #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
  384  #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
  385  #ifdef CATCH_CONFIG_COUNTER
  386  #  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
  387  #else
  388  #  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
  389  #endif
  390  
  391  #include <iosfwd>
  392  #include <string>
  393  #include <cstdint>
  394  
  395  // We need a dummy global operator<< so we can bring it into Catch namespace later
  396  struct Catch_global_namespace_dummy {};
  397  std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
  398  
  399  namespace Catch {
  400  
  401      struct CaseSensitive { enum Choice {
  402          Yes,
  403          No
  404      }; };
  405  
  406      class NonCopyable {
  407          NonCopyable( NonCopyable const& )              = delete;
  408          NonCopyable( NonCopyable && )                  = delete;
  409          NonCopyable& operator = ( NonCopyable const& ) = delete;
  410          NonCopyable& operator = ( NonCopyable && )     = delete;
  411  
  412      protected:
  413          NonCopyable();
  414          virtual ~NonCopyable();
  415      };
  416  
  417      struct SourceLineInfo {
  418  
  419          SourceLineInfo() = delete;
  420          SourceLineInfo( char const* _file, std::size_t _line ) noexcept
  421          :   file( _file ),
  422              line( _line )
  423          {}
  424  
  425          SourceLineInfo( SourceLineInfo const& other )            = default;
  426          SourceLineInfo& operator = ( SourceLineInfo const& )     = default;
  427          SourceLineInfo( SourceLineInfo&& )              noexcept = default;
  428          SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default;
  429  
  430          bool empty() const noexcept;
  431          bool operator == ( SourceLineInfo const& other ) const noexcept;
  432          bool operator < ( SourceLineInfo const& other ) const noexcept;
  433  
  434          char const* file;
  435          std::size_t line;
  436      };
  437  
  438      std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
  439  
  440      // Bring in operator<< from global namespace into Catch namespace
  441      // This is necessary because the overload of operator<< above makes
  442      // lookup stop at namespace Catch
  443      using ::operator<<;
  444  
  445      // Use this in variadic streaming macros to allow
  446      //    >> +StreamEndStop
  447      // as well as
  448      //    >> stuff +StreamEndStop
  449      struct StreamEndStop {
  450          std::string operator+() const;
  451      };
  452      template<typename T>
  453      T const& operator + ( T const& value, StreamEndStop ) {
  454          return value;
  455      }
  456  }
  457  
  458  #define CATCH_INTERNAL_LINEINFO \
  459      ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
  460  
  461  // end catch_common.h
  462  namespace Catch {
  463  
  464      struct RegistrarForTagAliases {
  465          RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
  466      };
  467  
  468  } // end namespace Catch
  469  
  470  #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
  471      CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  472      namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
  473      CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  474  
  475  // end catch_tag_alias_autoregistrar.h
  476  // start catch_test_registry.h
  477  
  478  // start catch_interfaces_testcase.h
  479  
  480  #include <vector>
  481  
  482  namespace Catch {
  483  
  484      class TestSpec;
  485  
  486      struct ITestInvoker {
  487          virtual void invoke () const = 0;
  488          virtual ~ITestInvoker();
  489      };
  490  
  491      class TestCase;
  492      struct IConfig;
  493  
  494      struct ITestCaseRegistry {
  495          virtual ~ITestCaseRegistry();
  496          virtual std::vector<TestCase> const& getAllTests() const = 0;
  497          virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
  498      };
  499  
  500      bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
  501      std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
  502      std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
  503  
  504  }
  505  
  506  // end catch_interfaces_testcase.h
  507  // start catch_stringref.h
  508  
  509  #include <cstddef>
  510  #include <string>
  511  #include <iosfwd>
  512  
  513  namespace Catch {
  514  
  515      /// A non-owning string class (similar to the forthcoming std::string_view)
  516      /// Note that, because a StringRef may be a substring of another string,
  517      /// it may not be null terminated. c_str() must return a null terminated
  518      /// string, however, and so the StringRef will internally take ownership
  519      /// (taking a copy), if necessary. In theory this ownership is not externally
  520      /// visible - but it does mean (substring) StringRefs should not be shared between
  521      /// threads.
  522      class StringRef {
  523      public:
  524          using size_type = std::size_t;
  525  
  526      private:
  527          friend struct StringRefTestAccess;
  528  
  529          char const* m_start;
  530          size_type m_size;
  531  
  532          char* m_data = nullptr;
  533  
  534          void takeOwnership();
  535  
  536          static constexpr char const* const s_empty = "";
  537  
  538      public: // construction/ assignment
  539          StringRef() noexcept
  540          :   StringRef( s_empty, 0 )
  541          {}
  542  
  543          StringRef( StringRef const& other ) noexcept
  544          :   m_start( other.m_start ),
  545              m_size( other.m_size )
  546          {}
  547  
  548          StringRef( StringRef&& other ) noexcept
  549          :   m_start( other.m_start ),
  550              m_size( other.m_size ),
  551              m_data( other.m_data )
  552          {
  553              other.m_data = nullptr;
  554          }
  555  
  556          StringRef( char const* rawChars ) noexcept;
  557  
  558          StringRef( char const* rawChars, size_type size ) noexcept
  559          :   m_start( rawChars ),
  560              m_size( size )
  561          {}
  562  
  563          StringRef( std::string const& stdString ) noexcept
  564          :   m_start( stdString.c_str() ),
  565              m_size( stdString.size() )
  566          {}
  567  
  568          ~StringRef() noexcept {
  569              delete[] m_data;
  570          }
  571  
  572          auto operator = ( StringRef const &other ) noexcept -> StringRef& {
  573              delete[] m_data;
  574              m_data = nullptr;
  575              m_start = other.m_start;
  576              m_size = other.m_size;
  577              return *this;
  578          }
  579  
  580          operator std::string() const;
  581  
  582          void swap( StringRef& other ) noexcept;
  583  
  584      public: // operators
  585          auto operator == ( StringRef const& other ) const noexcept -> bool;
  586          auto operator != ( StringRef const& other ) const noexcept -> bool;
  587  
  588          auto operator[] ( size_type index ) const noexcept -> char;
  589  
  590      public: // named queries
  591          auto empty() const noexcept -> bool {
  592              return m_size == 0;
  593          }
  594          auto size() const noexcept -> size_type {
  595              return m_size;
  596          }
  597  
  598          auto numberOfCharacters() const noexcept -> size_type;
  599          auto c_str() const -> char const*;
  600  
  601      public: // substrings and searches
  602          auto substr( size_type start, size_type size ) const noexcept -> StringRef;
  603  
  604          // Returns the current start pointer.
  605          // Note that the pointer can change when if the StringRef is a substring
  606          auto currentData() const noexcept -> char const*;
  607  
  608      private: // ownership queries - may not be consistent between calls
  609          auto isOwned() const noexcept -> bool;
  610          auto isSubstring() const noexcept -> bool;
  611      };
  612  
  613      auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string;
  614      auto operator + ( StringRef const& lhs, char const* rhs ) -> std::string;
  615      auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string;
  616  
  617      auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
  618      auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
  619  
  620      inline auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
  621          return StringRef( rawChars, size );
  622      }
  623  
  624  } // namespace Catch
  625  
  626  inline auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
  627      return Catch::StringRef( rawChars, size );
  628  }
  629  
  630  // end catch_stringref.h
  631  // start catch_type_traits.hpp
  632  
  633  
  634  #include <type_traits>
  635  
  636  namespace Catch{
  637  
  638  #ifdef CATCH_CPP17_OR_GREATER
  639  	template <typename...>
  640  	inline constexpr auto is_unique = std::true_type{};
  641  
  642  	template <typename T, typename... Rest>
  643  	inline constexpr auto is_unique<T, Rest...> = std::bool_constant<
  644  		(!std::is_same_v<T, Rest> && ...) && is_unique<Rest...>
  645  	>{};
  646  #else
  647  
  648  template <typename...>
  649  struct is_unique : std::true_type{};
  650  
  651  template <typename T0, typename T1, typename... Rest>
  652  struct is_unique<T0, T1, Rest...> : std::integral_constant
  653  <bool,
  654       !std::is_same<T0, T1>::value
  655       && is_unique<T0, Rest...>::value
  656       && is_unique<T1, Rest...>::value
  657  >{};
  658  
  659  #endif
  660  }
  661  
  662  // end catch_type_traits.hpp
  663  // start catch_preprocessor.hpp
  664  
  665  
  666  #define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__
  667  #define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))
  668  #define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))
  669  #define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__)))
  670  #define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__)))
  671  #define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__)))
  672  
  673  #ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  674  #define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__
  675  // MSVC needs more evaluations
  676  #define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__)))
  677  #define CATCH_RECURSE(...)  CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__))
  678  #else
  679  #define CATCH_RECURSE(...)  CATCH_RECURSION_LEVEL5(__VA_ARGS__)
  680  #endif
  681  
  682  #define CATCH_REC_END(...)
  683  #define CATCH_REC_OUT
  684  
  685  #define CATCH_EMPTY()
  686  #define CATCH_DEFER(id) id CATCH_EMPTY()
  687  
  688  #define CATCH_REC_GET_END2() 0, CATCH_REC_END
  689  #define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2
  690  #define CATCH_REC_GET_END(...) CATCH_REC_GET_END1
  691  #define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT
  692  #define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0)
  693  #define CATCH_REC_NEXT(test, next)  CATCH_REC_NEXT1(CATCH_REC_GET_END test, next)
  694  
  695  #define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
  696  #define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ )
  697  #define CATCH_REC_LIST2(f, x, peek, ...)   f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
  698  
  699  #define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )
  700  #define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ )
  701  #define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...)   f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )
  702  
  703  // Applies the function macro `f` to each of the remaining parameters, inserts commas between the results,
  704  // and passes userdata as the first parameter to each invocation,
  705  // e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c)
  706  #define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
  707  
  708  #define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
  709  
  710  #define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
  711  #define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__
  712  #define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
  713  #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
  714  #define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__)
  715  #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  716  #define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__
  717  #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param))
  718  #else
  719  // MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
  720  #define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__)
  721  #define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__
  722  #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1)
  723  #endif
  724  
  725  #define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)
  726  
  727  #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name, __VA_ARGS__)
  728  #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  729  #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name,...) Name " - " #__VA_ARGS__
  730  #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME(Name,...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
  731  #else
  732  // MSVC is adding extra space and needs more calls to properly remove ()
  733  #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name,...) Name " -" #__VA_ARGS__
  734  #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME1(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, __VA_ARGS__)
  735  #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME1(Name, INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
  736  #endif
  737  
  738  #define INTERNAL_CATCH_MAKE_TYPE_LIST(types) Catch::TypeList<INTERNAL_CATCH_REMOVE_PARENS(types)>
  739  
  740  #define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(types)\
  741      CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,INTERNAL_CATCH_REMOVE_PARENS(types))
  742  
  743  // end catch_preprocessor.hpp
  744  // start catch_meta.hpp
  745  
  746  
  747  #include <type_traits>
  748  
  749  namespace Catch {
  750  template< typename... >
  751  struct TypeList {};
  752  
  753  template< typename... >
  754  struct append;
  755  
  756  template< template<typename...> class L1
  757      , typename...E1
  758      , template<typename...> class L2
  759      , typename...E2
  760  >
  761  struct append< L1<E1...>, L2<E2...> > {
  762      using type = L1<E1..., E2...>;
  763  };
  764  
  765  template< template<typename...> class L1
  766      , typename...E1
  767      , template<typename...> class L2
  768      , typename...E2
  769      , typename...Rest
  770  >
  771  struct append< L1<E1...>, L2<E2...>, Rest...> {
  772      using type = typename append< L1<E1..., E2...>, Rest... >::type;
  773  };
  774  
  775  template< template<typename...> class
  776      , typename...
  777  >
  778  struct rewrap;
  779  
  780  template< template<typename...> class Container
  781      , template<typename...> class List
  782      , typename...elems
  783  >
  784  struct rewrap<Container, List<elems...>> {
  785      using type = TypeList< Container< elems... > >;
  786  };
  787  
  788  template< template<typename...> class Container
  789      , template<typename...> class List
  790      , class...Elems
  791      , typename...Elements>
  792      struct rewrap<Container, List<Elems...>, Elements...> {
  793      using type = typename append<TypeList<Container<Elems...>>, typename rewrap<Container, Elements...>::type>::type;
  794  };
  795  
  796  template< template<typename...> class...Containers >
  797  struct combine {
  798      template< typename...Types >
  799      struct with_types {
  800          template< template <typename...> class Final >
  801          struct into {
  802              using type = typename append<Final<>, typename rewrap<Containers, Types...>::type...>::type;
  803          };
  804      };
  805  };
  806  
  807  template<typename T>
  808  struct always_false : std::false_type {};
  809  
  810  } // namespace Catch
  811  
  812  // end catch_meta.hpp
  813  namespace Catch {
  814  
  815  template<typename C>
  816  class TestInvokerAsMethod : public ITestInvoker {
  817      void (C::*m_testAsMethod)();
  818  public:
  819      TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}
  820  
  821      void invoke() const override {
  822          C obj;
  823          (obj.*m_testAsMethod)();
  824      }
  825  };
  826  
  827  auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;
  828  
  829  template<typename C>
  830  auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {
  831      return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod );
  832  }
  833  
  834  struct NameAndTags {
  835      NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;
  836      StringRef name;
  837      StringRef tags;
  838  };
  839  
  840  struct AutoReg : NonCopyable {
  841      AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;
  842      ~AutoReg();
  843  };
  844  
  845  } // end namespace Catch
  846  
  847  #if defined(CATCH_CONFIG_DISABLE)
  848      #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
  849          static void TestName()
  850      #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
  851          namespace{                        \
  852              struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
  853                  void test();              \
  854              };                            \
  855          }                                 \
  856          void TestName::test()
  857      #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION( TestName, ... )  \
  858          template<typename TestType>                                             \
  859          static void TestName()
  860      #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... )    \
  861          namespace{                                                                                  \
  862              template<typename TestType>                                                             \
  863              struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) {     \
  864                  void test();                                                                        \
  865              };                                                                                      \
  866          }                                                                                           \
  867          template<typename TestType>                                                                 \
  868          void TestName::test()
  869  #endif
  870  
  871      ///////////////////////////////////////////////////////////////////////////////
  872      #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
  873          static void TestName(); \
  874          CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  875          namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
  876          CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  877          static void TestName()
  878      #define INTERNAL_CATCH_TESTCASE( ... ) \
  879          INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
  880  
  881      ///////////////////////////////////////////////////////////////////////////////
  882      #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
  883          CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  884          namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
  885          CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  886  
  887      ///////////////////////////////////////////////////////////////////////////////
  888      #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
  889          CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  890          namespace{ \
  891              struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
  892                  void test(); \
  893              }; \
  894              Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
  895          } \
  896          CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  897          void TestName::test()
  898      #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
  899          INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
  900  
  901      ///////////////////////////////////////////////////////////////////////////////
  902      #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
  903          CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  904          Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
  905          CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
  906  
  907      ///////////////////////////////////////////////////////////////////////////////
  908      #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, ... )\
  909          CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  910          template<typename TestType> \
  911          static void TestFunc();\
  912          namespace {\
  913              template<typename...Types> \
  914              struct TestName{\
  915                  template<typename...Ts> \
  916                  TestName(Ts...names){\
  917                      CATCH_INTERNAL_CHECK_UNIQUE_TYPES(CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)) \
  918                      using expander = int[];\
  919                      (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ names, Tags } ), 0)... };/* NOLINT */ \
  920                  }\
  921              };\
  922              INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestName, Name, __VA_ARGS__) \
  923          }\
  924          CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  925          template<typename TestType> \
  926          static void TestFunc()
  927  
  928  #if defined(CATCH_CPP17_OR_GREATER)
  929  #define CATCH_INTERNAL_CHECK_UNIQUE_TYPES(...) static_assert(Catch::is_unique<__VA_ARGS__>,"Duplicate type detected in declaration of template test case");
  930  #else
  931  #define CATCH_INTERNAL_CHECK_UNIQUE_TYPES(...) static_assert(Catch::is_unique<__VA_ARGS__>::value,"Duplicate type detected in declaration of template test case");
  932  #endif
  933  
  934  #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  935      #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
  936          INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, __VA_ARGS__ )
  937  #else
  938      #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
  939          INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, __VA_ARGS__ ) )
  940  #endif
  941  
  942      #define INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestName, Name, ...)\
  943          static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
  944              TestName<CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)>(CATCH_REC_LIST_UD(INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME,Name, __VA_ARGS__));\
  945              return 0;\
  946          }();
  947  
  948      #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, TmplTypes, TypesList) \
  949          CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                      \
  950          template<typename TestType> static void TestFuncName();       \
  951          namespace {                                                   \
  952              template<typename... Types>                               \
  953              struct TestName {                                         \
  954                  TestName() {                                          \
  955                      CATCH_INTERNAL_CHECK_UNIQUE_TYPES(Types...)       \
  956                      int index = 0;                                    \
  957                      using expander = int[];                           \
  958                      constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
  959                      constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
  960                      constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
  961                      (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */\
  962                  }                                                     \
  963              };                                                        \
  964              static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
  965                  using TestInit = Catch::combine<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)> \
  966                              ::with_types<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(TypesList)>::into<TestName>::type; \
  967                  TestInit();                                           \
  968                  return 0;                                             \
  969              }();                                                      \
  970          }                                                             \
  971          CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS                    \
  972          template<typename TestType>                                   \
  973          static void TestFuncName()
  974  
  975  #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  976      #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
  977          INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ),Name,Tags,__VA_ARGS__)
  978  #else
  979      #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
  980          INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, __VA_ARGS__ ) )
  981  #endif
  982  
  983      #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, ... ) \
  984          CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  985          namespace{ \
  986              template<typename TestType> \
  987              struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
  988                  void test();\
  989              };\
  990              template<typename...Types> \
  991              struct TestNameClass{\
  992                  template<typename...Ts> \
  993                  TestNameClass(Ts...names){\
  994                      CATCH_INTERNAL_CHECK_UNIQUE_TYPES(CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)) \
  995                      using expander = int[];\
  996                      (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ names, Tags } ), 0)... };/* NOLINT */ \
  997                  }\
  998              };\
  999              INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestNameClass, Name, __VA_ARGS__)\
 1000          }\
 1001          CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS\
 1002          template<typename TestType> \
 1003          void TestName<TestType>::test()
 1004  
 1005  #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
 1006      #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
 1007          INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, __VA_ARGS__ )
 1008  #else
 1009      #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
 1010          INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, __VA_ARGS__ ) )
 1011  #endif
 1012  
 1013      #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, TmplTypes, TypesList)\
 1014          CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
 1015          template<typename TestType> \
 1016              struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
 1017                  void test();\
 1018              };\
 1019          namespace {\
 1020              template<typename...Types>\
 1021              struct TestNameClass{\
 1022                  TestNameClass(){\
 1023                      CATCH_INTERNAL_CHECK_UNIQUE_TYPES(Types...)\
 1024                      int index = 0;\
 1025                      using expander = int[];\
 1026                      constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
 1027                      constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
 1028                      constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
 1029                      (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */ \
 1030                  }\
 1031              };\
 1032              static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
 1033                  using TestInit = Catch::combine<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>\
 1034                              ::with_types<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(TypesList)>::into<TestNameClass>::type;\
 1035                  TestInit();\
 1036                  return 0;\
 1037              }(); \
 1038          }\
 1039          CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
 1040          template<typename TestType> \
 1041          void TestName<TestType>::test()
 1042  
 1043  #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
 1044      #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
 1045          INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, __VA_ARGS__ )
 1046  #else
 1047      #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
 1048          INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, __VA_ARGS__ ) )
 1049  #endif
 1050  
 1051  // end catch_test_registry.h
 1052  // start catch_capture.hpp
 1053  
 1054  // start catch_assertionhandler.h
 1055  
 1056  // start catch_assertioninfo.h
 1057  
 1058  // start catch_result_type.h
 1059  
 1060  namespace Catch {
 1061  
 1062      // ResultWas::OfType enum
 1063      struct ResultWas { enum OfType {
 1064          Unknown = -1,
 1065          Ok = 0,
 1066          Info = 1,
 1067          Warning = 2,
 1068  
 1069          FailureBit = 0x10,
 1070  
 1071          ExpressionFailed = FailureBit | 1,
 1072          ExplicitFailure = FailureBit | 2,
 1073  
 1074          Exception = 0x100 | FailureBit,
 1075  
 1076          ThrewException = Exception | 1,
 1077          DidntThrowException = Exception | 2,
 1078  
 1079          FatalErrorCondition = 0x200 | FailureBit
 1080  
 1081      }; };
 1082  
 1083      bool isOk( ResultWas::OfType resultType );
 1084      bool isJustInfo( int flags );
 1085  
 1086      // ResultDisposition::Flags enum
 1087      struct ResultDisposition { enum Flags {
 1088          Normal = 0x01,
 1089  
 1090          ContinueOnFailure = 0x02,   // Failures fail test, but execution continues
 1091          FalseTest = 0x04,           // Prefix expression with !
 1092          SuppressFail = 0x08         // Failures are reported but do not fail the test
 1093      }; };
 1094  
 1095      ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs );
 1096  
 1097      bool shouldContinueOnFailure( int flags );
 1098      inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
 1099      bool shouldSuppressFailure( int flags );
 1100  
 1101  } // end namespace Catch
 1102  
 1103  // end catch_result_type.h
 1104  namespace Catch {
 1105  
 1106      struct AssertionInfo
 1107      {
 1108          StringRef macroName;
 1109          SourceLineInfo lineInfo;
 1110          StringRef capturedExpression;
 1111          ResultDisposition::Flags resultDisposition;
 1112  
 1113          // We want to delete this constructor but a compiler bug in 4.8 means
 1114          // the struct is then treated as non-aggregate
 1115          //AssertionInfo() = delete;
 1116      };
 1117  
 1118  } // end namespace Catch
 1119  
 1120  // end catch_assertioninfo.h
 1121  // start catch_decomposer.h
 1122  
 1123  // start catch_tostring.h
 1124  
 1125  #include <vector>
 1126  #include <cstddef>
 1127  #include <type_traits>
 1128  #include <string>
 1129  // start catch_stream.h
 1130  
 1131  #include <iosfwd>
 1132  #include <cstddef>
 1133  #include <ostream>
 1134  
 1135  namespace Catch {
 1136  
 1137      std::ostream& cout();
 1138      std::ostream& cerr();
 1139      std::ostream& clog();
 1140  
 1141      class StringRef;
 1142  
 1143      struct IStream {
 1144          virtual ~IStream();
 1145          virtual std::ostream& stream() const = 0;
 1146      };
 1147  
 1148      auto makeStream( StringRef const &filename ) -> IStream const*;
 1149  
 1150      class ReusableStringStream {
 1151          std::size_t m_index;
 1152          std::ostream* m_oss;
 1153      public:
 1154          ReusableStringStream();
 1155          ~ReusableStringStream();
 1156  
 1157          auto str() const -> std::string;
 1158  
 1159          template<typename T>
 1160          auto operator << ( T const& value ) -> ReusableStringStream& {
 1161              *m_oss << value;
 1162              return *this;
 1163          }
 1164          auto get() -> std::ostream& { return *m_oss; }
 1165      };
 1166  }
 1167  
 1168  // end catch_stream.h
 1169  
 1170  #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
 1171  #include <string_view>
 1172  #endif
 1173  
 1174  #ifdef __OBJC__
 1175  // start catch_objc_arc.hpp
 1176  
 1177  #import <Foundation/Foundation.h>
 1178  
 1179  #ifdef __has_feature
 1180  #define CATCH_ARC_ENABLED __has_feature(objc_arc)
 1181  #else
 1182  #define CATCH_ARC_ENABLED 0
 1183  #endif
 1184  
 1185  void arcSafeRelease( NSObject* obj );
 1186  id performOptionalSelector( id obj, SEL sel );
 1187  
 1188  #if !CATCH_ARC_ENABLED
 1189  inline void arcSafeRelease( NSObject* obj ) {
 1190      [obj release];
 1191  }
 1192  inline id performOptionalSelector( id obj, SEL sel ) {
 1193      if( [obj respondsToSelector: sel] )
 1194          return [obj performSelector: sel];
 1195      return nil;
 1196  }
 1197  #define CATCH_UNSAFE_UNRETAINED
 1198  #define CATCH_ARC_STRONG
 1199  #else
 1200  inline void arcSafeRelease( NSObject* ){}
 1201  inline id performOptionalSelector( id obj, SEL sel ) {
 1202  #ifdef __clang__
 1203  #pragma clang diagnostic push
 1204  #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
 1205  #endif
 1206      if( [obj respondsToSelector: sel] )
 1207          return [obj performSelector: sel];
 1208  #ifdef __clang__
 1209  #pragma clang diagnostic pop
 1210  #endif
 1211      return nil;
 1212  }
 1213  #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
 1214  #define CATCH_ARC_STRONG __strong
 1215  #endif
 1216  
 1217  // end catch_objc_arc.hpp
 1218  #endif
 1219  
 1220  #ifdef _MSC_VER
 1221  #pragma warning(push)
 1222  #pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
 1223  #endif
 1224  
 1225  namespace Catch {
 1226      namespace Detail {
 1227  
 1228          extern const std::string unprintableString;
 1229  
 1230          std::string rawMemoryToString( const void *object, std::size_t size );
 1231  
 1232          template<typename T>
 1233          std::string rawMemoryToString( const T& object ) {
 1234            return rawMemoryToString( &object, sizeof(object) );
 1235          }
 1236  
 1237          template<typename T>
 1238          class IsStreamInsertable {
 1239              template<typename SS, typename TT>
 1240              static auto test(int)
 1241                  -> decltype(std::declval<SS&>() << std::declval<TT>(), std::true_type());
 1242  
 1243              template<typename, typename>
 1244              static auto test(...)->std::false_type;
 1245  
 1246          public:
 1247              static const bool value = decltype(test<std::ostream, const T&>(0))::value;
 1248          };
 1249  
 1250          template<typename E>
 1251          std::string convertUnknownEnumToString( E e );
 1252  
 1253          template<typename T>
 1254          typename std::enable_if<
 1255              !std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value,
 1256          std::string>::type convertUnstreamable( T const& ) {
 1257              return Detail::unprintableString;
 1258          }
 1259          template<typename T>
 1260          typename std::enable_if<
 1261              !std::is_enum<T>::value && std::is_base_of<std::exception, T>::value,
 1262           std::string>::type convertUnstreamable(T const& ex) {
 1263              return ex.what();
 1264          }
 1265  
 1266          template<typename T>
 1267          typename std::enable_if<
 1268              std::is_enum<T>::value
 1269          , std::string>::type convertUnstreamable( T const& value ) {
 1270              return convertUnknownEnumToString( value );
 1271          }
 1272  
 1273  #if defined(_MANAGED)
 1274          //! Convert a CLR string to a utf8 std::string
 1275          template<typename T>
 1276          std::string clrReferenceToString( T^ ref ) {
 1277              if (ref == nullptr)
 1278                  return std::string("null");
 1279              auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
 1280              cli::pin_ptr<System::Byte> p = &bytes[0];
 1281              return std::string(reinterpret_cast<char const *>(p), bytes->Length);
 1282          }
 1283  #endif
 1284  
 1285      } // namespace Detail
 1286  
 1287      // If we decide for C++14, change these to enable_if_ts
 1288      template <typename T, typename = void>
 1289      struct StringMaker {
 1290          template <typename Fake = T>
 1291          static
 1292          typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
 1293              convert(const Fake& value) {
 1294                  ReusableStringStream rss;
 1295                  // NB: call using the function-like syntax to avoid ambiguity with
 1296                  // user-defined templated operator<< under clang.
 1297                  rss.operator<<(value);
 1298                  return rss.str();
 1299          }
 1300  
 1301          template <typename Fake = T>
 1302          static
 1303          typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
 1304              convert( const Fake& value ) {
 1305  #if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
 1306              return Detail::convertUnstreamable(value);
 1307  #else
 1308              return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
 1309  #endif
 1310          }
 1311      };
 1312  
 1313      namespace Detail {
 1314  
 1315          // This function dispatches all stringification requests inside of Catch.
 1316          // Should be preferably called fully qualified, like ::Catch::Detail::stringify
 1317          template <typename T>
 1318          std::string stringify(const T& e) {
 1319              return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);
 1320          }
 1321  
 1322          template<typename E>
 1323          std::string convertUnknownEnumToString( E e ) {
 1324              return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));
 1325          }
 1326  
 1327  #if defined(_MANAGED)
 1328          template <typename T>
 1329          std::string stringify( T^ e ) {
 1330              return ::Catch::StringMaker<T^>::convert(e);
 1331          }
 1332  #endif
 1333  
 1334      } // namespace Detail
 1335  
 1336      // Some predefined specializations
 1337  
 1338      template<>
 1339      struct StringMaker<std::string> {
 1340          static std::string convert(const std::string& str);
 1341      };
 1342  
 1343  #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
 1344      template<>
 1345      struct StringMaker<std::string_view> {
 1346          static std::string convert(std::string_view str);
 1347      };
 1348  #endif
 1349  
 1350      template<>
 1351      struct StringMaker<char const *> {
 1352          static std::string convert(char const * str);
 1353      };
 1354      template<>
 1355      struct StringMaker<char *> {
 1356          static std::string convert(char * str);
 1357      };
 1358  
 1359  #ifdef CATCH_CONFIG_WCHAR
 1360      template<>
 1361      struct StringMaker<std::wstring> {
 1362          static std::string convert(const std::wstring& wstr);
 1363      };
 1364  
 1365  # ifdef CATCH_CONFIG_CPP17_STRING_VIEW
 1366      template<>
 1367      struct StringMaker<std::wstring_view> {
 1368          static std::string convert(std::wstring_view str);
 1369      };
 1370  # endif
 1371  
 1372      template<>
 1373      struct StringMaker<wchar_t const *> {
 1374          static std::string convert(wchar_t const * str);
 1375      };
 1376      template<>
 1377      struct StringMaker<wchar_t *> {
 1378          static std::string convert(wchar_t * str);
 1379      };
 1380  #endif
 1381  
 1382      // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
 1383      //      while keeping string semantics?
 1384      template<int SZ>
 1385      struct StringMaker<char[SZ]> {
 1386          static std::string convert(char const* str) {
 1387              return ::Catch::Detail::stringify(std::string{ str });
 1388          }
 1389      };
 1390      template<int SZ>
 1391      struct StringMaker<signed char[SZ]> {
 1392          static std::string convert(signed char const* str) {
 1393              return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
 1394          }
 1395      };
 1396      template<int SZ>
 1397      struct StringMaker<unsigned char[SZ]> {
 1398          static std::string convert(unsigned char const* str) {
 1399              return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
 1400          }
 1401      };
 1402  
 1403      template<>
 1404      struct StringMaker<int> {
 1405          static std::string convert(int value);
 1406      };
 1407      template<>
 1408      struct StringMaker<long> {
 1409          static std::string convert(long value);
 1410      };
 1411      template<>
 1412      struct StringMaker<long long> {
 1413          static std::string convert(long long value);
 1414      };
 1415      template<>
 1416      struct StringMaker<unsigned int> {
 1417          static std::string convert(unsigned int value);
 1418      };
 1419      template<>
 1420      struct StringMaker<unsigned long> {
 1421          static std::string convert(unsigned long value);
 1422      };
 1423      template<>
 1424      struct StringMaker<unsigned long long> {
 1425          static std::string convert(unsigned long long value);
 1426      };
 1427  
 1428      template<>
 1429      struct StringMaker<bool> {
 1430          static std::string convert(bool b);
 1431      };
 1432  
 1433      template<>
 1434      struct StringMaker<char> {
 1435          static std::string convert(char c);
 1436      };
 1437      template<>
 1438      struct StringMaker<signed char> {
 1439          static std::string convert(signed char c);
 1440      };
 1441      template<>
 1442      struct StringMaker<unsigned char> {
 1443          static std::string convert(unsigned char c);
 1444      };
 1445  
 1446      template<>
 1447      struct StringMaker<std::nullptr_t> {
 1448          static std::string convert(std::nullptr_t);
 1449      };
 1450  
 1451      template<>
 1452      struct StringMaker<float> {
 1453          static std::string convert(float value);
 1454      };
 1455      template<>
 1456      struct StringMaker<double> {
 1457          static std::string convert(double value);
 1458      };
 1459  
 1460      template <typename T>
 1461      struct StringMaker<T*> {
 1462          template <typename U>
 1463          static std::string convert(U* p) {
 1464              if (p) {
 1465                  return ::Catch::Detail::rawMemoryToString(p);
 1466              } else {
 1467                  return "nullptr";
 1468              }
 1469          }
 1470      };
 1471  
 1472      template <typename R, typename C>
 1473      struct StringMaker<R C::*> {
 1474          static std::string convert(R C::* p) {
 1475              if (p) {
 1476                  return ::Catch::Detail::rawMemoryToString(p);
 1477              } else {
 1478                  return "nullptr";
 1479              }
 1480          }
 1481      };
 1482  
 1483  #if defined(_MANAGED)
 1484      template <typename T>
 1485      struct StringMaker<T^> {
 1486          static std::string convert( T^ ref ) {
 1487              return ::Catch::Detail::clrReferenceToString(ref);
 1488          }
 1489      };
 1490  #endif
 1491  
 1492      namespace Detail {
 1493          template<typename InputIterator>
 1494          std::string rangeToString(InputIterator first, InputIterator last) {
 1495              ReusableStringStream rss;
 1496              rss << "{ ";
 1497              if (first != last) {
 1498                  rss << ::Catch::Detail::stringify(*first);
 1499                  for (++first; first != last; ++first)
 1500                      rss << ", " << ::Catch::Detail::stringify(*first);
 1501              }
 1502              rss << " }";
 1503              return rss.str();
 1504          }
 1505      }
 1506  
 1507  #ifdef __OBJC__
 1508      template<>
 1509      struct StringMaker<NSString*> {
 1510          static std::string convert(NSString * nsstring) {
 1511              if (!nsstring)
 1512                  return "nil";
 1513              return std::string("@") + [nsstring UTF8String];
 1514          }
 1515      };
 1516      template<>
 1517      struct StringMaker<NSObject*> {
 1518          static std::string convert(NSObject* nsObject) {
 1519              return ::Catch::Detail::stringify([nsObject description]);
 1520          }
 1521  
 1522      };
 1523      namespace Detail {
 1524          inline std::string stringify( NSString* nsstring ) {
 1525              return StringMaker<NSString*>::convert( nsstring );
 1526          }
 1527  
 1528      } // namespace Detail
 1529  #endif // __OBJC__
 1530  
 1531  } // namespace Catch
 1532  
 1533  //////////////////////////////////////////////////////
 1534  // Separate std-lib types stringification, so it can be selectively enabled
 1535  // This means that we do not bring in
 1536  
 1537  #if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
 1538  #  define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
 1539  #  define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
 1540  #  define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
 1541  #  define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
 1542  #  define CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
 1543  #endif
 1544  
 1545  // Separate std::pair specialization
 1546  #if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
 1547  #include <utility>
 1548  namespace Catch {
 1549      template<typename T1, typename T2>
 1550      struct StringMaker<std::pair<T1, T2> > {
 1551          static std::string convert(const std::pair<T1, T2>& pair) {
 1552              ReusableStringStream rss;
 1553              rss << "{ "
 1554                  << ::Catch::Detail::stringify(pair.first)
 1555                  << ", "
 1556                  << ::Catch::Detail::stringify(pair.second)
 1557                  << " }";
 1558              return rss.str();
 1559          }
 1560      };
 1561  }
 1562  #endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
 1563  
 1564  #if defined(CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_OPTIONAL)
 1565  #include <optional>
 1566  namespace Catch {
 1567      template<typename T>
 1568      struct StringMaker<std::optional<T> > {
 1569          static std::string convert(const std::optional<T>& optional) {
 1570              ReusableStringStream rss;
 1571              if (optional.has_value()) {
 1572                  rss << ::Catch::Detail::stringify(*optional);
 1573              } else {
 1574                  rss << "{ }";
 1575              }
 1576              return rss.str();
 1577          }
 1578      };
 1579  }
 1580  #endif // CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
 1581  
 1582  // Separate std::tuple specialization
 1583  #if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
 1584  #include <tuple>
 1585  namespace Catch {
 1586      namespace Detail {
 1587          template<
 1588              typename Tuple,
 1589              std::size_t N = 0,
 1590              bool = (N < std::tuple_size<Tuple>::value)
 1591              >
 1592              struct TupleElementPrinter {
 1593              static void print(const Tuple& tuple, std::ostream& os) {
 1594                  os << (N ? ", " : " ")
 1595                      << ::Catch::Detail::stringify(std::get<N>(tuple));
 1596                  TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
 1597              }
 1598          };
 1599  
 1600          template<
 1601              typename Tuple,
 1602              std::size_t N
 1603          >
 1604              struct TupleElementPrinter<Tuple, N, false> {
 1605              static void print(const Tuple&, std::ostream&) {}
 1606          };
 1607  
 1608      }
 1609  
 1610      template<typename ...Types>
 1611      struct StringMaker<std::tuple<Types...>> {
 1612          static std::string convert(const std::tuple<Types...>& tuple) {
 1613              ReusableStringStream rss;
 1614              rss << '{';
 1615              Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
 1616              rss << " }";
 1617              return rss.str();
 1618          }
 1619      };
 1620  }
 1621  #endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
 1622  
 1623  #if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
 1624  #include <variant>
 1625  namespace Catch {
 1626      template<>
 1627      struct StringMaker<std::monostate> {
 1628          static std::string convert(const std::monostate&) {
 1629              return "{ }";
 1630          }
 1631      };
 1632  
 1633      template<typename... Elements>
 1634      struct StringMaker<std::variant<Elements...>> {
 1635          static std::string convert(const std::variant<Elements...>& variant) {
 1636              if (variant.valueless_by_exception()) {
 1637                  return "{valueless variant}";
 1638              } else {
 1639                  return std::visit(
 1640                      [](const auto& value) {
 1641                          return ::Catch::Detail::stringify(value);
 1642                      },
 1643                      variant
 1644                  );
 1645              }
 1646          }
 1647      };
 1648  }
 1649  #endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
 1650  
 1651  namespace Catch {
 1652      struct not_this_one {}; // Tag type for detecting which begin/ end are being selected
 1653  
 1654      // Import begin/ end from std here so they are considered alongside the fallback (...) overloads in this namespace
 1655      using std::begin;
 1656      using std::end;
 1657  
 1658      not_this_one begin( ... );
 1659      not_this_one end( ... );
 1660  
 1661      template <typename T>
 1662      struct is_range {
 1663          static const bool value =
 1664              !std::is_same<decltype(begin(std::declval<T>())), not_this_one>::value &&
 1665              !std::is_same<decltype(end(std::declval<T>())), not_this_one>::value;
 1666      };
 1667  
 1668  #if defined(_MANAGED) // Managed types are never ranges
 1669      template <typename T>
 1670      struct is_range<T^> {
 1671          static const bool value = false;
 1672      };
 1673  #endif
 1674  
 1675      template<typename Range>
 1676      std::string rangeToString( Range const& range ) {
 1677          return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
 1678      }
 1679  
 1680      // Handle vector<bool> specially
 1681      template<typename Allocator>
 1682      std::string rangeToString( std::vector<bool, Allocator> const& v ) {
 1683          ReusableStringStream rss;
 1684          rss << "{ ";
 1685          bool first = true;
 1686          for( bool b : v ) {
 1687              if( first )
 1688                  first = false;
 1689              else
 1690                  rss << ", ";
 1691              rss << ::Catch::Detail::stringify( b );
 1692          }
 1693          rss << " }";
 1694          return rss.str();
 1695      }
 1696  
 1697      template<typename R>
 1698      struct StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {
 1699          static std::string convert( R const& range ) {
 1700              return rangeToString( range );
 1701          }
 1702      };
 1703  
 1704      template <typename T, int SZ>
 1705      struct StringMaker<T[SZ]> {
 1706          static std::string convert(T const(&arr)[SZ]) {
 1707              return rangeToString(arr);
 1708          }
 1709      };
 1710  
 1711  } // namespace Catch
 1712  
 1713  // Separate std::chrono::duration specialization
 1714  #if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
 1715  #include <ctime>
 1716  #include <ratio>
 1717  #include <chrono>
 1718  
 1719  namespace Catch {
 1720  
 1721  template <class Ratio>
 1722  struct ratio_string {
 1723      static std::string symbol();
 1724  };
 1725  
 1726  template <class Ratio>
 1727  std::string ratio_string<Ratio>::symbol() {
 1728      Catch::ReusableStringStream rss;
 1729      rss << '[' << Ratio::num << '/'
 1730          << Ratio::den << ']';
 1731      return rss.str();
 1732  }
 1733  template <>
 1734  struct ratio_string<std::atto> {
 1735      static std::string symbol();
 1736  };
 1737  template <>
 1738  struct ratio_string<std::femto> {
 1739      static std::string symbol();
 1740  };
 1741  template <>
 1742  struct ratio_string<std::pico> {
 1743      static std::string symbol();
 1744  };
 1745  template <>
 1746  struct ratio_string<std::nano> {
 1747      static std::string symbol();
 1748  };
 1749  template <>
 1750  struct ratio_string<std::micro> {
 1751      static std::string symbol();
 1752  };
 1753  template <>
 1754  struct ratio_string<std::milli> {
 1755      static std::string symbol();
 1756  };
 1757  
 1758      ////////////
 1759      // std::chrono::duration specializations
 1760      template<typename Value, typename Ratio>
 1761      struct StringMaker<std::chrono::duration<Value, Ratio>> {
 1762          static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
 1763              ReusableStringStream rss;
 1764              rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
 1765              return rss.str();
 1766          }
 1767      };
 1768      template<typename Value>
 1769      struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
 1770          static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
 1771              ReusableStringStream rss;
 1772              rss << duration.count() << " s";
 1773              return rss.str();
 1774          }
 1775      };
 1776      template<typename Value>
 1777      struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
 1778          static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
 1779              ReusableStringStream rss;
 1780              rss << duration.count() << " m";
 1781              return rss.str();
 1782          }
 1783      };
 1784      template<typename Value>
 1785      struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
 1786          static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
 1787              ReusableStringStream rss;
 1788              rss << duration.count() << " h";
 1789              return rss.str();
 1790          }
 1791      };
 1792  
 1793      ////////////
 1794      // std::chrono::time_point specialization
 1795      // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
 1796      template<typename Clock, typename Duration>
 1797      struct StringMaker<std::chrono::time_point<Clock, Duration>> {
 1798          static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {
 1799              return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
 1800          }
 1801      };
 1802      // std::chrono::time_point<system_clock> specialization
 1803      template<typename Duration>
 1804      struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
 1805          static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
 1806              auto converted = std::chrono::system_clock::to_time_t(time_point);
 1807  
 1808  #ifdef _MSC_VER
 1809              std::tm timeInfo = {};
 1810              gmtime_s(&timeInfo, &converted);
 1811  #else
 1812              std::tm* timeInfo = std::gmtime(&converted);
 1813  #endif
 1814  
 1815              auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
 1816              char timeStamp[timeStampSize];
 1817              const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
 1818  
 1819  #ifdef _MSC_VER
 1820              std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
 1821  #else
 1822              std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
 1823  #endif
 1824              return std::string(timeStamp);
 1825          }
 1826      };
 1827  }
 1828  #endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
 1829  
 1830  #ifdef _MSC_VER
 1831  #pragma warning(pop)
 1832  #endif
 1833  
 1834  // end catch_tostring.h
 1835  #include <iosfwd>
 1836  
 1837  #ifdef _MSC_VER
 1838  #pragma warning(push)
 1839  #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
 1840  #pragma warning(disable:4018) // more "signed/unsigned mismatch"
 1841  #pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
 1842  #pragma warning(disable:4180) // qualifier applied to function type has no meaning
 1843  #pragma warning(disable:4800) // Forcing result to true or false
 1844  #endif
 1845  
 1846  namespace Catch {
 1847  
 1848      struct ITransientExpression {
 1849          auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
 1850          auto getResult() const -> bool { return m_result; }
 1851          virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
 1852  
 1853          ITransientExpression( bool isBinaryExpression, bool result )
 1854          :   m_isBinaryExpression( isBinaryExpression ),
 1855              m_result( result )
 1856          {}
 1857  
 1858          // We don't actually need a virtual destructor, but many static analysers
 1859          // complain if it's not here :-(
 1860          virtual ~ITransientExpression();
 1861  
 1862          bool m_isBinaryExpression;
 1863          bool m_result;
 1864  
 1865      };
 1866  
 1867      void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
 1868  
 1869      template<typename LhsT, typename RhsT>
 1870      class BinaryExpr  : public ITransientExpression {
 1871          LhsT m_lhs;
 1872          StringRef m_op;
 1873          RhsT m_rhs;
 1874  
 1875          void streamReconstructedExpression( std::ostream &os ) const override {
 1876              formatReconstructedExpression
 1877                      ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
 1878          }
 1879  
 1880      public:
 1881          BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
 1882          :   ITransientExpression{ true, comparisonResult },
 1883              m_lhs( lhs ),
 1884              m_op( op ),
 1885              m_rhs( rhs )
 1886          {}
 1887  
 1888          template<typename T>
 1889          auto operator && ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
 1890              static_assert(always_false<T>::value,
 1891              "chained comparisons are not supported inside assertions, "
 1892              "wrap the expression inside parentheses, or decompose it");
 1893          }
 1894  
 1895          template<typename T>
 1896          auto operator || ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
 1897              static_assert(always_false<T>::value,
 1898              "chained comparisons are not supported inside assertions, "
 1899              "wrap the expression inside parentheses, or decompose it");
 1900          }
 1901  
 1902          template<typename T>
 1903          auto operator == ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
 1904              static_assert(always_false<T>::value,
 1905              "chained comparisons are not supported inside assertions, "
 1906              "wrap the expression inside parentheses, or decompose it");
 1907          }
 1908  
 1909          template<typename T>
 1910          auto operator != ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
 1911              static_assert(always_false<T>::value,
 1912              "chained comparisons are not supported inside assertions, "
 1913              "wrap the expression inside parentheses, or decompose it");
 1914          }
 1915  
 1916          template<typename T>
 1917          auto operator > ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
 1918              static_assert(always_false<T>::value,
 1919              "chained comparisons are not supported inside assertions, "
 1920              "wrap the expression inside parentheses, or decompose it");
 1921          }
 1922  
 1923          template<typename T>
 1924          auto operator < ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
 1925              static_assert(always_false<T>::value,
 1926              "chained comparisons are not supported inside assertions, "
 1927              "wrap the expression inside parentheses, or decompose it");
 1928          }
 1929  
 1930          template<typename T>
 1931          auto operator >= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
 1932              static_assert(always_false<T>::value,
 1933              "chained comparisons are not supported inside assertions, "
 1934              "wrap the expression inside parentheses, or decompose it");
 1935          }
 1936  
 1937          template<typename T>
 1938          auto operator <= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
 1939              static_assert(always_false<T>::value,
 1940              "chained comparisons are not supported inside assertions, "
 1941              "wrap the expression inside parentheses, or decompose it");
 1942          }
 1943      };
 1944  
 1945      template<typename LhsT>
 1946      class UnaryExpr : public ITransientExpression {
 1947          LhsT m_lhs;
 1948  
 1949          void streamReconstructedExpression( std::ostream &os ) const override {
 1950              os << Catch::Detail::stringify( m_lhs );
 1951          }
 1952  
 1953      public:
 1954          explicit UnaryExpr( LhsT lhs )
 1955          :   ITransientExpression{ false, static_cast<bool>(lhs) },
 1956              m_lhs( lhs )
 1957          {}
 1958      };
 1959  
 1960      // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
 1961      template<typename LhsT, typename RhsT>
 1962      auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }
 1963      template<typename T>
 1964      auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
 1965      template<typename T>
 1966      auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
 1967      template<typename T>
 1968      auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
 1969      template<typename T>
 1970      auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
 1971  
 1972      template<typename LhsT, typename RhsT>
 1973      auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }
 1974      template<typename T>
 1975      auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
 1976      template<typename T>
 1977      auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
 1978      template<typename T>
 1979      auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
 1980      template<typename T>
 1981      auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
 1982  
 1983      template<typename LhsT>
 1984      class ExprLhs {
 1985          LhsT m_lhs;
 1986      public:
 1987          explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
 1988  
 1989          template<typename RhsT>
 1990          auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
 1991              return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs };
 1992          }
 1993          auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
 1994              return { m_lhs == rhs, m_lhs, "==", rhs };
 1995          }
 1996  
 1997          template<typename RhsT>
 1998          auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
 1999              return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs };
 2000          }
 2001          auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
 2002              return { m_lhs != rhs, m_lhs, "!=", rhs };
 2003          }
 2004  
 2005          template<typename RhsT>
 2006          auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
 2007              return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs };
 2008          }
 2009          template<typename RhsT>
 2010          auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
 2011              return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs };
 2012          }
 2013          template<typename RhsT>
 2014          auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
 2015              return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs };
 2016          }
 2017          template<typename RhsT>
 2018          auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
 2019              return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs };
 2020          }
 2021  
 2022          template<typename RhsT>
 2023          auto operator && ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
 2024              static_assert(always_false<RhsT>::value,
 2025              "operator&& is not supported inside assertions, "
 2026              "wrap the expression inside parentheses, or decompose it");
 2027          }
 2028  
 2029          template<typename RhsT>
 2030          auto operator || ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
 2031              static_assert(always_false<RhsT>::value,
 2032              "operator|| is not supported inside assertions, "
 2033              "wrap the expression inside parentheses, or decompose it");
 2034          }
 2035  
 2036          auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
 2037              return UnaryExpr<LhsT>{ m_lhs };
 2038          }
 2039      };
 2040  
 2041      void handleExpression( ITransientExpression const& expr );
 2042  
 2043      template<typename T>
 2044      void handleExpression( ExprLhs<T> const& expr ) {
 2045          handleExpression( expr.makeUnaryExpr() );
 2046      }
 2047  
 2048      struct Decomposer {
 2049          template<typename T>
 2050          auto operator <= ( T const& lhs ) -> ExprLhs<T const&> {
 2051              return ExprLhs<T const&>{ lhs };
 2052          }
 2053  
 2054          auto operator <=( bool value ) -> ExprLhs<bool> {
 2055              return ExprLhs<bool>{ value };
 2056          }
 2057      };
 2058  
 2059  } // end namespace Catch
 2060  
 2061  #ifdef _MSC_VER
 2062  #pragma warning(pop)
 2063  #endif
 2064  
 2065  // end catch_decomposer.h
 2066  // start catch_interfaces_capture.h
 2067  
 2068  #include <string>
 2069  
 2070  namespace Catch {
 2071  
 2072      class AssertionResult;
 2073      struct AssertionInfo;
 2074      struct SectionInfo;
 2075      struct SectionEndInfo;
 2076      struct MessageInfo;
 2077      struct MessageBuilder;
 2078      struct Counts;
 2079      struct BenchmarkInfo;
 2080      struct BenchmarkStats;
 2081      struct AssertionReaction;
 2082      struct SourceLineInfo;
 2083  
 2084      struct ITransientExpression;
 2085      struct IGeneratorTracker;
 2086  
 2087      struct IResultCapture {
 2088  
 2089          virtual ~IResultCapture();
 2090  
 2091          virtual bool sectionStarted(    SectionInfo const& sectionInfo,
 2092                                          Counts& assertions ) = 0;
 2093          virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
 2094          virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
 2095  
 2096          virtual auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
 2097  
 2098          virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
 2099          virtual void benchmarkEnded( BenchmarkStats const& stats ) = 0;
 2100  
 2101          virtual void pushScopedMessage( MessageInfo const& message ) = 0;
 2102          virtual void popScopedMessage( MessageInfo const& message ) = 0;
 2103  
 2104          virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0;
 2105  
 2106          virtual void handleFatalErrorCondition( StringRef message ) = 0;
 2107  
 2108          virtual void handleExpr
 2109                  (   AssertionInfo const& info,
 2110                      ITransientExpression const& expr,
 2111                      AssertionReaction& reaction ) = 0;
 2112          virtual void handleMessage
 2113                  (   AssertionInfo const& info,
 2114                      ResultWas::OfType resultType,
 2115                      StringRef const& message,
 2116                      AssertionReaction& reaction ) = 0;
 2117          virtual void handleUnexpectedExceptionNotThrown
 2118                  (   AssertionInfo const& info,
 2119                      AssertionReaction& reaction ) = 0;
 2120          virtual void handleUnexpectedInflightException
 2121                  (   AssertionInfo const& info,
 2122                      std::string const& message,
 2123                      AssertionReaction& reaction ) = 0;
 2124          virtual void handleIncomplete
 2125                  (   AssertionInfo const& info ) = 0;
 2126          virtual void handleNonExpr
 2127                  (   AssertionInfo const &info,
 2128                      ResultWas::OfType resultType,
 2129                      AssertionReaction &reaction ) = 0;
 2130  
 2131          virtual bool lastAssertionPassed() = 0;
 2132          virtual void assertionPassed() = 0;
 2133  
 2134          // Deprecated, do not use:
 2135          virtual std::string getCurrentTestName() const = 0;
 2136          virtual const AssertionResult* getLastResult() const = 0;
 2137          virtual void exceptionEarlyReported() = 0;
 2138      };
 2139  
 2140      IResultCapture& getResultCapture();
 2141  }
 2142  
 2143  // end catch_interfaces_capture.h
 2144  namespace Catch {
 2145  
 2146      struct TestFailureException{};
 2147      struct AssertionResultData;
 2148      struct IResultCapture;
 2149      class RunContext;
 2150  
 2151      class LazyExpression {
 2152          friend class AssertionHandler;
 2153          friend struct AssertionStats;
 2154          friend class RunContext;
 2155  
 2156          ITransientExpression const* m_transientExpression = nullptr;
 2157          bool m_isNegated;
 2158      public:
 2159          LazyExpression( bool isNegated );
 2160          LazyExpression( LazyExpression const& other );
 2161          LazyExpression& operator = ( LazyExpression const& ) = delete;
 2162  
 2163          explicit operator bool() const;
 2164  
 2165          friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&;
 2166      };
 2167  
 2168      struct AssertionReaction {
 2169          bool shouldDebugBreak = false;
 2170          bool shouldThrow = false;
 2171      };
 2172  
 2173      class AssertionHandler {
 2174          AssertionInfo m_assertionInfo;
 2175          AssertionReaction m_reaction;
 2176          bool m_completed = false;
 2177          IResultCapture& m_resultCapture;
 2178  
 2179      public:
 2180          AssertionHandler
 2181              (   StringRef const& macroName,
 2182                  SourceLineInfo const& lineInfo,
 2183                  StringRef capturedExpression,
 2184                  ResultDisposition::Flags resultDisposition );
 2185          ~AssertionHandler() {
 2186              if ( !m_completed ) {
 2187                  m_resultCapture.handleIncomplete( m_assertionInfo );
 2188              }
 2189          }
 2190  
 2191          template<typename T>
 2192          void handleExpr( ExprLhs<T> const& expr ) {
 2193              handleExpr( expr.makeUnaryExpr() );
 2194          }
 2195          void handleExpr( ITransientExpression const& expr );
 2196  
 2197          void handleMessage(ResultWas::OfType resultType, StringRef const& message);
 2198  
 2199          void handleExceptionThrownAsExpected();
 2200          void handleUnexpectedExceptionNotThrown();
 2201          void handleExceptionNotThrownAsExpected();
 2202          void handleThrowingCallSkipped();
 2203          void handleUnexpectedInflightException();
 2204  
 2205          void complete();
 2206          void setCompleted();
 2207  
 2208          // query
 2209          auto allowThrows() const -> bool;
 2210      };
 2211  
 2212      void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString );
 2213  
 2214  } // namespace Catch
 2215  
 2216  // end catch_assertionhandler.h
 2217  // start catch_message.h
 2218  
 2219  #include <string>
 2220  #include <vector>
 2221  
 2222  namespace Catch {
 2223  
 2224      struct MessageInfo {
 2225          MessageInfo(    StringRef const& _macroName,
 2226                          SourceLineInfo const& _lineInfo,
 2227                          ResultWas::OfType _type );
 2228  
 2229          StringRef macroName;
 2230          std::string message;
 2231          SourceLineInfo lineInfo;
 2232          ResultWas::OfType type;
 2233          unsigned int sequence;
 2234  
 2235          bool operator == ( MessageInfo const& other ) const;
 2236          bool operator < ( MessageInfo const& other ) const;
 2237      private:
 2238          static unsigned int globalCount;
 2239      };
 2240  
 2241      struct MessageStream {
 2242  
 2243          template<typename T>
 2244          MessageStream& operator << ( T const& value ) {
 2245              m_stream << value;
 2246              return *this;
 2247          }
 2248  
 2249          ReusableStringStream m_stream;
 2250      };
 2251  
 2252      struct MessageBuilder : MessageStream {
 2253          MessageBuilder( StringRef const& macroName,
 2254                          SourceLineInfo const& lineInfo,
 2255                          ResultWas::OfType type );
 2256  
 2257          template<typename T>
 2258          MessageBuilder& operator << ( T const& value ) {
 2259              m_stream << value;
 2260              return *this;
 2261          }
 2262  
 2263          MessageInfo m_info;
 2264      };
 2265  
 2266      class ScopedMessage {
 2267      public:
 2268          explicit ScopedMessage( MessageBuilder const& builder );
 2269          ScopedMessage( ScopedMessage& duplicate ) = delete;
 2270          ScopedMessage( ScopedMessage&& old );
 2271          ~ScopedMessage();
 2272  
 2273          MessageInfo m_info;
 2274          bool m_moved;
 2275      };
 2276  
 2277      class Capturer {
 2278          std::vector<MessageInfo> m_messages;
 2279          IResultCapture& m_resultCapture = getResultCapture();
 2280          size_t m_captured = 0;
 2281      public:
 2282          Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
 2283          ~Capturer();
 2284  
 2285          void captureValue( size_t index, std::string const& value );
 2286  
 2287          template<typename T>
 2288          void captureValues( size_t index, T const& value ) {
 2289              captureValue( index, Catch::Detail::stringify( value ) );
 2290          }
 2291  
 2292          template<typename T, typename... Ts>
 2293          void captureValues( size_t index, T const& value, Ts const&... values ) {
 2294              captureValue( index, Catch::Detail::stringify(value) );
 2295              captureValues( index+1, values... );
 2296          }
 2297      };
 2298  
 2299  } // end namespace Catch
 2300  
 2301  // end catch_message.h
 2302  #if !defined(CATCH_CONFIG_DISABLE)
 2303  
 2304  #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
 2305    #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
 2306  #else
 2307    #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
 2308  #endif
 2309  
 2310  #if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
 2311  
 2312  ///////////////////////////////////////////////////////////////////////////////
 2313  // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
 2314  // macros.
 2315  #define INTERNAL_CATCH_TRY
 2316  #define INTERNAL_CATCH_CATCH( capturer )
 2317  
 2318  #else // CATCH_CONFIG_FAST_COMPILE
 2319  
 2320  #define INTERNAL_CATCH_TRY try
 2321  #define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); }
 2322  
 2323  #endif
 2324  
 2325  #define INTERNAL_CATCH_REACT( handler ) handler.complete();
 2326  
 2327  ///////////////////////////////////////////////////////////////////////////////
 2328  #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
 2329      do { \
 2330          Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
 2331          INTERNAL_CATCH_TRY { \
 2332              CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
 2333              catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
 2334              CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
 2335          } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
 2336          INTERNAL_CATCH_REACT( catchAssertionHandler ) \
 2337      } while( (void)0, (false) && static_cast<bool>( !!(__VA_ARGS__) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look
 2338      // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
 2339  
 2340  ///////////////////////////////////////////////////////////////////////////////
 2341  #define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
 2342      INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
 2343      if( Catch::getResultCapture().lastAssertionPassed() )
 2344  
 2345  ///////////////////////////////////////////////////////////////////////////////
 2346  #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
 2347      INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
 2348      if( !Catch::getResultCapture().lastAssertionPassed() )
 2349  
 2350  ///////////////////////////////////////////////////////////////////////////////
 2351  #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
 2352      do { \
 2353          Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
 2354          try { \
 2355              static_cast<void>(__VA_ARGS__); \
 2356              catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
 2357          } \
 2358          catch( ... ) { \
 2359              catchAssertionHandler.handleUnexpectedInflightException(); \
 2360          } \
 2361          INTERNAL_CATCH_REACT( catchAssertionHandler ) \
 2362      } while( false )
 2363  
 2364  ///////////////////////////////////////////////////////////////////////////////
 2365  #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
 2366      do { \
 2367          Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
 2368          if( catchAssertionHandler.allowThrows() ) \
 2369              try { \
 2370                  static_cast<void>(__VA_ARGS__); \
 2371                  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
 2372              } \
 2373              catch( ... ) { \
 2374                  catchAssertionHandler.handleExceptionThrownAsExpected(); \
 2375              } \
 2376          else \
 2377              catchAssertionHandler.handleThrowingCallSkipped(); \
 2378          INTERNAL_CATCH_REACT( catchAssertionHandler ) \
 2379      } while( false )
 2380  
 2381  ///////////////////////////////////////////////////////////////////////////////
 2382  #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
 2383      do { \
 2384          Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
 2385          if( catchAssertionHandler.allowThrows() ) \
 2386              try { \
 2387                  static_cast<void>(expr); \
 2388                  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
 2389              } \
 2390              catch( exceptionType const& ) { \
 2391                  catchAssertionHandler.handleExceptionThrownAsExpected(); \
 2392              } \
 2393              catch( ... ) { \
 2394                  catchAssertionHandler.handleUnexpectedInflightException(); \
 2395              } \
 2396          else \
 2397              catchAssertionHandler.handleThrowingCallSkipped(); \
 2398          INTERNAL_CATCH_REACT( catchAssertionHandler ) \
 2399      } while( false )
 2400  
 2401  ///////////////////////////////////////////////////////////////////////////////
 2402  #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
 2403      do { \
 2404          Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
 2405          catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
 2406          INTERNAL_CATCH_REACT( catchAssertionHandler ) \
 2407      } while( false )
 2408  
 2409  ///////////////////////////////////////////////////////////////////////////////
 2410  #define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
 2411      auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \
 2412      varName.captureValues( 0, __VA_ARGS__ )
 2413  
 2414  ///////////////////////////////////////////////////////////////////////////////
 2415  #define INTERNAL_CATCH_INFO( macroName, log ) \
 2416      Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
 2417  
 2418  ///////////////////////////////////////////////////////////////////////////////
 2419  #define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \
 2420      Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )
 2421  
 2422  ///////////////////////////////////////////////////////////////////////////////
 2423  // Although this is matcher-based, it can be used with just a string
 2424  #define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
 2425      do { \
 2426          Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
 2427          if( catchAssertionHandler.allowThrows() ) \
 2428              try { \
 2429                  static_cast<void>(__VA_ARGS__); \
 2430                  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
 2431              } \
 2432              catch( ... ) { \
 2433                  Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \
 2434              } \
 2435          else \
 2436              catchAssertionHandler.handleThrowingCallSkipped(); \
 2437          INTERNAL_CATCH_REACT( catchAssertionHandler ) \
 2438      } while( false )
 2439  
 2440  #endif // CATCH_CONFIG_DISABLE
 2441  
 2442  // end catch_capture.hpp
 2443  // start catch_section.h
 2444  
 2445  // start catch_section_info.h
 2446  
 2447  // start catch_totals.h
 2448  
 2449  #include <cstddef>
 2450  
 2451  namespace Catch {
 2452  
 2453      struct Counts {
 2454          Counts operator - ( Counts const& other ) const;
 2455          Counts& operator += ( Counts const& other );
 2456  
 2457          std::size_t total() const;
 2458          bool allPassed() const;
 2459          bool allOk() const;
 2460  
 2461          std::size_t passed = 0;
 2462          std::size_t failed = 0;
 2463          std::size_t failedButOk = 0;
 2464      };
 2465  
 2466      struct Totals {
 2467  
 2468          Totals operator - ( Totals const& other ) const;
 2469          Totals& operator += ( Totals const& other );
 2470  
 2471          Totals delta( Totals const& prevTotals ) const;
 2472  
 2473          int error = 0;
 2474          Counts assertions;
 2475          Counts testCases;
 2476      };
 2477  }
 2478  
 2479  // end catch_totals.h
 2480  #include <string>
 2481  
 2482  namespace Catch {
 2483  
 2484      struct SectionInfo {
 2485          SectionInfo
 2486              (   SourceLineInfo const& _lineInfo,
 2487                  std::string const& _name );
 2488  
 2489          // Deprecated
 2490          SectionInfo
 2491              (   SourceLineInfo const& _lineInfo,
 2492                  std::string const& _name,
 2493                  std::string const& ) : SectionInfo( _lineInfo, _name ) {}
 2494  
 2495          std::string name;
 2496          std::string description; // !Deprecated: this will always be empty
 2497          SourceLineInfo lineInfo;
 2498      };
 2499  
 2500      struct SectionEndInfo {
 2501          SectionInfo sectionInfo;
 2502          Counts prevAssertions;
 2503          double durationInSeconds;
 2504      };
 2505  
 2506  } // end namespace Catch
 2507  
 2508  // end catch_section_info.h
 2509  // start catch_timer.h
 2510  
 2511  #include <cstdint>
 2512  
 2513  namespace Catch {
 2514  
 2515      auto getCurrentNanosecondsSinceEpoch() -> uint64_t;
 2516      auto getEstimatedClockResolution() -> uint64_t;
 2517  
 2518      class Timer {
 2519          uint64_t m_nanoseconds = 0;
 2520      public:
 2521          void start();
 2522          auto getElapsedNanoseconds() const -> uint64_t;
 2523          auto getElapsedMicroseconds() const -> uint64_t;
 2524          auto getElapsedMilliseconds() const -> unsigned int;
 2525          auto getElapsedSeconds() const -> double;
 2526      };
 2527  
 2528  } // namespace Catch
 2529  
 2530  // end catch_timer.h
 2531  #include <string>
 2532  
 2533  namespace Catch {
 2534  
 2535      class Section : NonCopyable {
 2536      public:
 2537          Section( SectionInfo const& info );
 2538          ~Section();
 2539  
 2540          // This indicates whether the section should be executed or not
 2541          explicit operator bool() const;
 2542  
 2543      private:
 2544          SectionInfo m_info;
 2545  
 2546          std::string m_name;
 2547          Counts m_assertions;
 2548          bool m_sectionIncluded;
 2549          Timer m_timer;
 2550      };
 2551  
 2552  } // end namespace Catch
 2553  
 2554  #define INTERNAL_CATCH_SECTION( ... ) \
 2555      CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
 2556      if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
 2557      CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
 2558  
 2559  #define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
 2560      CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
 2561      if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \
 2562      CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
 2563  
 2564  // end catch_section.h
 2565  // start catch_benchmark.h
 2566  
 2567  #include <cstdint>
 2568  #include <string>
 2569  
 2570  namespace Catch {
 2571  
 2572      class BenchmarkLooper {
 2573  
 2574          std::string m_name;
 2575          std::size_t m_count = 0;
 2576          std::size_t m_iterationsToRun = 1;
 2577          uint64_t m_resolution;
 2578          Timer m_timer;
 2579  
 2580          static auto getResolution() -> uint64_t;
 2581      public:
 2582          // Keep most of this inline as it's on the code path that is being timed
 2583          BenchmarkLooper( StringRef name )
 2584          :   m_name( name ),
 2585              m_resolution( getResolution() )
 2586          {
 2587              reportStart();
 2588              m_timer.start();
 2589          }
 2590  
 2591          explicit operator bool() {
 2592              if( m_count < m_iterationsToRun )
 2593                  return true;
 2594              return needsMoreIterations();
 2595          }
 2596  
 2597          void increment() {
 2598              ++m_count;
 2599          }
 2600  
 2601          void reportStart();
 2602          auto needsMoreIterations() -> bool;
 2603      };
 2604  
 2605  } // end namespace Catch
 2606  
 2607  #define BENCHMARK( name ) \
 2608      for( Catch::BenchmarkLooper looper( name ); looper; looper.increment() )
 2609  
 2610  // end catch_benchmark.h
 2611  // start catch_interfaces_exception.h
 2612  
 2613  // start catch_interfaces_registry_hub.h
 2614  
 2615  #include <string>
 2616  #include <memory>
 2617  
 2618  namespace Catch {
 2619  
 2620      class TestCase;
 2621      struct ITestCaseRegistry;
 2622      struct IExceptionTranslatorRegistry;
 2623      struct IExceptionTranslator;
 2624      struct IReporterRegistry;
 2625      struct IReporterFactory;
 2626      struct ITagAliasRegistry;
 2627      class StartupExceptionRegistry;
 2628  
 2629      using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
 2630  
 2631      struct IRegistryHub {
 2632          virtual ~IRegistryHub();
 2633  
 2634          virtual IReporterRegistry const& getReporterRegistry() const = 0;
 2635          virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
 2636          virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
 2637  
 2638          virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0;
 2639  
 2640          virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
 2641      };
 2642  
 2643      struct IMutableRegistryHub {
 2644          virtual ~IMutableRegistryHub();
 2645          virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0;
 2646          virtual void registerListener( IReporterFactoryPtr const& factory ) = 0;
 2647          virtual void registerTest( TestCase const& testInfo ) = 0;
 2648          virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
 2649          virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
 2650          virtual void registerStartupException() noexcept = 0;
 2651      };
 2652  
 2653      IRegistryHub const& getRegistryHub();
 2654      IMutableRegistryHub& getMutableRegistryHub();
 2655      void cleanUp();
 2656      std::string translateActiveException();
 2657  
 2658  }
 2659  
 2660  // end catch_interfaces_registry_hub.h
 2661  #if defined(CATCH_CONFIG_DISABLE)
 2662      #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \
 2663          static std::string translatorName( signature )
 2664  #endif
 2665  
 2666  #include <exception>
 2667  #include <string>
 2668  #include <vector>
 2669  
 2670  namespace Catch {
 2671      using exceptionTranslateFunction = std::string(*)();
 2672  
 2673      struct IExceptionTranslator;
 2674      using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;
 2675  
 2676      struct IExceptionTranslator {
 2677          virtual ~IExceptionTranslator();
 2678          virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
 2679      };
 2680  
 2681      struct IExceptionTranslatorRegistry {
 2682          virtual ~IExceptionTranslatorRegistry();
 2683  
 2684          virtual std::string translateActiveException() const = 0;
 2685      };
 2686  
 2687      class ExceptionTranslatorRegistrar {
 2688          template<typename T>
 2689          class ExceptionTranslator : public IExceptionTranslator {
 2690          public:
 2691  
 2692              ExceptionTranslator( std::string(*translateFunction)( T& ) )
 2693              : m_translateFunction( translateFunction )
 2694              {}
 2695  
 2696              std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override {
 2697                  try {
 2698                      if( it == itEnd )
 2699                          std::rethrow_exception(std::current_exception());
 2700                      else
 2701                          return (*it)->translate( it+1, itEnd );
 2702                  }
 2703                  catch( T& ex ) {
 2704                      return m_translateFunction( ex );
 2705                  }
 2706              }
 2707  
 2708          protected:
 2709              std::string(*m_translateFunction)( T& );
 2710          };
 2711  
 2712      public:
 2713          template<typename T>
 2714          ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
 2715              getMutableRegistryHub().registerTranslator
 2716                  ( new ExceptionTranslator<T>( translateFunction ) );
 2717          }
 2718      };
 2719  }
 2720  
 2721  ///////////////////////////////////////////////////////////////////////////////
 2722  #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
 2723      static std::string translatorName( signature ); \
 2724      CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
 2725      namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \
 2726      CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
 2727      static std::string translatorName( signature )
 2728  
 2729  #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
 2730  
 2731  // end catch_interfaces_exception.h
 2732  // start catch_approx.h
 2733  
 2734  #include <type_traits>
 2735  
 2736  namespace Catch {
 2737  namespace Detail {
 2738  
 2739      class Approx {
 2740      private:
 2741          bool equalityComparisonImpl(double other) const;
 2742          // Validates the new margin (margin >= 0)
 2743          // out-of-line to avoid including stdexcept in the header
 2744          void setMargin(double margin);
 2745          // Validates the new epsilon (0 < epsilon < 1)
 2746          // out-of-line to avoid including stdexcept in the header
 2747          void setEpsilon(double epsilon);
 2748  
 2749      public:
 2750          explicit Approx ( double value );
 2751  
 2752          static Approx custom();
 2753  
 2754          Approx operator-() const;
 2755  
 2756          template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
 2757          Approx operator()( T const& value ) {
 2758              Approx approx( static_cast<double>(value) );
 2759              approx.m_epsilon = m_epsilon;
 2760              approx.m_margin = m_margin;
 2761              approx.m_scale = m_scale;
 2762              return approx;
 2763          }
 2764  
 2765          template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
 2766          explicit Approx( T const& value ): Approx(static_cast<double>(value))
 2767          {}
 2768  
 2769          template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
 2770          friend bool operator == ( const T& lhs, Approx const& rhs ) {
 2771              auto lhs_v = static_cast<double>(lhs);
 2772              return rhs.equalityComparisonImpl(lhs_v);
 2773          }
 2774  
 2775          template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
 2776          friend bool operator == ( Approx const& lhs, const T& rhs ) {
 2777              return operator==( rhs, lhs );
 2778          }
 2779  
 2780          template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
 2781          friend bool operator != ( T const& lhs, Approx const& rhs ) {
 2782              return !operator==( lhs, rhs );
 2783          }
 2784  
 2785          template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
 2786          friend bool operator != ( Approx const& lhs, T const& rhs ) {
 2787              return !operator==( rhs, lhs );
 2788          }
 2789  
 2790          template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
 2791          friend bool operator <= ( T const& lhs, Approx const& rhs ) {
 2792              return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;
 2793          }
 2794  
 2795          template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
 2796          friend bool operator <= ( Approx const& lhs, T const& rhs ) {
 2797              return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
 2798          }
 2799  
 2800          template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
 2801          friend bool operator >= ( T const& lhs, Approx const& rhs ) {
 2802              return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;
 2803          }
 2804  
 2805          template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
 2806          friend bool operator >= ( Approx const& lhs, T const& rhs ) {
 2807              return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
 2808          }
 2809  
 2810          template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
 2811          Approx& epsilon( T const& newEpsilon ) {
 2812              double epsilonAsDouble = static_cast<double>(newEpsilon);
 2813              setEpsilon(epsilonAsDouble);
 2814              return *this;
 2815          }
 2816  
 2817          template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
 2818          Approx& margin( T const& newMargin ) {
 2819              double marginAsDouble = static_cast<double>(newMargin);
 2820              setMargin(marginAsDouble);
 2821              return *this;
 2822          }
 2823  
 2824          template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
 2825          Approx& scale( T const& newScale ) {
 2826              m_scale = static_cast<double>(newScale);
 2827              return *this;
 2828          }
 2829  
 2830          std::string toString() const;
 2831  
 2832      private:
 2833          double m_epsilon;
 2834          double m_margin;
 2835          double m_scale;
 2836          double m_value;
 2837      };
 2838  } // end namespace Detail
 2839  
 2840  namespace literals {
 2841      Detail::Approx operator "" _a(long double val);
 2842      Detail::Approx operator "" _a(unsigned long long val);
 2843  } // end namespace literals
 2844  
 2845  template<>
 2846  struct StringMaker<Catch::Detail::Approx> {
 2847      static std::string convert(Catch::Detail::Approx const& value);
 2848  };
 2849  
 2850  } // end namespace Catch
 2851  
 2852  // end catch_approx.h
 2853  // start catch_string_manip.h
 2854  
 2855  #include <string>
 2856  #include <iosfwd>
 2857  
 2858  namespace Catch {
 2859  
 2860      bool startsWith( std::string const& s, std::string const& prefix );
 2861      bool startsWith( std::string const& s, char prefix );
 2862      bool endsWith( std::string const& s, std::string const& suffix );
 2863      bool endsWith( std::string const& s, char suffix );
 2864      bool contains( std::string const& s, std::string const& infix );
 2865      void toLowerInPlace( std::string& s );
 2866      std::string toLower( std::string const& s );
 2867      std::string trim( std::string const& str );
 2868      bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
 2869  
 2870      struct pluralise {
 2871          pluralise( std::size_t count, std::string const& label );
 2872  
 2873          friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
 2874  
 2875          std::size_t m_count;
 2876          std::string m_label;
 2877      };
 2878  }
 2879  
 2880  // end catch_string_manip.h
 2881  #ifndef CATCH_CONFIG_DISABLE_MATCHERS
 2882  // start catch_capture_matchers.h
 2883  
 2884  // start catch_matchers.h
 2885  
 2886  #include <string>
 2887  #include <vector>
 2888  
 2889  namespace Catch {
 2890  namespace Matchers {
 2891      namespace Impl {
 2892  
 2893          template<typename ArgT> struct MatchAllOf;
 2894          template<typename ArgT> struct MatchAnyOf;
 2895          template<typename ArgT> struct MatchNotOf;
 2896  
 2897          class MatcherUntypedBase {
 2898          public:
 2899              MatcherUntypedBase() = default;
 2900              MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
 2901              MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete;
 2902              std::string toString() const;
 2903  
 2904          protected:
 2905              virtual ~MatcherUntypedBase();
 2906              virtual std::string describe() const = 0;
 2907              mutable std::string m_cachedToString;
 2908          };
 2909  
 2910  #ifdef __clang__
 2911  #    pragma clang diagnostic push
 2912  #    pragma clang diagnostic ignored "-Wnon-virtual-dtor"
 2913  #endif
 2914  
 2915          template<typename ObjectT>
 2916          struct MatcherMethod {
 2917              virtual bool match( ObjectT const& arg ) const = 0;
 2918          };
 2919  
 2920  #ifdef __clang__
 2921  #    pragma clang diagnostic pop
 2922  #endif
 2923  
 2924          template<typename T>
 2925          struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
 2926  
 2927              MatchAllOf<T> operator && ( MatcherBase const& other ) const;
 2928              MatchAnyOf<T> operator || ( MatcherBase const& other ) const;
 2929              MatchNotOf<T> operator ! () const;
 2930          };
 2931  
 2932          template<typename ArgT>
 2933          struct MatchAllOf : MatcherBase<ArgT> {
 2934              bool match( ArgT const& arg ) const override {
 2935                  for( auto matcher : m_matchers ) {
 2936                      if (!matcher->match(arg))
 2937                          return false;
 2938                  }
 2939                  return true;
 2940              }
 2941              std::string describe() const override {
 2942                  std::string description;
 2943                  description.reserve( 4 + m_matchers.size()*32 );
 2944                  description += "( ";
 2945                  bool first = true;
 2946                  for( auto matcher : m_matchers ) {
 2947                      if( first )
 2948                          first = false;
 2949                      else
 2950                          description += " and ";
 2951                      description += matcher->toString();
 2952                  }
 2953                  description += " )";
 2954                  return description;
 2955              }
 2956  
 2957              MatchAllOf<ArgT>& operator && ( MatcherBase<ArgT> const& other ) {
 2958                  m_matchers.push_back( &other );
 2959                  return *this;
 2960              }
 2961  
 2962              std::vector<MatcherBase<ArgT> const*> m_matchers;
 2963          };
 2964          template<typename ArgT>
 2965          struct MatchAnyOf : MatcherBase<ArgT> {
 2966  
 2967              bool match( ArgT const& arg ) const override {
 2968                  for( auto matcher : m_matchers ) {
 2969                      if (matcher->match(arg))
 2970                          return true;
 2971                  }
 2972                  return false;
 2973              }
 2974              std::string describe() const override {
 2975                  std::string description;
 2976                  description.reserve( 4 + m_matchers.size()*32 );
 2977                  description += "( ";
 2978                  bool first = true;
 2979                  for( auto matcher : m_matchers ) {
 2980                      if( first )
 2981                          first = false;
 2982                      else
 2983                          description += " or ";
 2984                      description += matcher->toString();
 2985                  }
 2986                  description += " )";
 2987                  return description;
 2988              }
 2989  
 2990              MatchAnyOf<ArgT>& operator || ( MatcherBase<ArgT> const& other ) {
 2991                  m_matchers.push_back( &other );
 2992                  return *this;
 2993              }
 2994  
 2995              std::vector<MatcherBase<ArgT> const*> m_matchers;
 2996          };
 2997  
 2998          template<typename ArgT>
 2999          struct MatchNotOf : MatcherBase<ArgT> {
 3000  
 3001              MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
 3002  
 3003              bool match( ArgT const& arg ) const override {
 3004                  return !m_underlyingMatcher.match( arg );
 3005              }
 3006  
 3007              std::string describe() const override {
 3008                  return "not " + m_underlyingMatcher.toString();
 3009              }
 3010              MatcherBase<ArgT> const& m_underlyingMatcher;
 3011          };
 3012  
 3013          template<typename T>
 3014          MatchAllOf<T> MatcherBase<T>::operator && ( MatcherBase const& other ) const {
 3015              return MatchAllOf<T>() && *this && other;
 3016          }
 3017          template<typename T>
 3018          MatchAnyOf<T> MatcherBase<T>::operator || ( MatcherBase const& other ) const {
 3019              return MatchAnyOf<T>() || *this || other;
 3020          }
 3021          template<typename T>
 3022          MatchNotOf<T> MatcherBase<T>::operator ! () const {
 3023              return MatchNotOf<T>( *this );
 3024          }
 3025  
 3026      } // namespace Impl
 3027  
 3028  } // namespace Matchers
 3029  
 3030  using namespace Matchers;
 3031  using Matchers::Impl::MatcherBase;
 3032  
 3033  } // namespace Catch
 3034  
 3035  // end catch_matchers.h
 3036  // start catch_matchers_floating.h
 3037  
 3038  #include <type_traits>
 3039  #include <cmath>
 3040  
 3041  namespace Catch {
 3042  namespace Matchers {
 3043  
 3044      namespace Floating {
 3045  
 3046          enum class FloatingPointKind : uint8_t;
 3047  
 3048          struct WithinAbsMatcher : MatcherBase<double> {
 3049              WithinAbsMatcher(double target, double margin);
 3050              bool match(double const& matchee) const override;
 3051              std::string describe() const override;
 3052          private:
 3053              double m_target;
 3054              double m_margin;
 3055          };
 3056  
 3057          struct WithinUlpsMatcher : MatcherBase<double> {
 3058              WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType);
 3059              bool match(double const& matchee) const override;
 3060              std::string describe() const override;
 3061          private:
 3062              double m_target;
 3063              int m_ulps;
 3064              FloatingPointKind m_type;
 3065          };
 3066  
 3067      } // namespace Floating
 3068  
 3069      // The following functions create the actual matcher objects.
 3070      // This allows the types to be inferred
 3071      Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff);
 3072      Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff);
 3073      Floating::WithinAbsMatcher WithinAbs(double target, double margin);
 3074  
 3075  } // namespace Matchers
 3076  } // namespace Catch
 3077  
 3078  // end catch_matchers_floating.h
 3079  // start catch_matchers_generic.hpp
 3080  
 3081  #include <functional>
 3082  #include <string>
 3083  
 3084  namespace Catch {
 3085  namespace Matchers {
 3086  namespace Generic {
 3087  
 3088  namespace Detail {
 3089      std::string finalizeDescription(const std::string& desc);
 3090  }
 3091  
 3092  template <typename T>
 3093  class PredicateMatcher : public MatcherBase<T> {
 3094      std::function<bool(T const&)> m_predicate;
 3095      std::string m_description;
 3096  public:
 3097  
 3098      PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr)
 3099          :m_predicate(std::move(elem)),
 3100          m_description(Detail::finalizeDescription(descr))
 3101      {}
 3102  
 3103      bool match( T const& item ) const override {
 3104          return m_predicate(item);
 3105      }
 3106  
 3107      std::string describe() const override {
 3108          return m_description;
 3109      }
 3110  };
 3111  
 3112  } // namespace Generic
 3113  
 3114      // The following functions create the actual matcher objects.
 3115      // The user has to explicitly specify type to the function, because
 3116      // inferring std::function<bool(T const&)> is hard (but possible) and
 3117      // requires a lot of TMP.
 3118      template<typename T>
 3119      Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") {
 3120          return Generic::PredicateMatcher<T>(predicate, description);
 3121      }
 3122  
 3123  } // namespace Matchers
 3124  } // namespace Catch
 3125  
 3126  // end catch_matchers_generic.hpp
 3127  // start catch_matchers_string.h
 3128  
 3129  #include <string>
 3130  
 3131  namespace Catch {
 3132  namespace Matchers {
 3133  
 3134      namespace StdString {
 3135  
 3136          struct CasedString
 3137          {
 3138              CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );
 3139              std::string adjustString( std::string const& str ) const;
 3140              std::string caseSensitivitySuffix() const;
 3141  
 3142              CaseSensitive::Choice m_caseSensitivity;
 3143              std::string m_str;
 3144          };
 3145  
 3146          struct StringMatcherBase : MatcherBase<std::string> {
 3147              StringMatcherBase( std::string const& operation, CasedString const& comparator );
 3148              std::string describe() const override;
 3149  
 3150              CasedString m_comparator;
 3151              std::string m_operation;
 3152          };
 3153  
 3154          struct EqualsMatcher : StringMatcherBase {
 3155              EqualsMatcher( CasedString const& comparator );
 3156              bool match( std::string const& source ) const override;
 3157          };
 3158          struct ContainsMatcher : StringMatcherBase {
 3159              ContainsMatcher( CasedString const& comparator );
 3160              bool match( std::string const& source ) const override;
 3161          };
 3162          struct StartsWithMatcher : StringMatcherBase {
 3163              StartsWithMatcher( CasedString const& comparator );
 3164              bool match( std::string const& source ) const override;
 3165          };
 3166          struct EndsWithMatcher : StringMatcherBase {
 3167              EndsWithMatcher( CasedString const& comparator );
 3168              bool match( std::string const& source ) const override;
 3169          };
 3170  
 3171          struct RegexMatcher : MatcherBase<std::string> {
 3172              RegexMatcher( std::string regex, CaseSensitive::Choice caseSensitivity );
 3173              bool match( std::string const& matchee ) const override;
 3174              std::string describe() const override;
 3175  
 3176          private:
 3177              std::string m_regex;
 3178              CaseSensitive::Choice m_caseSensitivity;
 3179          };
 3180  
 3181      } // namespace StdString
 3182  
 3183      // The following functions create the actual matcher objects.
 3184      // This allows the types to be inferred
 3185  
 3186      StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
 3187      StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
 3188      StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
 3189      StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
 3190      StdString::RegexMatcher Matches( std::string const& regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
 3191  
 3192  } // namespace Matchers
 3193  } // namespace Catch
 3194  
 3195  // end catch_matchers_string.h
 3196  // start catch_matchers_vector.h
 3197  
 3198  #include <algorithm>
 3199  
 3200  namespace Catch {
 3201  namespace Matchers {
 3202  
 3203      namespace Vector {
 3204          template<typename T>
 3205          struct ContainsElementMatcher : MatcherBase<std::vector<T>> {
 3206  
 3207              ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
 3208  
 3209              bool match(std::vector<T> const &v) const override {
 3210                  for (auto const& el : v) {
 3211                      if (el == m_comparator) {
 3212                          return true;
 3213                      }
 3214                  }
 3215                  return false;
 3216              }
 3217  
 3218              std::string describe() const override {
 3219                  return "Contains: " + ::Catch::Detail::stringify( m_comparator );
 3220              }
 3221  
 3222              T const& m_comparator;
 3223          };
 3224  
 3225          template<typename T>
 3226          struct ContainsMatcher : MatcherBase<std::vector<T>> {
 3227  
 3228              ContainsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
 3229  
 3230              bool match(std::vector<T> const &v) const override {
 3231                  // !TBD: see note in EqualsMatcher
 3232                  if (m_comparator.size() > v.size())
 3233                      return false;
 3234                  for (auto const& comparator : m_comparator) {
 3235                      auto present = false;
 3236                      for (const auto& el : v) {
 3237                          if (el == comparator) {
 3238                              present = true;
 3239                              break;
 3240                          }
 3241                      }
 3242                      if (!present) {
 3243                          return false;
 3244                      }
 3245                  }
 3246                  return true;
 3247              }
 3248              std::string describe() const override {
 3249                  return "Contains: " + ::Catch::Detail::stringify( m_comparator );
 3250              }
 3251  
 3252              std::vector<T> const& m_comparator;
 3253          };
 3254  
 3255          template<typename T>
 3256          struct EqualsMatcher : MatcherBase<std::vector<T>> {
 3257  
 3258              EqualsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
 3259  
 3260              bool match(std::vector<T> const &v) const override {
 3261                  // !TBD: This currently works if all elements can be compared using !=
 3262                  // - a more general approach would be via a compare template that defaults
 3263                  // to using !=. but could be specialised for, e.g. std::vector<T> etc
 3264                  // - then just call that directly
 3265                  if (m_comparator.size() != v.size())
 3266                      return false;
 3267                  for (std::size_t i = 0; i < v.size(); ++i)
 3268                      if (m_comparator[i] != v[i])
 3269                          return false;
 3270                  return true;
 3271              }
 3272              std::string describe() const override {
 3273                  return "Equals: " + ::Catch::Detail::stringify( m_comparator );
 3274              }
 3275              std::vector<T> const& m_comparator;
 3276          };
 3277  
 3278          template<typename T>
 3279          struct ApproxMatcher : MatcherBase<std::vector<T>> {
 3280  
 3281              ApproxMatcher(std::vector<T> const& comparator) : m_comparator( comparator ) {}
 3282  
 3283              bool match(std::vector<T> const &v) const override {
 3284                  if (m_comparator.size() != v.size())
 3285                      return false;
 3286                  for (std::size_t i = 0; i < v.size(); ++i)
 3287                      if (m_comparator[i] != approx(v[i]))
 3288                          return false;
 3289                  return true;
 3290              }
 3291              std::string describe() const override {
 3292                  return "is approx: " + ::Catch::Detail::stringify( m_comparator );
 3293              }
 3294              template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
 3295              ApproxMatcher& epsilon( T const& newEpsilon ) {
 3296                  approx.epsilon(newEpsilon);
 3297                  return *this;
 3298              }
 3299              template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
 3300              ApproxMatcher& margin( T const& newMargin ) {
 3301                  approx.margin(newMargin);
 3302                  return *this;
 3303              }
 3304              template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
 3305              ApproxMatcher& scale( T const& newScale ) {
 3306                  approx.scale(newScale);
 3307                  return *this;
 3308              }
 3309  
 3310              std::vector<T> const& m_comparator;
 3311              mutable Catch::Detail::Approx approx = Catch::Detail::Approx::custom();
 3312          };
 3313  
 3314          template<typename T>
 3315          struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>> {
 3316              UnorderedEqualsMatcher(std::vector<T> const& target) : m_target(target) {}
 3317              bool match(std::vector<T> const& vec) const override {
 3318                  // Note: This is a reimplementation of std::is_permutation,
 3319                  //       because I don't want to include <algorithm> inside the common path
 3320                  if (m_target.size() != vec.size()) {
 3321                      return false;
 3322                  }
 3323                  return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());
 3324              }
 3325  
 3326              std::string describe() const override {
 3327                  return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
 3328              }
 3329          private:
 3330              std::vector<T> const& m_target;
 3331          };
 3332  
 3333      } // namespace Vector
 3334  
 3335      // The following functions create the actual matcher objects.
 3336      // This allows the types to be inferred
 3337  
 3338      template<typename T>
 3339      Vector::ContainsMatcher<T> Contains( std::vector<T> const& comparator ) {
 3340          return Vector::ContainsMatcher<T>( comparator );
 3341      }
 3342  
 3343      template<typename T>
 3344      Vector::ContainsElementMatcher<T> VectorContains( T const& comparator ) {
 3345          return Vector::ContainsElementMatcher<T>( comparator );
 3346      }
 3347  
 3348      template<typename T>
 3349      Vector::EqualsMatcher<T> Equals( std::vector<T> const& comparator ) {
 3350          return Vector::EqualsMatcher<T>( comparator );
 3351      }
 3352  
 3353      template<typename T>
 3354      Vector::ApproxMatcher<T> Approx( std::vector<T> const& comparator ) {
 3355          return Vector::ApproxMatcher<T>( comparator );
 3356      }
 3357  
 3358      template<typename T>
 3359      Vector::UnorderedEqualsMatcher<T> UnorderedEquals(std::vector<T> const& target) {
 3360          return Vector::UnorderedEqualsMatcher<T>(target);
 3361      }
 3362  
 3363  } // namespace Matchers
 3364  } // namespace Catch
 3365  
 3366  // end catch_matchers_vector.h
 3367  namespace Catch {
 3368  
 3369      template<typename ArgT, typename MatcherT>
 3370      class MatchExpr : public ITransientExpression {
 3371          ArgT const& m_arg;
 3372          MatcherT m_matcher;
 3373          StringRef m_matcherString;
 3374      public:
 3375          MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString )
 3376          :   ITransientExpression{ true, matcher.match( arg ) },
 3377              m_arg( arg ),
 3378              m_matcher( matcher ),
 3379              m_matcherString( matcherString )
 3380          {}
 3381  
 3382          void streamReconstructedExpression( std::ostream &os ) const override {
 3383              auto matcherAsString = m_matcher.toString();
 3384              os << Catch::Detail::stringify( m_arg ) << ' ';
 3385              if( matcherAsString == Detail::unprintableString )
 3386                  os << m_matcherString;
 3387              else
 3388                  os << matcherAsString;
 3389          }
 3390      };
 3391  
 3392      using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
 3393  
 3394      void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  );
 3395  
 3396      template<typename ArgT, typename MatcherT>
 3397      auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString  ) -> MatchExpr<ArgT, MatcherT> {
 3398          return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );
 3399      }
 3400  
 3401  } // namespace Catch
 3402  
 3403  ///////////////////////////////////////////////////////////////////////////////
 3404  #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
 3405      do { \
 3406          Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
 3407          INTERNAL_CATCH_TRY { \
 3408              catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \
 3409          } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
 3410          INTERNAL_CATCH_REACT( catchAssertionHandler ) \
 3411      } while( false )
 3412  
 3413  ///////////////////////////////////////////////////////////////////////////////
 3414  #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
 3415      do { \
 3416          Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
 3417          if( catchAssertionHandler.allowThrows() ) \
 3418              try { \
 3419                  static_cast<void>(__VA_ARGS__ ); \
 3420                  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
 3421              } \
 3422              catch( exceptionType const& ex ) { \
 3423                  catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \
 3424              } \
 3425              catch( ... ) { \
 3426                  catchAssertionHandler.handleUnexpectedInflightException(); \
 3427              } \
 3428          else \
 3429              catchAssertionHandler.handleThrowingCallSkipped(); \
 3430          INTERNAL_CATCH_REACT( catchAssertionHandler ) \
 3431      } while( false )
 3432  
 3433  // end catch_capture_matchers.h
 3434  #endif
 3435  // start catch_generators.hpp
 3436  
 3437  // start catch_interfaces_generatortracker.h
 3438  
 3439  
 3440  #include <memory>
 3441  
 3442  namespace Catch {
 3443  
 3444      namespace Generators {
 3445          class GeneratorUntypedBase {
 3446          public:
 3447              GeneratorUntypedBase() = default;
 3448              virtual ~GeneratorUntypedBase();
 3449              // Attempts to move the generator to the next element
 3450               //
 3451               // Returns true iff the move succeeded (and a valid element
 3452               // can be retrieved).
 3453              virtual bool next() = 0;
 3454          };
 3455          using GeneratorBasePtr = std::unique_ptr<GeneratorUntypedBase>;
 3456  
 3457      } // namespace Generators
 3458  
 3459      struct IGeneratorTracker {
 3460          virtual ~IGeneratorTracker();
 3461          virtual auto hasGenerator() const -> bool = 0;
 3462          virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;
 3463          virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0;
 3464      };
 3465  
 3466  } // namespace Catch
 3467  
 3468  // end catch_interfaces_generatortracker.h
 3469  // start catch_enforce.h
 3470  
 3471  #include <stdexcept>
 3472  
 3473  namespace Catch {
 3474  #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
 3475      template <typename Ex>
 3476      [[noreturn]]
 3477      void throw_exception(Ex const& e) {
 3478          throw e;
 3479      }
 3480  #else // ^^ Exceptions are enabled //  Exceptions are disabled vv
 3481      [[noreturn]]
 3482      void throw_exception(std::exception const& e);
 3483  #endif
 3484  } // namespace Catch;
 3485  
 3486  #define CATCH_PREPARE_EXCEPTION( type, msg ) \
 3487      type( ( Catch::ReusableStringStream() << msg ).str() )
 3488  #define CATCH_INTERNAL_ERROR( msg ) \
 3489      Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg))
 3490  #define CATCH_ERROR( msg ) \
 3491      Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::domain_error, msg ))
 3492  #define CATCH_RUNTIME_ERROR( msg ) \
 3493      Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::runtime_error, msg ))
 3494  #define CATCH_ENFORCE( condition, msg ) \
 3495      do{ if( !(condition) ) CATCH_ERROR( msg ); } while(false)
 3496  
 3497  // end catch_enforce.h
 3498  #include <memory>
 3499  #include <vector>
 3500  #include <cassert>
 3501  
 3502  #include <utility>
 3503  #include <exception>
 3504  
 3505  namespace Catch {
 3506  
 3507  class GeneratorException : public std::exception {
 3508      const char* const m_msg = "";
 3509  
 3510  public:
 3511      GeneratorException(const char* msg):
 3512          m_msg(msg)
 3513      {}
 3514  
 3515      const char* what() const noexcept override final;
 3516  };
 3517  
 3518  namespace Generators {
 3519  
 3520      // !TBD move this into its own location?
 3521      namespace pf{
 3522          template<typename T, typename... Args>
 3523          std::unique_ptr<T> make_unique( Args&&... args ) {
 3524              return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
 3525          }
 3526      }
 3527  
 3528      template<typename T>
 3529      struct IGenerator : GeneratorUntypedBase {
 3530          virtual ~IGenerator() = default;
 3531  
 3532          // Returns the current element of the generator
 3533          //
 3534          // \Precondition The generator is either freshly constructed,
 3535          // or the last call to `next()` returned true
 3536          virtual T const& get() const = 0;
 3537          using type = T;
 3538      };
 3539  
 3540      template<typename T>
 3541      class SingleValueGenerator final : public IGenerator<T> {
 3542          T m_value;
 3543      public:
 3544          SingleValueGenerator(T const& value) : m_value( value ) {}
 3545          SingleValueGenerator(T&& value) : m_value(std::move(value)) {}
 3546  
 3547          T const& get() const override {
 3548              return m_value;
 3549          }
 3550          bool next() override {
 3551              return false;
 3552          }
 3553      };
 3554  
 3555      template<typename T>
 3556      class FixedValuesGenerator final : public IGenerator<T> {
 3557          std::vector<T> m_values;
 3558          size_t m_idx = 0;
 3559      public:
 3560          FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {}
 3561  
 3562          T const& get() const override {
 3563              return m_values[m_idx];
 3564          }
 3565          bool next() override {
 3566              ++m_idx;
 3567              return m_idx < m_values.size();
 3568          }
 3569      };
 3570  
 3571      template <typename T>
 3572      class GeneratorWrapper final {
 3573          std::unique_ptr<IGenerator<T>> m_generator;
 3574      public:
 3575          GeneratorWrapper(std::unique_ptr<IGenerator<T>> generator):
 3576              m_generator(std::move(generator))
 3577          {}
 3578          T const& get() const {
 3579              return m_generator->get();
 3580          }
 3581          bool next() {
 3582              return m_generator->next();
 3583          }
 3584      };
 3585  
 3586      template <typename T>
 3587      GeneratorWrapper<T> value(T&& value) {
 3588          return GeneratorWrapper<T>(pf::make_unique<SingleValueGenerator<T>>(std::forward<T>(value)));
 3589      }
 3590      template <typename T>
 3591      GeneratorWrapper<T> values(std::initializer_list<T> values) {
 3592          return GeneratorWrapper<T>(pf::make_unique<FixedValuesGenerator<T>>(values));
 3593      }
 3594  
 3595      template<typename T>
 3596      class Generators : public IGenerator<T> {
 3597          std::vector<GeneratorWrapper<T>> m_generators;
 3598          size_t m_current = 0;
 3599  
 3600          void populate(GeneratorWrapper<T>&& generator) {
 3601              m_generators.emplace_back(std::move(generator));
 3602          }
 3603          void populate(T&& val) {
 3604              m_generators.emplace_back(value(std::move(val)));
 3605          }
 3606          template<typename U>
 3607          void populate(U&& val) {
 3608              populate(T(std::move(val)));
 3609          }
 3610          template<typename U, typename... Gs>
 3611          void populate(U&& valueOrGenerator, Gs... moreGenerators) {
 3612              populate(std::forward<U>(valueOrGenerator));
 3613              populate(std::forward<Gs>(moreGenerators)...);
 3614          }
 3615  
 3616      public:
 3617          template <typename... Gs>
 3618          Generators(Gs... moreGenerators) {
 3619              m_generators.reserve(sizeof...(Gs));
 3620              populate(std::forward<Gs>(moreGenerators)...);
 3621          }
 3622  
 3623          T const& get() const override {
 3624              return m_generators[m_current].get();
 3625          }
 3626  
 3627          bool next() override {
 3628              if (m_current >= m_generators.size()) {
 3629                  return false;
 3630              }
 3631              const bool current_status = m_generators[m_current].next();
 3632              if (!current_status) {
 3633                  ++m_current;
 3634              }
 3635              return m_current < m_generators.size();
 3636          }
 3637      };
 3638  
 3639      template<typename... Ts>
 3640      GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std::tuple<typename std::decay<Ts>::type...>> tuples ) {
 3641          return values<std::tuple<Ts...>>( tuples );
 3642      }
 3643  
 3644      // Tag type to signal that a generator sequence should convert arguments to a specific type
 3645      template <typename T>
 3646      struct as {};
 3647  
 3648      template<typename T, typename... Gs>
 3649      auto makeGenerators( GeneratorWrapper<T>&& generator, Gs... moreGenerators ) -> Generators<T> {
 3650          return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...);
 3651      }
 3652      template<typename T>
 3653      auto makeGenerators( GeneratorWrapper<T>&& generator ) -> Generators<T> {
 3654          return Generators<T>(std::move(generator));
 3655      }
 3656      template<typename T, typename... Gs>
 3657      auto makeGenerators( T&& val, Gs... moreGenerators ) -> Generators<T> {
 3658          return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );
 3659      }
 3660      template<typename T, typename U, typename... Gs>
 3661      auto makeGenerators( as<T>, U&& val, Gs... moreGenerators ) -> Generators<T> {
 3662          return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );
 3663      }
 3664  
 3665      auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
 3666  
 3667      template<typename L>
 3668      // Note: The type after -> is weird, because VS2015 cannot parse
 3669      //       the expression used in the typedef inside, when it is in
 3670      //       return type. Yeah.
 3671      auto generate( SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) {
 3672          using UnderlyingType = typename decltype(generatorExpression())::type;
 3673  
 3674          IGeneratorTracker& tracker = acquireGeneratorTracker( lineInfo );
 3675          if (!tracker.hasGenerator()) {
 3676              tracker.setGenerator(pf::make_unique<Generators<UnderlyingType>>(generatorExpression()));
 3677          }
 3678  
 3679          auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() );
 3680          return generator.get();
 3681      }
 3682  
 3683  } // namespace Generators
 3684  } // namespace Catch
 3685  
 3686  #define GENERATE( ... ) \
 3687      Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
 3688  #define GENERATE_COPY( ... ) \
 3689      Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
 3690  #define GENERATE_REF( ... ) \
 3691      Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
 3692  
 3693  // end catch_generators.hpp
 3694  // start catch_generators_generic.hpp
 3695  
 3696  namespace Catch {
 3697  namespace Generators {
 3698  
 3699      template <typename T>
 3700      class TakeGenerator : public IGenerator<T> {
 3701          GeneratorWrapper<T> m_generator;
 3702          size_t m_returned = 0;
 3703          size_t m_target;
 3704      public:
 3705          TakeGenerator(size_t target, GeneratorWrapper<T>&& generator):
 3706              m_generator(std::move(generator)),
 3707              m_target(target)
 3708          {
 3709              assert(target != 0 && "Empty generators are not allowed");
 3710          }
 3711          T const& get() const override {
 3712              return m_generator.get();
 3713          }
 3714          bool next() override {
 3715              ++m_returned;
 3716              if (m_returned >= m_target) {
 3717                  return false;
 3718              }
 3719  
 3720              const auto success = m_generator.next();
 3721              // If the underlying generator does not contain enough values
 3722              // then we cut short as well
 3723              if (!success) {
 3724                  m_returned = m_target;
 3725              }
 3726              return success;
 3727          }
 3728      };
 3729  
 3730      template <typename T>
 3731      GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T>&& generator) {
 3732          return GeneratorWrapper<T>(pf::make_unique<TakeGenerator<T>>(target, std::move(generator)));
 3733      }
 3734  
 3735      template <typename T, typename Predicate>
 3736      class FilterGenerator : public IGenerator<T> {
 3737          GeneratorWrapper<T> m_generator;
 3738          Predicate m_predicate;
 3739      public:
 3740          template <typename P = Predicate>
 3741          FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator):
 3742              m_generator(std::move(generator)),
 3743              m_predicate(std::forward<P>(pred))
 3744          {
 3745              if (!m_predicate(m_generator.get())) {
 3746                  // It might happen that there are no values that pass the
 3747                  // filter. In that case we throw an exception.
 3748                  auto has_initial_value = next();
 3749                  if (!has_initial_value) {
 3750                      Catch::throw_exception(GeneratorException("No valid value found in filtered generator"));
 3751                  }
 3752              }
 3753          }
 3754  
 3755          T const& get() const override {
 3756              return m_generator.get();
 3757          }
 3758  
 3759          bool next() override {
 3760              bool success = m_generator.next();
 3761              if (!success) {
 3762                  return false;
 3763              }
 3764              while (!m_predicate(m_generator.get()) && (success = m_generator.next()) == true);
 3765              return success;
 3766          }
 3767      };
 3768  
 3769      template <typename T, typename Predicate>
 3770      GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& generator) {
 3771          return GeneratorWrapper<T>(std::unique_ptr<IGenerator<T>>(pf::make_unique<FilterGenerator<T, Predicate>>(std::forward<Predicate>(pred), std::move(generator))));
 3772      }
 3773  
 3774      template <typename T>
 3775      class RepeatGenerator : public IGenerator<T> {
 3776          GeneratorWrapper<T> m_generator;
 3777          mutable std::vector<T> m_returned;
 3778          size_t m_target_repeats;
 3779          size_t m_current_repeat = 0;
 3780          size_t m_repeat_index = 0;
 3781      public:
 3782          RepeatGenerator(size_t repeats, GeneratorWrapper<T>&& generator):
 3783              m_generator(std::move(generator)),
 3784              m_target_repeats(repeats)
 3785          {
 3786              assert(m_target_repeats > 0 && "Repeat generator must repeat at least once");
 3787          }
 3788  
 3789          T const& get() const override {
 3790              if (m_current_repeat == 0) {
 3791                  m_returned.push_back(m_generator.get());
 3792                  return m_returned.back();
 3793              }
 3794              return m_returned[m_repeat_index];
 3795          }
 3796  
 3797          bool next() override {
 3798              // There are 2 basic cases:
 3799              // 1) We are still reading the generator
 3800              // 2) We are reading our own cache
 3801  
 3802              // In the first case, we need to poke the underlying generator.
 3803              // If it happily moves, we are left in that state, otherwise it is time to start reading from our cache
 3804              if (m_current_repeat == 0) {
 3805                  const auto success = m_generator.next();
 3806                  if (!success) {
 3807                      ++m_current_repeat;
 3808                  }
 3809                  return m_current_repeat < m_target_repeats;
 3810              }
 3811  
 3812              // In the second case, we need to move indices forward and check that we haven't run up against the end
 3813              ++m_repeat_index;
 3814              if (m_repeat_index == m_returned.size()) {
 3815                  m_repeat_index = 0;
 3816                  ++m_current_repeat;
 3817              }
 3818              return m_current_repeat < m_target_repeats;
 3819          }
 3820      };
 3821  
 3822      template <typename T>
 3823      GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T>&& generator) {
 3824          return GeneratorWrapper<T>(pf::make_unique<RepeatGenerator<T>>(repeats, std::move(generator)));
 3825      }
 3826  
 3827      template <typename T, typename U, typename Func>
 3828      class MapGenerator : public IGenerator<T> {
 3829          // TBD: provide static assert for mapping function, for friendly error message
 3830          GeneratorWrapper<U> m_generator;
 3831          Func m_function;
 3832          // To avoid returning dangling reference, we have to save the values
 3833          T m_cache;
 3834      public:
 3835          template <typename F2 = Func>
 3836          MapGenerator(F2&& function, GeneratorWrapper<U>&& generator) :
 3837              m_generator(std::move(generator)),
 3838              m_function(std::forward<F2>(function)),
 3839              m_cache(m_function(m_generator.get()))
 3840          {}
 3841  
 3842          T const& get() const override {
 3843              return m_cache;
 3844          }
 3845          bool next() override {
 3846              const auto success = m_generator.next();
 3847              if (success) {
 3848                  m_cache = m_function(m_generator.get());
 3849              }
 3850              return success;
 3851          }
 3852      };
 3853  
 3854  #if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
 3855      // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
 3856      // replaced with std::invoke_result here. Also *_t format is preferred over
 3857      // typename *::type format.
 3858      template <typename Func, typename U>
 3859      using MapFunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U>>>;
 3860  #else
 3861      template <typename Func, typename U>
 3862      using MapFunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U)>::type>::type>::type;
 3863  #endif
 3864  
 3865      template <typename Func, typename U, typename T = MapFunctionReturnType<Func, U>>
 3866      GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
 3867          return GeneratorWrapper<T>(
 3868              pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
 3869          );
 3870      }
 3871  
 3872      template <typename T, typename U, typename Func>
 3873      GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
 3874          return GeneratorWrapper<T>(
 3875              pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
 3876          );
 3877      }
 3878  
 3879      template <typename T>
 3880      class ChunkGenerator final : public IGenerator<std::vector<T>> {
 3881          std::vector<T> m_chunk;
 3882          size_t m_chunk_size;
 3883          GeneratorWrapper<T> m_generator;
 3884          bool m_used_up = false;
 3885      public:
 3886          ChunkGenerator(size_t size, GeneratorWrapper<T> generator) :
 3887              m_chunk_size(size), m_generator(std::move(generator))
 3888          {
 3889              m_chunk.reserve(m_chunk_size);
 3890              m_chunk.push_back(m_generator.get());
 3891              for (size_t i = 1; i < m_chunk_size; ++i) {
 3892                  if (!m_generator.next()) {
 3893                      Catch::throw_exception(GeneratorException("Not enough values to initialize the first chunk"));
 3894                  }
 3895                  m_chunk.push_back(m_generator.get());
 3896              }
 3897          }
 3898          std::vector<T> const& get() const override {
 3899              return m_chunk;
 3900          }
 3901          bool next() override {
 3902              m_chunk.clear();
 3903              for (size_t idx = 0; idx < m_chunk_size; ++idx) {
 3904                  if (!m_generator.next()) {
 3905                      return false;
 3906                  }
 3907                  m_chunk.push_back(m_generator.get());
 3908              }
 3909              return true;
 3910          }
 3911      };
 3912  
 3913      template <typename T>
 3914      GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper<T>&& generator) {
 3915          return GeneratorWrapper<std::vector<T>>(
 3916              pf::make_unique<ChunkGenerator<T>>(size, std::move(generator))
 3917          );
 3918      }
 3919  
 3920  } // namespace Generators
 3921  } // namespace Catch
 3922  
 3923  // end catch_generators_generic.hpp
 3924  // start catch_generators_specific.hpp
 3925  
 3926  // start catch_context.h
 3927  
 3928  #include <memory>
 3929  
 3930  namespace Catch {
 3931  
 3932      struct IResultCapture;
 3933      struct IRunner;
 3934      struct IConfig;
 3935      struct IMutableContext;
 3936  
 3937      using IConfigPtr = std::shared_ptr<IConfig const>;
 3938  
 3939      struct IContext
 3940      {
 3941          virtual ~IContext();
 3942  
 3943          virtual IResultCapture* getResultCapture() = 0;
 3944          virtual IRunner* getRunner() = 0;
 3945          virtual IConfigPtr const& getConfig() const = 0;
 3946      };
 3947  
 3948      struct IMutableContext : IContext
 3949      {
 3950          virtual ~IMutableContext();
 3951          virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
 3952          virtual void setRunner( IRunner* runner ) = 0;
 3953          virtual void setConfig( IConfigPtr const& config ) = 0;
 3954  
 3955      private:
 3956          static IMutableContext *currentContext;
 3957          friend IMutableContext& getCurrentMutableContext();
 3958          friend void cleanUpContext();
 3959          static void createContext();
 3960      };
 3961  
 3962      inline IMutableContext& getCurrentMutableContext()
 3963      {
 3964          if( !IMutableContext::currentContext )
 3965              IMutableContext::createContext();
 3966          return *IMutableContext::currentContext;
 3967      }
 3968  
 3969      inline IContext& getCurrentContext()
 3970      {
 3971          return getCurrentMutableContext();
 3972      }
 3973  
 3974      void cleanUpContext();
 3975  }
 3976  
 3977  // end catch_context.h
 3978  // start catch_interfaces_config.h
 3979  
 3980  #include <iosfwd>
 3981  #include <string>
 3982  #include <vector>
 3983  #include <memory>
 3984  
 3985  namespace Catch {
 3986  
 3987      enum class Verbosity {
 3988          Quiet = 0,
 3989          Normal,
 3990          High
 3991      };
 3992  
 3993      struct WarnAbout { enum What {
 3994          Nothing = 0x00,
 3995          NoAssertions = 0x01,
 3996          NoTests = 0x02
 3997      }; };
 3998  
 3999      struct ShowDurations { enum OrNot {
 4000          DefaultForReporter,
 4001          Always,
 4002          Never
 4003      }; };
 4004      struct RunTests { enum InWhatOrder {
 4005          InDeclarationOrder,
 4006          InLexicographicalOrder,
 4007          InRandomOrder
 4008      }; };
 4009      struct UseColour { enum YesOrNo {
 4010          Auto,
 4011          Yes,
 4012          No
 4013      }; };
 4014      struct WaitForKeypress { enum When {
 4015          Never,
 4016          BeforeStart = 1,
 4017          BeforeExit = 2,
 4018          BeforeStartAndExit = BeforeStart | BeforeExit
 4019      }; };
 4020  
 4021      class TestSpec;
 4022  
 4023      struct IConfig : NonCopyable {
 4024  
 4025          virtual ~IConfig();
 4026  
 4027          virtual bool allowThrows() const = 0;
 4028          virtual std::ostream& stream() const = 0;
 4029          virtual std::string name() const = 0;
 4030          virtual bool includeSuccessfulResults() const = 0;
 4031          virtual bool shouldDebugBreak() const = 0;
 4032          virtual bool warnAboutMissingAssertions() const = 0;
 4033          virtual bool warnAboutNoTests() const = 0;
 4034          virtual int abortAfter() const = 0;
 4035          virtual bool showInvisibles() const = 0;
 4036          virtual ShowDurations::OrNot showDurations() const = 0;
 4037          virtual TestSpec const& testSpec() const = 0;
 4038          virtual bool hasTestFilters() const = 0;
 4039          virtual std::vector<std::string> const& getTestsOrTags() const = 0;
 4040          virtual RunTests::InWhatOrder runOrder() const = 0;
 4041          virtual unsigned int rngSeed() const = 0;
 4042          virtual int benchmarkResolutionMultiple() const = 0;
 4043          virtual UseColour::YesOrNo useColour() const = 0;
 4044          virtual std::vector<std::string> const& getSectionsToRun() const = 0;
 4045          virtual Verbosity verbosity() const = 0;
 4046      };
 4047  
 4048      using IConfigPtr = std::shared_ptr<IConfig const>;
 4049  }
 4050  
 4051  // end catch_interfaces_config.h
 4052  #include <random>
 4053  
 4054  namespace Catch {
 4055  namespace Generators {
 4056  
 4057  template <typename Float>
 4058  class RandomFloatingGenerator final : public IGenerator<Float> {
 4059      // FIXME: What is the right seed?
 4060      std::minstd_rand m_rand;
 4061      std::uniform_real_distribution<Float> m_dist;
 4062      Float m_current_number;
 4063  public:
 4064  
 4065      RandomFloatingGenerator(Float a, Float b):
 4066          m_rand(getCurrentContext().getConfig()->rngSeed()),
 4067          m_dist(a, b) {
 4068          static_cast<void>(next());
 4069      }
 4070  
 4071      Float const& get() const override {
 4072          return m_current_number;
 4073      }
 4074      bool next() override {
 4075          m_current_number = m_dist(m_rand);
 4076          return true;
 4077      }
 4078  };
 4079  
 4080  template <typename Integer>
 4081  class RandomIntegerGenerator final : public IGenerator<Integer> {
 4082      std::minstd_rand m_rand;
 4083      std::uniform_int_distribution<Integer> m_dist;
 4084      Integer m_current_number;
 4085  public:
 4086  
 4087      RandomIntegerGenerator(Integer a, Integer b):
 4088          m_rand(getCurrentContext().getConfig()->rngSeed()),
 4089          m_dist(a, b) {
 4090          static_cast<void>(next());
 4091      }
 4092  
 4093      Integer const& get() const override {
 4094          return m_current_number;
 4095      }
 4096      bool next() override {
 4097          m_current_number = m_dist(m_rand);
 4098          return true;
 4099      }
 4100  };
 4101  
 4102  // TODO: Ideally this would be also constrained against the various char types,
 4103  //       but I don't expect users to run into that in practice.
 4104  template <typename T>
 4105  typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value,
 4106  GeneratorWrapper<T>>::type
 4107  random(T a, T b) {
 4108      return GeneratorWrapper<T>(
 4109          pf::make_unique<RandomIntegerGenerator<T>>(a, b)
 4110      );
 4111  }
 4112  
 4113  template <typename T>
 4114  typename std::enable_if<std::is_floating_point<T>::value,
 4115  GeneratorWrapper<T>>::type
 4116  random(T a, T b) {
 4117      return GeneratorWrapper<T>(
 4118          pf::make_unique<RandomFloatingGenerator<T>>(a, b)
 4119      );
 4120  }
 4121  
 4122  template <typename T>
 4123  class RangeGenerator final : public IGenerator<T> {
 4124      T m_current;
 4125      T m_end;
 4126      T m_step;
 4127      bool m_positive;
 4128  
 4129  public:
 4130      RangeGenerator(T const& start, T const& end, T const& step):
 4131          m_current(start),
 4132          m_end(end),
 4133          m_step(step),
 4134          m_positive(m_step > T(0))
 4135      {
 4136          assert(m_current != m_end && "Range start and end cannot be equal");
 4137          assert(m_step != T(0) && "Step size cannot be zero");
 4138          assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && "Step moves away from end");
 4139      }
 4140  
 4141      RangeGenerator(T const& start, T const& end):
 4142          RangeGenerator(start, end, (start < end) ? T(1) : T(-1))
 4143      {}
 4144  
 4145      T const& get() const override {
 4146          return m_current;
 4147      }
 4148  
 4149      bool next() override {
 4150          m_current += m_step;
 4151          return (m_positive) ? (m_current < m_end) : (m_current > m_end);
 4152      }
 4153  };
 4154  
 4155  template <typename T>
 4156  GeneratorWrapper<T> range(T const& start, T const& end, T const& step) {
 4157      static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
 4158      return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end, step));
 4159  }
 4160  
 4161  template <typename T>
 4162  GeneratorWrapper<T> range(T const& start, T const& end) {
 4163      static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
 4164      return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end));
 4165  }
 4166  
 4167  } // namespace Generators
 4168  } // namespace Catch
 4169  
 4170  // end catch_generators_specific.hpp
 4171  
 4172  // These files are included here so the single_include script doesn't put them
 4173  // in the conditionally compiled sections
 4174  // start catch_test_case_info.h
 4175  
 4176  #include <string>
 4177  #include <vector>
 4178  #include <memory>
 4179  
 4180  #ifdef __clang__
 4181  #pragma clang diagnostic push
 4182  #pragma clang diagnostic ignored "-Wpadded"
 4183  #endif
 4184  
 4185  namespace Catch {
 4186  
 4187      struct ITestInvoker;
 4188  
 4189      struct TestCaseInfo {
 4190          enum SpecialProperties{
 4191              None = 0,
 4192              IsHidden = 1 << 1,
 4193              ShouldFail = 1 << 2,
 4194              MayFail = 1 << 3,
 4195              Throws = 1 << 4,
 4196              NonPortable = 1 << 5,
 4197              Benchmark = 1 << 6
 4198          };
 4199  
 4200          TestCaseInfo(   std::string const& _name,
 4201                          std::string const& _className,
 4202                          std::string const& _description,
 4203                          std::vector<std::string> const& _tags,
 4204                          SourceLineInfo const& _lineInfo );
 4205  
 4206          friend void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags );
 4207  
 4208          bool isHidden() const;
 4209          bool throws() const;
 4210          bool okToFail() const;
 4211          bool expectedToFail() const;
 4212  
 4213          std::string tagsAsString() const;
 4214  
 4215          std::string name;
 4216          std::string className;
 4217          std::string description;
 4218          std::vector<std::string> tags;
 4219          std::vector<std::string> lcaseTags;
 4220          SourceLineInfo lineInfo;
 4221          SpecialProperties properties;
 4222      };
 4223  
 4224      class TestCase : public TestCaseInfo {
 4225      public:
 4226  
 4227          TestCase( ITestInvoker* testCase, TestCaseInfo&& info );
 4228  
 4229          TestCase withName( std::string const& _newName ) const;
 4230  
 4231          void invoke() const;
 4232  
 4233          TestCaseInfo const& getTestCaseInfo() const;
 4234  
 4235          bool operator == ( TestCase const& other ) const;
 4236          bool operator < ( TestCase const& other ) const;
 4237  
 4238      private:
 4239          std::shared_ptr<ITestInvoker> test;
 4240      };
 4241  
 4242      TestCase makeTestCase(  ITestInvoker* testCase,
 4243                              std::string const& className,
 4244                              NameAndTags const& nameAndTags,
 4245                              SourceLineInfo const& lineInfo );
 4246  }
 4247  
 4248  #ifdef __clang__
 4249  #pragma clang diagnostic pop
 4250  #endif
 4251  
 4252  // end catch_test_case_info.h
 4253  // start catch_interfaces_runner.h
 4254  
 4255  namespace Catch {
 4256  
 4257      struct IRunner {
 4258          virtual ~IRunner();
 4259          virtual bool aborting() const = 0;
 4260      };
 4261  }
 4262  
 4263  // end catch_interfaces_runner.h
 4264  
 4265  #ifdef __OBJC__
 4266  // start catch_objc.hpp
 4267  
 4268  #import <objc/runtime.h>
 4269  
 4270  #include <string>
 4271  
 4272  // NB. Any general catch headers included here must be included
 4273  // in catch.hpp first to make sure they are included by the single
 4274  // header for non obj-usage
 4275  
 4276  ///////////////////////////////////////////////////////////////////////////////
 4277  // This protocol is really only here for (self) documenting purposes, since
 4278  // all its methods are optional.
 4279  @protocol OcFixture
 4280  
 4281  @optional
 4282  
 4283  -(void) setUp;
 4284  -(void) tearDown;
 4285  
 4286  @end
 4287  
 4288  namespace Catch {
 4289  
 4290      class OcMethod : public ITestInvoker {
 4291  
 4292      public:
 4293          OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
 4294  
 4295          virtual void invoke() const {
 4296              id obj = [[m_cls alloc] init];
 4297  
 4298              performOptionalSelector( obj, @selector(setUp)  );
 4299              performOptionalSelector( obj, m_sel );
 4300              performOptionalSelector( obj, @selector(tearDown)  );
 4301  
 4302              arcSafeRelease( obj );
 4303          }
 4304      private:
 4305          virtual ~OcMethod() {}
 4306  
 4307          Class m_cls;
 4308          SEL m_sel;
 4309      };
 4310  
 4311      namespace Detail{
 4312  
 4313          inline std::string getAnnotation(   Class cls,
 4314                                              std::string const& annotationName,
 4315                                              std::string const& testCaseName ) {
 4316              NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
 4317              SEL sel = NSSelectorFromString( selStr );
 4318              arcSafeRelease( selStr );
 4319              id value = performOptionalSelector( cls, sel );
 4320              if( value )
 4321                  return [(NSString*)value UTF8String];
 4322              return "";
 4323          }
 4324      }
 4325  
 4326      inline std::size_t registerTestMethods() {
 4327          std::size_t noTestMethods = 0;
 4328          int noClasses = objc_getClassList( nullptr, 0 );
 4329  
 4330          Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
 4331          objc_getClassList( classes, noClasses );
 4332  
 4333          for( int c = 0; c < noClasses; c++ ) {
 4334              Class cls = classes[c];
 4335              {
 4336                  u_int count;
 4337                  Method* methods = class_copyMethodList( cls, &count );
 4338                  for( u_int m = 0; m < count ; m++ ) {
 4339                      SEL selector = method_getName(methods[m]);
 4340                      std::string methodName = sel_getName(selector);
 4341                      if( startsWith( methodName, "Catch_TestCase_" ) ) {
 4342                          std::string testCaseName = methodName.substr( 15 );
 4343                          std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
 4344                          std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
 4345                          const char* className = class_getName( cls );
 4346  
 4347                          getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo("",0) ) );
 4348                          noTestMethods++;
 4349                      }
 4350                  }
 4351                  free(methods);
 4352              }
 4353          }
 4354          return noTestMethods;
 4355      }
 4356  
 4357  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
 4358  
 4359      namespace Matchers {
 4360          namespace Impl {
 4361          namespace NSStringMatchers {
 4362  
 4363              struct StringHolder : MatcherBase<NSString*>{
 4364                  StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
 4365                  StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
 4366                  StringHolder() {
 4367                      arcSafeRelease( m_substr );
 4368                  }
 4369  
 4370                  bool match( NSString* const& str ) const override {
 4371                      return false;
 4372                  }
 4373  
 4374                  NSString* CATCH_ARC_STRONG m_substr;
 4375              };
 4376  
 4377              struct Equals : StringHolder {
 4378                  Equals( NSString* substr ) : StringHolder( substr ){}
 4379  
 4380                  bool match( NSString* const& str ) const override {
 4381                      return  (str != nil || m_substr == nil ) &&
 4382                              [str isEqualToString:m_substr];
 4383                  }
 4384  
 4385                  std::string describe() const override {
 4386                      return "equals string: " + Catch::Detail::stringify( m_substr );
 4387                  }
 4388              };
 4389  
 4390              struct Contains : StringHolder {
 4391                  Contains( NSString* substr ) : StringHolder( substr ){}
 4392  
 4393                  bool match( NSString* const& str ) const override {
 4394                      return  (str != nil || m_substr == nil ) &&
 4395                              [str rangeOfString:m_substr].location != NSNotFound;
 4396                  }
 4397  
 4398                  std::string describe() const override {
 4399                      return "contains string: " + Catch::Detail::stringify( m_substr );
 4400                  }
 4401              };
 4402  
 4403              struct StartsWith : StringHolder {
 4404                  StartsWith( NSString* substr ) : StringHolder( substr ){}
 4405  
 4406                  bool match( NSString* const& str ) const override {
 4407                      return  (str != nil || m_substr == nil ) &&
 4408                              [str rangeOfString:m_substr].location == 0;
 4409                  }
 4410  
 4411                  std::string describe() const override {
 4412                      return "starts with: " + Catch::Detail::stringify( m_substr );
 4413                  }
 4414              };
 4415              struct EndsWith : StringHolder {
 4416                  EndsWith( NSString* substr ) : StringHolder( substr ){}
 4417  
 4418                  bool match( NSString* const& str ) const override {
 4419                      return  (str != nil || m_substr == nil ) &&
 4420                              [str rangeOfString:m_substr].location == [str length] - [m_substr length];
 4421                  }
 4422  
 4423                  std::string describe() const override {
 4424                      return "ends with: " + Catch::Detail::stringify( m_substr );
 4425                  }
 4426              };
 4427  
 4428          } // namespace NSStringMatchers
 4429          } // namespace Impl
 4430  
 4431          inline Impl::NSStringMatchers::Equals
 4432              Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
 4433  
 4434          inline Impl::NSStringMatchers::Contains
 4435              Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
 4436  
 4437          inline Impl::NSStringMatchers::StartsWith
 4438              StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
 4439  
 4440          inline Impl::NSStringMatchers::EndsWith
 4441              EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
 4442  
 4443      } // namespace Matchers
 4444  
 4445      using namespace Matchers;
 4446  
 4447  #endif // CATCH_CONFIG_DISABLE_MATCHERS
 4448  
 4449  } // namespace Catch
 4450  
 4451  ///////////////////////////////////////////////////////////////////////////////
 4452  #define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix
 4453  #define OC_TEST_CASE2( name, desc, uniqueSuffix ) \
 4454  +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \
 4455  { \
 4456  return @ name; \
 4457  } \
 4458  +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \
 4459  { \
 4460  return @ desc; \
 4461  } \
 4462  -(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix )
 4463  
 4464  #define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ )
 4465  
 4466  // end catch_objc.hpp
 4467  #endif
 4468  
 4469  #ifdef CATCH_CONFIG_EXTERNAL_INTERFACES
 4470  // start catch_external_interfaces.h
 4471  
 4472  // start catch_reporter_bases.hpp
 4473  
 4474  // start catch_interfaces_reporter.h
 4475  
 4476  // start catch_config.hpp
 4477  
 4478  // start catch_test_spec_parser.h
 4479  
 4480  #ifdef __clang__
 4481  #pragma clang diagnostic push
 4482  #pragma clang diagnostic ignored "-Wpadded"
 4483  #endif
 4484  
 4485  // start catch_test_spec.h
 4486  
 4487  #ifdef __clang__
 4488  #pragma clang diagnostic push
 4489  #pragma clang diagnostic ignored "-Wpadded"
 4490  #endif
 4491  
 4492  // start catch_wildcard_pattern.h
 4493  
 4494  namespace Catch
 4495  {
 4496      class WildcardPattern {
 4497          enum WildcardPosition {
 4498              NoWildcard = 0,
 4499              WildcardAtStart = 1,
 4500              WildcardAtEnd = 2,
 4501              WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
 4502          };
 4503  
 4504      public:
 4505  
 4506          WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity );
 4507          virtual ~WildcardPattern() = default;
 4508          virtual bool matches( std::string const& str ) const;
 4509  
 4510      private:
 4511          std::string adjustCase( std::string const& str ) const;
 4512          CaseSensitive::Choice m_caseSensitivity;
 4513          WildcardPosition m_wildcard = NoWildcard;
 4514          std::string m_pattern;
 4515      };
 4516  }
 4517  
 4518  // end catch_wildcard_pattern.h
 4519  #include <string>
 4520  #include <vector>
 4521  #include <memory>
 4522  
 4523  namespace Catch {
 4524  
 4525      class TestSpec {
 4526          struct Pattern {
 4527              virtual ~Pattern();
 4528              virtual bool matches( TestCaseInfo const& testCase ) const = 0;
 4529          };
 4530          using PatternPtr = std::shared_ptr<Pattern>;
 4531  
 4532          class NamePattern : public Pattern {
 4533          public:
 4534              NamePattern( std::string const& name );
 4535              virtual ~NamePattern();
 4536              bool matches( TestCaseInfo const& testCase ) const override;
 4537          private:
 4538              WildcardPattern m_wildcardPattern;
 4539          };
 4540  
 4541          class TagPattern : public Pattern {
 4542          public:
 4543              TagPattern( std::string const& tag );
 4544              virtual ~TagPattern();
 4545              bool matches( TestCaseInfo const& testCase ) const override;
 4546          private:
 4547              std::string m_tag;
 4548          };
 4549  
 4550          class ExcludedPattern : public Pattern {
 4551          public:
 4552              ExcludedPattern( PatternPtr const& underlyingPattern );
 4553              virtual ~ExcludedPattern();
 4554              bool matches( TestCaseInfo const& testCase ) const override;
 4555          private:
 4556              PatternPtr m_underlyingPattern;
 4557          };
 4558  
 4559          struct Filter {
 4560              std::vector<PatternPtr> m_patterns;
 4561  
 4562              bool matches( TestCaseInfo const& testCase ) const;
 4563          };
 4564  
 4565      public:
 4566          bool hasFilters() const;
 4567          bool matches( TestCaseInfo const& testCase ) const;
 4568  
 4569      private:
 4570          std::vector<Filter> m_filters;
 4571  
 4572          friend class TestSpecParser;
 4573      };
 4574  }
 4575  
 4576  #ifdef __clang__
 4577  #pragma clang diagnostic pop
 4578  #endif
 4579  
 4580  // end catch_test_spec.h
 4581  // start catch_interfaces_tag_alias_registry.h
 4582  
 4583  #include <string>
 4584  
 4585  namespace Catch {
 4586  
 4587      struct TagAlias;
 4588  
 4589      struct ITagAliasRegistry {
 4590          virtual ~ITagAliasRegistry();
 4591          // Nullptr if not present
 4592          virtual TagAlias const* find( std::string const& alias ) const = 0;
 4593          virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
 4594  
 4595          static ITagAliasRegistry const& get();
 4596      };
 4597  
 4598  } // end namespace Catch
 4599  
 4600  // end catch_interfaces_tag_alias_registry.h
 4601  namespace Catch {
 4602  
 4603      class TestSpecParser {
 4604          enum Mode{ None, Name, QuotedName, Tag, EscapedName };
 4605          Mode m_mode = None;
 4606          bool m_exclusion = false;
 4607          std::size_t m_start = std::string::npos, m_pos = 0;
 4608          std::string m_arg;
 4609          std::vector<std::size_t> m_escapeChars;
 4610          TestSpec::Filter m_currentFilter;
 4611          TestSpec m_testSpec;
 4612          ITagAliasRegistry const* m_tagAliases = nullptr;
 4613  
 4614      public:
 4615          TestSpecParser( ITagAliasRegistry const& tagAliases );
 4616  
 4617          TestSpecParser& parse( std::string const& arg );
 4618          TestSpec testSpec();
 4619  
 4620      private:
 4621          void visitChar( char c );
 4622          void startNewMode( Mode mode, std::size_t start );
 4623          void escape();
 4624          std::string subString() const;
 4625  
 4626          template<typename T>
 4627          void addPattern() {
 4628              std::string token = subString();
 4629              for( std::size_t i = 0; i < m_escapeChars.size(); ++i )
 4630                  token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 );
 4631              m_escapeChars.clear();
 4632              if( startsWith( token, "exclude:" ) ) {
 4633                  m_exclusion = true;
 4634                  token = token.substr( 8 );
 4635              }
 4636              if( !token.empty() ) {
 4637                  TestSpec::PatternPtr pattern = std::make_shared<T>( token );
 4638                  if( m_exclusion )
 4639                      pattern = std::make_shared<TestSpec::ExcludedPattern>( pattern );
 4640                  m_currentFilter.m_patterns.push_back( pattern );
 4641              }
 4642              m_exclusion = false;
 4643              m_mode = None;
 4644          }
 4645  
 4646          void addFilter();
 4647      };
 4648      TestSpec parseTestSpec( std::string const& arg );
 4649  
 4650  } // namespace Catch
 4651  
 4652  #ifdef __clang__
 4653  #pragma clang diagnostic pop
 4654  #endif
 4655  
 4656  // end catch_test_spec_parser.h
 4657  // Libstdc++ doesn't like incomplete classes for unique_ptr
 4658  
 4659  #include <memory>
 4660  #include <vector>
 4661  #include <string>
 4662  
 4663  #ifndef CATCH_CONFIG_CONSOLE_WIDTH
 4664  #define CATCH_CONFIG_CONSOLE_WIDTH 80
 4665  #endif
 4666  
 4667  namespace Catch {
 4668  
 4669      struct IStream;
 4670  
 4671      struct ConfigData {
 4672          bool listTests = false;
 4673          bool listTags = false;
 4674          bool listReporters = false;
 4675          bool listTestNamesOnly = false;
 4676  
 4677          bool showSuccessfulTests = false;
 4678          bool shouldDebugBreak = false;
 4679          bool noThrow = false;
 4680          bool showHelp = false;
 4681          bool showInvisibles = false;
 4682          bool filenamesAsTags = false;
 4683          bool libIdentify = false;
 4684  
 4685          int abortAfter = -1;
 4686          unsigned int rngSeed = 0;
 4687          int benchmarkResolutionMultiple = 100;
 4688  
 4689          Verbosity verbosity = Verbosity::Normal;
 4690          WarnAbout::What warnings = WarnAbout::Nothing;
 4691          ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;
 4692          RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;
 4693          UseColour::YesOrNo useColour = UseColour::Auto;
 4694          WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
 4695  
 4696          std::string outputFilename;
 4697          std::string name;
 4698          std::string processName;
 4699  #ifndef CATCH_CONFIG_DEFAULT_REPORTER
 4700  #define CATCH_CONFIG_DEFAULT_REPORTER "console"
 4701  #endif
 4702          std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER;
 4703  #undef CATCH_CONFIG_DEFAULT_REPORTER
 4704  
 4705          std::vector<std::string> testsOrTags;
 4706          std::vector<std::string> sectionsToRun;
 4707      };
 4708  
 4709      class Config : public IConfig {
 4710      public:
 4711  
 4712          Config() = default;
 4713          Config( ConfigData const& data );
 4714          virtual ~Config() = default;
 4715  
 4716          std::string const& getFilename() const;
 4717  
 4718          bool listTests() const;
 4719          bool listTestNamesOnly() const;
 4720          bool listTags() const;
 4721          bool listReporters() const;
 4722  
 4723          std::string getProcessName() const;
 4724          std::string const& getReporterName() const;
 4725  
 4726          std::vector<std::string> const& getTestsOrTags() const override;
 4727          std::vector<std::string> const& getSectionsToRun() const override;
 4728  
 4729          TestSpec const& testSpec() const override;
 4730          bool hasTestFilters() const override;
 4731  
 4732          bool showHelp() const;
 4733  
 4734          // IConfig interface
 4735          bool allowThrows() const override;
 4736          std::ostream& stream() const override;
 4737          std::string name() const override;
 4738          bool includeSuccessfulResults() const override;
 4739          bool warnAboutMissingAssertions() const override;
 4740          bool warnAboutNoTests() const override;
 4741          ShowDurations::OrNot showDurations() const override;
 4742          RunTests::InWhatOrder runOrder() const override;
 4743          unsigned int rngSeed() const override;
 4744          int benchmarkResolutionMultiple() const override;
 4745          UseColour::YesOrNo useColour() const override;
 4746          bool shouldDebugBreak() const override;
 4747          int abortAfter() const override;
 4748          bool showInvisibles() const override;
 4749          Verbosity verbosity() const override;
 4750  
 4751      private:
 4752  
 4753          IStream const* openStream();
 4754          ConfigData m_data;
 4755  
 4756          std::unique_ptr<IStream const> m_stream;
 4757          TestSpec m_testSpec;
 4758          bool m_hasTestFilters = false;
 4759      };
 4760  
 4761  } // end namespace Catch
 4762  
 4763  // end catch_config.hpp
 4764  // start catch_assertionresult.h
 4765  
 4766  #include <string>
 4767  
 4768  namespace Catch {
 4769  
 4770      struct AssertionResultData
 4771      {
 4772          AssertionResultData() = delete;
 4773  
 4774          AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression );
 4775  
 4776          std::string message;
 4777          mutable std::string reconstructedExpression;
 4778          LazyExpression lazyExpression;
 4779          ResultWas::OfType resultType;
 4780  
 4781          std::string reconstructExpression() const;
 4782      };
 4783  
 4784      class AssertionResult {
 4785      public:
 4786          AssertionResult() = delete;
 4787          AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
 4788  
 4789          bool isOk() const;
 4790          bool succeeded() const;
 4791          ResultWas::OfType getResultType() const;
 4792          bool hasExpression() const;
 4793          bool hasMessage() const;
 4794          std::string getExpression() const;
 4795          std::string getExpressionInMacro() const;
 4796          bool hasExpandedExpression() const;
 4797          std::string getExpandedExpression() const;
 4798          std::string getMessage() const;
 4799          SourceLineInfo getSourceInfo() const;
 4800          StringRef getTestMacroName() const;
 4801  
 4802      //protected:
 4803          AssertionInfo m_info;
 4804          AssertionResultData m_resultData;
 4805      };
 4806  
 4807  } // end namespace Catch
 4808  
 4809  // end catch_assertionresult.h
 4810  // start catch_option.hpp
 4811  
 4812  namespace Catch {
 4813  
 4814      // An optional type
 4815      template<typename T>
 4816      class Option {
 4817      public:
 4818          Option() : nullableValue( nullptr ) {}
 4819          Option( T const& _value )
 4820          : nullableValue( new( storage ) T( _value ) )
 4821          {}
 4822          Option( Option const& _other )
 4823          : nullableValue( _other ? new( storage ) T( *_other ) : nullptr )
 4824          {}
 4825  
 4826          ~Option() {
 4827              reset();
 4828          }
 4829  
 4830          Option& operator= ( Option const& _other ) {
 4831              if( &_other != this ) {
 4832                  reset();
 4833                  if( _other )
 4834                      nullableValue = new( storage ) T( *_other );
 4835              }
 4836              return *this;
 4837          }
 4838          Option& operator = ( T const& _value ) {
 4839              reset();
 4840              nullableValue = new( storage ) T( _value );
 4841              return *this;
 4842          }
 4843  
 4844          void reset() {
 4845              if( nullableValue )
 4846                  nullableValue->~T();
 4847              nullableValue = nullptr;
 4848          }
 4849  
 4850          T& operator*() { return *nullableValue; }
 4851          T const& operator*() const { return *nullableValue; }
 4852          T* operator->() { return nullableValue; }
 4853          const T* operator->() const { return nullableValue; }
 4854  
 4855          T valueOr( T const& defaultValue ) const {
 4856              return nullableValue ? *nullableValue : defaultValue;
 4857          }
 4858  
 4859          bool some() const { return nullableValue != nullptr; }
 4860          bool none() const { return nullableValue == nullptr; }
 4861  
 4862          bool operator !() const { return nullableValue == nullptr; }
 4863          explicit operator bool() const {
 4864              return some();
 4865          }
 4866  
 4867      private:
 4868          T *nullableValue;
 4869          alignas(alignof(T)) char storage[sizeof(T)];
 4870      };
 4871  
 4872  } // end namespace Catch
 4873  
 4874  // end catch_option.hpp
 4875  #include <string>
 4876  #include <iosfwd>
 4877  #include <map>
 4878  #include <set>
 4879  #include <memory>
 4880  
 4881  namespace Catch {
 4882  
 4883      struct ReporterConfig {
 4884          explicit ReporterConfig( IConfigPtr const& _fullConfig );
 4885  
 4886          ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream );
 4887  
 4888          std::ostream& stream() const;
 4889          IConfigPtr fullConfig() const;
 4890  
 4891      private:
 4892          std::ostream* m_stream;
 4893          IConfigPtr m_fullConfig;
 4894      };
 4895  
 4896      struct ReporterPreferences {
 4897          bool shouldRedirectStdOut = false;
 4898          bool shouldReportAllAssertions = false;
 4899      };
 4900  
 4901      template<typename T>
 4902      struct LazyStat : Option<T> {
 4903          LazyStat& operator=( T const& _value ) {
 4904              Option<T>::operator=( _value );
 4905              used = false;
 4906              return *this;
 4907          }
 4908          void reset() {
 4909              Option<T>::reset();
 4910              used = false;
 4911          }
 4912          bool used = false;
 4913      };
 4914  
 4915      struct TestRunInfo {
 4916          TestRunInfo( std::string const& _name );
 4917          std::string name;
 4918      };
 4919      struct GroupInfo {
 4920          GroupInfo(  std::string const& _name,
 4921                      std::size_t _groupIndex,
 4922                      std::size_t _groupsCount );
 4923  
 4924          std::string name;
 4925          std::size_t groupIndex;
 4926          std::size_t groupsCounts;
 4927      };
 4928  
 4929      struct AssertionStats {
 4930          AssertionStats( AssertionResult const& _assertionResult,
 4931                          std::vector<MessageInfo> const& _infoMessages,
 4932                          Totals const& _totals );
 4933  
 4934          AssertionStats( AssertionStats const& )              = default;
 4935          AssertionStats( AssertionStats && )                  = default;
 4936          AssertionStats& operator = ( AssertionStats const& ) = delete;
 4937          AssertionStats& operator = ( AssertionStats && )     = delete;
 4938          virtual ~AssertionStats();
 4939  
 4940          AssertionResult assertionResult;
 4941          std::vector<MessageInfo> infoMessages;
 4942          Totals totals;
 4943      };
 4944  
 4945      struct SectionStats {
 4946          SectionStats(   SectionInfo const& _sectionInfo,
 4947                          Counts const& _assertions,
 4948                          double _durationInSeconds,
 4949                          bool _missingAssertions );
 4950          SectionStats( SectionStats const& )              = default;
 4951          SectionStats( SectionStats && )                  = default;
 4952          SectionStats& operator = ( SectionStats const& ) = default;
 4953          SectionStats& operator = ( SectionStats && )     = default;
 4954          virtual ~SectionStats();
 4955  
 4956          SectionInfo sectionInfo;
 4957          Counts assertions;
 4958          double durationInSeconds;
 4959          bool missingAssertions;
 4960      };
 4961  
 4962      struct TestCaseStats {
 4963          TestCaseStats(  TestCaseInfo const& _testInfo,
 4964                          Totals const& _totals,
 4965                          std::string const& _stdOut,
 4966                          std::string const& _stdErr,
 4967                          bool _aborting );
 4968  
 4969          TestCaseStats( TestCaseStats const& )              = default;
 4970          TestCaseStats( TestCaseStats && )                  = default;
 4971          TestCaseStats& operator = ( TestCaseStats const& ) = default;
 4972          TestCaseStats& operator = ( TestCaseStats && )     = default;
 4973          virtual ~TestCaseStats();
 4974  
 4975          TestCaseInfo testInfo;
 4976          Totals totals;
 4977          std::string stdOut;
 4978          std::string stdErr;
 4979          bool aborting;
 4980      };
 4981  
 4982      struct TestGroupStats {
 4983          TestGroupStats( GroupInfo const& _groupInfo,
 4984                          Totals const& _totals,
 4985                          bool _aborting );
 4986          TestGroupStats( GroupInfo const& _groupInfo );
 4987  
 4988          TestGroupStats( TestGroupStats const& )              = default;
 4989          TestGroupStats( TestGroupStats && )                  = default;
 4990          TestGroupStats& operator = ( TestGroupStats const& ) = default;
 4991          TestGroupStats& operator = ( TestGroupStats && )     = default;
 4992          virtual ~TestGroupStats();
 4993  
 4994          GroupInfo groupInfo;
 4995          Totals totals;
 4996          bool aborting;
 4997      };
 4998  
 4999      struct TestRunStats {
 5000          TestRunStats(   TestRunInfo const& _runInfo,
 5001                          Totals const& _totals,
 5002                          bool _aborting );
 5003  
 5004          TestRunStats( TestRunStats const& )              = default;
 5005          TestRunStats( TestRunStats && )                  = default;
 5006          TestRunStats& operator = ( TestRunStats const& ) = default;
 5007          TestRunStats& operator = ( TestRunStats && )     = default;
 5008          virtual ~TestRunStats();
 5009  
 5010          TestRunInfo runInfo;
 5011          Totals totals;
 5012          bool aborting;
 5013      };
 5014  
 5015      struct BenchmarkInfo {
 5016          std::string name;
 5017      };
 5018      struct BenchmarkStats {
 5019          BenchmarkInfo info;
 5020          std::size_t iterations;
 5021          uint64_t elapsedTimeInNanoseconds;
 5022      };
 5023  
 5024      struct IStreamingReporter {
 5025          virtual ~IStreamingReporter() = default;
 5026  
 5027          // Implementing class must also provide the following static methods:
 5028          // static std::string getDescription();
 5029          // static std::set<Verbosity> getSupportedVerbosities()
 5030  
 5031          virtual ReporterPreferences getPreferences() const = 0;
 5032  
 5033          virtual void noMatchingTestCases( std::string const& spec ) = 0;
 5034  
 5035          virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
 5036          virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
 5037  
 5038          virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
 5039          virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
 5040  
 5041          // *** experimental ***
 5042          virtual void benchmarkStarting( BenchmarkInfo const& ) {}
 5043  
 5044          virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
 5045  
 5046          // The return value indicates if the messages buffer should be cleared:
 5047          virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
 5048  
 5049          // *** experimental ***
 5050          virtual void benchmarkEnded( BenchmarkStats const& ) {}
 5051  
 5052          virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
 5053          virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
 5054          virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
 5055          virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
 5056  
 5057          virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
 5058  
 5059          // Default empty implementation provided
 5060          virtual void fatalErrorEncountered( StringRef name );
 5061  
 5062          virtual bool isMulti() const;
 5063      };
 5064      using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>;
 5065  
 5066      struct IReporterFactory {
 5067          virtual ~IReporterFactory();
 5068          virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0;
 5069          virtual std::string getDescription() const = 0;
 5070      };
 5071      using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
 5072  
 5073      struct IReporterRegistry {
 5074          using FactoryMap = std::map<std::string, IReporterFactoryPtr>;
 5075          using Listeners = std::vector<IReporterFactoryPtr>;
 5076  
 5077          virtual ~IReporterRegistry();
 5078          virtual IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const = 0;
 5079          virtual FactoryMap const& getFactories() const = 0;
 5080          virtual Listeners const& getListeners() const = 0;
 5081      };
 5082  
 5083  } // end namespace Catch
 5084  
 5085  // end catch_interfaces_reporter.h
 5086  #include <algorithm>
 5087  #include <cstring>
 5088  #include <cfloat>
 5089  #include <cstdio>
 5090  #include <cassert>
 5091  #include <memory>
 5092  #include <ostream>
 5093  
 5094  namespace Catch {
 5095      void prepareExpandedExpression(AssertionResult& result);
 5096  
 5097      // Returns double formatted as %.3f (format expected on output)
 5098      std::string getFormattedDuration( double duration );
 5099  
 5100      std::string serializeFilters( std::vector<std::string> const& container );
 5101  
 5102      template<typename DerivedT>
 5103      struct StreamingReporterBase : IStreamingReporter {
 5104  
 5105          StreamingReporterBase( ReporterConfig const& _config )
 5106          :   m_config( _config.fullConfig() ),
 5107              stream( _config.stream() )
 5108          {
 5109              m_reporterPrefs.shouldRedirectStdOut = false;
 5110              if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
 5111                  CATCH_ERROR( "Verbosity level not supported by this reporter" );
 5112          }
 5113  
 5114          ReporterPreferences getPreferences() const override {
 5115              return m_reporterPrefs;
 5116          }
 5117  
 5118          static std::set<Verbosity> getSupportedVerbosities() {
 5119              return { Verbosity::Normal };
 5120          }
 5121  
 5122          ~StreamingReporterBase() override = default;
 5123  
 5124          void noMatchingTestCases(std::string const&) override {}
 5125  
 5126          void testRunStarting(TestRunInfo const& _testRunInfo) override {
 5127              currentTestRunInfo = _testRunInfo;
 5128          }
 5129  
 5130          void testGroupStarting(GroupInfo const& _groupInfo) override {
 5131              currentGroupInfo = _groupInfo;
 5132          }
 5133  
 5134          void testCaseStarting(TestCaseInfo const& _testInfo) override  {
 5135              currentTestCaseInfo = _testInfo;
 5136          }
 5137          void sectionStarting(SectionInfo const& _sectionInfo) override {
 5138              m_sectionStack.push_back(_sectionInfo);
 5139          }
 5140  
 5141          void sectionEnded(SectionStats const& /* _sectionStats */) override {
 5142              m_sectionStack.pop_back();
 5143          }
 5144          void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {
 5145              currentTestCaseInfo.reset();
 5146          }
 5147          void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override {
 5148              currentGroupInfo.reset();
 5149          }
 5150          void testRunEnded(TestRunStats const& /* _testRunStats */) override {
 5151              currentTestCaseInfo.reset();
 5152              currentGroupInfo.reset();
 5153              currentTestRunInfo.reset();
 5154          }
 5155  
 5156          void skipTest(TestCaseInfo const&) override {
 5157              // Don't do anything with this by default.
 5158              // It can optionally be overridden in the derived class.
 5159          }
 5160  
 5161          IConfigPtr m_config;
 5162          std::ostream& stream;
 5163  
 5164          LazyStat<TestRunInfo> currentTestRunInfo;
 5165          LazyStat<GroupInfo> currentGroupInfo;
 5166          LazyStat<TestCaseInfo> currentTestCaseInfo;
 5167  
 5168          std::vector<SectionInfo> m_sectionStack;
 5169          ReporterPreferences m_reporterPrefs;
 5170      };
 5171  
 5172      template<typename DerivedT>
 5173      struct CumulativeReporterBase : IStreamingReporter {
 5174          template<typename T, typename ChildNodeT>
 5175          struct Node {
 5176              explicit Node( T const& _value ) : value( _value ) {}
 5177              virtual ~Node() {}
 5178  
 5179              using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;
 5180              T value;
 5181              ChildNodes children;
 5182          };
 5183          struct SectionNode {
 5184              explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}
 5185              virtual ~SectionNode() = default;
 5186  
 5187              bool operator == (SectionNode const& other) const {
 5188                  return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
 5189              }
 5190              bool operator == (std::shared_ptr<SectionNode> const& other) const {
 5191                  return operator==(*other);
 5192              }
 5193  
 5194              SectionStats stats;
 5195              using ChildSections = std::vector<std::shared_ptr<SectionNode>>;
 5196              using Assertions = std::vector<AssertionStats>;
 5197              ChildSections childSections;
 5198              Assertions assertions;
 5199              std::string stdOut;
 5200              std::string stdErr;
 5201          };
 5202  
 5203          struct BySectionInfo {
 5204              BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
 5205              BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
 5206              bool operator() (std::shared_ptr<SectionNode> const& node) const {
 5207                  return ((node->stats.sectionInfo.name == m_other.name) &&
 5208                          (node->stats.sectionInfo.lineInfo == m_other.lineInfo));
 5209              }
 5210              void operator=(BySectionInfo const&) = delete;
 5211  
 5212          private:
 5213              SectionInfo const& m_other;
 5214          };
 5215  
 5216          using TestCaseNode = Node<TestCaseStats, SectionNode>;
 5217          using TestGroupNode = Node<TestGroupStats, TestCaseNode>;
 5218          using TestRunNode = Node<TestRunStats, TestGroupNode>;
 5219  
 5220          CumulativeReporterBase( ReporterConfig const& _config )
 5221          :   m_config( _config.fullConfig() ),
 5222              stream( _config.stream() )
 5223          {
 5224              m_reporterPrefs.shouldRedirectStdOut = false;
 5225              if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
 5226                  CATCH_ERROR( "Verbosity level not supported by this reporter" );
 5227          }
 5228          ~CumulativeReporterBase() override = default;
 5229  
 5230          ReporterPreferences getPreferences() const override {
 5231              return m_reporterPrefs;
 5232          }
 5233  
 5234          static std::set<Verbosity> getSupportedVerbosities() {
 5235              return { Verbosity::Normal };
 5236          }
 5237  
 5238          void testRunStarting( TestRunInfo const& ) override {}
 5239          void testGroupStarting( GroupInfo const& ) override {}
 5240  
 5241          void testCaseStarting( TestCaseInfo const& ) override {}
 5242  
 5243          void sectionStarting( SectionInfo const& sectionInfo ) override {
 5244              SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
 5245              std::shared_ptr<SectionNode> node;
 5246              if( m_sectionStack.empty() ) {
 5247                  if( !m_rootSection )
 5248                      m_rootSection = std::make_shared<SectionNode>( incompleteStats );
 5249                  node = m_rootSection;
 5250              }
 5251              else {
 5252                  SectionNode& parentNode = *m_sectionStack.back();
 5253                  auto it =
 5254                      std::find_if(   parentNode.childSections.begin(),
 5255                                      parentNode.childSections.end(),
 5256                                      BySectionInfo( sectionInfo ) );
 5257                  if( it == parentNode.childSections.end() ) {
 5258                      node = std::make_shared<SectionNode>( incompleteStats );
 5259                      parentNode.childSections.push_back( node );
 5260                  }
 5261                  else
 5262                      node = *it;
 5263              }
 5264              m_sectionStack.push_back( node );
 5265              m_deepestSection = std::move(node);
 5266          }
 5267  
 5268          void assertionStarting(AssertionInfo const&) override {}
 5269  
 5270          bool assertionEnded(AssertionStats const& assertionStats) override {
 5271              assert(!m_sectionStack.empty());
 5272              // AssertionResult holds a pointer to a temporary DecomposedExpression,
 5273              // which getExpandedExpression() calls to build the expression string.
 5274              // Our section stack copy of the assertionResult will likely outlive the
 5275              // temporary, so it must be expanded or discarded now to avoid calling
 5276              // a destroyed object later.
 5277              prepareExpandedExpression(const_cast<AssertionResult&>( assertionStats.assertionResult ) );
 5278              SectionNode& sectionNode = *m_sectionStack.back();
 5279              sectionNode.assertions.push_back(assertionStats);
 5280              return true;
 5281          }
 5282          void sectionEnded(SectionStats const& sectionStats) override {
 5283              assert(!m_sectionStack.empty());
 5284              SectionNode& node = *m_sectionStack.back();
 5285              node.stats = sectionStats;
 5286              m_sectionStack.pop_back();
 5287          }
 5288          void testCaseEnded(TestCaseStats const& testCaseStats) override {
 5289              auto node = std::make_shared<TestCaseNode>(testCaseStats);
 5290              assert(m_sectionStack.size() == 0);
 5291              node->children.push_back(m_rootSection);
 5292              m_testCases.push_back(node);
 5293              m_rootSection.reset();
 5294  
 5295              assert(m_deepestSection);
 5296              m_deepestSection->stdOut = testCaseStats.stdOut;
 5297              m_deepestSection->stdErr = testCaseStats.stdErr;
 5298          }
 5299          void testGroupEnded(TestGroupStats const& testGroupStats) override {
 5300              auto node = std::make_shared<TestGroupNode>(testGroupStats);
 5301              node->children.swap(m_testCases);
 5302              m_testGroups.push_back(node);
 5303          }
 5304          void testRunEnded(TestRunStats const& testRunStats) override {
 5305              auto node = std::make_shared<TestRunNode>(testRunStats);
 5306              node->children.swap(m_testGroups);
 5307              m_testRuns.push_back(node);
 5308              testRunEndedCumulative();
 5309          }
 5310          virtual void testRunEndedCumulative() = 0;
 5311  
 5312          void skipTest(TestCaseInfo const&) override {}
 5313  
 5314          IConfigPtr m_config;
 5315          std::ostream& stream;
 5316          std::vector<AssertionStats> m_assertions;
 5317          std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;
 5318          std::vector<std::shared_ptr<TestCaseNode>> m_testCases;
 5319          std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;
 5320  
 5321          std::vector<std::shared_ptr<TestRunNode>> m_testRuns;
 5322  
 5323          std::shared_ptr<SectionNode> m_rootSection;
 5324          std::shared_ptr<SectionNode> m_deepestSection;
 5325          std::vector<std::shared_ptr<SectionNode>> m_sectionStack;
 5326          ReporterPreferences m_reporterPrefs;
 5327      };
 5328  
 5329      template<char C>
 5330      char const* getLineOfChars() {
 5331          static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
 5332          if( !*line ) {
 5333              std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
 5334              line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
 5335          }
 5336          return line;
 5337      }
 5338  
 5339      struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> {
 5340          TestEventListenerBase( ReporterConfig const& _config );
 5341  
 5342          static std::set<Verbosity> getSupportedVerbosities();
 5343  
 5344          void assertionStarting(AssertionInfo const&) override;
 5345          bool assertionEnded(AssertionStats const&) override;
 5346      };
 5347  
 5348  } // end namespace Catch
 5349  
 5350  // end catch_reporter_bases.hpp
 5351  // start catch_console_colour.h
 5352  
 5353  namespace Catch {
 5354  
 5355      struct Colour {
 5356          enum Code {
 5357              None = 0,
 5358  
 5359              White,
 5360              Red,
 5361              Green,
 5362              Blue,
 5363              Cyan,
 5364              Yellow,
 5365              Grey,
 5366  
 5367              Bright = 0x10,
 5368  
 5369              BrightRed = Bright | Red,
 5370              BrightGreen = Bright | Green,
 5371              LightGrey = Bright | Grey,
 5372              BrightWhite = Bright | White,
 5373              BrightYellow = Bright | Yellow,
 5374  
 5375              // By intention
 5376              FileName = LightGrey,
 5377              Warning = BrightYellow,
 5378              ResultError = BrightRed,
 5379              ResultSuccess = BrightGreen,
 5380              ResultExpectedFailure = Warning,
 5381  
 5382              Error = BrightRed,
 5383              Success = Green,
 5384  
 5385              OriginalExpression = Cyan,
 5386              ReconstructedExpression = BrightYellow,
 5387  
 5388              SecondaryText = LightGrey,
 5389              Headers = White
 5390          };
 5391  
 5392          // Use constructed object for RAII guard
 5393          Colour( Code _colourCode );
 5394          Colour( Colour&& other ) noexcept;
 5395          Colour& operator=( Colour&& other ) noexcept;
 5396          ~Colour();
 5397  
 5398          // Use static method for one-shot changes
 5399          static void use( Code _colourCode );
 5400  
 5401      private:
 5402          bool m_moved = false;
 5403      };
 5404  
 5405      std::ostream& operator << ( std::ostream& os, Colour const& );
 5406  
 5407  } // end namespace Catch
 5408  
 5409  // end catch_console_colour.h
 5410  // start catch_reporter_registrars.hpp
 5411  
 5412  
 5413  namespace Catch {
 5414  
 5415      template<typename T>
 5416      class ReporterRegistrar {
 5417  
 5418          class ReporterFactory : public IReporterFactory {
 5419  
 5420              IStreamingReporterPtr create( ReporterConfig const& config ) const override {
 5421                  return std::unique_ptr<T>( new T( config ) );
 5422              }
 5423  
 5424              std::string getDescription() const override {
 5425                  return T::getDescription();
 5426              }
 5427          };
 5428  
 5429      public:
 5430  
 5431          explicit ReporterRegistrar( std::string const& name ) {
 5432              getMutableRegistryHub().registerReporter( name, std::make_shared<ReporterFactory>() );
 5433          }
 5434      };
 5435  
 5436      template<typename T>
 5437      class ListenerRegistrar {
 5438  
 5439          class ListenerFactory : public IReporterFactory {
 5440  
 5441              IStreamingReporterPtr create( ReporterConfig const& config ) const override {
 5442                  return std::unique_ptr<T>( new T( config ) );
 5443              }
 5444              std::string getDescription() const override {
 5445                  return std::string();
 5446              }
 5447          };
 5448  
 5449      public:
 5450  
 5451          ListenerRegistrar() {
 5452              getMutableRegistryHub().registerListener( std::make_shared<ListenerFactory>() );
 5453          }
 5454      };
 5455  }
 5456  
 5457  #if !defined(CATCH_CONFIG_DISABLE)
 5458  
 5459  #define CATCH_REGISTER_REPORTER( name, reporterType ) \
 5460      CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS          \
 5461      namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \
 5462      CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
 5463  
 5464  #define CATCH_REGISTER_LISTENER( listenerType ) \
 5465       CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS   \
 5466       namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \
 5467       CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
 5468  #else // CATCH_CONFIG_DISABLE
 5469  
 5470  #define CATCH_REGISTER_REPORTER(name, reporterType)
 5471  #define CATCH_REGISTER_LISTENER(listenerType)
 5472  
 5473  #endif // CATCH_CONFIG_DISABLE
 5474  
 5475  // end catch_reporter_registrars.hpp
 5476  // Allow users to base their work off existing reporters
 5477  // start catch_reporter_compact.h
 5478  
 5479  namespace Catch {
 5480  
 5481      struct CompactReporter : StreamingReporterBase<CompactReporter> {
 5482  
 5483          using StreamingReporterBase::StreamingReporterBase;
 5484  
 5485          ~CompactReporter() override;
 5486  
 5487          static std::string getDescription();
 5488  
 5489          ReporterPreferences getPreferences() const override;
 5490  
 5491          void noMatchingTestCases(std::string const& spec) override;
 5492  
 5493          void assertionStarting(AssertionInfo const&) override;
 5494  
 5495          bool assertionEnded(AssertionStats const& _assertionStats) override;
 5496  
 5497          void sectionEnded(SectionStats const& _sectionStats) override;
 5498  
 5499          void testRunEnded(TestRunStats const& _testRunStats) override;
 5500  
 5501      };
 5502  
 5503  } // end namespace Catch
 5504  
 5505  // end catch_reporter_compact.h
 5506  // start catch_reporter_console.h
 5507  
 5508  #if defined(_MSC_VER)
 5509  #pragma warning(push)
 5510  #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
 5511                                // Note that 4062 (not all labels are handled
 5512                                // and default is missing) is enabled
 5513  #endif
 5514  
 5515  namespace Catch {
 5516      // Fwd decls
 5517      struct SummaryColumn;
 5518      class TablePrinter;
 5519  
 5520      struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> {
 5521          std::unique_ptr<TablePrinter> m_tablePrinter;
 5522  
 5523          ConsoleReporter(ReporterConfig const& config);
 5524          ~ConsoleReporter() override;
 5525          static std::string getDescription();
 5526  
 5527          void noMatchingTestCases(std::string const& spec) override;
 5528  
 5529          void assertionStarting(AssertionInfo const&) override;
 5530  
 5531          bool assertionEnded(AssertionStats const& _assertionStats) override;
 5532  
 5533          void sectionStarting(SectionInfo const& _sectionInfo) override;
 5534          void sectionEnded(SectionStats const& _sectionStats) override;
 5535  
 5536          void benchmarkStarting(BenchmarkInfo const& info) override;
 5537          void benchmarkEnded(BenchmarkStats const& stats) override;
 5538  
 5539          void testCaseEnded(TestCaseStats const& _testCaseStats) override;
 5540          void testGroupEnded(TestGroupStats const& _testGroupStats) override;
 5541          void testRunEnded(TestRunStats const& _testRunStats) override;
 5542          void testRunStarting(TestRunInfo const& _testRunInfo) override;
 5543      private:
 5544  
 5545          void lazyPrint();
 5546  
 5547          void lazyPrintWithoutClosingBenchmarkTable();
 5548          void lazyPrintRunInfo();
 5549          void lazyPrintGroupInfo();
 5550          void printTestCaseAndSectionHeader();
 5551  
 5552          void printClosedHeader(std::string const& _name);
 5553          void printOpenHeader(std::string const& _name);
 5554  
 5555          // if string has a : in first line will set indent to follow it on
 5556          // subsequent lines
 5557          void printHeaderString(std::string const& _string, std::size_t indent = 0);
 5558  
 5559          void printTotals(Totals const& totals);
 5560          void printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row);
 5561  
 5562          void printTotalsDivider(Totals const& totals);
 5563          void printSummaryDivider();
 5564          void printTestFilters();
 5565  
 5566      private:
 5567          bool m_headerPrinted = false;
 5568      };
 5569  
 5570  } // end namespace Catch
 5571  
 5572  #if defined(_MSC_VER)
 5573  #pragma warning(pop)
 5574  #endif
 5575  
 5576  // end catch_reporter_console.h
 5577  // start catch_reporter_junit.h
 5578  
 5579  // start catch_xmlwriter.h
 5580  
 5581  #include <vector>
 5582  
 5583  namespace Catch {
 5584  
 5585      class XmlEncode {
 5586      public:
 5587          enum ForWhat { ForTextNodes, ForAttributes };
 5588  
 5589          XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes );
 5590  
 5591          void encodeTo( std::ostream& os ) const;
 5592  
 5593          friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );
 5594  
 5595      private:
 5596          std::string m_str;
 5597          ForWhat m_forWhat;
 5598      };
 5599  
 5600      class XmlWriter {
 5601      public:
 5602  
 5603          class ScopedElement {
 5604          public:
 5605              ScopedElement( XmlWriter* writer );
 5606  
 5607              ScopedElement( ScopedElement&& other ) noexcept;
 5608              ScopedElement& operator=( ScopedElement&& other ) noexcept;
 5609  
 5610              ~ScopedElement();
 5611  
 5612              ScopedElement& writeText( std::string const& text, bool indent = true );
 5613  
 5614              template<typename T>
 5615              ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
 5616                  m_writer->writeAttribute( name, attribute );
 5617                  return *this;
 5618              }
 5619  
 5620          private:
 5621              mutable XmlWriter* m_writer = nullptr;
 5622          };
 5623  
 5624          XmlWriter( std::ostream& os = Catch::cout() );
 5625          ~XmlWriter();
 5626  
 5627          XmlWriter( XmlWriter const& ) = delete;
 5628          XmlWriter& operator=( XmlWriter const& ) = delete;
 5629  
 5630          XmlWriter& startElement( std::string const& name );
 5631  
 5632          ScopedElement scopedElement( std::string const& name );
 5633  
 5634          XmlWriter& endElement();
 5635  
 5636          XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );
 5637  
 5638          XmlWriter& writeAttribute( std::string const& name, bool attribute );
 5639  
 5640          template<typename T>
 5641          XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
 5642              ReusableStringStream rss;
 5643              rss << attribute;
 5644              return writeAttribute( name, rss.str() );
 5645          }
 5646  
 5647          XmlWriter& writeText( std::string const& text, bool indent = true );
 5648  
 5649          XmlWriter& writeComment( std::string const& text );
 5650  
 5651          void writeStylesheetRef( std::string const& url );
 5652  
 5653          XmlWriter& writeBlankLine();
 5654  
 5655          void ensureTagClosed();
 5656  
 5657      private:
 5658  
 5659          void writeDeclaration();
 5660  
 5661          void newlineIfNecessary();
 5662  
 5663          bool m_tagIsOpen = false;
 5664          bool m_needsNewline = false;
 5665          std::vector<std::string> m_tags;
 5666          std::string m_indent;
 5667          std::ostream& m_os;
 5668      };
 5669  
 5670  }
 5671  
 5672  // end catch_xmlwriter.h
 5673  namespace Catch {
 5674  
 5675      class JunitReporter : public CumulativeReporterBase<JunitReporter> {
 5676      public:
 5677          JunitReporter(ReporterConfig const& _config);
 5678  
 5679          ~JunitReporter() override;
 5680  
 5681          static std::string getDescription();
 5682  
 5683          void noMatchingTestCases(std::string const& /*spec*/) override;
 5684  
 5685          void testRunStarting(TestRunInfo const& runInfo) override;
 5686  
 5687          void testGroupStarting(GroupInfo const& groupInfo) override;
 5688  
 5689          void testCaseStarting(TestCaseInfo const& testCaseInfo) override;
 5690          bool assertionEnded(AssertionStats const& assertionStats) override;
 5691  
 5692          void testCaseEnded(TestCaseStats const& testCaseStats) override;
 5693  
 5694          void testGroupEnded(TestGroupStats const& testGroupStats) override;
 5695  
 5696          void testRunEndedCumulative() override;
 5697  
 5698          void writeGroup(TestGroupNode const& groupNode, double suiteTime);
 5699  
 5700          void writeTestCase(TestCaseNode const& testCaseNode);
 5701  
 5702          void writeSection(std::string const& className,
 5703                            std::string const& rootName,
 5704                            SectionNode const& sectionNode);
 5705  
 5706          void writeAssertions(SectionNode const& sectionNode);
 5707          void writeAssertion(AssertionStats const& stats);
 5708  
 5709          XmlWriter xml;
 5710          Timer suiteTimer;
 5711          std::string stdOutForSuite;
 5712          std::string stdErrForSuite;
 5713          unsigned int unexpectedExceptions = 0;
 5714          bool m_okToFail = false;
 5715      };
 5716  
 5717  } // end namespace Catch
 5718  
 5719  // end catch_reporter_junit.h
 5720  // start catch_reporter_xml.h
 5721  
 5722  namespace Catch {
 5723      class XmlReporter : public StreamingReporterBase<XmlReporter> {
 5724      public:
 5725          XmlReporter(ReporterConfig const& _config);
 5726  
 5727          ~XmlReporter() override;
 5728  
 5729          static std::string getDescription();
 5730  
 5731          virtual std::string getStylesheetRef() const;
 5732  
 5733          void writeSourceInfo(SourceLineInfo const& sourceInfo);
 5734  
 5735      public: // StreamingReporterBase
 5736  
 5737          void noMatchingTestCases(std::string const& s) override;
 5738  
 5739          void testRunStarting(TestRunInfo const& testInfo) override;
 5740  
 5741          void testGroupStarting(GroupInfo const& groupInfo) override;
 5742  
 5743          void testCaseStarting(TestCaseInfo const& testInfo) override;
 5744  
 5745          void sectionStarting(SectionInfo const& sectionInfo) override;
 5746  
 5747          void assertionStarting(AssertionInfo const&) override;
 5748  
 5749          bool assertionEnded(AssertionStats const& assertionStats) override;
 5750  
 5751          void sectionEnded(SectionStats const& sectionStats) override;
 5752  
 5753          void testCaseEnded(TestCaseStats const& testCaseStats) override;
 5754  
 5755          void testGroupEnded(TestGroupStats const& testGroupStats) override;
 5756  
 5757          void testRunEnded(TestRunStats const& testRunStats) override;
 5758  
 5759      private:
 5760          Timer m_testCaseTimer;
 5761          XmlWriter m_xml;
 5762          int m_sectionDepth = 0;
 5763      };
 5764  
 5765  } // end namespace Catch
 5766  
 5767  // end catch_reporter_xml.h
 5768  
 5769  // end catch_external_interfaces.h
 5770  #endif
 5771  
 5772  #endif // ! CATCH_CONFIG_IMPL_ONLY
 5773  
 5774  #ifdef CATCH_IMPL
 5775  // start catch_impl.hpp
 5776  
 5777  #ifdef __clang__
 5778  #pragma clang diagnostic push
 5779  #pragma clang diagnostic ignored "-Wweak-vtables"
 5780  #endif
 5781  
 5782  // Keep these here for external reporters
 5783  // start catch_test_case_tracker.h
 5784  
 5785  #include <string>
 5786  #include <vector>
 5787  #include <memory>
 5788  
 5789  namespace Catch {
 5790  namespace TestCaseTracking {
 5791  
 5792      struct NameAndLocation {
 5793          std::string name;
 5794          SourceLineInfo location;
 5795  
 5796          NameAndLocation( std::string const& _name, SourceLineInfo const& _location );
 5797      };
 5798  
 5799      struct ITracker;
 5800  
 5801      using ITrackerPtr = std::shared_ptr<ITracker>;
 5802  
 5803      struct ITracker {
 5804          virtual ~ITracker();
 5805  
 5806          // static queries
 5807          virtual NameAndLocation const& nameAndLocation() const = 0;
 5808  
 5809          // dynamic queries
 5810          virtual bool isComplete() const = 0; // Successfully completed or failed
 5811          virtual bool isSuccessfullyCompleted() const = 0;
 5812          virtual bool isOpen() const = 0; // Started but not complete
 5813          virtual bool hasChildren() const = 0;
 5814  
 5815          virtual ITracker& parent() = 0;
 5816  
 5817          // actions
 5818          virtual void close() = 0; // Successfully complete
 5819          virtual void fail() = 0;
 5820          virtual void markAsNeedingAnotherRun() = 0;
 5821  
 5822          virtual void addChild( ITrackerPtr const& child ) = 0;
 5823          virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0;
 5824          virtual void openChild() = 0;
 5825  
 5826          // Debug/ checking
 5827          virtual bool isSectionTracker() const = 0;
 5828          virtual bool isGeneratorTracker() const = 0;
 5829      };
 5830  
 5831      class TrackerContext {
 5832  
 5833          enum RunState {
 5834              NotStarted,
 5835              Executing,
 5836              CompletedCycle
 5837          };
 5838  
 5839          ITrackerPtr m_rootTracker;
 5840          ITracker* m_currentTracker = nullptr;
 5841          RunState m_runState = NotStarted;
 5842  
 5843      public:
 5844  
 5845          ITracker& startRun();
 5846          void endRun();
 5847  
 5848          void startCycle();
 5849          void completeCycle();
 5850  
 5851          bool completedCycle() const;
 5852          ITracker& currentTracker();
 5853          void setCurrentTracker( ITracker* tracker );
 5854      };
 5855  
 5856      class TrackerBase : public ITracker {
 5857      protected:
 5858          enum CycleState {
 5859              NotStarted,
 5860              Executing,
 5861              ExecutingChildren,
 5862              NeedsAnotherRun,
 5863              CompletedSuccessfully,
 5864              Failed
 5865          };
 5866  
 5867          using Children = std::vector<ITrackerPtr>;
 5868          NameAndLocation m_nameAndLocation;
 5869          TrackerContext& m_ctx;
 5870          ITracker* m_parent;
 5871          Children m_children;
 5872          CycleState m_runState = NotStarted;
 5873  
 5874      public:
 5875          TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
 5876  
 5877          NameAndLocation const& nameAndLocation() const override;
 5878          bool isComplete() const override;
 5879          bool isSuccessfullyCompleted() const override;
 5880          bool isOpen() const override;
 5881          bool hasChildren() const override;
 5882  
 5883          void addChild( ITrackerPtr const& child ) override;
 5884  
 5885          ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override;
 5886          ITracker& parent() override;
 5887  
 5888          void openChild() override;
 5889  
 5890          bool isSectionTracker() const override;
 5891          bool isGeneratorTracker() const override;
 5892  
 5893          void open();
 5894  
 5895          void close() override;
 5896          void fail() override;
 5897          void markAsNeedingAnotherRun() override;
 5898  
 5899      private:
 5900          void moveToParent();
 5901          void moveToThis();
 5902      };
 5903  
 5904      class SectionTracker : public TrackerBase {
 5905          std::vector<std::string> m_filters;
 5906      public:
 5907          SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
 5908  
 5909          bool isSectionTracker() const override;
 5910  
 5911          bool isComplete() const override;
 5912  
 5913          static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation );
 5914  
 5915          void tryOpen();
 5916  
 5917          void addInitialFilters( std::vector<std::string> const& filters );
 5918          void addNextFilters( std::vector<std::string> const& filters );
 5919      };
 5920  
 5921  } // namespace TestCaseTracking
 5922  
 5923  using TestCaseTracking::ITracker;
 5924  using TestCaseTracking::TrackerContext;
 5925  using TestCaseTracking::SectionTracker;
 5926  
 5927  } // namespace Catch
 5928  
 5929  // end catch_test_case_tracker.h
 5930  
 5931  // start catch_leak_detector.h
 5932  
 5933  namespace Catch {
 5934  
 5935      struct LeakDetector {
 5936          LeakDetector();
 5937          ~LeakDetector();
 5938      };
 5939  
 5940  }
 5941  // end catch_leak_detector.h
 5942  // Cpp files will be included in the single-header file here
 5943  // start catch_approx.cpp
 5944  
 5945  #include <cmath>
 5946  #include <limits>
 5947  
 5948  namespace {
 5949  
 5950  // Performs equivalent check of std::fabs(lhs - rhs) <= margin
 5951  // But without the subtraction to allow for INFINITY in comparison
 5952  bool marginComparison(double lhs, double rhs, double margin) {
 5953      return (lhs + margin >= rhs) && (rhs + margin >= lhs);
 5954  }
 5955  
 5956  }
 5957  
 5958  namespace Catch {
 5959  namespace Detail {
 5960  
 5961      Approx::Approx ( double value )
 5962      :   m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
 5963          m_margin( 0.0 ),
 5964          m_scale( 0.0 ),
 5965          m_value( value )
 5966      {}
 5967  
 5968      Approx Approx::custom() {
 5969          return Approx( 0 );
 5970      }
 5971  
 5972      Approx Approx::operator-() const {
 5973          auto temp(*this);
 5974          temp.m_value = -temp.m_value;
 5975          return temp;
 5976      }
 5977  
 5978      std::string Approx::toString() const {
 5979          ReusableStringStream rss;
 5980          rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
 5981          return rss.str();
 5982      }
 5983  
 5984      bool Approx::equalityComparisonImpl(const double other) const {
 5985          // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
 5986          // Thanks to Richard Harris for his help refining the scaled margin value
 5987          return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
 5988      }
 5989  
 5990      void Approx::setMargin(double newMargin) {
 5991          CATCH_ENFORCE(newMargin >= 0,
 5992              "Invalid Approx::margin: " << newMargin << '.'
 5993              << " Approx::Margin has to be non-negative.");
 5994          m_margin = newMargin;
 5995      }
 5996  
 5997      void Approx::setEpsilon(double newEpsilon) {
 5998          CATCH_ENFORCE(newEpsilon >= 0 && newEpsilon <= 1.0,
 5999              "Invalid Approx::epsilon: " << newEpsilon << '.'
 6000              << " Approx::epsilon has to be in [0, 1]");
 6001          m_epsilon = newEpsilon;
 6002      }
 6003  
 6004  } // end namespace Detail
 6005  
 6006  namespace literals {
 6007      Detail::Approx operator "" _a(long double val) {
 6008          return Detail::Approx(val);
 6009      }
 6010      Detail::Approx operator "" _a(unsigned long long val) {
 6011          return Detail::Approx(val);
 6012      }
 6013  } // end namespace literals
 6014  
 6015  std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
 6016      return value.toString();
 6017  }
 6018  
 6019  } // end namespace Catch
 6020  // end catch_approx.cpp
 6021  // start catch_assertionhandler.cpp
 6022  
 6023  // start catch_debugger.h
 6024  
 6025  namespace Catch {
 6026      bool isDebuggerActive();
 6027  }
 6028  
 6029  #ifdef CATCH_PLATFORM_MAC
 6030  
 6031      #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
 6032  
 6033  #elif defined(CATCH_PLATFORM_LINUX)
 6034      // If we can use inline assembler, do it because this allows us to break
 6035      // directly at the location of the failing check instead of breaking inside
 6036      // raise() called from it, i.e. one stack frame below.
 6037      #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
 6038          #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
 6039      #else // Fall back to the generic way.
 6040          #include <signal.h>
 6041  
 6042          #define CATCH_TRAP() raise(SIGTRAP)
 6043      #endif
 6044  #elif defined(_MSC_VER)
 6045      #define CATCH_TRAP() __debugbreak()
 6046  #elif defined(__MINGW32__)
 6047      extern "C" __declspec(dllimport) void __stdcall DebugBreak();
 6048      #define CATCH_TRAP() DebugBreak()
 6049  #endif
 6050  
 6051  #ifdef CATCH_TRAP
 6052      #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }()
 6053  #else
 6054      #define CATCH_BREAK_INTO_DEBUGGER() []{}()
 6055  #endif
 6056  
 6057  // end catch_debugger.h
 6058  // start catch_run_context.h
 6059  
 6060  // start catch_fatal_condition.h
 6061  
 6062  // start catch_windows_h_proxy.h
 6063  
 6064  
 6065  #if defined(CATCH_PLATFORM_WINDOWS)
 6066  
 6067  #if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
 6068  #  define CATCH_DEFINED_NOMINMAX
 6069  #  define NOMINMAX
 6070  #endif
 6071  #if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
 6072  #  define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
 6073  #  define WIN32_LEAN_AND_MEAN
 6074  #endif
 6075  
 6076  #ifdef __AFXDLL
 6077  #include <AfxWin.h>
 6078  #else
 6079  #include <windows.h>
 6080  #endif
 6081  
 6082  #ifdef CATCH_DEFINED_NOMINMAX
 6083  #  undef NOMINMAX
 6084  #endif
 6085  #ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
 6086  #  undef WIN32_LEAN_AND_MEAN
 6087  #endif
 6088  
 6089  #endif // defined(CATCH_PLATFORM_WINDOWS)
 6090  
 6091  // end catch_windows_h_proxy.h
 6092  #if defined( CATCH_CONFIG_WINDOWS_SEH )
 6093  
 6094  namespace Catch {
 6095  
 6096      struct FatalConditionHandler {
 6097  
 6098          static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
 6099          FatalConditionHandler();
 6100          static void reset();
 6101          ~FatalConditionHandler();
 6102  
 6103      private:
 6104          static bool isSet;
 6105          static ULONG guaranteeSize;
 6106          static PVOID exceptionHandlerHandle;
 6107      };
 6108  
 6109  } // namespace Catch
 6110  
 6111  #elif defined ( CATCH_CONFIG_POSIX_SIGNALS )
 6112  
 6113  #include <signal.h>
 6114  
 6115  namespace Catch {
 6116  
 6117      struct FatalConditionHandler {
 6118  
 6119          static bool isSet;
 6120          static struct sigaction oldSigActions[];
 6121          static stack_t oldSigStack;
 6122          static char altStackMem[];
 6123  
 6124          static void handleSignal( int sig );
 6125  
 6126          FatalConditionHandler();
 6127          ~FatalConditionHandler();
 6128          static void reset();
 6129      };
 6130  
 6131  } // namespace Catch
 6132  
 6133  #else
 6134  
 6135  namespace Catch {
 6136      struct FatalConditionHandler {
 6137          void reset();
 6138      };
 6139  }
 6140  
 6141  #endif
 6142  
 6143  // end catch_fatal_condition.h
 6144  #include <string>
 6145  
 6146  namespace Catch {
 6147  
 6148      struct IMutableContext;
 6149  
 6150      ///////////////////////////////////////////////////////////////////////////
 6151  
 6152      class RunContext : public IResultCapture, public IRunner {
 6153  
 6154      public:
 6155          RunContext( RunContext const& ) = delete;
 6156          RunContext& operator =( RunContext const& ) = delete;
 6157  
 6158          explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr&& reporter );
 6159  
 6160          ~RunContext() override;
 6161  
 6162          void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount );
 6163          void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount );
 6164  
 6165          Totals runTest(TestCase const& testCase);
 6166  
 6167          IConfigPtr config() const;
 6168          IStreamingReporter& reporter() const;
 6169  
 6170      public: // IResultCapture
 6171  
 6172          // Assertion handlers
 6173          void handleExpr
 6174                  (   AssertionInfo const& info,
 6175                      ITransientExpression const& expr,
 6176                      AssertionReaction& reaction ) override;
 6177          void handleMessage
 6178                  (   AssertionInfo const& info,
 6179                      ResultWas::OfType resultType,
 6180                      StringRef const& message,
 6181                      AssertionReaction& reaction ) override;
 6182          void handleUnexpectedExceptionNotThrown
 6183                  (   AssertionInfo const& info,
 6184                      AssertionReaction& reaction ) override;
 6185          void handleUnexpectedInflightException
 6186                  (   AssertionInfo const& info,
 6187                      std::string const& message,
 6188                      AssertionReaction& reaction ) override;
 6189          void handleIncomplete
 6190                  (   AssertionInfo const& info ) override;
 6191          void handleNonExpr
 6192                  (   AssertionInfo const &info,
 6193                      ResultWas::OfType resultType,
 6194                      AssertionReaction &reaction ) override;
 6195  
 6196          bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override;
 6197  
 6198          void sectionEnded( SectionEndInfo const& endInfo ) override;
 6199          void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
 6200  
 6201          auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
 6202  
 6203          void benchmarkStarting( BenchmarkInfo const& info ) override;
 6204          void benchmarkEnded( BenchmarkStats const& stats ) override;
 6205  
 6206          void pushScopedMessage( MessageInfo const& message ) override;
 6207          void popScopedMessage( MessageInfo const& message ) override;
 6208  
 6209          void emplaceUnscopedMessage( MessageBuilder const& builder ) override;
 6210  
 6211          std::string getCurrentTestName() const override;
 6212  
 6213          const AssertionResult* getLastResult() const override;
 6214  
 6215          void exceptionEarlyReported() override;
 6216  
 6217          void handleFatalErrorCondition( StringRef message ) override;
 6218  
 6219          bool lastAssertionPassed() override;
 6220  
 6221          void assertionPassed() override;
 6222  
 6223      public:
 6224          // !TBD We need to do this another way!
 6225          bool aborting() const final;
 6226  
 6227      private:
 6228  
 6229          void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr );
 6230          void invokeActiveTestCase();
 6231  
 6232          void resetAssertionInfo();
 6233          bool testForMissingAssertions( Counts& assertions );
 6234  
 6235          void assertionEnded( AssertionResult const& result );
 6236          void reportExpr
 6237                  (   AssertionInfo const &info,
 6238                      ResultWas::OfType resultType,
 6239                      ITransientExpression const *expr,
 6240                      bool negated );
 6241  
 6242          void populateReaction( AssertionReaction& reaction );
 6243  
 6244      private:
 6245  
 6246          void handleUnfinishedSections();
 6247  
 6248          TestRunInfo m_runInfo;
 6249          IMutableContext& m_context;
 6250          TestCase const* m_activeTestCase = nullptr;
 6251          ITracker* m_testCaseTracker = nullptr;
 6252          Option<AssertionResult> m_lastResult;
 6253  
 6254          IConfigPtr m_config;
 6255          Totals m_totals;
 6256          IStreamingReporterPtr m_reporter;
 6257          std::vector<MessageInfo> m_messages;
 6258          std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */
 6259          AssertionInfo m_lastAssertionInfo;
 6260          std::vector<SectionEndInfo> m_unfinishedSections;
 6261          std::vector<ITracker*> m_activeSections;
 6262          TrackerContext m_trackerContext;
 6263          bool m_lastAssertionPassed = false;
 6264          bool m_shouldReportUnexpected = true;
 6265          bool m_includeSuccessfulResults;
 6266      };
 6267  
 6268  } // end namespace Catch
 6269  
 6270  // end catch_run_context.h
 6271  namespace Catch {
 6272  
 6273      namespace {
 6274          auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
 6275              expr.streamReconstructedExpression( os );
 6276              return os;
 6277          }
 6278      }
 6279  
 6280      LazyExpression::LazyExpression( bool isNegated )
 6281      :   m_isNegated( isNegated )
 6282      {}
 6283  
 6284      LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {}
 6285  
 6286      LazyExpression::operator bool() const {
 6287          return m_transientExpression != nullptr;
 6288      }
 6289  
 6290      auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& {
 6291          if( lazyExpr.m_isNegated )
 6292              os << "!";
 6293  
 6294          if( lazyExpr ) {
 6295              if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() )
 6296                  os << "(" << *lazyExpr.m_transientExpression << ")";
 6297              else
 6298                  os << *lazyExpr.m_transientExpression;
 6299          }
 6300          else {
 6301              os << "{** error - unchecked empty expression requested **}";
 6302          }
 6303          return os;
 6304      }
 6305  
 6306      AssertionHandler::AssertionHandler
 6307          (   StringRef const& macroName,
 6308              SourceLineInfo const& lineInfo,
 6309              StringRef capturedExpression,
 6310              ResultDisposition::Flags resultDisposition )
 6311      :   m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },
 6312          m_resultCapture( getResultCapture() )
 6313      {}
 6314  
 6315      void AssertionHandler::handleExpr( ITransientExpression const& expr ) {
 6316          m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );
 6317      }
 6318      void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) {
 6319          m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction );
 6320      }
 6321  
 6322      auto AssertionHandler::allowThrows() const -> bool {
 6323          return getCurrentContext().getConfig()->allowThrows();
 6324      }
 6325  
 6326      void AssertionHandler::complete() {
 6327          setCompleted();
 6328          if( m_reaction.shouldDebugBreak ) {
 6329  
 6330              // If you find your debugger stopping you here then go one level up on the
 6331              // call-stack for the code that caused it (typically a failed assertion)
 6332  
 6333              // (To go back to the test and change execution, jump over the throw, next)
 6334              CATCH_BREAK_INTO_DEBUGGER();
 6335          }
 6336          if (m_reaction.shouldThrow) {
 6337  #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
 6338              throw Catch::TestFailureException();
 6339  #else
 6340              CATCH_ERROR( "Test failure requires aborting test!" );
 6341  #endif
 6342          }
 6343      }
 6344      void AssertionHandler::setCompleted() {
 6345          m_completed = true;
 6346      }
 6347  
 6348      void AssertionHandler::handleUnexpectedInflightException() {
 6349          m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction );
 6350      }
 6351  
 6352      void AssertionHandler::handleExceptionThrownAsExpected() {
 6353          m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
 6354      }
 6355      void AssertionHandler::handleExceptionNotThrownAsExpected() {
 6356          m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
 6357      }
 6358  
 6359      void AssertionHandler::handleUnexpectedExceptionNotThrown() {
 6360          m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction );
 6361      }
 6362  
 6363      void AssertionHandler::handleThrowingCallSkipped() {
 6364          m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
 6365      }
 6366  
 6367      // This is the overload that takes a string and infers the Equals matcher from it
 6368      // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
 6369      void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString  ) {
 6370          handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );
 6371      }
 6372  
 6373  } // namespace Catch
 6374  // end catch_assertionhandler.cpp
 6375  // start catch_assertionresult.cpp
 6376  
 6377  namespace Catch {
 6378      AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression):
 6379          lazyExpression(_lazyExpression),
 6380          resultType(_resultType) {}
 6381  
 6382      std::string AssertionResultData::reconstructExpression() const {
 6383  
 6384          if( reconstructedExpression.empty() ) {
 6385              if( lazyExpression ) {
 6386                  ReusableStringStream rss;
 6387                  rss << lazyExpression;
 6388                  reconstructedExpression = rss.str();
 6389              }
 6390          }
 6391          return reconstructedExpression;
 6392      }
 6393  
 6394      AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
 6395      :   m_info( info ),
 6396          m_resultData( data )
 6397      {}
 6398  
 6399      // Result was a success
 6400      bool AssertionResult::succeeded() const {
 6401          return Catch::isOk( m_resultData.resultType );
 6402      }
 6403  
 6404      // Result was a success, or failure is suppressed
 6405      bool AssertionResult::isOk() const {
 6406          return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
 6407      }
 6408  
 6409      ResultWas::OfType AssertionResult::getResultType() const {
 6410          return m_resultData.resultType;
 6411      }
 6412  
 6413      bool AssertionResult::hasExpression() const {
 6414          return m_info.capturedExpression[0] != 0;
 6415      }
 6416  
 6417      bool AssertionResult::hasMessage() const {
 6418          return !m_resultData.message.empty();
 6419      }
 6420  
 6421      std::string AssertionResult::getExpression() const {
 6422          if( isFalseTest( m_info.resultDisposition ) )
 6423              return "!(" + m_info.capturedExpression + ")";
 6424          else
 6425              return m_info.capturedExpression;
 6426      }
 6427  
 6428      std::string AssertionResult::getExpressionInMacro() const {
 6429          std::string expr;
 6430          if( m_info.macroName[0] == 0 )
 6431              expr = m_info.capturedExpression;
 6432          else {
 6433              expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
 6434              expr += m_info.macroName;
 6435              expr += "( ";
 6436              expr += m_info.capturedExpression;
 6437              expr += " )";
 6438          }
 6439          return expr;
 6440      }
 6441  
 6442      bool AssertionResult::hasExpandedExpression() const {
 6443          return hasExpression() && getExpandedExpression() != getExpression();
 6444      }
 6445  
 6446      std::string AssertionResult::getExpandedExpression() const {
 6447          std::string expr = m_resultData.reconstructExpression();
 6448          return expr.empty()
 6449                  ? getExpression()
 6450                  : expr;
 6451      }
 6452  
 6453      std::string AssertionResult::getMessage() const {
 6454          return m_resultData.message;
 6455      }
 6456      SourceLineInfo AssertionResult::getSourceInfo() const {
 6457          return m_info.lineInfo;
 6458      }
 6459  
 6460      StringRef AssertionResult::getTestMacroName() const {
 6461          return m_info.macroName;
 6462      }
 6463  
 6464  } // end namespace Catch
 6465  // end catch_assertionresult.cpp
 6466  // start catch_benchmark.cpp
 6467  
 6468  namespace Catch {
 6469  
 6470      auto BenchmarkLooper::getResolution() -> uint64_t {
 6471          return getEstimatedClockResolution() * getCurrentContext().getConfig()->benchmarkResolutionMultiple();
 6472      }
 6473  
 6474      void BenchmarkLooper::reportStart() {
 6475          getResultCapture().benchmarkStarting( { m_name } );
 6476      }
 6477      auto BenchmarkLooper::needsMoreIterations() -> bool {
 6478          auto elapsed = m_timer.getElapsedNanoseconds();
 6479  
 6480          // Exponentially increasing iterations until we're confident in our timer resolution
 6481          if( elapsed < m_resolution ) {
 6482              m_iterationsToRun *= 10;
 6483              return true;
 6484          }
 6485  
 6486          getResultCapture().benchmarkEnded( { { m_name }, m_count, elapsed } );
 6487          return false;
 6488      }
 6489  
 6490  } // end namespace Catch
 6491  // end catch_benchmark.cpp
 6492  // start catch_capture_matchers.cpp
 6493  
 6494  namespace Catch {
 6495  
 6496      using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
 6497  
 6498      // This is the general overload that takes a any string matcher
 6499      // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
 6500      // the Equals matcher (so the header does not mention matchers)
 6501      void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  ) {
 6502          std::string exceptionMessage = Catch::translateActiveException();
 6503          MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );
 6504          handler.handleExpr( expr );
 6505      }
 6506  
 6507  } // namespace Catch
 6508  // end catch_capture_matchers.cpp
 6509  // start catch_commandline.cpp
 6510  
 6511  // start catch_commandline.h
 6512  
 6513  // start catch_clara.h
 6514  
 6515  // Use Catch's value for console width (store Clara's off to the side, if present)
 6516  #ifdef CLARA_CONFIG_CONSOLE_WIDTH
 6517  #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
 6518  #undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
 6519  #endif
 6520  #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1
 6521  
 6522  #ifdef __clang__
 6523  #pragma clang diagnostic push
 6524  #pragma clang diagnostic ignored "-Wweak-vtables"
 6525  #pragma clang diagnostic ignored "-Wexit-time-destructors"
 6526  #pragma clang diagnostic ignored "-Wshadow"
 6527  #endif
 6528  
 6529  // start clara.hpp
 6530  // Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
 6531  //
 6532  // Distributed under the Boost Software License, Version 1.0. (See accompanying
 6533  // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 6534  //
 6535  // See https://github.com/philsquared/Clara for more details
 6536  
 6537  // Clara v1.1.5
 6538  
 6539  
 6540  #ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
 6541  #define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80
 6542  #endif
 6543  
 6544  #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
 6545  #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH
 6546  #endif
 6547  
 6548  #ifndef CLARA_CONFIG_OPTIONAL_TYPE
 6549  #ifdef __has_include
 6550  #if __has_include(<optional>) && __cplusplus >= 201703L
 6551  #include <optional>
 6552  #define CLARA_CONFIG_OPTIONAL_TYPE std::optional
 6553  #endif
 6554  #endif
 6555  #endif
 6556  
 6557  // ----------- #included from clara_textflow.hpp -----------
 6558  
 6559  // TextFlowCpp
 6560  //
 6561  // A single-header library for wrapping and laying out basic text, by Phil Nash
 6562  //
 6563  // Distributed under the Boost Software License, Version 1.0. (See accompanying
 6564  // file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 6565  //
 6566  // This project is hosted at https://github.com/philsquared/textflowcpp
 6567  
 6568  
 6569  #include <cassert>
 6570  #include <ostream>
 6571  #include <sstream>
 6572  #include <vector>
 6573  
 6574  #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
 6575  #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80
 6576  #endif
 6577  
 6578  namespace Catch {
 6579  namespace clara {
 6580  namespace TextFlow {
 6581  
 6582  inline auto isWhitespace(char c) -> bool {
 6583  	static std::string chars = " \t\n\r";
 6584  	return chars.find(c) != std::string::npos;
 6585  }
 6586  inline auto isBreakableBefore(char c) -> bool {
 6587  	static std::string chars = "[({<|";
 6588  	return chars.find(c) != std::string::npos;
 6589  }
 6590  inline auto isBreakableAfter(char c) -> bool {
 6591  	static std::string chars = "])}>.,:;*+-=&/\\";
 6592  	return chars.find(c) != std::string::npos;
 6593  }
 6594  
 6595  class Columns;
 6596  
 6597  class Column {
 6598  	std::vector<std::string> m_strings;
 6599  	size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
 6600  	size_t m_indent = 0;
 6601  	size_t m_initialIndent = std::string::npos;
 6602  
 6603  public:
 6604  	class iterator {
 6605  		friend Column;
 6606  
 6607  		Column const& m_column;
 6608  		size_t m_stringIndex = 0;
 6609  		size_t m_pos = 0;
 6610  
 6611  		size_t m_len = 0;
 6612  		size_t m_end = 0;
 6613  		bool m_suffix = false;
 6614  
 6615  		iterator(Column const& column, size_t stringIndex)
 6616  			: m_column(column),
 6617  			m_stringIndex(stringIndex) {}
 6618  
 6619  		auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
 6620  
 6621  		auto isBoundary(size_t at) const -> bool {
 6622  			assert(at > 0);
 6623  			assert(at <= line().size());
 6624  
 6625  			return at == line().size() ||
 6626  				(isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) ||
 6627  				isBreakableBefore(line()[at]) ||
 6628  				isBreakableAfter(line()[at - 1]);
 6629  		}
 6630  
 6631  		void calcLength() {
 6632  			assert(m_stringIndex < m_column.m_strings.size());
 6633  
 6634  			m_suffix = false;
 6635  			auto width = m_column.m_width - indent();
 6636  			m_end = m_pos;
 6637  			if (line()[m_pos] == '\n') {
 6638  				++m_end;
 6639  			}
 6640  			while (m_end < line().size() && line()[m_end] != '\n')
 6641  				++m_end;
 6642  
 6643  			if (m_end < m_pos + width) {
 6644  				m_len = m_end - m_pos;
 6645  			} else {
 6646  				size_t len = width;
 6647  				while (len > 0 && !isBoundary(m_pos + len))
 6648  					--len;
 6649  				while (len > 0 && isWhitespace(line()[m_pos + len - 1]))
 6650  					--len;
 6651  
 6652  				if (len > 0) {
 6653  					m_len = len;
 6654  				} else {
 6655  					m_suffix = true;
 6656  					m_len = width - 1;
 6657  				}
 6658  			}
 6659  		}
 6660  
 6661  		auto indent() const -> size_t {
 6662  			auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
 6663  			return initial == std::string::npos ? m_column.m_indent : initial;
 6664  		}
 6665  
 6666  		auto addIndentAndSuffix(std::string const &plain) const -> std::string {
 6667  			return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain);
 6668  		}
 6669  
 6670  	public:
 6671  		using difference_type = std::ptrdiff_t;
 6672  		using value_type = std::string;
 6673  		using pointer = value_type * ;
 6674  		using reference = value_type & ;
 6675  		using iterator_category = std::forward_iterator_tag;
 6676  
 6677  		explicit iterator(Column const& column) : m_column(column) {
 6678  			assert(m_column.m_width > m_column.m_indent);
 6679  			assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent);
 6680  			calcLength();
 6681  			if (m_len == 0)
 6682  				m_stringIndex++; // Empty string
 6683  		}
 6684  
 6685  		auto operator *() const -> std::string {
 6686  			assert(m_stringIndex < m_column.m_strings.size());
 6687  			assert(m_pos <= m_end);
 6688  			return addIndentAndSuffix(line().substr(m_pos, m_len));
 6689  		}
 6690  
 6691  		auto operator ++() -> iterator& {
 6692  			m_pos += m_len;
 6693  			if (m_pos < line().size() && line()[m_pos] == '\n')
 6694  				m_pos += 1;
 6695  			else
 6696  				while (m_pos < line().size() && isWhitespace(line()[m_pos]))
 6697  					++m_pos;
 6698  
 6699  			if (m_pos == line().size()) {
 6700  				m_pos = 0;
 6701  				++m_stringIndex;
 6702  			}
 6703  			if (m_stringIndex < m_column.m_strings.size())
 6704  				calcLength();
 6705  			return *this;
 6706  		}
 6707  		auto operator ++(int) -> iterator {
 6708  			iterator prev(*this);
 6709  			operator++();
 6710  			return prev;
 6711  		}
 6712  
 6713  		auto operator ==(iterator const& other) const -> bool {
 6714  			return
 6715  				m_pos == other.m_pos &&
 6716  				m_stringIndex == other.m_stringIndex &&
 6717  				&m_column == &other.m_column;
 6718  		}
 6719  		auto operator !=(iterator const& other) const -> bool {
 6720  			return !operator==(other);
 6721  		}
 6722  	};
 6723  	using const_iterator = iterator;
 6724  
 6725  	explicit Column(std::string const& text) { m_strings.push_back(text); }
 6726  
 6727  	auto width(size_t newWidth) -> Column& {
 6728  		assert(newWidth > 0);
 6729  		m_width = newWidth;
 6730  		return *this;
 6731  	}
 6732  	auto indent(size_t newIndent) -> Column& {
 6733  		m_indent = newIndent;
 6734  		return *this;
 6735  	}
 6736  	auto initialIndent(size_t newIndent) -> Column& {
 6737  		m_initialIndent = newIndent;
 6738  		return *this;
 6739  	}
 6740  
 6741  	auto width() const -> size_t { return m_width; }
 6742  	auto begin() const -> iterator { return iterator(*this); }
 6743  	auto end() const -> iterator { return { *this, m_strings.size() }; }
 6744  
 6745  	inline friend std::ostream& operator << (std::ostream& os, Column const& col) {
 6746  		bool first = true;
 6747  		for (auto line : col) {
 6748  			if (first)
 6749  				first = false;
 6750  			else
 6751  				os << "\n";
 6752  			os << line;
 6753  		}
 6754  		return os;
 6755  	}
 6756  
 6757  	auto operator + (Column const& other)->Columns;
 6758  
 6759  	auto toString() const -> std::string {
 6760  		std::ostringstream oss;
 6761  		oss << *this;
 6762  		return oss.str();
 6763  	}
 6764  };
 6765  
 6766  class Spacer : public Column {
 6767  
 6768  public:
 6769  	explicit Spacer(size_t spaceWidth) : Column("") {
 6770  		width(spaceWidth);
 6771  	}
 6772  };
 6773  
 6774  class Columns {
 6775  	std::vector<Column> m_columns;
 6776  
 6777  public:
 6778  
 6779  	class iterator {
 6780  		friend Columns;
 6781  		struct EndTag {};
 6782  
 6783  		std::vector<Column> const& m_columns;
 6784  		std::vector<Column::iterator> m_iterators;
 6785  		size_t m_activeIterators;
 6786  
 6787  		iterator(Columns const& columns, EndTag)
 6788  			: m_columns(columns.m_columns),
 6789  			m_activeIterators(0) {
 6790  			m_iterators.reserve(m_columns.size());
 6791  
 6792  			for (auto const& col : m_columns)
 6793  				m_iterators.push_back(col.end());
 6794  		}
 6795  
 6796  	public:
 6797  		using difference_type = std::ptrdiff_t;
 6798  		using value_type = std::string;
 6799  		using pointer = value_type * ;
 6800  		using reference = value_type & ;
 6801  		using iterator_category = std::forward_iterator_tag;
 6802  
 6803  		explicit iterator(Columns const& columns)
 6804  			: m_columns(columns.m_columns),
 6805  			m_activeIterators(m_columns.size()) {
 6806  			m_iterators.reserve(m_columns.size());
 6807  
 6808  			for (auto const& col : m_columns)
 6809  				m_iterators.push_back(col.begin());
 6810  		}
 6811  
 6812  		auto operator ==(iterator const& other) const -> bool {
 6813  			return m_iterators == other.m_iterators;
 6814  		}
 6815  		auto operator !=(iterator const& other) const -> bool {
 6816  			return m_iterators != other.m_iterators;
 6817  		}
 6818  		auto operator *() const -> std::string {
 6819  			std::string row, padding;
 6820  
 6821  			for (size_t i = 0; i < m_columns.size(); ++i) {
 6822  				auto width = m_columns[i].width();
 6823  				if (m_iterators[i] != m_columns[i].end()) {
 6824  					std::string col = *m_iterators[i];
 6825  					row += padding + col;
 6826  					if (col.size() < width)
 6827  						padding = std::string(width - col.size(), ' ');
 6828  					else
 6829  						padding = "";
 6830  				} else {
 6831  					padding += std::string(width, ' ');
 6832  				}
 6833  			}
 6834  			return row;
 6835  		}
 6836  		auto operator ++() -> iterator& {
 6837  			for (size_t i = 0; i < m_columns.size(); ++i) {
 6838  				if (m_iterators[i] != m_columns[i].end())
 6839  					++m_iterators[i];
 6840  			}
 6841  			return *this;
 6842  		}
 6843  		auto operator ++(int) -> iterator {
 6844  			iterator prev(*this);
 6845  			operator++();
 6846  			return prev;
 6847  		}
 6848  	};
 6849  	using const_iterator = iterator;
 6850  
 6851  	auto begin() const -> iterator { return iterator(*this); }
 6852  	auto end() const -> iterator { return { *this, iterator::EndTag() }; }
 6853  
 6854  	auto operator += (Column const& col) -> Columns& {
 6855  		m_columns.push_back(col);
 6856  		return *this;
 6857  	}
 6858  	auto operator + (Column const& col) -> Columns {
 6859  		Columns combined = *this;
 6860  		combined += col;
 6861  		return combined;
 6862  	}
 6863  
 6864  	inline friend std::ostream& operator << (std::ostream& os, Columns const& cols) {
 6865  
 6866  		bool first = true;
 6867  		for (auto line : cols) {
 6868  			if (first)
 6869  				first = false;
 6870  			else
 6871  				os << "\n";
 6872  			os << line;
 6873  		}
 6874  		return os;
 6875  	}
 6876  
 6877  	auto toString() const -> std::string {
 6878  		std::ostringstream oss;
 6879  		oss << *this;
 6880  		return oss.str();
 6881  	}
 6882  };
 6883  
 6884  inline auto Column::operator + (Column const& other) -> Columns {
 6885  	Columns cols;
 6886  	cols += *this;
 6887  	cols += other;
 6888  	return cols;
 6889  }
 6890  }
 6891  
 6892  }
 6893  }
 6894  
 6895  // ----------- end of #include from clara_textflow.hpp -----------
 6896  // ........... back in clara.hpp
 6897  
 6898  #include <cctype>
 6899  #include <string>
 6900  #include <memory>
 6901  #include <set>
 6902  #include <algorithm>
 6903  
 6904  #if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) )
 6905  #define CATCH_PLATFORM_WINDOWS
 6906  #endif
 6907  
 6908  namespace Catch { namespace clara {
 6909  namespace detail {
 6910  
 6911      // Traits for extracting arg and return type of lambdas (for single argument lambdas)
 6912      template<typename L>
 6913      struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {};
 6914  
 6915      template<typename ClassT, typename ReturnT, typename... Args>
 6916      struct UnaryLambdaTraits<ReturnT( ClassT::* )( Args... ) const> {
 6917          static const bool isValid = false;
 6918      };
 6919  
 6920      template<typename ClassT, typename ReturnT, typename ArgT>
 6921      struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
 6922          static const bool isValid = true;
 6923          using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;
 6924          using ReturnType = ReturnT;
 6925      };
 6926  
 6927      class TokenStream;
 6928  
 6929      // Transport for raw args (copied from main args, or supplied via init list for testing)
 6930      class Args {
 6931          friend TokenStream;
 6932          std::string m_exeName;
 6933          std::vector<std::string> m_args;
 6934  
 6935      public:
 6936          Args( int argc, char const* const* argv )
 6937              : m_exeName(argv[0]),
 6938                m_args(argv + 1, argv + argc) {}
 6939  
 6940          Args( std::initializer_list<std::string> args )
 6941          :   m_exeName( *args.begin() ),
 6942              m_args( args.begin()+1, args.end() )
 6943          {}
 6944  
 6945          auto exeName() const -> std::string {
 6946              return m_exeName;
 6947          }
 6948      };
 6949  
 6950      // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string
 6951      // may encode an option + its argument if the : or = form is used
 6952      enum class TokenType {
 6953          Option, Argument
 6954      };
 6955      struct Token {
 6956          TokenType type;
 6957          std::string token;
 6958      };
 6959  
 6960      inline auto isOptPrefix( char c ) -> bool {
 6961          return c == '-'
 6962  #ifdef CATCH_PLATFORM_WINDOWS
 6963              || c == '/'
 6964  #endif
 6965          ;
 6966      }
 6967  
 6968      // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
 6969      class TokenStream {
 6970          using Iterator = std::vector<std::string>::const_iterator;
 6971          Iterator it;
 6972          Iterator itEnd;
 6973          std::vector<Token> m_tokenBuffer;
 6974  
 6975          void loadBuffer() {
 6976              m_tokenBuffer.resize( 0 );
 6977  
 6978              // Skip any empty strings
 6979              while( it != itEnd && it->empty() )
 6980                  ++it;
 6981  
 6982              if( it != itEnd ) {
 6983                  auto const &next = *it;
 6984                  if( isOptPrefix( next[0] ) ) {
 6985                      auto delimiterPos = next.find_first_of( " :=" );
 6986                      if( delimiterPos != std::string::npos ) {
 6987                          m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
 6988                          m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } );
 6989                      } else {
 6990                          if( next[1] != '-' && next.size() > 2 ) {
 6991                              std::string opt = "- ";
 6992                              for( size_t i = 1; i < next.size(); ++i ) {
 6993                                  opt[1] = next[i];
 6994                                  m_tokenBuffer.push_back( { TokenType::Option, opt } );
 6995                              }
 6996                          } else {
 6997                              m_tokenBuffer.push_back( { TokenType::Option, next } );
 6998                          }
 6999                      }
 7000                  } else {
 7001                      m_tokenBuffer.push_back( { TokenType::Argument, next } );
 7002                  }
 7003              }
 7004          }
 7005  
 7006      public:
 7007          explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {}
 7008  
 7009          TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) {
 7010              loadBuffer();
 7011          }
 7012  
 7013          explicit operator bool() const {
 7014              return !m_tokenBuffer.empty() || it != itEnd;
 7015          }
 7016  
 7017          auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); }
 7018  
 7019          auto operator*() const -> Token {
 7020              assert( !m_tokenBuffer.empty() );
 7021              return m_tokenBuffer.front();
 7022          }
 7023  
 7024          auto operator->() const -> Token const * {
 7025              assert( !m_tokenBuffer.empty() );
 7026              return &m_tokenBuffer.front();
 7027          }
 7028  
 7029          auto operator++() -> TokenStream & {
 7030              if( m_tokenBuffer.size() >= 2 ) {
 7031                  m_tokenBuffer.erase( m_tokenBuffer.begin() );
 7032              } else {
 7033                  if( it != itEnd )
 7034                      ++it;
 7035                  loadBuffer();
 7036              }
 7037              return *this;
 7038          }
 7039      };
 7040  
 7041      class ResultBase {
 7042      public:
 7043          enum Type {
 7044              Ok, LogicError, RuntimeError
 7045          };
 7046  
 7047      protected:
 7048          ResultBase( Type type ) : m_type( type ) {}
 7049          virtual ~ResultBase() = default;
 7050  
 7051          virtual void enforceOk() const = 0;
 7052  
 7053          Type m_type;
 7054      };
 7055  
 7056      template<typename T>
 7057      class ResultValueBase : public ResultBase {
 7058      public:
 7059          auto value() const -> T const & {
 7060              enforceOk();
 7061              return m_value;
 7062          }
 7063  
 7064      protected:
 7065          ResultValueBase( Type type ) : ResultBase( type ) {}
 7066  
 7067          ResultValueBase( ResultValueBase const &other ) : ResultBase( other ) {
 7068              if( m_type == ResultBase::Ok )
 7069                  new( &m_value ) T( other.m_value );
 7070          }
 7071  
 7072          ResultValueBase( Type, T const &value ) : ResultBase( Ok ) {
 7073              new( &m_value ) T( value );
 7074          }
 7075  
 7076          auto operator=( ResultValueBase const &other ) -> ResultValueBase & {
 7077              if( m_type == ResultBase::Ok )
 7078                  m_value.~T();
 7079              ResultBase::operator=(other);
 7080              if( m_type == ResultBase::Ok )
 7081                  new( &m_value ) T( other.m_value );
 7082              return *this;
 7083          }
 7084  
 7085          ~ResultValueBase() override {
 7086              if( m_type == Ok )
 7087                  m_value.~T();
 7088          }
 7089  
 7090          union {
 7091              T m_value;
 7092          };
 7093      };
 7094  
 7095      template<>
 7096      class ResultValueBase<void> : public ResultBase {
 7097      protected:
 7098          using ResultBase::ResultBase;
 7099      };
 7100  
 7101      template<typename T = void>
 7102      class BasicResult : public ResultValueBase<T> {
 7103      public:
 7104          template<typename U>
 7105          explicit BasicResult( BasicResult<U> const &other )
 7106          :   ResultValueBase<T>( other.type() ),
 7107              m_errorMessage( other.errorMessage() )
 7108          {
 7109              assert( type() != ResultBase::Ok );
 7110          }
 7111  
 7112          template<typename U>
 7113          static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; }
 7114          static auto ok() -> BasicResult { return { ResultBase::Ok }; }
 7115          static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; }
 7116          static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; }
 7117  
 7118          explicit operator bool() const { return m_type == ResultBase::Ok; }
 7119          auto type() const -> ResultBase::Type { return m_type; }
 7120          auto errorMessage() const -> std::string { return m_errorMessage; }
 7121  
 7122      protected:
 7123          void enforceOk() const override {
 7124  
 7125              // Errors shouldn't reach this point, but if they do
 7126              // the actual error message will be in m_errorMessage
 7127              assert( m_type != ResultBase::LogicError );
 7128              assert( m_type != ResultBase::RuntimeError );
 7129              if( m_type != ResultBase::Ok )
 7130                  std::abort();
 7131          }
 7132  
 7133          std::string m_errorMessage; // Only populated if resultType is an error
 7134  
 7135          BasicResult( ResultBase::Type type, std::string const &message )
 7136          :   ResultValueBase<T>(type),
 7137              m_errorMessage(message)
 7138          {
 7139              assert( m_type != ResultBase::Ok );
 7140          }
 7141  
 7142          using ResultValueBase<T>::ResultValueBase;
 7143          using ResultBase::m_type;
 7144      };
 7145  
 7146      enum class ParseResultType {
 7147          Matched, NoMatch, ShortCircuitAll, ShortCircuitSame
 7148      };
 7149  
 7150      class ParseState {
 7151      public:
 7152  
 7153          ParseState( ParseResultType type, TokenStream const &remainingTokens )
 7154          : m_type(type),
 7155            m_remainingTokens( remainingTokens )
 7156          {}
 7157  
 7158          auto type() const -> ParseResultType { return m_type; }
 7159          auto remainingTokens() const -> TokenStream { return m_remainingTokens; }
 7160  
 7161      private:
 7162          ParseResultType m_type;
 7163          TokenStream m_remainingTokens;
 7164      };
 7165  
 7166      using Result = BasicResult<void>;
 7167      using ParserResult = BasicResult<ParseResultType>;
 7168      using InternalParseResult = BasicResult<ParseState>;
 7169  
 7170      struct HelpColumns {
 7171          std::string left;
 7172          std::string right;
 7173      };
 7174  
 7175      template<typename T>
 7176      inline auto convertInto( std::string const &source, T& target ) -> ParserResult {
 7177          std::stringstream ss;
 7178          ss << source;
 7179          ss >> target;
 7180          if( ss.fail() )
 7181              return ParserResult::runtimeError( "Unable to convert '" + source + "' to destination type" );
 7182          else
 7183              return ParserResult::ok( ParseResultType::Matched );
 7184      }
 7185      inline auto convertInto( std::string const &source, std::string& target ) -> ParserResult {
 7186          target = source;
 7187          return ParserResult::ok( ParseResultType::Matched );
 7188      }
 7189      inline auto convertInto( std::string const &source, bool &target ) -> ParserResult {
 7190          std::string srcLC = source;
 7191          std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast<char>( std::tolower(c) ); } );
 7192          if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
 7193              target = true;
 7194          else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
 7195              target = false;
 7196          else
 7197              return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" );
 7198          return ParserResult::ok( ParseResultType::Matched );
 7199      }
 7200  #ifdef CLARA_CONFIG_OPTIONAL_TYPE
 7201      template<typename T>
 7202      inline auto convertInto( std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target ) -> ParserResult {
 7203          T temp;
 7204          auto result = convertInto( source, temp );
 7205          if( result )
 7206              target = std::move(temp);
 7207          return result;
 7208      }
 7209  #endif // CLARA_CONFIG_OPTIONAL_TYPE
 7210  
 7211      struct NonCopyable {
 7212          NonCopyable() = default;
 7213          NonCopyable( NonCopyable const & ) = delete;
 7214          NonCopyable( NonCopyable && ) = delete;
 7215          NonCopyable &operator=( NonCopyable const & ) = delete;
 7216          NonCopyable &operator=( NonCopyable && ) = delete;
 7217      };
 7218  
 7219      struct BoundRef : NonCopyable {
 7220          virtual ~BoundRef() = default;
 7221          virtual auto isContainer() const -> bool { return false; }
 7222          virtual auto isFlag() const -> bool { return false; }
 7223      };
 7224      struct BoundValueRefBase : BoundRef {
 7225          virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
 7226      };
 7227      struct BoundFlagRefBase : BoundRef {
 7228          virtual auto setFlag( bool flag ) -> ParserResult = 0;
 7229          virtual auto isFlag() const -> bool { return true; }
 7230      };
 7231  
 7232      template<typename T>
 7233      struct BoundValueRef : BoundValueRefBase {
 7234          T &m_ref;
 7235  
 7236          explicit BoundValueRef( T &ref ) : m_ref( ref ) {}
 7237  
 7238          auto setValue( std::string const &arg ) -> ParserResult override {
 7239              return convertInto( arg, m_ref );
 7240          }
 7241      };
 7242  
 7243      template<typename T>
 7244      struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
 7245          std::vector<T> &m_ref;
 7246  
 7247          explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {}
 7248  
 7249          auto isContainer() const -> bool override { return true; }
 7250  
 7251          auto setValue( std::string const &arg ) -> ParserResult override {
 7252              T temp;
 7253              auto result = convertInto( arg, temp );
 7254              if( result )
 7255                  m_ref.push_back( temp );
 7256              return result;
 7257          }
 7258      };
 7259  
 7260      struct BoundFlagRef : BoundFlagRefBase {
 7261          bool &m_ref;
 7262  
 7263          explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {}
 7264  
 7265          auto setFlag( bool flag ) -> ParserResult override {
 7266              m_ref = flag;
 7267              return ParserResult::ok( ParseResultType::Matched );
 7268          }
 7269      };
 7270  
 7271      template<typename ReturnType>
 7272      struct LambdaInvoker {
 7273          static_assert( std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult" );
 7274  
 7275          template<typename L, typename ArgType>
 7276          static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
 7277              return lambda( arg );
 7278          }
 7279      };
 7280  
 7281      template<>
 7282      struct LambdaInvoker<void> {
 7283          template<typename L, typename ArgType>
 7284          static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
 7285              lambda( arg );
 7286              return ParserResult::ok( ParseResultType::Matched );
 7287          }
 7288      };
 7289  
 7290      template<typename ArgType, typename L>
 7291      inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
 7292          ArgType temp{};
 7293          auto result = convertInto( arg, temp );
 7294          return !result
 7295             ? result
 7296             : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
 7297      }
 7298  
 7299      template<typename L>
 7300      struct BoundLambda : BoundValueRefBase {
 7301          L m_lambda;
 7302  
 7303          static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
 7304          explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {}
 7305  
 7306          auto setValue( std::string const &arg ) -> ParserResult override {
 7307              return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>( m_lambda, arg );
 7308          }
 7309      };
 7310  
 7311      template<typename L>
 7312      struct BoundFlagLambda : BoundFlagRefBase {
 7313          L m_lambda;
 7314  
 7315          static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
 7316          static_assert( std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, "flags must be boolean" );
 7317  
 7318          explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {}
 7319  
 7320          auto setFlag( bool flag ) -> ParserResult override {
 7321              return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( m_lambda, flag );
 7322          }
 7323      };
 7324  
 7325      enum class Optionality { Optional, Required };
 7326  
 7327      struct Parser;
 7328  
 7329      class ParserBase {
 7330      public:
 7331          virtual ~ParserBase() = default;
 7332          virtual auto validate() const -> Result { return Result::ok(); }
 7333          virtual auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult  = 0;
 7334          virtual auto cardinality() const -> size_t { return 1; }
 7335  
 7336          auto parse( Args const &args ) const -> InternalParseResult {
 7337              return parse( args.exeName(), TokenStream( args ) );
 7338          }
 7339      };
 7340  
 7341      template<typename DerivedT>
 7342      class ComposableParserImpl : public ParserBase {
 7343      public:
 7344          template<typename T>
 7345          auto operator|( T const &other ) const -> Parser;
 7346  
 7347  		template<typename T>
 7348          auto operator+( T const &other ) const -> Parser;
 7349      };
 7350  
 7351      // Common code and state for Args and Opts
 7352      template<typename DerivedT>
 7353      class ParserRefImpl : public ComposableParserImpl<DerivedT> {
 7354      protected:
 7355          Optionality m_optionality = Optionality::Optional;
 7356          std::shared_ptr<BoundRef> m_ref;
 7357          std::string m_hint;
 7358          std::string m_description;
 7359  
 7360          explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {}
 7361  
 7362      public:
 7363          template<typename T>
 7364          ParserRefImpl( T &ref, std::string const &hint )
 7365          :   m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
 7366              m_hint( hint )
 7367          {}
 7368  
 7369          template<typename LambdaT>
 7370          ParserRefImpl( LambdaT const &ref, std::string const &hint )
 7371          :   m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),
 7372              m_hint(hint)
 7373          {}
 7374  
 7375          auto operator()( std::string const &description ) -> DerivedT & {
 7376              m_description = description;
 7377              return static_cast<DerivedT &>( *this );
 7378          }
 7379  
 7380          auto optional() -> DerivedT & {
 7381              m_optionality = Optionality::Optional;
 7382              return static_cast<DerivedT &>( *this );
 7383          };
 7384  
 7385          auto required() -> DerivedT & {
 7386              m_optionality = Optionality::Required;
 7387              return static_cast<DerivedT &>( *this );
 7388          };
 7389  
 7390          auto isOptional() const -> bool {
 7391              return m_optionality == Optionality::Optional;
 7392          }
 7393  
 7394          auto cardinality() const -> size_t override {
 7395              if( m_ref->isContainer() )
 7396                  return 0;
 7397              else
 7398                  return 1;
 7399          }
 7400  
 7401          auto hint() const -> std::string { return m_hint; }
 7402      };
 7403  
 7404      class ExeName : public ComposableParserImpl<ExeName> {
 7405          std::shared_ptr<std::string> m_name;
 7406          std::shared_ptr<BoundValueRefBase> m_ref;
 7407  
 7408          template<typename LambdaT>
 7409          static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {
 7410              return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
 7411          }
 7412  
 7413      public:
 7414          ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
 7415  
 7416          explicit ExeName( std::string &ref ) : ExeName() {
 7417              m_ref = std::make_shared<BoundValueRef<std::string>>( ref );
 7418          }
 7419  
 7420          template<typename LambdaT>
 7421          explicit ExeName( LambdaT const& lambda ) : ExeName() {
 7422              m_ref = std::make_shared<BoundLambda<LambdaT>>( lambda );
 7423          }
 7424  
 7425          // The exe name is not parsed out of the normal tokens, but is handled specially
 7426          auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
 7427              return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
 7428          }
 7429  
 7430          auto name() const -> std::string { return *m_name; }
 7431          auto set( std::string const& newName ) -> ParserResult {
 7432  
 7433              auto lastSlash = newName.find_last_of( "\\/" );
 7434              auto filename = ( lastSlash == std::string::npos )
 7435                      ? newName
 7436                      : newName.substr( lastSlash+1 );
 7437  
 7438              *m_name = filename;
 7439              if( m_ref )
 7440                  return m_ref->setValue( filename );
 7441              else
 7442                  return ParserResult::ok( ParseResultType::Matched );
 7443          }
 7444      };
 7445  
 7446      class Arg : public ParserRefImpl<Arg> {
 7447      public:
 7448          using ParserRefImpl::ParserRefImpl;
 7449  
 7450          auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override {
 7451              auto validationResult = validate();
 7452              if( !validationResult )
 7453                  return InternalParseResult( validationResult );
 7454  
 7455              auto remainingTokens = tokens;
 7456              auto const &token = *remainingTokens;
 7457              if( token.type != TokenType::Argument )
 7458                  return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
 7459  
 7460              assert( !m_ref->isFlag() );
 7461              auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
 7462  
 7463              auto result = valueRef->setValue( remainingTokens->token );
 7464              if( !result )
 7465                  return InternalParseResult( result );
 7466              else
 7467                  return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
 7468          }
 7469      };
 7470  
 7471      inline auto normaliseOpt( std::string const &optName ) -> std::string {
 7472  #ifdef CATCH_PLATFORM_WINDOWS
 7473          if( optName[0] == '/' )
 7474              return "-" + optName.substr( 1 );
 7475          else
 7476  #endif
 7477              return optName;
 7478      }
 7479  
 7480      class Opt : public ParserRefImpl<Opt> {
 7481      protected:
 7482          std::vector<std::string> m_optNames;
 7483  
 7484      public:
 7485          template<typename LambdaT>
 7486          explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared<BoundFlagLambda<LambdaT>>( ref ) ) {}
 7487  
 7488          explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared<BoundFlagRef>( ref ) ) {}
 7489  
 7490          template<typename LambdaT>
 7491          Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
 7492  
 7493          template<typename T>
 7494          Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
 7495  
 7496          auto operator[]( std::string const &optName ) -> Opt & {
 7497              m_optNames.push_back( optName );
 7498              return *this;
 7499          }
 7500  
 7501          auto getHelpColumns() const -> std::vector<HelpColumns> {
 7502              std::ostringstream oss;
 7503              bool first = true;
 7504              for( auto const &opt : m_optNames ) {
 7505                  if (first)
 7506                      first = false;
 7507                  else
 7508                      oss << ", ";
 7509                  oss << opt;
 7510              }
 7511              if( !m_hint.empty() )
 7512                  oss << " <" << m_hint << ">";
 7513              return { { oss.str(), m_description } };
 7514          }
 7515  
 7516          auto isMatch( std::string const &optToken ) const -> bool {
 7517              auto normalisedToken = normaliseOpt( optToken );
 7518              for( auto const &name : m_optNames ) {
 7519                  if( normaliseOpt( name ) == normalisedToken )
 7520                      return true;
 7521              }
 7522              return false;
 7523          }
 7524  
 7525          using ParserBase::parse;
 7526  
 7527          auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
 7528              auto validationResult = validate();
 7529              if( !validationResult )
 7530                  return InternalParseResult( validationResult );
 7531  
 7532              auto remainingTokens = tokens;
 7533              if( remainingTokens && remainingTokens->type == TokenType::Option ) {
 7534                  auto const &token = *remainingTokens;
 7535                  if( isMatch(token.token ) ) {
 7536                      if( m_ref->isFlag() ) {
 7537                          auto flagRef = static_cast<detail::BoundFlagRefBase*>( m_ref.get() );
 7538                          auto result = flagRef->setFlag( true );
 7539                          if( !result )
 7540                              return InternalParseResult( result );
 7541                          if( result.value() == ParseResultType::ShortCircuitAll )
 7542                              return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
 7543                      } else {
 7544                          auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
 7545                          ++remainingTokens;
 7546                          if( !remainingTokens )
 7547                              return InternalParseResult::runtimeError( "Expected argument following " + token.token );
 7548                          auto const &argToken = *remainingTokens;
 7549                          if( argToken.type != TokenType::Argument )
 7550                              return InternalParseResult::runtimeError( "Expected argument following " + token.token );
 7551                          auto result = valueRef->setValue( argToken.token );
 7552                          if( !result )
 7553                              return InternalParseResult( result );
 7554                          if( result.value() == ParseResultType::ShortCircuitAll )
 7555                              return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
 7556                      }
 7557                      return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
 7558                  }
 7559              }
 7560              return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
 7561          }
 7562  
 7563          auto validate() const -> Result override {
 7564              if( m_optNames.empty() )
 7565                  return Result::logicError( "No options supplied to Opt" );
 7566              for( auto const &name : m_optNames ) {
 7567                  if( name.empty() )
 7568                      return Result::logicError( "Option name cannot be empty" );
 7569  #ifdef CATCH_PLATFORM_WINDOWS
 7570                  if( name[0] != '-' && name[0] != '/' )
 7571                      return Result::logicError( "Option name must begin with '-' or '/'" );
 7572  #else
 7573                  if( name[0] != '-' )
 7574                      return Result::logicError( "Option name must begin with '-'" );
 7575  #endif
 7576              }
 7577              return ParserRefImpl::validate();
 7578          }
 7579      };
 7580  
 7581      struct Help : Opt {
 7582          Help( bool &showHelpFlag )
 7583          :   Opt([&]( bool flag ) {
 7584                  showHelpFlag = flag;
 7585                  return ParserResult::ok( ParseResultType::ShortCircuitAll );
 7586              })
 7587          {
 7588              static_cast<Opt &>( *this )
 7589                      ("display usage information")
 7590                      ["-?"]["-h"]["--help"]
 7591                      .optional();
 7592          }
 7593      };
 7594  
 7595      struct Parser : ParserBase {
 7596  
 7597          mutable ExeName m_exeName;
 7598          std::vector<Opt> m_options;
 7599          std::vector<Arg> m_args;
 7600  
 7601          auto operator|=( ExeName const &exeName ) -> Parser & {
 7602              m_exeName = exeName;
 7603              return *this;
 7604          }
 7605  
 7606          auto operator|=( Arg const &arg ) -> Parser & {
 7607              m_args.push_back(arg);
 7608              return *this;
 7609          }
 7610  
 7611          auto operator|=( Opt const &opt ) -> Parser & {
 7612              m_options.push_back(opt);
 7613              return *this;
 7614          }
 7615  
 7616          auto operator|=( Parser const &other ) -> Parser & {
 7617              m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
 7618              m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
 7619              return *this;
 7620          }
 7621  
 7622          template<typename T>
 7623          auto operator|( T const &other ) const -> Parser {
 7624              return Parser( *this ) |= other;
 7625          }
 7626  
 7627          // Forward deprecated interface with '+' instead of '|'
 7628          template<typename T>
 7629          auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }
 7630          template<typename T>
 7631          auto operator+( T const &other ) const -> Parser { return operator|( other ); }
 7632  
 7633          auto getHelpColumns() const -> std::vector<HelpColumns> {
 7634              std::vector<HelpColumns> cols;
 7635              for (auto const &o : m_options) {
 7636                  auto childCols = o.getHelpColumns();
 7637                  cols.insert( cols.end(), childCols.begin(), childCols.end() );
 7638              }
 7639              return cols;
 7640          }
 7641  
 7642          void writeToStream( std::ostream &os ) const {
 7643              if (!m_exeName.name().empty()) {
 7644                  os << "usage:\n" << "  " << m_exeName.name() << " ";
 7645                  bool required = true, first = true;
 7646                  for( auto const &arg : m_args ) {
 7647                      if (first)
 7648                          first = false;
 7649                      else
 7650                          os << " ";
 7651                      if( arg.isOptional() && required ) {
 7652                          os << "[";
 7653                          required = false;
 7654                      }
 7655                      os << "<" << arg.hint() << ">";
 7656                      if( arg.cardinality() == 0 )
 7657                          os << " ... ";
 7658                  }
 7659                  if( !required )
 7660                      os << "]";
 7661                  if( !m_options.empty() )
 7662                      os << " options";
 7663                  os << "\n\nwhere options are:" << std::endl;
 7664              }
 7665  
 7666              auto rows = getHelpColumns();
 7667              size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
 7668              size_t optWidth = 0;
 7669              for( auto const &cols : rows )
 7670                  optWidth = (std::max)(optWidth, cols.left.size() + 2);
 7671  
 7672              optWidth = (std::min)(optWidth, consoleWidth/2);
 7673  
 7674              for( auto const &cols : rows ) {
 7675                  auto row =
 7676                          TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
 7677                          TextFlow::Spacer(4) +
 7678                          TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth );
 7679                  os << row << std::endl;
 7680              }
 7681          }
 7682  
 7683          friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream& {
 7684              parser.writeToStream( os );
 7685              return os;
 7686          }
 7687  
 7688          auto validate() const -> Result override {
 7689              for( auto const &opt : m_options ) {
 7690                  auto result = opt.validate();
 7691                  if( !result )
 7692                      return result;
 7693              }
 7694              for( auto const &arg : m_args ) {
 7695                  auto result = arg.validate();
 7696                  if( !result )
 7697                      return result;
 7698              }
 7699              return Result::ok();
 7700          }
 7701  
 7702          using ParserBase::parse;
 7703  
 7704          auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override {
 7705  
 7706              struct ParserInfo {
 7707                  ParserBase const* parser = nullptr;
 7708                  size_t count = 0;
 7709              };
 7710              const size_t totalParsers = m_options.size() + m_args.size();
 7711              assert( totalParsers < 512 );
 7712              // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do
 7713              ParserInfo parseInfos[512];
 7714  
 7715              {
 7716                  size_t i = 0;
 7717                  for (auto const &opt : m_options) parseInfos[i++].parser = &opt;
 7718                  for (auto const &arg : m_args) parseInfos[i++].parser = &arg;
 7719              }
 7720  
 7721              m_exeName.set( exeName );
 7722  
 7723              auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
 7724              while( result.value().remainingTokens() ) {
 7725                  bool tokenParsed = false;
 7726  
 7727                  for( size_t i = 0; i < totalParsers; ++i ) {
 7728                      auto&  parseInfo = parseInfos[i];
 7729                      if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) {
 7730                          result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
 7731                          if (!result)
 7732                              return result;
 7733                          if (result.value().type() != ParseResultType::NoMatch) {
 7734                              tokenParsed = true;
 7735                              ++parseInfo.count;
 7736                              break;
 7737                          }
 7738                      }
 7739                  }
 7740  
 7741                  if( result.value().type() == ParseResultType::ShortCircuitAll )
 7742                      return result;
 7743                  if( !tokenParsed )
 7744                      return InternalParseResult::runtimeError( "Unrecognised token: " + result.value().remainingTokens()->token );
 7745              }
 7746              // !TBD Check missing required options
 7747              return result;
 7748          }
 7749      };
 7750  
 7751      template<typename DerivedT>
 7752      template<typename T>
 7753      auto ComposableParserImpl<DerivedT>::operator|( T const &other ) const -> Parser {
 7754          return Parser() | static_cast<DerivedT const &>( *this ) | other;
 7755      }
 7756  } // namespace detail
 7757  
 7758  // A Combined parser
 7759  using detail::Parser;
 7760  
 7761  // A parser for options
 7762  using detail::Opt;
 7763  
 7764  // A parser for arguments
 7765  using detail::Arg;
 7766  
 7767  // Wrapper for argc, argv from main()
 7768  using detail::Args;
 7769  
 7770  // Specifies the name of the executable
 7771  using detail::ExeName;
 7772  
 7773  // Convenience wrapper for option parser that specifies the help option
 7774  using detail::Help;
 7775  
 7776  // enum of result types from a parse
 7777  using detail::ParseResultType;
 7778  
 7779  // Result type for parser operation
 7780  using detail::ParserResult;
 7781  
 7782  }} // namespace Catch::clara
 7783  
 7784  // end clara.hpp
 7785  #ifdef __clang__
 7786  #pragma clang diagnostic pop
 7787  #endif
 7788  
 7789  // Restore Clara's value for console width, if present
 7790  #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
 7791  #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
 7792  #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
 7793  #endif
 7794  
 7795  // end catch_clara.h
 7796  namespace Catch {
 7797  
 7798      clara::Parser makeCommandLineParser( ConfigData& config );
 7799  
 7800  } // end namespace Catch
 7801  
 7802  // end catch_commandline.h
 7803  #include <fstream>
 7804  #include <ctime>
 7805  
 7806  namespace Catch {
 7807  
 7808      clara::Parser makeCommandLineParser( ConfigData& config ) {
 7809  
 7810          using namespace clara;
 7811  
 7812          auto const setWarning = [&]( std::string const& warning ) {
 7813                  auto warningSet = [&]() {
 7814                      if( warning == "NoAssertions" )
 7815                          return WarnAbout::NoAssertions;
 7816  
 7817                      if ( warning == "NoTests" )
 7818                          return WarnAbout::NoTests;
 7819  
 7820                      return WarnAbout::Nothing;
 7821                  }();
 7822  
 7823                  if (warningSet == WarnAbout::Nothing)
 7824                      return ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" );
 7825                  config.warnings = static_cast<WarnAbout::What>( config.warnings | warningSet );
 7826                  return ParserResult::ok( ParseResultType::Matched );
 7827              };
 7828          auto const loadTestNamesFromFile = [&]( std::string const& filename ) {
 7829                  std::ifstream f( filename.c_str() );
 7830                  if( !f.is_open() )
 7831                      return ParserResult::runtimeError( "Unable to load input file: '" + filename + "'" );
 7832  
 7833                  std::string line;
 7834                  while( std::getline( f, line ) ) {
 7835                      line = trim(line);
 7836                      if( !line.empty() && !startsWith( line, '#' ) ) {
 7837                          if( !startsWith( line, '"' ) )
 7838                              line = '"' + line + '"';
 7839                          config.testsOrTags.push_back( line + ',' );
 7840                      }
 7841                  }
 7842                  return ParserResult::ok( ParseResultType::Matched );
 7843              };
 7844          auto const setTestOrder = [&]( std::string const& order ) {
 7845                  if( startsWith( "declared", order ) )
 7846                      config.runOrder = RunTests::InDeclarationOrder;
 7847                  else if( startsWith( "lexical", order ) )
 7848                      config.runOrder = RunTests::InLexicographicalOrder;
 7849                  else if( startsWith( "random", order ) )
 7850                      config.runOrder = RunTests::InRandomOrder;
 7851                  else
 7852                      return clara::ParserResult::runtimeError( "Unrecognised ordering: '" + order + "'" );
 7853                  return ParserResult::ok( ParseResultType::Matched );
 7854              };
 7855          auto const setRngSeed = [&]( std::string const& seed ) {
 7856                  if( seed != "time" )
 7857                      return clara::detail::convertInto( seed, config.rngSeed );
 7858                  config.rngSeed = static_cast<unsigned int>( std::time(nullptr) );
 7859                  return ParserResult::ok( ParseResultType::Matched );
 7860              };
 7861          auto const setColourUsage = [&]( std::string const& useColour ) {
 7862                      auto mode = toLower( useColour );
 7863  
 7864                      if( mode == "yes" )
 7865                          config.useColour = UseColour::Yes;
 7866                      else if( mode == "no" )
 7867                          config.useColour = UseColour::No;
 7868                      else if( mode == "auto" )
 7869                          config.useColour = UseColour::Auto;
 7870                      else
 7871                          return ParserResult::runtimeError( "colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised" );
 7872                  return ParserResult::ok( ParseResultType::Matched );
 7873              };
 7874          auto const setWaitForKeypress = [&]( std::string const& keypress ) {
 7875                  auto keypressLc = toLower( keypress );
 7876                  if( keypressLc == "start" )
 7877                      config.waitForKeypress = WaitForKeypress::BeforeStart;
 7878                  else if( keypressLc == "exit" )
 7879                      config.waitForKeypress = WaitForKeypress::BeforeExit;
 7880                  else if( keypressLc == "both" )
 7881                      config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
 7882                  else
 7883                      return ParserResult::runtimeError( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" );
 7884              return ParserResult::ok( ParseResultType::Matched );
 7885              };
 7886          auto const setVerbosity = [&]( std::string const& verbosity ) {
 7887              auto lcVerbosity = toLower( verbosity );
 7888              if( lcVerbosity == "quiet" )
 7889                  config.verbosity = Verbosity::Quiet;
 7890              else if( lcVerbosity == "normal" )
 7891                  config.verbosity = Verbosity::Normal;
 7892              else if( lcVerbosity == "high" )
 7893                  config.verbosity = Verbosity::High;
 7894              else
 7895                  return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" );
 7896              return ParserResult::ok( ParseResultType::Matched );
 7897          };
 7898          auto const setReporter = [&]( std::string const& reporter ) {
 7899              IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
 7900  
 7901              auto lcReporter = toLower( reporter );
 7902              auto result = factories.find( lcReporter );
 7903  
 7904              if( factories.end() != result )
 7905                  config.reporterName = lcReporter;
 7906              else
 7907                  return ParserResult::runtimeError( "Unrecognized reporter, '" + reporter + "'. Check available with --list-reporters" );
 7908              return ParserResult::ok( ParseResultType::Matched );
 7909          };
 7910  
 7911          auto cli
 7912              = ExeName( config.processName )
 7913              | Help( config.showHelp )
 7914              | Opt( config.listTests )
 7915                  ["-l"]["--list-tests"]
 7916                  ( "list all/matching test cases" )
 7917              | Opt( config.listTags )
 7918                  ["-t"]["--list-tags"]
 7919                  ( "list all/matching tags" )
 7920              | Opt( config.showSuccessfulTests )
 7921                  ["-s"]["--success"]
 7922                  ( "include successful tests in output" )
 7923              | Opt( config.shouldDebugBreak )
 7924                  ["-b"]["--break"]
 7925                  ( "break into debugger on failure" )
 7926              | Opt( config.noThrow )
 7927                  ["-e"]["--nothrow"]
 7928                  ( "skip exception tests" )
 7929              | Opt( config.showInvisibles )
 7930                  ["-i"]["--invisibles"]
 7931                  ( "show invisibles (tabs, newlines)" )
 7932              | Opt( config.outputFilename, "filename" )
 7933                  ["-o"]["--out"]
 7934                  ( "output filename" )
 7935              | Opt( setReporter, "name" )
 7936                  ["-r"]["--reporter"]
 7937                  ( "reporter to use (defaults to console)" )
 7938              | Opt( config.name, "name" )
 7939                  ["-n"]["--name"]
 7940                  ( "suite name" )
 7941              | Opt( [&]( bool ){ config.abortAfter = 1; } )
 7942                  ["-a"]["--abort"]
 7943                  ( "abort at first failure" )
 7944              | Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" )
 7945                  ["-x"]["--abortx"]
 7946                  ( "abort after x failures" )
 7947              | Opt( setWarning, "warning name" )
 7948                  ["-w"]["--warn"]
 7949                  ( "enable warnings" )
 7950              | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" )
 7951                  ["-d"]["--durations"]
 7952                  ( "show test durations" )
 7953              | Opt( loadTestNamesFromFile, "filename" )
 7954                  ["-f"]["--input-file"]
 7955                  ( "load test names to run from a file" )
 7956              | Opt( config.filenamesAsTags )
 7957                  ["-#"]["--filenames-as-tags"]
 7958                  ( "adds a tag for the filename" )
 7959              | Opt( config.sectionsToRun, "section name" )
 7960                  ["-c"]["--section"]
 7961                  ( "specify section to run" )
 7962              | Opt( setVerbosity, "quiet|normal|high" )
 7963                  ["-v"]["--verbosity"]
 7964                  ( "set output verbosity" )
 7965              | Opt( config.listTestNamesOnly )
 7966                  ["--list-test-names-only"]
 7967                  ( "list all/matching test cases names only" )
 7968              | Opt( config.listReporters )
 7969                  ["--list-reporters"]
 7970                  ( "list all reporters" )
 7971              | Opt( setTestOrder, "decl|lex|rand" )
 7972                  ["--order"]
 7973                  ( "test case order (defaults to decl)" )
 7974              | Opt( setRngSeed, "'time'|number" )
 7975                  ["--rng-seed"]
 7976                  ( "set a specific seed for random numbers" )
 7977              | Opt( setColourUsage, "yes|no" )
 7978                  ["--use-colour"]
 7979                  ( "should output be colourised" )
 7980              | Opt( config.libIdentify )
 7981                  ["--libidentify"]
 7982                  ( "report name and version according to libidentify standard" )
 7983              | Opt( setWaitForKeypress, "start|exit|both" )
 7984                  ["--wait-for-keypress"]
 7985                  ( "waits for a keypress before exiting" )
 7986              | Opt( config.benchmarkResolutionMultiple, "multiplier" )
 7987                  ["--benchmark-resolution-multiple"]
 7988                  ( "multiple of clock resolution to run benchmarks" )
 7989  
 7990              | Arg( config.testsOrTags, "test name|pattern|tags" )
 7991                  ( "which test or tests to use" );
 7992  
 7993          return cli;
 7994      }
 7995  
 7996  } // end namespace Catch
 7997  // end catch_commandline.cpp
 7998  // start catch_common.cpp
 7999  
 8000  #include <cstring>
 8001  #include <ostream>
 8002  
 8003  namespace Catch {
 8004  
 8005      bool SourceLineInfo::empty() const noexcept {
 8006          return file[0] == '\0';
 8007      }
 8008      bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept {
 8009          return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
 8010      }
 8011      bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept {
 8012          // We can assume that the same file will usually have the same pointer.
 8013          // Thus, if the pointers are the same, there is no point in calling the strcmp
 8014          return line < other.line || ( line == other.line && file != other.file && (std::strcmp(file, other.file) < 0));
 8015      }
 8016  
 8017      std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
 8018  #ifndef __GNUG__
 8019          os << info.file << '(' << info.line << ')';
 8020  #else
 8021          os << info.file << ':' << info.line;
 8022  #endif
 8023          return os;
 8024      }
 8025  
 8026      std::string StreamEndStop::operator+() const {
 8027          return std::string();
 8028      }
 8029  
 8030      NonCopyable::NonCopyable() = default;
 8031      NonCopyable::~NonCopyable() = default;
 8032  
 8033  }
 8034  // end catch_common.cpp
 8035  // start catch_config.cpp
 8036  
 8037  namespace Catch {
 8038  
 8039      Config::Config( ConfigData const& data )
 8040      :   m_data( data ),
 8041          m_stream( openStream() )
 8042      {
 8043          TestSpecParser parser(ITagAliasRegistry::get());
 8044          if (!data.testsOrTags.empty()) {
 8045              m_hasTestFilters = true;
 8046              for( auto const& testOrTags : data.testsOrTags )
 8047                  parser.parse( testOrTags );
 8048          }
 8049          m_testSpec = parser.testSpec();
 8050      }
 8051  
 8052      std::string const& Config::getFilename() const {
 8053          return m_data.outputFilename ;
 8054      }
 8055  
 8056      bool Config::listTests() const          { return m_data.listTests; }
 8057      bool Config::listTestNamesOnly() const  { return m_data.listTestNamesOnly; }
 8058      bool Config::listTags() const           { return m_data.listTags; }
 8059      bool Config::listReporters() const      { return m_data.listReporters; }
 8060  
 8061      std::string Config::getProcessName() const { return m_data.processName; }
 8062      std::string const& Config::getReporterName() const { return m_data.reporterName; }
 8063  
 8064      std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }
 8065      std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
 8066  
 8067      TestSpec const& Config::testSpec() const { return m_testSpec; }
 8068      bool Config::hasTestFilters() const { return m_hasTestFilters; }
 8069  
 8070      bool Config::showHelp() const { return m_data.showHelp; }
 8071  
 8072      // IConfig interface
 8073      bool Config::allowThrows() const                   { return !m_data.noThrow; }
 8074      std::ostream& Config::stream() const               { return m_stream->stream(); }
 8075      std::string Config::name() const                   { return m_data.name.empty() ? m_data.processName : m_data.name; }
 8076      bool Config::includeSuccessfulResults() const      { return m_data.showSuccessfulTests; }
 8077      bool Config::warnAboutMissingAssertions() const    { return !!(m_data.warnings & WarnAbout::NoAssertions); }
 8078      bool Config::warnAboutNoTests() const              { return !!(m_data.warnings & WarnAbout::NoTests); }
 8079      ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }
 8080      RunTests::InWhatOrder Config::runOrder() const     { return m_data.runOrder; }
 8081      unsigned int Config::rngSeed() const               { return m_data.rngSeed; }
 8082      int Config::benchmarkResolutionMultiple() const    { return m_data.benchmarkResolutionMultiple; }
 8083      UseColour::YesOrNo Config::useColour() const       { return m_data.useColour; }
 8084      bool Config::shouldDebugBreak() const              { return m_data.shouldDebugBreak; }
 8085      int Config::abortAfter() const                     { return m_data.abortAfter; }
 8086      bool Config::showInvisibles() const                { return m_data.showInvisibles; }
 8087      Verbosity Config::verbosity() const                { return m_data.verbosity; }
 8088  
 8089      IStream const* Config::openStream() {
 8090          return Catch::makeStream(m_data.outputFilename);
 8091      }
 8092  
 8093  } // end namespace Catch
 8094  // end catch_config.cpp
 8095  // start catch_console_colour.cpp
 8096  
 8097  #if defined(__clang__)
 8098  #    pragma clang diagnostic push
 8099  #    pragma clang diagnostic ignored "-Wexit-time-destructors"
 8100  #endif
 8101  
 8102  // start catch_errno_guard.h
 8103  
 8104  namespace Catch {
 8105  
 8106      class ErrnoGuard {
 8107      public:
 8108          ErrnoGuard();
 8109          ~ErrnoGuard();
 8110      private:
 8111          int m_oldErrno;
 8112      };
 8113  
 8114  }
 8115  
 8116  // end catch_errno_guard.h
 8117  #include <sstream>
 8118  
 8119  namespace Catch {
 8120      namespace {
 8121  
 8122          struct IColourImpl {
 8123              virtual ~IColourImpl() = default;
 8124              virtual void use( Colour::Code _colourCode ) = 0;
 8125          };
 8126  
 8127          struct NoColourImpl : IColourImpl {
 8128              void use( Colour::Code ) {}
 8129  
 8130              static IColourImpl* instance() {
 8131                  static NoColourImpl s_instance;
 8132                  return &s_instance;
 8133              }
 8134          };
 8135  
 8136      } // anon namespace
 8137  } // namespace Catch
 8138  
 8139  #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
 8140  #   ifdef CATCH_PLATFORM_WINDOWS
 8141  #       define CATCH_CONFIG_COLOUR_WINDOWS
 8142  #   else
 8143  #       define CATCH_CONFIG_COLOUR_ANSI
 8144  #   endif
 8145  #endif
 8146  
 8147  #if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
 8148  
 8149  namespace Catch {
 8150  namespace {
 8151  
 8152      class Win32ColourImpl : public IColourImpl {
 8153      public:
 8154          Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
 8155          {
 8156              CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
 8157              GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
 8158              originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
 8159              originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
 8160          }
 8161  
 8162          void use( Colour::Code _colourCode ) override {
 8163              switch( _colourCode ) {
 8164                  case Colour::None:      return setTextAttribute( originalForegroundAttributes );
 8165                  case Colour::White:     return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
 8166                  case Colour::Red:       return setTextAttribute( FOREGROUND_RED );
 8167                  case Colour::Green:     return setTextAttribute( FOREGROUND_GREEN );
 8168                  case Colour::Blue:      return setTextAttribute( FOREGROUND_BLUE );
 8169                  case Colour::Cyan:      return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
 8170                  case Colour::Yellow:    return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
 8171                  case Colour::Grey:      return setTextAttribute( 0 );
 8172  
 8173                  case Colour::LightGrey:     return setTextAttribute( FOREGROUND_INTENSITY );
 8174                  case Colour::BrightRed:     return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
 8175                  case Colour::BrightGreen:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
 8176                  case Colour::BrightWhite:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
 8177                  case Colour::BrightYellow:  return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN );
 8178  
 8179                  case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
 8180  
 8181                  default:
 8182                      CATCH_ERROR( "Unknown colour requested" );
 8183              }
 8184          }
 8185  
 8186      private:
 8187          void setTextAttribute( WORD _textAttribute ) {
 8188              SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
 8189          }
 8190          HANDLE stdoutHandle;
 8191          WORD originalForegroundAttributes;
 8192          WORD originalBackgroundAttributes;
 8193      };
 8194  
 8195      IColourImpl* platformColourInstance() {
 8196          static Win32ColourImpl s_instance;
 8197  
 8198          IConfigPtr config = getCurrentContext().getConfig();
 8199          UseColour::YesOrNo colourMode = config
 8200              ? config->useColour()
 8201              : UseColour::Auto;
 8202          if( colourMode == UseColour::Auto )
 8203              colourMode = UseColour::Yes;
 8204          return colourMode == UseColour::Yes
 8205              ? &s_instance
 8206              : NoColourImpl::instance();
 8207      }
 8208  
 8209  } // end anon namespace
 8210  } // end namespace Catch
 8211  
 8212  #elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
 8213  
 8214  #include <unistd.h>
 8215  
 8216  namespace Catch {
 8217  namespace {
 8218  
 8219      // use POSIX/ ANSI console terminal codes
 8220      // Thanks to Adam Strzelecki for original contribution
 8221      // (http://github.com/nanoant)
 8222      // https://github.com/philsquared/Catch/pull/131
 8223      class PosixColourImpl : public IColourImpl {
 8224      public:
 8225          void use( Colour::Code _colourCode ) override {
 8226              switch( _colourCode ) {
 8227                  case Colour::None:
 8228                  case Colour::White:     return setColour( "[0m" );
 8229                  case Colour::Red:       return setColour( "[0;31m" );
 8230                  case Colour::Green:     return setColour( "[0;32m" );
 8231                  case Colour::Blue:      return setColour( "[0;34m" );
 8232                  case Colour::Cyan:      return setColour( "[0;36m" );
 8233                  case Colour::Yellow:    return setColour( "[0;33m" );
 8234                  case Colour::Grey:      return setColour( "[1;30m" );
 8235  
 8236                  case Colour::LightGrey:     return setColour( "[0;37m" );
 8237                  case Colour::BrightRed:     return setColour( "[1;31m" );
 8238                  case Colour::BrightGreen:   return setColour( "[1;32m" );
 8239                  case Colour::BrightWhite:   return setColour( "[1;37m" );
 8240                  case Colour::BrightYellow:  return setColour( "[1;33m" );
 8241  
 8242                  case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
 8243                  default: CATCH_INTERNAL_ERROR( "Unknown colour requested" );
 8244              }
 8245          }
 8246          static IColourImpl* instance() {
 8247              static PosixColourImpl s_instance;
 8248              return &s_instance;
 8249          }
 8250  
 8251      private:
 8252          void setColour( const char* _escapeCode ) {
 8253              getCurrentContext().getConfig()->stream()
 8254                  << '\033' << _escapeCode;
 8255          }
 8256      };
 8257  
 8258      bool useColourOnPlatform() {
 8259          return
 8260  #ifdef CATCH_PLATFORM_MAC
 8261              !isDebuggerActive() &&
 8262  #endif
 8263  #if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
 8264              isatty(STDOUT_FILENO)
 8265  #else
 8266              false
 8267  #endif
 8268              ;
 8269      }
 8270      IColourImpl* platformColourInstance() {
 8271          ErrnoGuard guard;
 8272          IConfigPtr config = getCurrentContext().getConfig();
 8273          UseColour::YesOrNo colourMode = config
 8274              ? config->useColour()
 8275              : UseColour::Auto;
 8276          if( colourMode == UseColour::Auto )
 8277              colourMode = useColourOnPlatform()
 8278                  ? UseColour::Yes
 8279                  : UseColour::No;
 8280          return colourMode == UseColour::Yes
 8281              ? PosixColourImpl::instance()
 8282              : NoColourImpl::instance();
 8283      }
 8284  
 8285  } // end anon namespace
 8286  } // end namespace Catch
 8287  
 8288  #else  // not Windows or ANSI ///////////////////////////////////////////////
 8289  
 8290  namespace Catch {
 8291  
 8292      static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
 8293  
 8294  } // end namespace Catch
 8295  
 8296  #endif // Windows/ ANSI/ None
 8297  
 8298  namespace Catch {
 8299  
 8300      Colour::Colour( Code _colourCode ) { use( _colourCode ); }
 8301      Colour::Colour( Colour&& rhs ) noexcept {
 8302          m_moved = rhs.m_moved;
 8303          rhs.m_moved = true;
 8304      }
 8305      Colour& Colour::operator=( Colour&& rhs ) noexcept {
 8306          m_moved = rhs.m_moved;
 8307          rhs.m_moved  = true;
 8308          return *this;
 8309      }
 8310  
 8311      Colour::~Colour(){ if( !m_moved ) use( None ); }
 8312  
 8313      void Colour::use( Code _colourCode ) {
 8314          static IColourImpl* impl = platformColourInstance();
 8315          impl->use( _colourCode );
 8316      }
 8317  
 8318      std::ostream& operator << ( std::ostream& os, Colour const& ) {
 8319          return os;
 8320      }
 8321  
 8322  } // end namespace Catch
 8323  
 8324  #if defined(__clang__)
 8325  #    pragma clang diagnostic pop
 8326  #endif
 8327  
 8328  // end catch_console_colour.cpp
 8329  // start catch_context.cpp
 8330  
 8331  namespace Catch {
 8332  
 8333      class Context : public IMutableContext, NonCopyable {
 8334  
 8335      public: // IContext
 8336          IResultCapture* getResultCapture() override {
 8337              return m_resultCapture;
 8338          }
 8339          IRunner* getRunner() override {
 8340              return m_runner;
 8341          }
 8342  
 8343          IConfigPtr const& getConfig() const override {
 8344              return m_config;
 8345          }
 8346  
 8347          ~Context() override;
 8348  
 8349      public: // IMutableContext
 8350          void setResultCapture( IResultCapture* resultCapture ) override {
 8351              m_resultCapture = resultCapture;
 8352          }
 8353          void setRunner( IRunner* runner ) override {
 8354              m_runner = runner;
 8355          }
 8356          void setConfig( IConfigPtr const& config ) override {
 8357              m_config = config;
 8358          }
 8359  
 8360          friend IMutableContext& getCurrentMutableContext();
 8361  
 8362      private:
 8363          IConfigPtr m_config;
 8364          IRunner* m_runner = nullptr;
 8365          IResultCapture* m_resultCapture = nullptr;
 8366      };
 8367  
 8368      IMutableContext *IMutableContext::currentContext = nullptr;
 8369  
 8370      void IMutableContext::createContext()
 8371      {
 8372          currentContext = new Context();
 8373      }
 8374  
 8375      void cleanUpContext() {
 8376          delete IMutableContext::currentContext;
 8377          IMutableContext::currentContext = nullptr;
 8378      }
 8379      IContext::~IContext() = default;
 8380      IMutableContext::~IMutableContext() = default;
 8381      Context::~Context() = default;
 8382  }
 8383  // end catch_context.cpp
 8384  // start catch_debug_console.cpp
 8385  
 8386  // start catch_debug_console.h
 8387  
 8388  #include <string>
 8389  
 8390  namespace Catch {
 8391      void writeToDebugConsole( std::string const& text );
 8392  }
 8393  
 8394  // end catch_debug_console.h
 8395  #ifdef CATCH_PLATFORM_WINDOWS
 8396  
 8397      namespace Catch {
 8398          void writeToDebugConsole( std::string const& text ) {
 8399              ::OutputDebugStringA( text.c_str() );
 8400          }
 8401      }
 8402  
 8403  #else
 8404  
 8405      namespace Catch {
 8406          void writeToDebugConsole( std::string const& text ) {
 8407              // !TBD: Need a version for Mac/ XCode and other IDEs
 8408              Catch::cout() << text;
 8409          }
 8410      }
 8411  
 8412  #endif // Platform
 8413  // end catch_debug_console.cpp
 8414  // start catch_debugger.cpp
 8415  
 8416  #ifdef CATCH_PLATFORM_MAC
 8417  
 8418  #  include <assert.h>
 8419  #  include <stdbool.h>
 8420  #  include <sys/types.h>
 8421  #  include <unistd.h>
 8422  #  include <cstddef>
 8423  #  include <ostream>
 8424  
 8425  #ifdef __apple_build_version__
 8426      // These headers will only compile with AppleClang (XCode)
 8427      // For other compilers (Clang, GCC, ... ) we need to exclude them
 8428  #  include <sys/sysctl.h>
 8429  #endif
 8430  
 8431      namespace Catch {
 8432          #ifdef __apple_build_version__
 8433          // The following function is taken directly from the following technical note:
 8434          // https://developer.apple.com/library/archive/qa/qa1361/_index.html
 8435  
 8436          // Returns true if the current process is being debugged (either
 8437          // running under the debugger or has a debugger attached post facto).
 8438          bool isDebuggerActive(){
 8439              int                 mib[4];
 8440              struct kinfo_proc   info;
 8441              std::size_t         size;
 8442  
 8443              // Initialize the flags so that, if sysctl fails for some bizarre
 8444              // reason, we get a predictable result.
 8445  
 8446              info.kp_proc.p_flag = 0;
 8447  
 8448              // Initialize mib, which tells sysctl the info we want, in this case
 8449              // we're looking for information about a specific process ID.
 8450  
 8451              mib[0] = CTL_KERN;
 8452              mib[1] = KERN_PROC;
 8453              mib[2] = KERN_PROC_PID;
 8454              mib[3] = getpid();
 8455  
 8456              // Call sysctl.
 8457  
 8458              size = sizeof(info);
 8459              if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) {
 8460                  Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
 8461                  return false;
 8462              }
 8463  
 8464              // We're being debugged if the P_TRACED flag is set.
 8465  
 8466              return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
 8467          }
 8468          #else
 8469          bool isDebuggerActive() {
 8470              // We need to find another way to determine this for non-appleclang compilers on macOS
 8471              return false;
 8472          }
 8473          #endif
 8474      } // namespace Catch
 8475  
 8476  #elif defined(CATCH_PLATFORM_LINUX)
 8477      #include <fstream>
 8478      #include <string>
 8479  
 8480      namespace Catch{
 8481          // The standard POSIX way of detecting a debugger is to attempt to
 8482          // ptrace() the process, but this needs to be done from a child and not
 8483          // this process itself to still allow attaching to this process later
 8484          // if wanted, so is rather heavy. Under Linux we have the PID of the
 8485          // "debugger" (which doesn't need to be gdb, of course, it could also
 8486          // be strace, for example) in /proc/$PID/status, so just get it from
 8487          // there instead.
 8488          bool isDebuggerActive(){
 8489              // Libstdc++ has a bug, where std::ifstream sets errno to 0
 8490              // This way our users can properly assert over errno values
 8491              ErrnoGuard guard;
 8492              std::ifstream in("/proc/self/status");
 8493              for( std::string line; std::getline(in, line); ) {
 8494                  static const int PREFIX_LEN = 11;
 8495                  if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
 8496                      // We're traced if the PID is not 0 and no other PID starts
 8497                      // with 0 digit, so it's enough to check for just a single
 8498                      // character.
 8499                      return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
 8500                  }
 8501              }
 8502  
 8503              return false;
 8504          }
 8505      } // namespace Catch
 8506  #elif defined(_MSC_VER)
 8507      extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
 8508      namespace Catch {
 8509          bool isDebuggerActive() {
 8510              return IsDebuggerPresent() != 0;
 8511          }
 8512      }
 8513  #elif defined(__MINGW32__)
 8514      extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
 8515      namespace Catch {
 8516          bool isDebuggerActive() {
 8517              return IsDebuggerPresent() != 0;
 8518          }
 8519      }
 8520  #else
 8521      namespace Catch {
 8522         bool isDebuggerActive() { return false; }
 8523      }
 8524  #endif // Platform
 8525  // end catch_debugger.cpp
 8526  // start catch_decomposer.cpp
 8527  
 8528  namespace Catch {
 8529  
 8530      ITransientExpression::~ITransientExpression() = default;
 8531  
 8532      void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {
 8533          if( lhs.size() + rhs.size() < 40 &&
 8534                  lhs.find('\n') == std::string::npos &&
 8535                  rhs.find('\n') == std::string::npos )
 8536              os << lhs << " " << op << " " << rhs;
 8537          else
 8538              os << lhs << "\n" << op << "\n" << rhs;
 8539      }
 8540  }
 8541  // end catch_decomposer.cpp
 8542  // start catch_enforce.cpp
 8543  
 8544  namespace Catch {
 8545  #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)
 8546      [[noreturn]]
 8547      void throw_exception(std::exception const& e) {
 8548          Catch::cerr() << "Catch will terminate because it needed to throw an exception.\n"
 8549                        << "The message was: " << e.what() << '\n';
 8550          std::terminate();
 8551      }
 8552  #endif
 8553  } // namespace Catch;
 8554  // end catch_enforce.cpp
 8555  // start catch_errno_guard.cpp
 8556  
 8557  #include <cerrno>
 8558  
 8559  namespace Catch {
 8560          ErrnoGuard::ErrnoGuard():m_oldErrno(errno){}
 8561          ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }
 8562  }
 8563  // end catch_errno_guard.cpp
 8564  // start catch_exception_translator_registry.cpp
 8565  
 8566  // start catch_exception_translator_registry.h
 8567  
 8568  #include <vector>
 8569  #include <string>
 8570  #include <memory>
 8571  
 8572  namespace Catch {
 8573  
 8574      class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
 8575      public:
 8576          ~ExceptionTranslatorRegistry();
 8577          virtual void registerTranslator( const IExceptionTranslator* translator );
 8578          std::string translateActiveException() const override;
 8579          std::string tryTranslators() const;
 8580  
 8581      private:
 8582          std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators;
 8583      };
 8584  }
 8585  
 8586  // end catch_exception_translator_registry.h
 8587  #ifdef __OBJC__
 8588  #import "Foundation/Foundation.h"
 8589  #endif
 8590  
 8591  namespace Catch {
 8592  
 8593      ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {
 8594      }
 8595  
 8596      void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) {
 8597          m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );
 8598      }
 8599  
 8600  #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
 8601      std::string ExceptionTranslatorRegistry::translateActiveException() const {
 8602          try {
 8603  #ifdef __OBJC__
 8604              // In Objective-C try objective-c exceptions first
 8605              @try {
 8606                  return tryTranslators();
 8607              }
 8608              @catch (NSException *exception) {
 8609                  return Catch::Detail::stringify( [exception description] );
 8610              }
 8611  #else
 8612              // Compiling a mixed mode project with MSVC means that CLR
 8613              // exceptions will be caught in (...) as well. However, these
 8614              // do not fill-in std::current_exception and thus lead to crash
 8615              // when attempting rethrow.
 8616              // /EHa switch also causes structured exceptions to be caught
 8617              // here, but they fill-in current_exception properly, so
 8618              // at worst the output should be a little weird, instead of
 8619              // causing a crash.
 8620              if (std::current_exception() == nullptr) {
 8621                  return "Non C++ exception. Possibly a CLR exception.";
 8622              }
 8623              return tryTranslators();
 8624  #endif
 8625          }
 8626          catch( TestFailureException& ) {
 8627              std::rethrow_exception(std::current_exception());
 8628          }
 8629          catch( std::exception& ex ) {
 8630              return ex.what();
 8631          }
 8632          catch( std::string& msg ) {
 8633              return msg;
 8634          }
 8635          catch( const char* msg ) {
 8636              return msg;
 8637          }
 8638          catch(...) {
 8639              return "Unknown exception";
 8640          }
 8641      }
 8642  
 8643      std::string ExceptionTranslatorRegistry::tryTranslators() const {
 8644          if (m_translators.empty()) {
 8645              std::rethrow_exception(std::current_exception());
 8646          } else {
 8647              return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end());
 8648          }
 8649      }
 8650  
 8651  #else // ^^ Exceptions are enabled // Exceptions are disabled vv
 8652      std::string ExceptionTranslatorRegistry::translateActiveException() const {
 8653          CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
 8654      }
 8655  
 8656      std::string ExceptionTranslatorRegistry::tryTranslators() const {
 8657          CATCH_INTERNAL_ERROR("Attempted to use exception translators under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
 8658      }
 8659  #endif
 8660  
 8661  }
 8662  // end catch_exception_translator_registry.cpp
 8663  // start catch_fatal_condition.cpp
 8664  
 8665  #if defined(__GNUC__)
 8666  #    pragma GCC diagnostic push
 8667  #    pragma GCC diagnostic ignored "-Wmissing-field-initializers"
 8668  #endif
 8669  
 8670  #if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )
 8671  
 8672  namespace {
 8673      // Report the error condition
 8674      void reportFatal( char const * const message ) {
 8675          Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
 8676      }
 8677  }
 8678  
 8679  #endif // signals/SEH handling
 8680  
 8681  #if defined( CATCH_CONFIG_WINDOWS_SEH )
 8682  
 8683  namespace Catch {
 8684      struct SignalDefs { DWORD id; const char* name; };
 8685  
 8686      // There is no 1-1 mapping between signals and windows exceptions.
 8687      // Windows can easily distinguish between SO and SigSegV,
 8688      // but SigInt, SigTerm, etc are handled differently.
 8689      static SignalDefs signalDefs[] = {
 8690          { static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION),  "SIGILL - Illegal instruction signal" },
 8691          { static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow" },
 8692          { static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION), "SIGSEGV - Segmentation violation signal" },
 8693          { static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" },
 8694      };
 8695  
 8696      LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
 8697          for (auto const& def : signalDefs) {
 8698              if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
 8699                  reportFatal(def.name);
 8700              }
 8701          }
 8702          // If its not an exception we care about, pass it along.
 8703          // This stops us from eating debugger breaks etc.
 8704          return EXCEPTION_CONTINUE_SEARCH;
 8705      }
 8706  
 8707      FatalConditionHandler::FatalConditionHandler() {
 8708          isSet = true;
 8709          // 32k seems enough for Catch to handle stack overflow,
 8710          // but the value was found experimentally, so there is no strong guarantee
 8711          guaranteeSize = 32 * 1024;
 8712          exceptionHandlerHandle = nullptr;
 8713          // Register as first handler in current chain
 8714          exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
 8715          // Pass in guarantee size to be filled
 8716          SetThreadStackGuarantee(&guaranteeSize);
 8717      }
 8718  
 8719      void FatalConditionHandler::reset() {
 8720          if (isSet) {
 8721              RemoveVectoredExceptionHandler(exceptionHandlerHandle);
 8722              SetThreadStackGuarantee(&guaranteeSize);
 8723              exceptionHandlerHandle = nullptr;
 8724              isSet = false;
 8725          }
 8726      }
 8727  
 8728      FatalConditionHandler::~FatalConditionHandler() {
 8729          reset();
 8730      }
 8731  
 8732  bool FatalConditionHandler::isSet = false;
 8733  ULONG FatalConditionHandler::guaranteeSize = 0;
 8734  PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;
 8735  
 8736  } // namespace Catch
 8737  
 8738  #elif defined( CATCH_CONFIG_POSIX_SIGNALS )
 8739  
 8740  namespace Catch {
 8741  
 8742      struct SignalDefs {
 8743          int id;
 8744          const char* name;
 8745      };
 8746  
 8747      // 32kb for the alternate stack seems to be sufficient. However, this value
 8748      // is experimentally determined, so that's not guaranteed.
 8749      constexpr static std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
 8750  
 8751      static SignalDefs signalDefs[] = {
 8752          { SIGINT,  "SIGINT - Terminal interrupt signal" },
 8753          { SIGILL,  "SIGILL - Illegal instruction signal" },
 8754          { SIGFPE,  "SIGFPE - Floating point error signal" },
 8755          { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
 8756          { SIGTERM, "SIGTERM - Termination request signal" },
 8757          { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
 8758      };
 8759  
 8760      void FatalConditionHandler::handleSignal( int sig ) {
 8761          char const * name = "<unknown signal>";
 8762          for (auto const& def : signalDefs) {
 8763              if (sig == def.id) {
 8764                  name = def.name;
 8765                  break;
 8766              }
 8767          }
 8768          reset();
 8769          reportFatal(name);
 8770          raise( sig );
 8771      }
 8772  
 8773      FatalConditionHandler::FatalConditionHandler() {
 8774          isSet = true;
 8775          stack_t sigStack;
 8776          sigStack.ss_sp = altStackMem;
 8777          sigStack.ss_size = sigStackSize;
 8778          sigStack.ss_flags = 0;
 8779          sigaltstack(&sigStack, &oldSigStack);
 8780          struct sigaction sa = { };
 8781  
 8782          sa.sa_handler = handleSignal;
 8783          sa.sa_flags = SA_ONSTACK;
 8784          for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {
 8785              sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
 8786          }
 8787      }
 8788  
 8789      FatalConditionHandler::~FatalConditionHandler() {
 8790          reset();
 8791      }
 8792  
 8793      void FatalConditionHandler::reset() {
 8794          if( isSet ) {
 8795              // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
 8796              for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
 8797                  sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
 8798              }
 8799              // Return the old stack
 8800              sigaltstack(&oldSigStack, nullptr);
 8801              isSet = false;
 8802          }
 8803      }
 8804  
 8805      bool FatalConditionHandler::isSet = false;
 8806      struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
 8807      stack_t FatalConditionHandler::oldSigStack = {};
 8808      char FatalConditionHandler::altStackMem[sigStackSize] = {};
 8809  
 8810  } // namespace Catch
 8811  
 8812  #else
 8813  
 8814  namespace Catch {
 8815      void FatalConditionHandler::reset() {}
 8816  }
 8817  
 8818  #endif // signals/SEH handling
 8819  
 8820  #if defined(__GNUC__)
 8821  #    pragma GCC diagnostic pop
 8822  #endif
 8823  // end catch_fatal_condition.cpp
 8824  // start catch_generators.cpp
 8825  
 8826  // start catch_random_number_generator.h
 8827  
 8828  #include <algorithm>
 8829  #include <random>
 8830  
 8831  namespace Catch {
 8832  
 8833      struct IConfig;
 8834  
 8835      std::mt19937& rng();
 8836      void seedRng( IConfig const& config );
 8837      unsigned int rngSeed();
 8838  
 8839  }
 8840  
 8841  // end catch_random_number_generator.h
 8842  #include <limits>
 8843  #include <set>
 8844  
 8845  namespace Catch {
 8846  
 8847  IGeneratorTracker::~IGeneratorTracker() {}
 8848  
 8849  const char* GeneratorException::what() const noexcept {
 8850      return m_msg;
 8851  }
 8852  
 8853  namespace Generators {
 8854  
 8855      GeneratorUntypedBase::~GeneratorUntypedBase() {}
 8856  
 8857      auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
 8858          return getResultCapture().acquireGeneratorTracker( lineInfo );
 8859      }
 8860  
 8861  } // namespace Generators
 8862  } // namespace Catch
 8863  // end catch_generators.cpp
 8864  // start catch_interfaces_capture.cpp
 8865  
 8866  namespace Catch {
 8867      IResultCapture::~IResultCapture() = default;
 8868  }
 8869  // end catch_interfaces_capture.cpp
 8870  // start catch_interfaces_config.cpp
 8871  
 8872  namespace Catch {
 8873      IConfig::~IConfig() = default;
 8874  }
 8875  // end catch_interfaces_config.cpp
 8876  // start catch_interfaces_exception.cpp
 8877  
 8878  namespace Catch {
 8879      IExceptionTranslator::~IExceptionTranslator() = default;
 8880      IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default;
 8881  }
 8882  // end catch_interfaces_exception.cpp
 8883  // start catch_interfaces_registry_hub.cpp
 8884  
 8885  namespace Catch {
 8886      IRegistryHub::~IRegistryHub() = default;
 8887      IMutableRegistryHub::~IMutableRegistryHub() = default;
 8888  }
 8889  // end catch_interfaces_registry_hub.cpp
 8890  // start catch_interfaces_reporter.cpp
 8891  
 8892  // start catch_reporter_listening.h
 8893  
 8894  namespace Catch {
 8895  
 8896      class ListeningReporter : public IStreamingReporter {
 8897          using Reporters = std::vector<IStreamingReporterPtr>;
 8898          Reporters m_listeners;
 8899          IStreamingReporterPtr m_reporter = nullptr;
 8900          ReporterPreferences m_preferences;
 8901  
 8902      public:
 8903          ListeningReporter();
 8904  
 8905          void addListener( IStreamingReporterPtr&& listener );
 8906          void addReporter( IStreamingReporterPtr&& reporter );
 8907  
 8908      public: // IStreamingReporter
 8909  
 8910          ReporterPreferences getPreferences() const override;
 8911  
 8912          void noMatchingTestCases( std::string const& spec ) override;
 8913  
 8914          static std::set<Verbosity> getSupportedVerbosities();
 8915  
 8916          void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;
 8917          void benchmarkEnded( BenchmarkStats const& benchmarkStats ) override;
 8918  
 8919          void testRunStarting( TestRunInfo const& testRunInfo ) override;
 8920          void testGroupStarting( GroupInfo const& groupInfo ) override;
 8921          void testCaseStarting( TestCaseInfo const& testInfo ) override;
 8922          void sectionStarting( SectionInfo const& sectionInfo ) override;
 8923          void assertionStarting( AssertionInfo const& assertionInfo ) override;
 8924  
 8925          // The return value indicates if the messages buffer should be cleared:
 8926          bool assertionEnded( AssertionStats const& assertionStats ) override;
 8927          void sectionEnded( SectionStats const& sectionStats ) override;
 8928          void testCaseEnded( TestCaseStats const& testCaseStats ) override;
 8929          void testGroupEnded( TestGroupStats const& testGroupStats ) override;
 8930          void testRunEnded( TestRunStats const& testRunStats ) override;
 8931  
 8932          void skipTest( TestCaseInfo const& testInfo ) override;
 8933          bool isMulti() const override;
 8934  
 8935      };
 8936  
 8937  } // end namespace Catch
 8938  
 8939  // end catch_reporter_listening.h
 8940  namespace Catch {
 8941  
 8942      ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig )
 8943      :   m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
 8944  
 8945      ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream )
 8946      :   m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
 8947  
 8948      std::ostream& ReporterConfig::stream() const { return *m_stream; }
 8949      IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; }
 8950  
 8951      TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {}
 8952  
 8953      GroupInfo::GroupInfo(  std::string const& _name,
 8954                             std::size_t _groupIndex,
 8955                             std::size_t _groupsCount )
 8956      :   name( _name ),
 8957          groupIndex( _groupIndex ),
 8958          groupsCounts( _groupsCount )
 8959      {}
 8960  
 8961       AssertionStats::AssertionStats( AssertionResult const& _assertionResult,
 8962                                       std::vector<MessageInfo> const& _infoMessages,
 8963                                       Totals const& _totals )
 8964      :   assertionResult( _assertionResult ),
 8965          infoMessages( _infoMessages ),
 8966          totals( _totals )
 8967      {
 8968          assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;
 8969  
 8970          if( assertionResult.hasMessage() ) {
 8971              // Copy message into messages list.
 8972              // !TBD This should have been done earlier, somewhere
 8973              MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
 8974              builder << assertionResult.getMessage();
 8975              builder.m_info.message = builder.m_stream.str();
 8976  
 8977              infoMessages.push_back( builder.m_info );
 8978          }
 8979      }
 8980  
 8981       AssertionStats::~AssertionStats() = default;
 8982  
 8983      SectionStats::SectionStats(  SectionInfo const& _sectionInfo,
 8984                                   Counts const& _assertions,
 8985                                   double _durationInSeconds,
 8986                                   bool _missingAssertions )
 8987      :   sectionInfo( _sectionInfo ),
 8988          assertions( _assertions ),
 8989          durationInSeconds( _durationInSeconds ),
 8990          missingAssertions( _missingAssertions )
 8991      {}
 8992  
 8993      SectionStats::~SectionStats() = default;
 8994  
 8995      TestCaseStats::TestCaseStats(  TestCaseInfo const& _testInfo,
 8996                                     Totals const& _totals,
 8997                                     std::string const& _stdOut,
 8998                                     std::string const& _stdErr,
 8999                                     bool _aborting )
 9000      : testInfo( _testInfo ),
 9001          totals( _totals ),
 9002          stdOut( _stdOut ),
 9003          stdErr( _stdErr ),
 9004          aborting( _aborting )
 9005      {}
 9006  
 9007      TestCaseStats::~TestCaseStats() = default;
 9008  
 9009      TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo,
 9010                                      Totals const& _totals,
 9011                                      bool _aborting )
 9012      :   groupInfo( _groupInfo ),
 9013          totals( _totals ),
 9014          aborting( _aborting )
 9015      {}
 9016  
 9017      TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo )
 9018      :   groupInfo( _groupInfo ),
 9019          aborting( false )
 9020      {}
 9021  
 9022      TestGroupStats::~TestGroupStats() = default;
 9023  
 9024      TestRunStats::TestRunStats(   TestRunInfo const& _runInfo,
 9025                      Totals const& _totals,
 9026                      bool _aborting )
 9027      :   runInfo( _runInfo ),
 9028          totals( _totals ),
 9029          aborting( _aborting )
 9030      {}
 9031  
 9032      TestRunStats::~TestRunStats() = default;
 9033  
 9034      void IStreamingReporter::fatalErrorEncountered( StringRef ) {}
 9035      bool IStreamingReporter::isMulti() const { return false; }
 9036  
 9037      IReporterFactory::~IReporterFactory() = default;
 9038      IReporterRegistry::~IReporterRegistry() = default;
 9039  
 9040  } // end namespace Catch
 9041  // end catch_interfaces_reporter.cpp
 9042  // start catch_interfaces_runner.cpp
 9043  
 9044  namespace Catch {
 9045      IRunner::~IRunner() = default;
 9046  }
 9047  // end catch_interfaces_runner.cpp
 9048  // start catch_interfaces_testcase.cpp
 9049  
 9050  namespace Catch {
 9051      ITestInvoker::~ITestInvoker() = default;
 9052      ITestCaseRegistry::~ITestCaseRegistry() = default;
 9053  }
 9054  // end catch_interfaces_testcase.cpp
 9055  // start catch_leak_detector.cpp
 9056  
 9057  #ifdef CATCH_CONFIG_WINDOWS_CRTDBG
 9058  #include <crtdbg.h>
 9059  
 9060  namespace Catch {
 9061  
 9062      LeakDetector::LeakDetector() {
 9063          int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
 9064          flag |= _CRTDBG_LEAK_CHECK_DF;
 9065          flag |= _CRTDBG_ALLOC_MEM_DF;
 9066          _CrtSetDbgFlag(flag);
 9067          _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
 9068          _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
 9069          // Change this to leaking allocation's number to break there
 9070          _CrtSetBreakAlloc(-1);
 9071      }
 9072  }
 9073  
 9074  #else
 9075  
 9076      Catch::LeakDetector::LeakDetector() {}
 9077  
 9078  #endif
 9079  
 9080  Catch::LeakDetector::~LeakDetector() {
 9081      Catch::cleanUp();
 9082  }
 9083  // end catch_leak_detector.cpp
 9084  // start catch_list.cpp
 9085  
 9086  // start catch_list.h
 9087  
 9088  #include <set>
 9089  
 9090  namespace Catch {
 9091  
 9092      std::size_t listTests( Config const& config );
 9093  
 9094      std::size_t listTestsNamesOnly( Config const& config );
 9095  
 9096      struct TagInfo {
 9097          void add( std::string const& spelling );
 9098          std::string all() const;
 9099  
 9100          std::set<std::string> spellings;
 9101          std::size_t count = 0;
 9102      };
 9103  
 9104      std::size_t listTags( Config const& config );
 9105  
 9106      std::size_t listReporters();
 9107  
 9108      Option<std::size_t> list( std::shared_ptr<Config> const& config );
 9109  
 9110  } // end namespace Catch
 9111  
 9112  // end catch_list.h
 9113  // start catch_text.h
 9114  
 9115  namespace Catch {
 9116      using namespace clara::TextFlow;
 9117  }
 9118  
 9119  // end catch_text.h
 9120  #include <limits>
 9121  #include <algorithm>
 9122  #include <iomanip>
 9123  
 9124  namespace Catch {
 9125  
 9126      std::size_t listTests( Config const& config ) {
 9127          TestSpec testSpec = config.testSpec();
 9128          if( config.hasTestFilters() )
 9129              Catch::cout() << "Matching test cases:\n";
 9130          else {
 9131              Catch::cout() << "All available test cases:\n";
 9132          }
 9133  
 9134          auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
 9135          for( auto const& testCaseInfo : matchedTestCases ) {
 9136              Colour::Code colour = testCaseInfo.isHidden()
 9137                  ? Colour::SecondaryText
 9138                  : Colour::None;
 9139              Colour colourGuard( colour );
 9140  
 9141              Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << "\n";
 9142              if( config.verbosity() >= Verbosity::High ) {
 9143                  Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl;
 9144                  std::string description = testCaseInfo.description;
 9145                  if( description.empty() )
 9146                      description = "(NO DESCRIPTION)";
 9147                  Catch::cout() << Column( description ).indent(4) << std::endl;
 9148              }
 9149              if( !testCaseInfo.tags.empty() )
 9150                  Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << "\n";
 9151          }
 9152  
 9153          if( !config.hasTestFilters() )
 9154              Catch::cout() << pluralise( matchedTestCases.size(), "test case" ) << '\n' << std::endl;
 9155          else
 9156              Catch::cout() << pluralise( matchedTestCases.size(), "matching test case" ) << '\n' << std::endl;
 9157          return matchedTestCases.size();
 9158      }
 9159  
 9160      std::size_t listTestsNamesOnly( Config const& config ) {
 9161          TestSpec testSpec = config.testSpec();
 9162          std::size_t matchedTests = 0;
 9163          std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
 9164          for( auto const& testCaseInfo : matchedTestCases ) {
 9165              matchedTests++;
 9166              if( startsWith( testCaseInfo.name, '#' ) )
 9167                 Catch::cout() << '"' << testCaseInfo.name << '"';
 9168              else
 9169                 Catch::cout() << testCaseInfo.name;
 9170              if ( config.verbosity() >= Verbosity::High )
 9171                  Catch::cout() << "\t@" << testCaseInfo.lineInfo;
 9172              Catch::cout() << std::endl;
 9173          }
 9174          return matchedTests;
 9175      }
 9176  
 9177      void TagInfo::add( std::string const& spelling ) {
 9178          ++count;
 9179          spellings.insert( spelling );
 9180      }
 9181  
 9182      std::string TagInfo::all() const {
 9183          std::string out;
 9184          for( auto const& spelling : spellings )
 9185              out += "[" + spelling + "]";
 9186          return out;
 9187      }
 9188  
 9189      std::size_t listTags( Config const& config ) {
 9190          TestSpec testSpec = config.testSpec();
 9191          if( config.hasTestFilters() )
 9192              Catch::cout() << "Tags for matching test cases:\n";
 9193          else {
 9194              Catch::cout() << "All available tags:\n";
 9195          }
 9196  
 9197          std::map<std::string, TagInfo> tagCounts;
 9198  
 9199          std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
 9200          for( auto const& testCase : matchedTestCases ) {
 9201              for( auto const& tagName : testCase.getTestCaseInfo().tags ) {
 9202                  std::string lcaseTagName = toLower( tagName );
 9203                  auto countIt = tagCounts.find( lcaseTagName );
 9204                  if( countIt == tagCounts.end() )
 9205                      countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
 9206                  countIt->second.add( tagName );
 9207              }
 9208          }
 9209  
 9210          for( auto const& tagCount : tagCounts ) {
 9211              ReusableStringStream rss;
 9212              rss << "  " << std::setw(2) << tagCount.second.count << "  ";
 9213              auto str = rss.str();
 9214              auto wrapper = Column( tagCount.second.all() )
 9215                                                      .initialIndent( 0 )
 9216                                                      .indent( str.size() )
 9217                                                      .width( CATCH_CONFIG_CONSOLE_WIDTH-10 );
 9218              Catch::cout() << str << wrapper << '\n';
 9219          }
 9220          Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl;
 9221          return tagCounts.size();
 9222      }
 9223  
 9224      std::size_t listReporters() {
 9225          Catch::cout() << "Available reporters:\n";
 9226          IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
 9227          std::size_t maxNameLen = 0;
 9228          for( auto const& factoryKvp : factories )
 9229              maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() );
 9230  
 9231          for( auto const& factoryKvp : factories ) {
 9232              Catch::cout()
 9233                      << Column( factoryKvp.first + ":" )
 9234                              .indent(2)
 9235                              .width( 5+maxNameLen )
 9236                      +  Column( factoryKvp.second->getDescription() )
 9237                              .initialIndent(0)
 9238                              .indent(2)
 9239                              .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 )
 9240                      << "\n";
 9241          }
 9242          Catch::cout() << std::endl;
 9243          return factories.size();
 9244      }
 9245  
 9246      Option<std::size_t> list( std::shared_ptr<Config> const& config ) {
 9247          Option<std::size_t> listedCount;
 9248          getCurrentMutableContext().setConfig( config );
 9249          if( config->listTests() )
 9250              listedCount = listedCount.valueOr(0) + listTests( *config );
 9251          if( config->listTestNamesOnly() )
 9252              listedCount = listedCount.valueOr(0) + listTestsNamesOnly( *config );
 9253          if( config->listTags() )
 9254              listedCount = listedCount.valueOr(0) + listTags( *config );
 9255          if( config->listReporters() )
 9256              listedCount = listedCount.valueOr(0) + listReporters();
 9257          return listedCount;
 9258      }
 9259  
 9260  } // end namespace Catch
 9261  // end catch_list.cpp
 9262  // start catch_matchers.cpp
 9263  
 9264  namespace Catch {
 9265  namespace Matchers {
 9266      namespace Impl {
 9267  
 9268          std::string MatcherUntypedBase::toString() const {
 9269              if( m_cachedToString.empty() )
 9270                  m_cachedToString = describe();
 9271              return m_cachedToString;
 9272          }
 9273  
 9274          MatcherUntypedBase::~MatcherUntypedBase() = default;
 9275  
 9276      } // namespace Impl
 9277  } // namespace Matchers
 9278  
 9279  using namespace Matchers;
 9280  using Matchers::Impl::MatcherBase;
 9281  
 9282  } // namespace Catch
 9283  // end catch_matchers.cpp
 9284  // start catch_matchers_floating.cpp
 9285  
 9286  // start catch_polyfills.hpp
 9287  
 9288  namespace Catch {
 9289      bool isnan(float f);
 9290      bool isnan(double d);
 9291  }
 9292  
 9293  // end catch_polyfills.hpp
 9294  // start catch_to_string.hpp
 9295  
 9296  #include <string>
 9297  
 9298  namespace Catch {
 9299      template <typename T>
 9300      std::string to_string(T const& t) {
 9301  #if defined(CATCH_CONFIG_CPP11_TO_STRING)
 9302          return std::to_string(t);
 9303  #else
 9304          ReusableStringStream rss;
 9305          rss << t;
 9306          return rss.str();
 9307  #endif
 9308      }
 9309  } // end namespace Catch
 9310  
 9311  // end catch_to_string.hpp
 9312  #include <cstdlib>
 9313  #include <cstdint>
 9314  #include <cstring>
 9315  
 9316  namespace Catch {
 9317  namespace Matchers {
 9318  namespace Floating {
 9319  enum class FloatingPointKind : uint8_t {
 9320      Float,
 9321      Double
 9322  };
 9323  }
 9324  }
 9325  }
 9326  
 9327  namespace {
 9328  
 9329  template <typename T>
 9330  struct Converter;
 9331  
 9332  template <>
 9333  struct Converter<float> {
 9334      static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
 9335      Converter(float f) {
 9336          std::memcpy(&i, &f, sizeof(f));
 9337      }
 9338      int32_t i;
 9339  };
 9340  
 9341  template <>
 9342  struct Converter<double> {
 9343      static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
 9344      Converter(double d) {
 9345          std::memcpy(&i, &d, sizeof(d));
 9346      }
 9347      int64_t i;
 9348  };
 9349  
 9350  template <typename T>
 9351  auto convert(T t) -> Converter<T> {
 9352      return Converter<T>(t);
 9353  }
 9354  
 9355  template <typename FP>
 9356  bool almostEqualUlps(FP lhs, FP rhs, int maxUlpDiff) {
 9357      // Comparison with NaN should always be false.
 9358      // This way we can rule it out before getting into the ugly details
 9359      if (Catch::isnan(lhs) || Catch::isnan(rhs)) {
 9360          return false;
 9361      }
 9362  
 9363      auto lc = convert(lhs);
 9364      auto rc = convert(rhs);
 9365  
 9366      if ((lc.i < 0) != (rc.i < 0)) {
 9367          // Potentially we can have +0 and -0
 9368          return lhs == rhs;
 9369      }
 9370  
 9371      auto ulpDiff = std::abs(lc.i - rc.i);
 9372      return ulpDiff <= maxUlpDiff;
 9373  }
 9374  
 9375  }
 9376  
 9377  namespace Catch {
 9378  namespace Matchers {
 9379  namespace Floating {
 9380      WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
 9381          :m_target{ target }, m_margin{ margin } {
 9382          CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.'
 9383              << " Margin has to be non-negative.");
 9384      }
 9385  
 9386      // Performs equivalent check of std::fabs(lhs - rhs) <= margin
 9387      // But without the subtraction to allow for INFINITY in comparison
 9388      bool WithinAbsMatcher::match(double const& matchee) const {
 9389          return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);
 9390      }
 9391  
 9392      std::string WithinAbsMatcher::describe() const {
 9393          return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target);
 9394      }
 9395  
 9396      WithinUlpsMatcher::WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType)
 9397          :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
 9398          CATCH_ENFORCE(ulps >= 0, "Invalid ULP setting: " << ulps << '.'
 9399              << " ULPs have to be non-negative.");
 9400      }
 9401  
 9402  #if defined(__clang__)
 9403  #pragma clang diagnostic push
 9404  // Clang <3.5 reports on the default branch in the switch below
 9405  #pragma clang diagnostic ignored "-Wunreachable-code"
 9406  #endif
 9407  
 9408      bool WithinUlpsMatcher::match(double const& matchee) const {
 9409          switch (m_type) {
 9410          case FloatingPointKind::Float:
 9411              return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps);
 9412          case FloatingPointKind::Double:
 9413              return almostEqualUlps<double>(matchee, m_target, m_ulps);
 9414          default:
 9415              CATCH_INTERNAL_ERROR( "Unknown FloatingPointKind value" );
 9416          }
 9417      }
 9418  
 9419  #if defined(__clang__)
 9420  #pragma clang diagnostic pop
 9421  #endif
 9422  
 9423      std::string WithinUlpsMatcher::describe() const {
 9424          return "is within " + Catch::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : "");
 9425      }
 9426  
 9427  }// namespace Floating
 9428  
 9429  Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff) {
 9430      return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
 9431  }
 9432  
 9433  Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff) {
 9434      return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
 9435  }
 9436  
 9437  Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
 9438      return Floating::WithinAbsMatcher(target, margin);
 9439  }
 9440  
 9441  } // namespace Matchers
 9442  } // namespace Catch
 9443  
 9444  // end catch_matchers_floating.cpp
 9445  // start catch_matchers_generic.cpp
 9446  
 9447  std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) {
 9448      if (desc.empty()) {
 9449          return "matches undescribed predicate";
 9450      } else {
 9451          return "matches predicate: \"" + desc + '"';
 9452      }
 9453  }
 9454  // end catch_matchers_generic.cpp
 9455  // start catch_matchers_string.cpp
 9456  
 9457  #include <regex>
 9458  
 9459  namespace Catch {
 9460  namespace Matchers {
 9461  
 9462      namespace StdString {
 9463  
 9464          CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
 9465          :   m_caseSensitivity( caseSensitivity ),
 9466              m_str( adjustString( str ) )
 9467          {}
 9468          std::string CasedString::adjustString( std::string const& str ) const {
 9469              return m_caseSensitivity == CaseSensitive::No
 9470                     ? toLower( str )
 9471                     : str;
 9472          }
 9473          std::string CasedString::caseSensitivitySuffix() const {
 9474              return m_caseSensitivity == CaseSensitive::No
 9475                     ? " (case insensitive)"
 9476                     : std::string();
 9477          }
 9478  
 9479          StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )
 9480          : m_comparator( comparator ),
 9481            m_operation( operation ) {
 9482          }
 9483  
 9484          std::string StringMatcherBase::describe() const {
 9485              std::string description;
 9486              description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +
 9487                                          m_comparator.caseSensitivitySuffix().size());
 9488              description += m_operation;
 9489              description += ": \"";
 9490              description += m_comparator.m_str;
 9491              description += "\"";
 9492              description += m_comparator.caseSensitivitySuffix();
 9493              return description;
 9494          }
 9495  
 9496          EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {}
 9497  
 9498          bool EqualsMatcher::match( std::string const& source ) const {
 9499              return m_comparator.adjustString( source ) == m_comparator.m_str;
 9500          }
 9501  
 9502          ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {}
 9503  
 9504          bool ContainsMatcher::match( std::string const& source ) const {
 9505              return contains( m_comparator.adjustString( source ), m_comparator.m_str );
 9506          }
 9507  
 9508          StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {}
 9509  
 9510          bool StartsWithMatcher::match( std::string const& source ) const {
 9511              return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );
 9512          }
 9513  
 9514          EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {}
 9515  
 9516          bool EndsWithMatcher::match( std::string const& source ) const {
 9517              return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );
 9518          }
 9519  
 9520          RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity): m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {}
 9521  
 9522          bool RegexMatcher::match(std::string const& matchee) const {
 9523              auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway
 9524              if (m_caseSensitivity == CaseSensitive::Choice::No) {
 9525                  flags |= std::regex::icase;
 9526              }
 9527              auto reg = std::regex(m_regex, flags);
 9528              return std::regex_match(matchee, reg);
 9529          }
 9530  
 9531          std::string RegexMatcher::describe() const {
 9532              return "matches " + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? " case sensitively" : " case insensitively");
 9533          }
 9534  
 9535      } // namespace StdString
 9536  
 9537      StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
 9538          return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );
 9539      }
 9540      StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
 9541          return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );
 9542      }
 9543      StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
 9544          return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );
 9545      }
 9546      StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
 9547          return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );
 9548      }
 9549  
 9550      StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity) {
 9551          return StdString::RegexMatcher(regex, caseSensitivity);
 9552      }
 9553  
 9554  } // namespace Matchers
 9555  } // namespace Catch
 9556  // end catch_matchers_string.cpp
 9557  // start catch_message.cpp
 9558  
 9559  // start catch_uncaught_exceptions.h
 9560  
 9561  namespace Catch {
 9562      bool uncaught_exceptions();
 9563  } // end namespace Catch
 9564  
 9565  // end catch_uncaught_exceptions.h
 9566  #include <cassert>
 9567  #include <stack>
 9568  
 9569  namespace Catch {
 9570  
 9571      MessageInfo::MessageInfo(   StringRef const& _macroName,
 9572                                  SourceLineInfo const& _lineInfo,
 9573                                  ResultWas::OfType _type )
 9574      :   macroName( _macroName ),
 9575          lineInfo( _lineInfo ),
 9576          type( _type ),
 9577          sequence( ++globalCount )
 9578      {}
 9579  
 9580      bool MessageInfo::operator==( MessageInfo const& other ) const {
 9581          return sequence == other.sequence;
 9582      }
 9583  
 9584      bool MessageInfo::operator<( MessageInfo const& other ) const {
 9585          return sequence < other.sequence;
 9586      }
 9587  
 9588      // This may need protecting if threading support is added
 9589      unsigned int MessageInfo::globalCount = 0;
 9590  
 9591      ////////////////////////////////////////////////////////////////////////////
 9592  
 9593      Catch::MessageBuilder::MessageBuilder( StringRef const& macroName,
 9594                                             SourceLineInfo const& lineInfo,
 9595                                             ResultWas::OfType type )
 9596          :m_info(macroName, lineInfo, type) {}
 9597  
 9598      ////////////////////////////////////////////////////////////////////////////
 9599  
 9600      ScopedMessage::ScopedMessage( MessageBuilder const& builder )
 9601      : m_info( builder.m_info ), m_moved()
 9602      {
 9603          m_info.message = builder.m_stream.str();
 9604          getResultCapture().pushScopedMessage( m_info );
 9605      }
 9606  
 9607      ScopedMessage::ScopedMessage( ScopedMessage&& old )
 9608      : m_info( old.m_info ), m_moved()
 9609      {
 9610          old.m_moved = true;
 9611      }
 9612  
 9613      ScopedMessage::~ScopedMessage() {
 9614          if ( !uncaught_exceptions() && !m_moved ){
 9615              getResultCapture().popScopedMessage(m_info);
 9616          }
 9617      }
 9618  
 9619      Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {
 9620          auto trimmed = [&] (size_t start, size_t end) {
 9621              while (names[start] == ',' || isspace(names[start])) {
 9622                  ++start;
 9623              }
 9624              while (names[end] == ',' || isspace(names[end])) {
 9625                  --end;
 9626              }
 9627              return names.substr(start, end - start + 1);
 9628          };
 9629  
 9630          size_t start = 0;
 9631          std::stack<char> openings;
 9632          for (size_t pos = 0; pos < names.size(); ++pos) {
 9633              char c = names[pos];
 9634              switch (c) {
 9635              case '[':
 9636              case '{':
 9637              case '(':
 9638              // It is basically impossible to disambiguate between
 9639              // comparison and start of template args in this context
 9640  //            case '<':
 9641                  openings.push(c);
 9642                  break;
 9643              case ']':
 9644              case '}':
 9645              case ')':
 9646  //           case '>':
 9647                  openings.pop();
 9648                  break;
 9649              case ',':
 9650                  if (start != pos && openings.size() == 0) {
 9651                      m_messages.emplace_back(macroName, lineInfo, resultType);
 9652                      m_messages.back().message = trimmed(start, pos);
 9653                      m_messages.back().message += " := ";
 9654                      start = pos;
 9655                  }
 9656              }
 9657          }
 9658          assert(openings.size() == 0 && "Mismatched openings");
 9659          m_messages.emplace_back(macroName, lineInfo, resultType);
 9660          m_messages.back().message = trimmed(start, names.size() - 1);
 9661          m_messages.back().message += " := ";
 9662      }
 9663      Capturer::~Capturer() {
 9664          if ( !uncaught_exceptions() ){
 9665              assert( m_captured == m_messages.size() );
 9666              for( size_t i = 0; i < m_captured; ++i  )
 9667                  m_resultCapture.popScopedMessage( m_messages[i] );
 9668          }
 9669      }
 9670  
 9671      void Capturer::captureValue( size_t index, std::string const& value ) {
 9672          assert( index < m_messages.size() );
 9673          m_messages[index].message += value;
 9674          m_resultCapture.pushScopedMessage( m_messages[index] );
 9675          m_captured++;
 9676      }
 9677  
 9678  } // end namespace Catch
 9679  // end catch_message.cpp
 9680  // start catch_output_redirect.cpp
 9681  
 9682  // start catch_output_redirect.h
 9683  #ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
 9684  #define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
 9685  
 9686  #include <cstdio>
 9687  #include <iosfwd>
 9688  #include <string>
 9689  
 9690  namespace Catch {
 9691  
 9692      class RedirectedStream {
 9693          std::ostream& m_originalStream;
 9694          std::ostream& m_redirectionStream;
 9695          std::streambuf* m_prevBuf;
 9696  
 9697      public:
 9698          RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream );
 9699          ~RedirectedStream();
 9700      };
 9701  
 9702      class RedirectedStdOut {
 9703          ReusableStringStream m_rss;
 9704          RedirectedStream m_cout;
 9705      public:
 9706          RedirectedStdOut();
 9707          auto str() const -> std::string;
 9708      };
 9709  
 9710      // StdErr has two constituent streams in C++, std::cerr and std::clog
 9711      // This means that we need to redirect 2 streams into 1 to keep proper
 9712      // order of writes
 9713      class RedirectedStdErr {
 9714          ReusableStringStream m_rss;
 9715          RedirectedStream m_cerr;
 9716          RedirectedStream m_clog;
 9717      public:
 9718          RedirectedStdErr();
 9719          auto str() const -> std::string;
 9720      };
 9721  
 9722      class RedirectedStreams {
 9723      public:
 9724          RedirectedStreams(RedirectedStreams const&) = delete;
 9725          RedirectedStreams& operator=(RedirectedStreams const&) = delete;
 9726          RedirectedStreams(RedirectedStreams&&) = delete;
 9727          RedirectedStreams& operator=(RedirectedStreams&&) = delete;
 9728  
 9729          RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr);
 9730          ~RedirectedStreams();
 9731      private:
 9732          std::string& m_redirectedCout;
 9733          std::string& m_redirectedCerr;
 9734          RedirectedStdOut m_redirectedStdOut;
 9735          RedirectedStdErr m_redirectedStdErr;
 9736      };
 9737  
 9738  #if defined(CATCH_CONFIG_NEW_CAPTURE)
 9739  
 9740      // Windows's implementation of std::tmpfile is terrible (it tries
 9741      // to create a file inside system folder, thus requiring elevated
 9742      // privileges for the binary), so we have to use tmpnam(_s) and
 9743      // create the file ourselves there.
 9744      class TempFile {
 9745      public:
 9746          TempFile(TempFile const&) = delete;
 9747          TempFile& operator=(TempFile const&) = delete;
 9748          TempFile(TempFile&&) = delete;
 9749          TempFile& operator=(TempFile&&) = delete;
 9750  
 9751          TempFile();
 9752          ~TempFile();
 9753  
 9754          std::FILE* getFile();
 9755          std::string getContents();
 9756  
 9757      private:
 9758          std::FILE* m_file = nullptr;
 9759      #if defined(_MSC_VER)
 9760          char m_buffer[L_tmpnam] = { 0 };
 9761      #endif
 9762      };
 9763  
 9764      class OutputRedirect {
 9765      public:
 9766          OutputRedirect(OutputRedirect const&) = delete;
 9767          OutputRedirect& operator=(OutputRedirect const&) = delete;
 9768          OutputRedirect(OutputRedirect&&) = delete;
 9769          OutputRedirect& operator=(OutputRedirect&&) = delete;
 9770  
 9771          OutputRedirect(std::string& stdout_dest, std::string& stderr_dest);
 9772          ~OutputRedirect();
 9773  
 9774      private:
 9775          int m_originalStdout = -1;
 9776          int m_originalStderr = -1;
 9777          TempFile m_stdoutFile;
 9778          TempFile m_stderrFile;
 9779          std::string& m_stdoutDest;
 9780          std::string& m_stderrDest;
 9781      };
 9782  
 9783  #endif
 9784  
 9785  } // end namespace Catch
 9786  
 9787  #endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
 9788  // end catch_output_redirect.h
 9789  #include <cstdio>
 9790  #include <cstring>
 9791  #include <fstream>
 9792  #include <sstream>
 9793  #include <stdexcept>
 9794  
 9795  #if defined(CATCH_CONFIG_NEW_CAPTURE)
 9796      #if defined(_MSC_VER)
 9797      #include <io.h>      //_dup and _dup2
 9798      #define dup _dup
 9799      #define dup2 _dup2
 9800      #define fileno _fileno
 9801      #else
 9802      #include <unistd.h>  // dup and dup2
 9803      #endif
 9804  #endif
 9805  
 9806  namespace Catch {
 9807  
 9808      RedirectedStream::RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream )
 9809      :   m_originalStream( originalStream ),
 9810          m_redirectionStream( redirectionStream ),
 9811          m_prevBuf( m_originalStream.rdbuf() )
 9812      {
 9813          m_originalStream.rdbuf( m_redirectionStream.rdbuf() );
 9814      }
 9815  
 9816      RedirectedStream::~RedirectedStream() {
 9817          m_originalStream.rdbuf( m_prevBuf );
 9818      }
 9819  
 9820      RedirectedStdOut::RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {}
 9821      auto RedirectedStdOut::str() const -> std::string { return m_rss.str(); }
 9822  
 9823      RedirectedStdErr::RedirectedStdErr()
 9824      :   m_cerr( Catch::cerr(), m_rss.get() ),
 9825          m_clog( Catch::clog(), m_rss.get() )
 9826      {}
 9827      auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }
 9828  
 9829      RedirectedStreams::RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr)
 9830      :   m_redirectedCout(redirectedCout),
 9831          m_redirectedCerr(redirectedCerr)
 9832      {}
 9833  
 9834      RedirectedStreams::~RedirectedStreams() {
 9835          m_redirectedCout += m_redirectedStdOut.str();
 9836          m_redirectedCerr += m_redirectedStdErr.str();
 9837      }
 9838  
 9839  #if defined(CATCH_CONFIG_NEW_CAPTURE)
 9840  
 9841  #if defined(_MSC_VER)
 9842      TempFile::TempFile() {
 9843          if (tmpnam_s(m_buffer)) {
 9844              CATCH_RUNTIME_ERROR("Could not get a temp filename");
 9845          }
 9846          if (fopen_s(&m_file, m_buffer, "w")) {
 9847              char buffer[100];
 9848              if (strerror_s(buffer, errno)) {
 9849                  CATCH_RUNTIME_ERROR("Could not translate errno to a string");
 9850              }
 9851              CATCH_RUNTIME_ERROR("Could not open the temp file: '" << m_buffer << "' because: " << buffer);
 9852          }
 9853      }
 9854  #else
 9855      TempFile::TempFile() {
 9856          m_file = std::tmpfile();
 9857          if (!m_file) {
 9858              CATCH_RUNTIME_ERROR("Could not create a temp file.");
 9859          }
 9860      }
 9861  
 9862  #endif
 9863  
 9864      TempFile::~TempFile() {
 9865           // TBD: What to do about errors here?
 9866           std::fclose(m_file);
 9867           // We manually create the file on Windows only, on Linux
 9868           // it will be autodeleted
 9869  #if defined(_MSC_VER)
 9870           std::remove(m_buffer);
 9871  #endif
 9872      }
 9873  
 9874      FILE* TempFile::getFile() {
 9875          return m_file;
 9876      }
 9877  
 9878      std::string TempFile::getContents() {
 9879          std::stringstream sstr;
 9880          char buffer[100] = {};
 9881          std::rewind(m_file);
 9882          while (std::fgets(buffer, sizeof(buffer), m_file)) {
 9883              sstr << buffer;
 9884          }
 9885          return sstr.str();
 9886      }
 9887  
 9888      OutputRedirect::OutputRedirect(std::string& stdout_dest, std::string& stderr_dest) :
 9889          m_originalStdout(dup(1)),
 9890          m_originalStderr(dup(2)),
 9891          m_stdoutDest(stdout_dest),
 9892          m_stderrDest(stderr_dest) {
 9893          dup2(fileno(m_stdoutFile.getFile()), 1);
 9894          dup2(fileno(m_stderrFile.getFile()), 2);
 9895      }
 9896  
 9897      OutputRedirect::~OutputRedirect() {
 9898          Catch::cout() << std::flush;
 9899          fflush(stdout);
 9900          // Since we support overriding these streams, we flush cerr
 9901          // even though std::cerr is unbuffered
 9902          Catch::cerr() << std::flush;
 9903          Catch::clog() << std::flush;
 9904          fflush(stderr);
 9905  
 9906          dup2(m_originalStdout, 1);
 9907          dup2(m_originalStderr, 2);
 9908  
 9909          m_stdoutDest += m_stdoutFile.getContents();
 9910          m_stderrDest += m_stderrFile.getContents();
 9911      }
 9912  
 9913  #endif // CATCH_CONFIG_NEW_CAPTURE
 9914  
 9915  } // namespace Catch
 9916  
 9917  #if defined(CATCH_CONFIG_NEW_CAPTURE)
 9918      #if defined(_MSC_VER)
 9919      #undef dup
 9920      #undef dup2
 9921      #undef fileno
 9922      #endif
 9923  #endif
 9924  // end catch_output_redirect.cpp
 9925  // start catch_polyfills.cpp
 9926  
 9927  #include <cmath>
 9928  
 9929  namespace Catch {
 9930  
 9931  #if !defined(CATCH_CONFIG_POLYFILL_ISNAN)
 9932      bool isnan(float f) {
 9933          return std::isnan(f);
 9934      }
 9935      bool isnan(double d) {
 9936          return std::isnan(d);
 9937      }
 9938  #else
 9939      // For now we only use this for embarcadero
 9940      bool isnan(float f) {
 9941          return std::_isnan(f);
 9942      }
 9943      bool isnan(double d) {
 9944          return std::_isnan(d);
 9945      }
 9946  #endif
 9947  
 9948  } // end namespace Catch
 9949  // end catch_polyfills.cpp
 9950  // start catch_random_number_generator.cpp
 9951  
 9952  namespace Catch {
 9953  
 9954      std::mt19937& rng() {
 9955          static std::mt19937 s_rng;
 9956          return s_rng;
 9957      }
 9958  
 9959      void seedRng( IConfig const& config ) {
 9960          if( config.rngSeed() != 0 ) {
 9961              std::srand( config.rngSeed() );
 9962              rng().seed( config.rngSeed() );
 9963          }
 9964      }
 9965  
 9966      unsigned int rngSeed() {
 9967          return getCurrentContext().getConfig()->rngSeed();
 9968      }
 9969  }
 9970  // end catch_random_number_generator.cpp
 9971  // start catch_registry_hub.cpp
 9972  
 9973  // start catch_test_case_registry_impl.h
 9974  
 9975  #include <vector>
 9976  #include <set>
 9977  #include <algorithm>
 9978  #include <ios>
 9979  
 9980  namespace Catch {
 9981  
 9982      class TestCase;
 9983      struct IConfig;
 9984  
 9985      std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases );
 9986      bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
 9987  
 9988      void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions );
 9989  
 9990      std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
 9991      std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
 9992  
 9993      class TestRegistry : public ITestCaseRegistry {
 9994      public:
 9995          virtual ~TestRegistry() = default;
 9996  
 9997          virtual void registerTest( TestCase const& testCase );
 9998  
 9999          std::vector<TestCase> const& getAllTests() const override;
10000          std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const override;
10001  
10002      private:
10003          std::vector<TestCase> m_functions;
10004          mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;
10005          mutable std::vector<TestCase> m_sortedFunctions;
10006          std::size_t m_unnamedCount = 0;
10007          std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
10008      };
10009  
10010      ///////////////////////////////////////////////////////////////////////////
10011  
10012      class TestInvokerAsFunction : public ITestInvoker {
10013          void(*m_testAsFunction)();
10014      public:
10015          TestInvokerAsFunction( void(*testAsFunction)() ) noexcept;
10016  
10017          void invoke() const override;
10018      };
10019  
10020      std::string extractClassName( StringRef const& classOrQualifiedMethodName );
10021  
10022      ///////////////////////////////////////////////////////////////////////////
10023  
10024  } // end namespace Catch
10025  
10026  // end catch_test_case_registry_impl.h
10027  // start catch_reporter_registry.h
10028  
10029  #include <map>
10030  
10031  namespace Catch {
10032  
10033      class ReporterRegistry : public IReporterRegistry {
10034  
10035      public:
10036  
10037          ~ReporterRegistry() override;
10038  
10039          IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const override;
10040  
10041          void registerReporter( std::string const& name, IReporterFactoryPtr const& factory );
10042          void registerListener( IReporterFactoryPtr const& factory );
10043  
10044          FactoryMap const& getFactories() const override;
10045          Listeners const& getListeners() const override;
10046  
10047      private:
10048          FactoryMap m_factories;
10049          Listeners m_listeners;
10050      };
10051  }
10052  
10053  // end catch_reporter_registry.h
10054  // start catch_tag_alias_registry.h
10055  
10056  // start catch_tag_alias.h
10057  
10058  #include <string>
10059  
10060  namespace Catch {
10061  
10062      struct TagAlias {
10063          TagAlias(std::string const& _tag, SourceLineInfo _lineInfo);
10064  
10065          std::string tag;
10066          SourceLineInfo lineInfo;
10067      };
10068  
10069  } // end namespace Catch
10070  
10071  // end catch_tag_alias.h
10072  #include <map>
10073  
10074  namespace Catch {
10075  
10076      class TagAliasRegistry : public ITagAliasRegistry {
10077      public:
10078          ~TagAliasRegistry() override;
10079          TagAlias const* find( std::string const& alias ) const override;
10080          std::string expandAliases( std::string const& unexpandedTestSpec ) const override;
10081          void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
10082  
10083      private:
10084          std::map<std::string, TagAlias> m_registry;
10085      };
10086  
10087  } // end namespace Catch
10088  
10089  // end catch_tag_alias_registry.h
10090  // start catch_startup_exception_registry.h
10091  
10092  #include <vector>
10093  #include <exception>
10094  
10095  namespace Catch {
10096  
10097      class StartupExceptionRegistry {
10098      public:
10099          void add(std::exception_ptr const& exception) noexcept;
10100          std::vector<std::exception_ptr> const& getExceptions() const noexcept;
10101      private:
10102          std::vector<std::exception_ptr> m_exceptions;
10103      };
10104  
10105  } // end namespace Catch
10106  
10107  // end catch_startup_exception_registry.h
10108  // start catch_singletons.hpp
10109  
10110  namespace Catch {
10111  
10112      struct ISingleton {
10113          virtual ~ISingleton();
10114      };
10115  
10116      void addSingleton( ISingleton* singleton );
10117      void cleanupSingletons();
10118  
10119      template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>
10120      class Singleton : SingletonImplT, public ISingleton {
10121  
10122          static auto getInternal() -> Singleton* {
10123              static Singleton* s_instance = nullptr;
10124              if( !s_instance ) {
10125                  s_instance = new Singleton;
10126                  addSingleton( s_instance );
10127              }
10128              return s_instance;
10129          }
10130  
10131      public:
10132          static auto get() -> InterfaceT const& {
10133              return *getInternal();
10134          }
10135          static auto getMutable() -> MutableInterfaceT& {
10136              return *getInternal();
10137          }
10138      };
10139  
10140  } // namespace Catch
10141  
10142  // end catch_singletons.hpp
10143  namespace Catch {
10144  
10145      namespace {
10146  
10147          class RegistryHub : public IRegistryHub, public IMutableRegistryHub,
10148                              private NonCopyable {
10149  
10150          public: // IRegistryHub
10151              RegistryHub() = default;
10152              IReporterRegistry const& getReporterRegistry() const override {
10153                  return m_reporterRegistry;
10154              }
10155              ITestCaseRegistry const& getTestCaseRegistry() const override {
10156                  return m_testCaseRegistry;
10157              }
10158              IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override {
10159                  return m_exceptionTranslatorRegistry;
10160              }
10161              ITagAliasRegistry const& getTagAliasRegistry() const override {
10162                  return m_tagAliasRegistry;
10163              }
10164              StartupExceptionRegistry const& getStartupExceptionRegistry() const override {
10165                  return m_exceptionRegistry;
10166              }
10167  
10168          public: // IMutableRegistryHub
10169              void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) override {
10170                  m_reporterRegistry.registerReporter( name, factory );
10171              }
10172              void registerListener( IReporterFactoryPtr const& factory ) override {
10173                  m_reporterRegistry.registerListener( factory );
10174              }
10175              void registerTest( TestCase const& testInfo ) override {
10176                  m_testCaseRegistry.registerTest( testInfo );
10177              }
10178              void registerTranslator( const IExceptionTranslator* translator ) override {
10179                  m_exceptionTranslatorRegistry.registerTranslator( translator );
10180              }
10181              void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override {
10182                  m_tagAliasRegistry.add( alias, tag, lineInfo );
10183              }
10184              void registerStartupException() noexcept override {
10185                  m_exceptionRegistry.add(std::current_exception());
10186              }
10187  
10188          private:
10189              TestRegistry m_testCaseRegistry;
10190              ReporterRegistry m_reporterRegistry;
10191              ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
10192              TagAliasRegistry m_tagAliasRegistry;
10193              StartupExceptionRegistry m_exceptionRegistry;
10194          };
10195      }
10196  
10197      using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>;
10198  
10199      IRegistryHub const& getRegistryHub() {
10200          return RegistryHubSingleton::get();
10201      }
10202      IMutableRegistryHub& getMutableRegistryHub() {
10203          return RegistryHubSingleton::getMutable();
10204      }
10205      void cleanUp() {
10206          cleanupSingletons();
10207          cleanUpContext();
10208      }
10209      std::string translateActiveException() {
10210          return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
10211      }
10212  
10213  } // end namespace Catch
10214  // end catch_registry_hub.cpp
10215  // start catch_reporter_registry.cpp
10216  
10217  namespace Catch {
10218  
10219      ReporterRegistry::~ReporterRegistry() = default;
10220  
10221      IStreamingReporterPtr ReporterRegistry::create( std::string const& name, IConfigPtr const& config ) const {
10222          auto it =  m_factories.find( name );
10223          if( it == m_factories.end() )
10224              return nullptr;
10225          return it->second->create( ReporterConfig( config ) );
10226      }
10227  
10228      void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) {
10229          m_factories.emplace(name, factory);
10230      }
10231      void ReporterRegistry::registerListener( IReporterFactoryPtr const& factory ) {
10232          m_listeners.push_back( factory );
10233      }
10234  
10235      IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const {
10236          return m_factories;
10237      }
10238      IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const {
10239          return m_listeners;
10240      }
10241  
10242  }
10243  // end catch_reporter_registry.cpp
10244  // start catch_result_type.cpp
10245  
10246  namespace Catch {
10247  
10248      bool isOk( ResultWas::OfType resultType ) {
10249          return ( resultType & ResultWas::FailureBit ) == 0;
10250      }
10251      bool isJustInfo( int flags ) {
10252          return flags == ResultWas::Info;
10253      }
10254  
10255      ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
10256          return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
10257      }
10258  
10259      bool shouldContinueOnFailure( int flags )    { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
10260      bool shouldSuppressFailure( int flags )      { return ( flags & ResultDisposition::SuppressFail ) != 0; }
10261  
10262  } // end namespace Catch
10263  // end catch_result_type.cpp
10264  // start catch_run_context.cpp
10265  
10266  #include <cassert>
10267  #include <algorithm>
10268  #include <sstream>
10269  
10270  namespace Catch {
10271  
10272      namespace Generators {
10273          struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {
10274              GeneratorBasePtr m_generator;
10275  
10276              GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
10277              :   TrackerBase( nameAndLocation, ctx, parent )
10278              {}
10279              ~GeneratorTracker();
10280  
10281              static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {
10282                  std::shared_ptr<GeneratorTracker> tracker;
10283  
10284                  ITracker& currentTracker = ctx.currentTracker();
10285                  if( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
10286                      assert( childTracker );
10287                      assert( childTracker->isGeneratorTracker() );
10288                      tracker = std::static_pointer_cast<GeneratorTracker>( childTracker );
10289                  }
10290                  else {
10291                      tracker = std::make_shared<GeneratorTracker>( nameAndLocation, ctx, &currentTracker );
10292                      currentTracker.addChild( tracker );
10293                  }
10294  
10295                  if( !ctx.completedCycle() && !tracker->isComplete() ) {
10296                      tracker->open();
10297                  }
10298  
10299                  return *tracker;
10300              }
10301  
10302              // TrackerBase interface
10303              bool isGeneratorTracker() const override { return true; }
10304              auto hasGenerator() const -> bool override {
10305                  return !!m_generator;
10306              }
10307              void close() override {
10308                  TrackerBase::close();
10309                  // Generator interface only finds out if it has another item on atual move
10310                  if (m_runState == CompletedSuccessfully && m_generator->next()) {
10311                      m_children.clear();
10312                      m_runState = Executing;
10313                  }
10314              }
10315  
10316              // IGeneratorTracker interface
10317              auto getGenerator() const -> GeneratorBasePtr const& override {
10318                  return m_generator;
10319              }
10320              void setGenerator( GeneratorBasePtr&& generator ) override {
10321                  m_generator = std::move( generator );
10322              }
10323          };
10324          GeneratorTracker::~GeneratorTracker() {}
10325      }
10326  
10327      RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
10328      :   m_runInfo(_config->name()),
10329          m_context(getCurrentMutableContext()),
10330          m_config(_config),
10331          m_reporter(std::move(reporter)),
10332          m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
10333          m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )
10334      {
10335          m_context.setRunner(this);
10336          m_context.setConfig(m_config);
10337          m_context.setResultCapture(this);
10338          m_reporter->testRunStarting(m_runInfo);
10339      }
10340  
10341      RunContext::~RunContext() {
10342          m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
10343      }
10344  
10345      void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) {
10346          m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));
10347      }
10348  
10349      void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) {
10350          m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));
10351      }
10352  
10353      Totals RunContext::runTest(TestCase const& testCase) {
10354          Totals prevTotals = m_totals;
10355  
10356          std::string redirectedCout;
10357          std::string redirectedCerr;
10358  
10359          auto const& testInfo = testCase.getTestCaseInfo();
10360  
10361          m_reporter->testCaseStarting(testInfo);
10362  
10363          m_activeTestCase = &testCase;
10364  
10365          ITracker& rootTracker = m_trackerContext.startRun();
10366          assert(rootTracker.isSectionTracker());
10367          static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun());
10368          do {
10369              m_trackerContext.startCycle();
10370              m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));
10371              runCurrentTest(redirectedCout, redirectedCerr);
10372          } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());
10373  
10374          Totals deltaTotals = m_totals.delta(prevTotals);
10375          if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) {
10376              deltaTotals.assertions.failed++;
10377              deltaTotals.testCases.passed--;
10378              deltaTotals.testCases.failed++;
10379          }
10380          m_totals.testCases += deltaTotals.testCases;
10381          m_reporter->testCaseEnded(TestCaseStats(testInfo,
10382                                    deltaTotals,
10383                                    redirectedCout,
10384                                    redirectedCerr,
10385                                    aborting()));
10386  
10387          m_activeTestCase = nullptr;
10388          m_testCaseTracker = nullptr;
10389  
10390          return deltaTotals;
10391      }
10392  
10393      IConfigPtr RunContext::config() const {
10394          return m_config;
10395      }
10396  
10397      IStreamingReporter& RunContext::reporter() const {
10398          return *m_reporter;
10399      }
10400  
10401      void RunContext::assertionEnded(AssertionResult const & result) {
10402          if (result.getResultType() == ResultWas::Ok) {
10403              m_totals.assertions.passed++;
10404              m_lastAssertionPassed = true;
10405          } else if (!result.isOk()) {
10406              m_lastAssertionPassed = false;
10407              if( m_activeTestCase->getTestCaseInfo().okToFail() )
10408                  m_totals.assertions.failedButOk++;
10409              else
10410                  m_totals.assertions.failed++;
10411          }
10412          else {
10413              m_lastAssertionPassed = true;
10414          }
10415  
10416          // We have no use for the return value (whether messages should be cleared), because messages were made scoped
10417          // and should be let to clear themselves out.
10418          static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
10419  
10420          if (result.getResultType() != ResultWas::Warning)
10421              m_messageScopes.clear();
10422  
10423          // Reset working state
10424          resetAssertionInfo();
10425          m_lastResult = result;
10426      }
10427      void RunContext::resetAssertionInfo() {
10428          m_lastAssertionInfo.macroName = StringRef();
10429          m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
10430      }
10431  
10432      bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) {
10433          ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));
10434          if (!sectionTracker.isOpen())
10435              return false;
10436          m_activeSections.push_back(&sectionTracker);
10437  
10438          m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
10439  
10440          m_reporter->sectionStarting(sectionInfo);
10441  
10442          assertions = m_totals.assertions;
10443  
10444          return true;
10445      }
10446      auto RunContext::acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
10447          using namespace Generators;
10448          GeneratorTracker& tracker = GeneratorTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( "generator", lineInfo ) );
10449          assert( tracker.isOpen() );
10450          m_lastAssertionInfo.lineInfo = lineInfo;
10451          return tracker;
10452      }
10453  
10454      bool RunContext::testForMissingAssertions(Counts& assertions) {
10455          if (assertions.total() != 0)
10456              return false;
10457          if (!m_config->warnAboutMissingAssertions())
10458              return false;
10459          if (m_trackerContext.currentTracker().hasChildren())
10460              return false;
10461          m_totals.assertions.failed++;
10462          assertions.failed++;
10463          return true;
10464      }
10465  
10466      void RunContext::sectionEnded(SectionEndInfo const & endInfo) {
10467          Counts assertions = m_totals.assertions - endInfo.prevAssertions;
10468          bool missingAssertions = testForMissingAssertions(assertions);
10469  
10470          if (!m_activeSections.empty()) {
10471              m_activeSections.back()->close();
10472              m_activeSections.pop_back();
10473          }
10474  
10475          m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
10476          m_messages.clear();
10477          m_messageScopes.clear();
10478      }
10479  
10480      void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {
10481          if (m_unfinishedSections.empty())
10482              m_activeSections.back()->fail();
10483          else
10484              m_activeSections.back()->close();
10485          m_activeSections.pop_back();
10486  
10487          m_unfinishedSections.push_back(endInfo);
10488      }
10489      void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {
10490          m_reporter->benchmarkStarting( info );
10491      }
10492      void RunContext::benchmarkEnded( BenchmarkStats const& stats ) {
10493          m_reporter->benchmarkEnded( stats );
10494      }
10495  
10496      void RunContext::pushScopedMessage(MessageInfo const & message) {
10497          m_messages.push_back(message);
10498      }
10499  
10500      void RunContext::popScopedMessage(MessageInfo const & message) {
10501          m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
10502      }
10503  
10504      void RunContext::emplaceUnscopedMessage( MessageBuilder const& builder ) {
10505          m_messageScopes.emplace_back( builder );
10506      }
10507  
10508      std::string RunContext::getCurrentTestName() const {
10509          return m_activeTestCase
10510              ? m_activeTestCase->getTestCaseInfo().name
10511              : std::string();
10512      }
10513  
10514      const AssertionResult * RunContext::getLastResult() const {
10515          return &(*m_lastResult);
10516      }
10517  
10518      void RunContext::exceptionEarlyReported() {
10519          m_shouldReportUnexpected = false;
10520      }
10521  
10522      void RunContext::handleFatalErrorCondition( StringRef message ) {
10523          // First notify reporter that bad things happened
10524          m_reporter->fatalErrorEncountered(message);
10525  
10526          // Don't rebuild the result -- the stringification itself can cause more fatal errors
10527          // Instead, fake a result data.
10528          AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );
10529          tempResult.message = message;
10530          AssertionResult result(m_lastAssertionInfo, tempResult);
10531  
10532          assertionEnded(result);
10533  
10534          handleUnfinishedSections();
10535  
10536          // Recreate section for test case (as we will lose the one that was in scope)
10537          auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
10538          SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
10539  
10540          Counts assertions;
10541          assertions.failed = 1;
10542          SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);
10543          m_reporter->sectionEnded(testCaseSectionStats);
10544  
10545          auto const& testInfo = m_activeTestCase->getTestCaseInfo();
10546  
10547          Totals deltaTotals;
10548          deltaTotals.testCases.failed = 1;
10549          deltaTotals.assertions.failed = 1;
10550          m_reporter->testCaseEnded(TestCaseStats(testInfo,
10551                                    deltaTotals,
10552                                    std::string(),
10553                                    std::string(),
10554                                    false));
10555          m_totals.testCases.failed++;
10556          testGroupEnded(std::string(), m_totals, 1, 1);
10557          m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
10558      }
10559  
10560      bool RunContext::lastAssertionPassed() {
10561           return m_lastAssertionPassed;
10562      }
10563  
10564      void RunContext::assertionPassed() {
10565          m_lastAssertionPassed = true;
10566          ++m_totals.assertions.passed;
10567          resetAssertionInfo();
10568          m_messageScopes.clear();
10569      }
10570  
10571      bool RunContext::aborting() const {
10572          return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter());
10573      }
10574  
10575      void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
10576          auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
10577          SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
10578          m_reporter->sectionStarting(testCaseSection);
10579          Counts prevAssertions = m_totals.assertions;
10580          double duration = 0;
10581          m_shouldReportUnexpected = true;
10582          m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal };
10583  
10584          seedRng(*m_config);
10585  
10586          Timer timer;
10587          CATCH_TRY {
10588              if (m_reporter->getPreferences().shouldRedirectStdOut) {
10589  #if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
10590                  RedirectedStreams redirectedStreams(redirectedCout, redirectedCerr);
10591  
10592                  timer.start();
10593                  invokeActiveTestCase();
10594  #else
10595                  OutputRedirect r(redirectedCout, redirectedCerr);
10596                  timer.start();
10597                  invokeActiveTestCase();
10598  #endif
10599              } else {
10600                  timer.start();
10601                  invokeActiveTestCase();
10602              }
10603              duration = timer.getElapsedSeconds();
10604          } CATCH_CATCH_ANON (TestFailureException&) {
10605              // This just means the test was aborted due to failure
10606          } CATCH_CATCH_ALL {
10607              // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
10608              // are reported without translation at the point of origin.
10609              if( m_shouldReportUnexpected ) {
10610                  AssertionReaction dummyReaction;
10611                  handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction );
10612              }
10613          }
10614          Counts assertions = m_totals.assertions - prevAssertions;
10615          bool missingAssertions = testForMissingAssertions(assertions);
10616  
10617          m_testCaseTracker->close();
10618          handleUnfinishedSections();
10619          m_messages.clear();
10620          m_messageScopes.clear();
10621  
10622          SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
10623          m_reporter->sectionEnded(testCaseSectionStats);
10624      }
10625  
10626      void RunContext::invokeActiveTestCase() {
10627          FatalConditionHandler fatalConditionHandler; // Handle signals
10628          m_activeTestCase->invoke();
10629          fatalConditionHandler.reset();
10630      }
10631  
10632      void RunContext::handleUnfinishedSections() {
10633          // If sections ended prematurely due to an exception we stored their
10634          // infos here so we can tear them down outside the unwind process.
10635          for (auto it = m_unfinishedSections.rbegin(),
10636               itEnd = m_unfinishedSections.rend();
10637               it != itEnd;
10638               ++it)
10639              sectionEnded(*it);
10640          m_unfinishedSections.clear();
10641      }
10642  
10643      void RunContext::handleExpr(
10644          AssertionInfo const& info,
10645          ITransientExpression const& expr,
10646          AssertionReaction& reaction
10647      ) {
10648          m_reporter->assertionStarting( info );
10649  
10650          bool negated = isFalseTest( info.resultDisposition );
10651          bool result = expr.getResult() != negated;
10652  
10653          if( result ) {
10654              if (!m_includeSuccessfulResults) {
10655                  assertionPassed();
10656              }
10657              else {
10658                  reportExpr(info, ResultWas::Ok, &expr, negated);
10659              }
10660          }
10661          else {
10662              reportExpr(info, ResultWas::ExpressionFailed, &expr, negated );
10663              populateReaction( reaction );
10664          }
10665      }
10666      void RunContext::reportExpr(
10667              AssertionInfo const &info,
10668              ResultWas::OfType resultType,
10669              ITransientExpression const *expr,
10670              bool negated ) {
10671  
10672          m_lastAssertionInfo = info;
10673          AssertionResultData data( resultType, LazyExpression( negated ) );
10674  
10675          AssertionResult assertionResult{ info, data };
10676          assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;
10677  
10678          assertionEnded( assertionResult );
10679      }
10680  
10681      void RunContext::handleMessage(
10682              AssertionInfo const& info,
10683              ResultWas::OfType resultType,
10684              StringRef const& message,
10685              AssertionReaction& reaction
10686      ) {
10687          m_reporter->assertionStarting( info );
10688  
10689          m_lastAssertionInfo = info;
10690  
10691          AssertionResultData data( resultType, LazyExpression( false ) );
10692          data.message = message;
10693          AssertionResult assertionResult{ m_lastAssertionInfo, data };
10694          assertionEnded( assertionResult );
10695          if( !assertionResult.isOk() )
10696              populateReaction( reaction );
10697      }
10698      void RunContext::handleUnexpectedExceptionNotThrown(
10699              AssertionInfo const& info,
10700              AssertionReaction& reaction
10701      ) {
10702          handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction);
10703      }
10704  
10705      void RunContext::handleUnexpectedInflightException(
10706              AssertionInfo const& info,
10707              std::string const& message,
10708              AssertionReaction& reaction
10709      ) {
10710          m_lastAssertionInfo = info;
10711  
10712          AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
10713          data.message = message;
10714          AssertionResult assertionResult{ info, data };
10715          assertionEnded( assertionResult );
10716          populateReaction( reaction );
10717      }
10718  
10719      void RunContext::populateReaction( AssertionReaction& reaction ) {
10720          reaction.shouldDebugBreak = m_config->shouldDebugBreak();
10721          reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal);
10722      }
10723  
10724      void RunContext::handleIncomplete(
10725              AssertionInfo const& info
10726      ) {
10727          m_lastAssertionInfo = info;
10728  
10729          AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
10730          data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
10731          AssertionResult assertionResult{ info, data };
10732          assertionEnded( assertionResult );
10733      }
10734      void RunContext::handleNonExpr(
10735              AssertionInfo const &info,
10736              ResultWas::OfType resultType,
10737              AssertionReaction &reaction
10738      ) {
10739          m_lastAssertionInfo = info;
10740  
10741          AssertionResultData data( resultType, LazyExpression( false ) );
10742          AssertionResult assertionResult{ info, data };
10743          assertionEnded( assertionResult );
10744  
10745          if( !assertionResult.isOk() )
10746              populateReaction( reaction );
10747      }
10748  
10749      IResultCapture& getResultCapture() {
10750          if (auto* capture = getCurrentContext().getResultCapture())
10751              return *capture;
10752          else
10753              CATCH_INTERNAL_ERROR("No result capture instance");
10754      }
10755  }
10756  // end catch_run_context.cpp
10757  // start catch_section.cpp
10758  
10759  namespace Catch {
10760  
10761      Section::Section( SectionInfo const& info )
10762      :   m_info( info ),
10763          m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
10764      {
10765          m_timer.start();
10766      }
10767  
10768      Section::~Section() {
10769          if( m_sectionIncluded ) {
10770              SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };
10771              if( uncaught_exceptions() )
10772                  getResultCapture().sectionEndedEarly( endInfo );
10773              else
10774                  getResultCapture().sectionEnded( endInfo );
10775          }
10776      }
10777  
10778      // This indicates whether the section should be executed or not
10779      Section::operator bool() const {
10780          return m_sectionIncluded;
10781      }
10782  
10783  } // end namespace Catch
10784  // end catch_section.cpp
10785  // start catch_section_info.cpp
10786  
10787  namespace Catch {
10788  
10789      SectionInfo::SectionInfo
10790          (   SourceLineInfo const& _lineInfo,
10791              std::string const& _name )
10792      :   name( _name ),
10793          lineInfo( _lineInfo )
10794      {}
10795  
10796  } // end namespace Catch
10797  // end catch_section_info.cpp
10798  // start catch_session.cpp
10799  
10800  // start catch_session.h
10801  
10802  #include <memory>
10803  
10804  namespace Catch {
10805  
10806      class Session : NonCopyable {
10807      public:
10808  
10809          Session();
10810          ~Session() override;
10811  
10812          void showHelp() const;
10813          void libIdentify();
10814  
10815          int applyCommandLine( int argc, char const * const * argv );
10816      #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
10817          int applyCommandLine( int argc, wchar_t const * const * argv );
10818      #endif
10819  
10820          void useConfigData( ConfigData const& configData );
10821  
10822          template<typename CharT>
10823          int run(int argc, CharT const * const argv[]) {
10824              if (m_startupExceptions)
10825                  return 1;
10826              int returnCode = applyCommandLine(argc, argv);
10827              if (returnCode == 0)
10828                  returnCode = run();
10829              return returnCode;
10830          }
10831  
10832          int run();
10833  
10834          clara::Parser const& cli() const;
10835          void cli( clara::Parser const& newParser );
10836          ConfigData& configData();
10837          Config& config();
10838      private:
10839          int runInternal();
10840  
10841          clara::Parser m_cli;
10842          ConfigData m_configData;
10843          std::shared_ptr<Config> m_config;
10844          bool m_startupExceptions = false;
10845      };
10846  
10847  } // end namespace Catch
10848  
10849  // end catch_session.h
10850  // start catch_version.h
10851  
10852  #include <iosfwd>
10853  
10854  namespace Catch {
10855  
10856      // Versioning information
10857      struct Version {
10858          Version( Version const& ) = delete;
10859          Version& operator=( Version const& ) = delete;
10860          Version(    unsigned int _majorVersion,
10861                      unsigned int _minorVersion,
10862                      unsigned int _patchNumber,
10863                      char const * const _branchName,
10864                      unsigned int _buildNumber );
10865  
10866          unsigned int const majorVersion;
10867          unsigned int const minorVersion;
10868          unsigned int const patchNumber;
10869  
10870          // buildNumber is only used if branchName is not null
10871          char const * const branchName;
10872          unsigned int const buildNumber;
10873  
10874          friend std::ostream& operator << ( std::ostream& os, Version const& version );
10875      };
10876  
10877      Version const& libraryVersion();
10878  }
10879  
10880  // end catch_version.h
10881  #include <cstdlib>
10882  #include <iomanip>
10883  
10884  namespace Catch {
10885  
10886      namespace {
10887          const int MaxExitCode = 255;
10888  
10889          IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) {
10890              auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config);
10891              CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'");
10892  
10893              return reporter;
10894          }
10895  
10896          IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) {
10897              if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) {
10898                  return createReporter(config->getReporterName(), config);
10899              }
10900  
10901              // On older platforms, returning std::unique_ptr<ListeningReporter>
10902              // when the return type is std::unique_ptr<IStreamingReporter>
10903              // doesn't compile without a std::move call. However, this causes
10904              // a warning on newer platforms. Thus, we have to work around
10905              // it a bit and downcast the pointer manually.
10906              auto ret = std::unique_ptr<IStreamingReporter>(new ListeningReporter);
10907              auto& multi = static_cast<ListeningReporter&>(*ret);
10908              auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();
10909              for (auto const& listener : listeners) {
10910                  multi.addListener(listener->create(Catch::ReporterConfig(config)));
10911              }
10912              multi.addReporter(createReporter(config->getReporterName(), config));
10913              return ret;
10914          }
10915  
10916          Catch::Totals runTests(std::shared_ptr<Config> const& config) {
10917              auto reporter = makeReporter(config);
10918  
10919              RunContext context(config, std::move(reporter));
10920  
10921              Totals totals;
10922  
10923              context.testGroupStarting(config->name(), 1, 1);
10924  
10925              TestSpec testSpec = config->testSpec();
10926  
10927              auto const& allTestCases = getAllTestCasesSorted(*config);
10928              for (auto const& testCase : allTestCases) {
10929                  bool matching = (!testSpec.hasFilters() && !testCase.isHidden()) ||
10930                                   (testSpec.hasFilters() && matchTest(testCase, testSpec, *config));
10931  
10932                  if (!context.aborting() && matching)
10933                      totals += context.runTest(testCase);
10934                  else
10935                      context.reporter().skipTest(testCase);
10936              }
10937  
10938              if (config->warnAboutNoTests() && totals.testCases.total() == 0) {
10939                  ReusableStringStream testConfig;
10940  
10941                  bool first = true;
10942                  for (const auto& input : config->getTestsOrTags()) {
10943                      if (!first) { testConfig << ' '; }
10944                      first = false;
10945                      testConfig << input;
10946                  }
10947  
10948                  context.reporter().noMatchingTestCases(testConfig.str());
10949                  totals.error = -1;
10950              }
10951  
10952              context.testGroupEnded(config->name(), totals, 1, 1);
10953              return totals;
10954          }
10955  
10956          void applyFilenamesAsTags(Catch::IConfig const& config) {
10957              auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));
10958              for (auto& testCase : tests) {
10959                  auto tags = testCase.tags;
10960  
10961                  std::string filename = testCase.lineInfo.file;
10962                  auto lastSlash = filename.find_last_of("\\/");
10963                  if (lastSlash != std::string::npos) {
10964                      filename.erase(0, lastSlash);
10965                      filename[0] = '#';
10966                  }
10967  
10968                  auto lastDot = filename.find_last_of('.');
10969                  if (lastDot != std::string::npos) {
10970                      filename.erase(lastDot);
10971                  }
10972  
10973                  tags.push_back(std::move(filename));
10974                  setTags(testCase, tags);
10975              }
10976          }
10977  
10978      } // anon namespace
10979  
10980      Session::Session() {
10981          static bool alreadyInstantiated = false;
10982          if( alreadyInstantiated ) {
10983              CATCH_TRY { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
10984              CATCH_CATCH_ALL { getMutableRegistryHub().registerStartupException(); }
10985          }
10986  
10987          // There cannot be exceptions at startup in no-exception mode.
10988  #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
10989          const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
10990          if ( !exceptions.empty() ) {
10991              m_startupExceptions = true;
10992              Colour colourGuard( Colour::Red );
10993              Catch::cerr() << "Errors occurred during startup!" << '\n';
10994              // iterate over all exceptions and notify user
10995              for ( const auto& ex_ptr : exceptions ) {
10996                  try {
10997                      std::rethrow_exception(ex_ptr);
10998                  } catch ( std::exception const& ex ) {
10999                      Catch::cerr() << Column( ex.what() ).indent(2) << '\n';
11000                  }
11001              }
11002          }
11003  #endif
11004  
11005          alreadyInstantiated = true;
11006          m_cli = makeCommandLineParser( m_configData );
11007      }
11008      Session::~Session() {
11009          Catch::cleanUp();
11010      }
11011  
11012      void Session::showHelp() const {
11013          Catch::cout()
11014                  << "\nCatch v" << libraryVersion() << "\n"
11015                  << m_cli << std::endl
11016                  << "For more detailed usage please see the project docs\n" << std::endl;
11017      }
11018      void Session::libIdentify() {
11019          Catch::cout()
11020                  << std::left << std::setw(16) << "description: " << "A Catch test executable\n"
11021                  << std::left << std::setw(16) << "category: " << "testframework\n"
11022                  << std::left << std::setw(16) << "framework: " << "Catch Test\n"
11023                  << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
11024      }
11025  
11026      int Session::applyCommandLine( int argc, char const * const * argv ) {
11027          if( m_startupExceptions )
11028              return 1;
11029  
11030          auto result = m_cli.parse( clara::Args( argc, argv ) );
11031          if( !result ) {
11032              config();
11033              getCurrentMutableContext().setConfig(m_config);
11034              Catch::cerr()
11035                  << Colour( Colour::Red )
11036                  << "\nError(s) in input:\n"
11037                  << Column( result.errorMessage() ).indent( 2 )
11038                  << "\n\n";
11039              Catch::cerr() << "Run with -? for usage\n" << std::endl;
11040              return MaxExitCode;
11041          }
11042  
11043          if( m_configData.showHelp )
11044              showHelp();
11045          if( m_configData.libIdentify )
11046              libIdentify();
11047          m_config.reset();
11048          return 0;
11049      }
11050  
11051  #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
11052      int Session::applyCommandLine( int argc, wchar_t const * const * argv ) {
11053  
11054          char **utf8Argv = new char *[ argc ];
11055  
11056          for ( int i = 0; i < argc; ++i ) {
11057              int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL );
11058  
11059              utf8Argv[ i ] = new char[ bufSize ];
11060  
11061              WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL );
11062          }
11063  
11064          int returnCode = applyCommandLine( argc, utf8Argv );
11065  
11066          for ( int i = 0; i < argc; ++i )
11067              delete [] utf8Argv[ i ];
11068  
11069          delete [] utf8Argv;
11070  
11071          return returnCode;
11072      }
11073  #endif
11074  
11075      void Session::useConfigData( ConfigData const& configData ) {
11076          m_configData = configData;
11077          m_config.reset();
11078      }
11079  
11080      int Session::run() {
11081          if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {
11082              Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
11083              static_cast<void>(std::getchar());
11084          }
11085          int exitCode = runInternal();
11086          if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {
11087              Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
11088              static_cast<void>(std::getchar());
11089          }
11090          return exitCode;
11091      }
11092  
11093      clara::Parser const& Session::cli() const {
11094          return m_cli;
11095      }
11096      void Session::cli( clara::Parser const& newParser ) {
11097          m_cli = newParser;
11098      }
11099      ConfigData& Session::configData() {
11100          return m_configData;
11101      }
11102      Config& Session::config() {
11103          if( !m_config )
11104              m_config = std::make_shared<Config>( m_configData );
11105          return *m_config;
11106      }
11107  
11108      int Session::runInternal() {
11109          if( m_startupExceptions )
11110              return 1;
11111  
11112          if (m_configData.showHelp || m_configData.libIdentify) {
11113              return 0;
11114          }
11115  
11116          CATCH_TRY {
11117              config(); // Force config to be constructed
11118  
11119              seedRng( *m_config );
11120  
11121              if( m_configData.filenamesAsTags )
11122                  applyFilenamesAsTags( *m_config );
11123  
11124              // Handle list request
11125              if( Option<std::size_t> listed = list( m_config ) )
11126                  return static_cast<int>( *listed );
11127  
11128              auto totals = runTests( m_config );
11129              // Note that on unices only the lower 8 bits are usually used, clamping
11130              // the return value to 255 prevents false negative when some multiple
11131              // of 256 tests has failed
11132              return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed)));
11133          }
11134  #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
11135          catch( std::exception& ex ) {
11136              Catch::cerr() << ex.what() << std::endl;
11137              return MaxExitCode;
11138          }
11139  #endif
11140      }
11141  
11142  } // end namespace Catch
11143  // end catch_session.cpp
11144  // start catch_singletons.cpp
11145  
11146  #include <vector>
11147  
11148  namespace Catch {
11149  
11150      namespace {
11151          static auto getSingletons() -> std::vector<ISingleton*>*& {
11152              static std::vector<ISingleton*>* g_singletons = nullptr;
11153              if( !g_singletons )
11154                  g_singletons = new std::vector<ISingleton*>();
11155              return g_singletons;
11156          }
11157      }
11158  
11159      ISingleton::~ISingleton() {}
11160  
11161      void addSingleton(ISingleton* singleton ) {
11162          getSingletons()->push_back( singleton );
11163      }
11164      void cleanupSingletons() {
11165          auto& singletons = getSingletons();
11166          for( auto singleton : *singletons )
11167              delete singleton;
11168          delete singletons;
11169          singletons = nullptr;
11170      }
11171  
11172  } // namespace Catch
11173  // end catch_singletons.cpp
11174  // start catch_startup_exception_registry.cpp
11175  
11176  namespace Catch {
11177  void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
11178          CATCH_TRY {
11179              m_exceptions.push_back(exception);
11180          } CATCH_CATCH_ALL {
11181              // If we run out of memory during start-up there's really not a lot more we can do about it
11182              std::terminate();
11183          }
11184      }
11185  
11186      std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept {
11187          return m_exceptions;
11188      }
11189  
11190  } // end namespace Catch
11191  // end catch_startup_exception_registry.cpp
11192  // start catch_stream.cpp
11193  
11194  #include <cstdio>
11195  #include <iostream>
11196  #include <fstream>
11197  #include <sstream>
11198  #include <vector>
11199  #include <memory>
11200  
11201  namespace Catch {
11202  
11203      Catch::IStream::~IStream() = default;
11204  
11205      namespace detail { namespace {
11206          template<typename WriterF, std::size_t bufferSize=256>
11207          class StreamBufImpl : public std::streambuf {
11208              char data[bufferSize];
11209              WriterF m_writer;
11210  
11211          public:
11212              StreamBufImpl() {
11213                  setp( data, data + sizeof(data) );
11214              }
11215  
11216              ~StreamBufImpl() noexcept {
11217                  StreamBufImpl::sync();
11218              }
11219  
11220          private:
11221              int overflow( int c ) override {
11222                  sync();
11223  
11224                  if( c != EOF ) {
11225                      if( pbase() == epptr() )
11226                          m_writer( std::string( 1, static_cast<char>( c ) ) );
11227                      else
11228                          sputc( static_cast<char>( c ) );
11229                  }
11230                  return 0;
11231              }
11232  
11233              int sync() override {
11234                  if( pbase() != pptr() ) {
11235                      m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
11236                      setp( pbase(), epptr() );
11237                  }
11238                  return 0;
11239              }
11240          };
11241  
11242          ///////////////////////////////////////////////////////////////////////////
11243  
11244          struct OutputDebugWriter {
11245  
11246              void operator()( std::string const&str ) {
11247                  writeToDebugConsole( str );
11248              }
11249          };
11250  
11251          ///////////////////////////////////////////////////////////////////////////
11252  
11253          class FileStream : public IStream {
11254              mutable std::ofstream m_ofs;
11255          public:
11256              FileStream( StringRef filename ) {
11257                  m_ofs.open( filename.c_str() );
11258                  CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << "'" );
11259              }
11260              ~FileStream() override = default;
11261          public: // IStream
11262              std::ostream& stream() const override {
11263                  return m_ofs;
11264              }
11265          };
11266  
11267          ///////////////////////////////////////////////////////////////////////////
11268  
11269          class CoutStream : public IStream {
11270              mutable std::ostream m_os;
11271          public:
11272              // Store the streambuf from cout up-front because
11273              // cout may get redirected when running tests
11274              CoutStream() : m_os( Catch::cout().rdbuf() ) {}
11275              ~CoutStream() override = default;
11276  
11277          public: // IStream
11278              std::ostream& stream() const override { return m_os; }
11279          };
11280  
11281          ///////////////////////////////////////////////////////////////////////////
11282  
11283          class DebugOutStream : public IStream {
11284              std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf;
11285              mutable std::ostream m_os;
11286          public:
11287              DebugOutStream()
11288              :   m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
11289                  m_os( m_streamBuf.get() )
11290              {}
11291  
11292              ~DebugOutStream() override = default;
11293  
11294          public: // IStream
11295              std::ostream& stream() const override { return m_os; }
11296          };
11297  
11298      }} // namespace anon::detail
11299  
11300      ///////////////////////////////////////////////////////////////////////////
11301  
11302      auto makeStream( StringRef const &filename ) -> IStream const* {
11303          if( filename.empty() )
11304              return new detail::CoutStream();
11305          else if( filename[0] == '%' ) {
11306              if( filename == "%debug" )
11307                  return new detail::DebugOutStream();
11308              else
11309                  CATCH_ERROR( "Unrecognised stream: '" << filename << "'" );
11310          }
11311          else
11312              return new detail::FileStream( filename );
11313      }
11314  
11315      // This class encapsulates the idea of a pool of ostringstreams that can be reused.
11316      struct StringStreams {
11317          std::vector<std::unique_ptr<std::ostringstream>> m_streams;
11318          std::vector<std::size_t> m_unused;
11319          std::ostringstream m_referenceStream; // Used for copy state/ flags from
11320  
11321          auto add() -> std::size_t {
11322              if( m_unused.empty() ) {
11323                  m_streams.push_back( std::unique_ptr<std::ostringstream>( new std::ostringstream ) );
11324                  return m_streams.size()-1;
11325              }
11326              else {
11327                  auto index = m_unused.back();
11328                  m_unused.pop_back();
11329                  return index;
11330              }
11331          }
11332  
11333          void release( std::size_t index ) {
11334              m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state
11335              m_unused.push_back(index);
11336          }
11337      };
11338  
11339      ReusableStringStream::ReusableStringStream()
11340      :   m_index( Singleton<StringStreams>::getMutable().add() ),
11341          m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].get() )
11342      {}
11343  
11344      ReusableStringStream::~ReusableStringStream() {
11345          static_cast<std::ostringstream*>( m_oss )->str("");
11346          m_oss->clear();
11347          Singleton<StringStreams>::getMutable().release( m_index );
11348      }
11349  
11350      auto ReusableStringStream::str() const -> std::string {
11351          return static_cast<std::ostringstream*>( m_oss )->str();
11352      }
11353  
11354      ///////////////////////////////////////////////////////////////////////////
11355  
11356  #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
11357      std::ostream& cout() { return std::cout; }
11358      std::ostream& cerr() { return std::cerr; }
11359      std::ostream& clog() { return std::clog; }
11360  #endif
11361  }
11362  // end catch_stream.cpp
11363  // start catch_string_manip.cpp
11364  
11365  #include <algorithm>
11366  #include <ostream>
11367  #include <cstring>
11368  #include <cctype>
11369  
11370  namespace Catch {
11371  
11372      namespace {
11373          char toLowerCh(char c) {
11374              return static_cast<char>( std::tolower( c ) );
11375          }
11376      }
11377  
11378      bool startsWith( std::string const& s, std::string const& prefix ) {
11379          return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
11380      }
11381      bool startsWith( std::string const& s, char prefix ) {
11382          return !s.empty() && s[0] == prefix;
11383      }
11384      bool endsWith( std::string const& s, std::string const& suffix ) {
11385          return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
11386      }
11387      bool endsWith( std::string const& s, char suffix ) {
11388          return !s.empty() && s[s.size()-1] == suffix;
11389      }
11390      bool contains( std::string const& s, std::string const& infix ) {
11391          return s.find( infix ) != std::string::npos;
11392      }
11393      void toLowerInPlace( std::string& s ) {
11394          std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
11395      }
11396      std::string toLower( std::string const& s ) {
11397          std::string lc = s;
11398          toLowerInPlace( lc );
11399          return lc;
11400      }
11401      std::string trim( std::string const& str ) {
11402          static char const* whitespaceChars = "\n\r\t ";
11403          std::string::size_type start = str.find_first_not_of( whitespaceChars );
11404          std::string::size_type end = str.find_last_not_of( whitespaceChars );
11405  
11406          return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
11407      }
11408  
11409      bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
11410          bool replaced = false;
11411          std::size_t i = str.find( replaceThis );
11412          while( i != std::string::npos ) {
11413              replaced = true;
11414              str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
11415              if( i < str.size()-withThis.size() )
11416                  i = str.find( replaceThis, i+withThis.size() );
11417              else
11418                  i = std::string::npos;
11419          }
11420          return replaced;
11421      }
11422  
11423      pluralise::pluralise( std::size_t count, std::string const& label )
11424      :   m_count( count ),
11425          m_label( label )
11426      {}
11427  
11428      std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
11429          os << pluraliser.m_count << ' ' << pluraliser.m_label;
11430          if( pluraliser.m_count != 1 )
11431              os << 's';
11432          return os;
11433      }
11434  
11435  }
11436  // end catch_string_manip.cpp
11437  // start catch_stringref.cpp
11438  
11439  #if defined(__clang__)
11440  #    pragma clang diagnostic push
11441  #    pragma clang diagnostic ignored "-Wexit-time-destructors"
11442  #endif
11443  
11444  #include <ostream>
11445  #include <cstring>
11446  #include <cstdint>
11447  
11448  namespace {
11449      const uint32_t byte_2_lead = 0xC0;
11450      const uint32_t byte_3_lead = 0xE0;
11451      const uint32_t byte_4_lead = 0xF0;
11452  }
11453  
11454  namespace Catch {
11455      StringRef::StringRef( char const* rawChars ) noexcept
11456      : StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) )
11457      {}
11458  
11459      StringRef::operator std::string() const {
11460          return std::string( m_start, m_size );
11461      }
11462  
11463      void StringRef::swap( StringRef& other ) noexcept {
11464          std::swap( m_start, other.m_start );
11465          std::swap( m_size, other.m_size );
11466          std::swap( m_data, other.m_data );
11467      }
11468  
11469      auto StringRef::c_str() const -> char const* {
11470          if( isSubstring() )
11471             const_cast<StringRef*>( this )->takeOwnership();
11472          return m_start;
11473      }
11474      auto StringRef::currentData() const noexcept -> char const* {
11475          return m_start;
11476      }
11477  
11478      auto StringRef::isOwned() const noexcept -> bool {
11479          return m_data != nullptr;
11480      }
11481      auto StringRef::isSubstring() const noexcept -> bool {
11482          return m_start[m_size] != '\0';
11483      }
11484  
11485      void StringRef::takeOwnership() {
11486          if( !isOwned() ) {
11487              m_data = new char[m_size+1];
11488              memcpy( m_data, m_start, m_size );
11489              m_data[m_size] = '\0';
11490              m_start = m_data;
11491          }
11492      }
11493      auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {
11494          if( start < m_size )
11495              return StringRef( m_start+start, size );
11496          else
11497              return StringRef();
11498      }
11499      auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool {
11500          return
11501              size() == other.size() &&
11502              (std::strncmp( m_start, other.m_start, size() ) == 0);
11503      }
11504      auto StringRef::operator != ( StringRef const& other ) const noexcept -> bool {
11505          return !operator==( other );
11506      }
11507  
11508      auto StringRef::operator[](size_type index) const noexcept -> char {
11509          return m_start[index];
11510      }
11511  
11512      auto StringRef::numberOfCharacters() const noexcept -> size_type {
11513          size_type noChars = m_size;
11514          // Make adjustments for uft encodings
11515          for( size_type i=0; i < m_size; ++i ) {
11516              char c = m_start[i];
11517              if( ( c & byte_2_lead ) == byte_2_lead ) {
11518                  noChars--;
11519                  if (( c & byte_3_lead ) == byte_3_lead )
11520                      noChars--;
11521                  if( ( c & byte_4_lead ) == byte_4_lead )
11522                      noChars--;
11523              }
11524          }
11525          return noChars;
11526      }
11527  
11528      auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string {
11529          std::string str;
11530          str.reserve( lhs.size() + rhs.size() );
11531          str += lhs;
11532          str += rhs;
11533          return str;
11534      }
11535      auto operator + ( StringRef const& lhs, const char* rhs ) -> std::string {
11536          return std::string( lhs ) + std::string( rhs );
11537      }
11538      auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string {
11539          return std::string( lhs ) + std::string( rhs );
11540      }
11541  
11542      auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {
11543          return os.write(str.currentData(), str.size());
11544      }
11545  
11546      auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& {
11547          lhs.append(rhs.currentData(), rhs.size());
11548          return lhs;
11549      }
11550  
11551  } // namespace Catch
11552  
11553  #if defined(__clang__)
11554  #    pragma clang diagnostic pop
11555  #endif
11556  // end catch_stringref.cpp
11557  // start catch_tag_alias.cpp
11558  
11559  namespace Catch {
11560      TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {}
11561  }
11562  // end catch_tag_alias.cpp
11563  // start catch_tag_alias_autoregistrar.cpp
11564  
11565  namespace Catch {
11566  
11567      RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {
11568          CATCH_TRY {
11569              getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
11570          } CATCH_CATCH_ALL {
11571              // Do not throw when constructing global objects, instead register the exception to be processed later
11572              getMutableRegistryHub().registerStartupException();
11573          }
11574      }
11575  
11576  }
11577  // end catch_tag_alias_autoregistrar.cpp
11578  // start catch_tag_alias_registry.cpp
11579  
11580  #include <sstream>
11581  
11582  namespace Catch {
11583  
11584      TagAliasRegistry::~TagAliasRegistry() {}
11585  
11586      TagAlias const* TagAliasRegistry::find( std::string const& alias ) const {
11587          auto it = m_registry.find( alias );
11588          if( it != m_registry.end() )
11589              return &(it->second);
11590          else
11591              return nullptr;
11592      }
11593  
11594      std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
11595          std::string expandedTestSpec = unexpandedTestSpec;
11596          for( auto const& registryKvp : m_registry ) {
11597              std::size_t pos = expandedTestSpec.find( registryKvp.first );
11598              if( pos != std::string::npos ) {
11599                  expandedTestSpec =  expandedTestSpec.substr( 0, pos ) +
11600                                      registryKvp.second.tag +
11601                                      expandedTestSpec.substr( pos + registryKvp.first.size() );
11602              }
11603          }
11604          return expandedTestSpec;
11605      }
11606  
11607      void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) {
11608          CATCH_ENFORCE( startsWith(alias, "[@") && endsWith(alias, ']'),
11609                        "error: tag alias, '" << alias << "' is not of the form [@alias name].\n" << lineInfo );
11610  
11611          CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,
11612                        "error: tag alias, '" << alias << "' already registered.\n"
11613                        << "\tFirst seen at: " << find(alias)->lineInfo << "\n"
11614                        << "\tRedefined at: " << lineInfo );
11615      }
11616  
11617      ITagAliasRegistry::~ITagAliasRegistry() {}
11618  
11619      ITagAliasRegistry const& ITagAliasRegistry::get() {
11620          return getRegistryHub().getTagAliasRegistry();
11621      }
11622  
11623  } // end namespace Catch
11624  // end catch_tag_alias_registry.cpp
11625  // start catch_test_case_info.cpp
11626  
11627  #include <cctype>
11628  #include <exception>
11629  #include <algorithm>
11630  #include <sstream>
11631  
11632  namespace Catch {
11633  
11634      namespace {
11635          TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
11636              if( startsWith( tag, '.' ) ||
11637                  tag == "!hide" )
11638                  return TestCaseInfo::IsHidden;
11639              else if( tag == "!throws" )
11640                  return TestCaseInfo::Throws;
11641              else if( tag == "!shouldfail" )
11642                  return TestCaseInfo::ShouldFail;
11643              else if( tag == "!mayfail" )
11644                  return TestCaseInfo::MayFail;
11645              else if( tag == "!nonportable" )
11646                  return TestCaseInfo::NonPortable;
11647              else if( tag == "!benchmark" )
11648                  return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden );
11649              else
11650                  return TestCaseInfo::None;
11651          }
11652          bool isReservedTag( std::string const& tag ) {
11653              return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) );
11654          }
11655          void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
11656              CATCH_ENFORCE( !isReservedTag(tag),
11657                            "Tag name: [" << tag << "] is not allowed.\n"
11658                            << "Tag names starting with non alphanumeric characters are reserved\n"
11659                            << _lineInfo );
11660          }
11661      }
11662  
11663      TestCase makeTestCase(  ITestInvoker* _testCase,
11664                              std::string const& _className,
11665                              NameAndTags const& nameAndTags,
11666                              SourceLineInfo const& _lineInfo )
11667      {
11668          bool isHidden = false;
11669  
11670          // Parse out tags
11671          std::vector<std::string> tags;
11672          std::string desc, tag;
11673          bool inTag = false;
11674          std::string _descOrTags = nameAndTags.tags;
11675          for (char c : _descOrTags) {
11676              if( !inTag ) {
11677                  if( c == '[' )
11678                      inTag = true;
11679                  else
11680                      desc += c;
11681              }
11682              else {
11683                  if( c == ']' ) {
11684                      TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
11685                      if( ( prop & TestCaseInfo::IsHidden ) != 0 )
11686                          isHidden = true;
11687                      else if( prop == TestCaseInfo::None )
11688                          enforceNotReservedTag( tag, _lineInfo );
11689  
11690                      // Merged hide tags like `[.approvals]` should be added as
11691                      // `[.][approvals]`. The `[.]` is added at later point, so
11692                      // we only strip the prefix
11693                      if (startsWith(tag, '.') && tag.size() > 1) {
11694                          tag.erase(0, 1);
11695                      }
11696                      tags.push_back( tag );
11697                      tag.clear();
11698                      inTag = false;
11699                  }
11700                  else
11701                      tag += c;
11702              }
11703          }
11704          if( isHidden ) {
11705              tags.push_back( "." );
11706          }
11707  
11708          TestCaseInfo info( nameAndTags.name, _className, desc, tags, _lineInfo );
11709          return TestCase( _testCase, std::move(info) );
11710      }
11711  
11712      void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ) {
11713          std::sort(begin(tags), end(tags));
11714          tags.erase(std::unique(begin(tags), end(tags)), end(tags));
11715          testCaseInfo.lcaseTags.clear();
11716  
11717          for( auto const& tag : tags ) {
11718              std::string lcaseTag = toLower( tag );
11719              testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
11720              testCaseInfo.lcaseTags.push_back( lcaseTag );
11721          }
11722          testCaseInfo.tags = std::move(tags);
11723      }
11724  
11725      TestCaseInfo::TestCaseInfo( std::string const& _name,
11726                                  std::string const& _className,
11727                                  std::string const& _description,
11728                                  std::vector<std::string> const& _tags,
11729                                  SourceLineInfo const& _lineInfo )
11730      :   name( _name ),
11731          className( _className ),
11732          description( _description ),
11733          lineInfo( _lineInfo ),
11734          properties( None )
11735      {
11736          setTags( *this, _tags );
11737      }
11738  
11739      bool TestCaseInfo::isHidden() const {
11740          return ( properties & IsHidden ) != 0;
11741      }
11742      bool TestCaseInfo::throws() const {
11743          return ( properties & Throws ) != 0;
11744      }
11745      bool TestCaseInfo::okToFail() const {
11746          return ( properties & (ShouldFail | MayFail ) ) != 0;
11747      }
11748      bool TestCaseInfo::expectedToFail() const {
11749          return ( properties & (ShouldFail ) ) != 0;
11750      }
11751  
11752      std::string TestCaseInfo::tagsAsString() const {
11753          std::string ret;
11754          // '[' and ']' per tag
11755          std::size_t full_size = 2 * tags.size();
11756          for (const auto& tag : tags) {
11757              full_size += tag.size();
11758          }
11759          ret.reserve(full_size);
11760          for (const auto& tag : tags) {
11761              ret.push_back('[');
11762              ret.append(tag);
11763              ret.push_back(']');
11764          }
11765  
11766          return ret;
11767      }
11768  
11769      TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( std::move(info) ), test( testCase ) {}
11770  
11771      TestCase TestCase::withName( std::string const& _newName ) const {
11772          TestCase other( *this );
11773          other.name = _newName;
11774          return other;
11775      }
11776  
11777      void TestCase::invoke() const {
11778          test->invoke();
11779      }
11780  
11781      bool TestCase::operator == ( TestCase const& other ) const {
11782          return  test.get() == other.test.get() &&
11783                  name == other.name &&
11784                  className == other.className;
11785      }
11786  
11787      bool TestCase::operator < ( TestCase const& other ) const {
11788          return name < other.name;
11789      }
11790  
11791      TestCaseInfo const& TestCase::getTestCaseInfo() const
11792      {
11793          return *this;
11794      }
11795  
11796  } // end namespace Catch
11797  // end catch_test_case_info.cpp
11798  // start catch_test_case_registry_impl.cpp
11799  
11800  #include <sstream>
11801  
11802  namespace Catch {
11803  
11804      std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
11805  
11806          std::vector<TestCase> sorted = unsortedTestCases;
11807  
11808          switch( config.runOrder() ) {
11809              case RunTests::InLexicographicalOrder:
11810                  std::sort( sorted.begin(), sorted.end() );
11811                  break;
11812              case RunTests::InRandomOrder:
11813                  seedRng( config );
11814                  std::shuffle( sorted.begin(), sorted.end(), rng() );
11815                  break;
11816              case RunTests::InDeclarationOrder:
11817                  // already in declaration order
11818                  break;
11819          }
11820          return sorted;
11821      }
11822      bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
11823          return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
11824      }
11825  
11826      void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
11827          std::set<TestCase> seenFunctions;
11828          for( auto const& function : functions ) {
11829              auto prev = seenFunctions.insert( function );
11830              CATCH_ENFORCE( prev.second,
11831                      "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n"
11832                      << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
11833                      << "\tRedefined at " << function.getTestCaseInfo().lineInfo );
11834          }
11835      }
11836  
11837      std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
11838          std::vector<TestCase> filtered;
11839          filtered.reserve( testCases.size() );
11840          for (auto const& testCase : testCases) {
11841              if ((!testSpec.hasFilters() && !testCase.isHidden()) ||
11842                  (testSpec.hasFilters() && matchTest(testCase, testSpec, config))) {
11843                  filtered.push_back(testCase);
11844              }
11845          }
11846          return filtered;
11847      }
11848      std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
11849          return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
11850      }
11851  
11852      void TestRegistry::registerTest( TestCase const& testCase ) {
11853          std::string name = testCase.getTestCaseInfo().name;
11854          if( name.empty() ) {
11855              ReusableStringStream rss;
11856              rss << "Anonymous test case " << ++m_unnamedCount;
11857              return registerTest( testCase.withName( rss.str() ) );
11858          }
11859          m_functions.push_back( testCase );
11860      }
11861  
11862      std::vector<TestCase> const& TestRegistry::getAllTests() const {
11863          return m_functions;
11864      }
11865      std::vector<TestCase> const& TestRegistry::getAllTestsSorted( IConfig const& config ) const {
11866          if( m_sortedFunctions.empty() )
11867              enforceNoDuplicateTestCases( m_functions );
11868  
11869          if(  m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
11870              m_sortedFunctions = sortTests( config, m_functions );
11871              m_currentSortOrder = config.runOrder();
11872          }
11873          return m_sortedFunctions;
11874      }
11875  
11876      ///////////////////////////////////////////////////////////////////////////
11877      TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {}
11878  
11879      void TestInvokerAsFunction::invoke() const {
11880          m_testAsFunction();
11881      }
11882  
11883      std::string extractClassName( StringRef const& classOrQualifiedMethodName ) {
11884          std::string className = classOrQualifiedMethodName;
11885          if( startsWith( className, '&' ) )
11886          {
11887              std::size_t lastColons = className.rfind( "::" );
11888              std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
11889              if( penultimateColons == std::string::npos )
11890                  penultimateColons = 1;
11891              className = className.substr( penultimateColons, lastColons-penultimateColons );
11892          }
11893          return className;
11894      }
11895  
11896  } // end namespace Catch
11897  // end catch_test_case_registry_impl.cpp
11898  // start catch_test_case_tracker.cpp
11899  
11900  #include <algorithm>
11901  #include <cassert>
11902  #include <stdexcept>
11903  #include <memory>
11904  #include <sstream>
11905  
11906  #if defined(__clang__)
11907  #    pragma clang diagnostic push
11908  #    pragma clang diagnostic ignored "-Wexit-time-destructors"
11909  #endif
11910  
11911  namespace Catch {
11912  namespace TestCaseTracking {
11913  
11914      NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location )
11915      :   name( _name ),
11916          location( _location )
11917      {}
11918  
11919      ITracker::~ITracker() = default;
11920  
11921      ITracker& TrackerContext::startRun() {
11922          m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr );
11923          m_currentTracker = nullptr;
11924          m_runState = Executing;
11925          return *m_rootTracker;
11926      }
11927  
11928      void TrackerContext::endRun() {
11929          m_rootTracker.reset();
11930          m_currentTracker = nullptr;
11931          m_runState = NotStarted;
11932      }
11933  
11934      void TrackerContext::startCycle() {
11935          m_currentTracker = m_rootTracker.get();
11936          m_runState = Executing;
11937      }
11938      void TrackerContext::completeCycle() {
11939          m_runState = CompletedCycle;
11940      }
11941  
11942      bool TrackerContext::completedCycle() const {
11943          return m_runState == CompletedCycle;
11944      }
11945      ITracker& TrackerContext::currentTracker() {
11946          return *m_currentTracker;
11947      }
11948      void TrackerContext::setCurrentTracker( ITracker* tracker ) {
11949          m_currentTracker = tracker;
11950      }
11951  
11952      TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
11953      :   m_nameAndLocation( nameAndLocation ),
11954          m_ctx( ctx ),
11955          m_parent( parent )
11956      {}
11957  
11958      NameAndLocation const& TrackerBase::nameAndLocation() const {
11959          return m_nameAndLocation;
11960      }
11961      bool TrackerBase::isComplete() const {
11962          return m_runState == CompletedSuccessfully || m_runState == Failed;
11963      }
11964      bool TrackerBase::isSuccessfullyCompleted() const {
11965          return m_runState == CompletedSuccessfully;
11966      }
11967      bool TrackerBase::isOpen() const {
11968          return m_runState != NotStarted && !isComplete();
11969      }
11970      bool TrackerBase::hasChildren() const {
11971          return !m_children.empty();
11972      }
11973  
11974      void TrackerBase::addChild( ITrackerPtr const& child ) {
11975          m_children.push_back( child );
11976      }
11977  
11978      ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) {
11979          auto it = std::find_if( m_children.begin(), m_children.end(),
11980              [&nameAndLocation]( ITrackerPtr const& tracker ){
11981                  return
11982                      tracker->nameAndLocation().location == nameAndLocation.location &&
11983                      tracker->nameAndLocation().name == nameAndLocation.name;
11984              } );
11985          return( it != m_children.end() )
11986              ? *it
11987              : nullptr;
11988      }
11989      ITracker& TrackerBase::parent() {
11990          assert( m_parent ); // Should always be non-null except for root
11991          return *m_parent;
11992      }
11993  
11994      void TrackerBase::openChild() {
11995          if( m_runState != ExecutingChildren ) {
11996              m_runState = ExecutingChildren;
11997              if( m_parent )
11998                  m_parent->openChild();
11999          }
12000      }
12001  
12002      bool TrackerBase::isSectionTracker() const { return false; }
12003      bool TrackerBase::isGeneratorTracker() const { return false; }
12004  
12005      void TrackerBase::open() {
12006          m_runState = Executing;
12007          moveToThis();
12008          if( m_parent )
12009              m_parent->openChild();
12010      }
12011  
12012      void TrackerBase::close() {
12013  
12014          // Close any still open children (e.g. generators)
12015          while( &m_ctx.currentTracker() != this )
12016              m_ctx.currentTracker().close();
12017  
12018          switch( m_runState ) {
12019              case NeedsAnotherRun:
12020                  break;
12021  
12022              case Executing:
12023                  m_runState = CompletedSuccessfully;
12024                  break;
12025              case ExecutingChildren:
12026                  if( m_children.empty() || m_children.back()->isComplete() )
12027                      m_runState = CompletedSuccessfully;
12028                  break;
12029  
12030              case NotStarted:
12031              case CompletedSuccessfully:
12032              case Failed:
12033                  CATCH_INTERNAL_ERROR( "Illogical state: " << m_runState );
12034  
12035              default:
12036                  CATCH_INTERNAL_ERROR( "Unknown state: " << m_runState );
12037          }
12038          moveToParent();
12039          m_ctx.completeCycle();
12040      }
12041      void TrackerBase::fail() {
12042          m_runState = Failed;
12043          if( m_parent )
12044              m_parent->markAsNeedingAnotherRun();
12045          moveToParent();
12046          m_ctx.completeCycle();
12047      }
12048      void TrackerBase::markAsNeedingAnotherRun() {
12049          m_runState = NeedsAnotherRun;
12050      }
12051  
12052      void TrackerBase::moveToParent() {
12053          assert( m_parent );
12054          m_ctx.setCurrentTracker( m_parent );
12055      }
12056      void TrackerBase::moveToThis() {
12057          m_ctx.setCurrentTracker( this );
12058      }
12059  
12060      SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
12061      :   TrackerBase( nameAndLocation, ctx, parent )
12062      {
12063          if( parent ) {
12064              while( !parent->isSectionTracker() )
12065                  parent = &parent->parent();
12066  
12067              SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );
12068              addNextFilters( parentSection.m_filters );
12069          }
12070      }
12071  
12072      bool SectionTracker::isComplete() const {
12073          bool complete = true;
12074  
12075          if ((m_filters.empty() || m_filters[0] == "") ||
12076               std::find(m_filters.begin(), m_filters.end(),
12077                         m_nameAndLocation.name) != m_filters.end())
12078              complete = TrackerBase::isComplete();
12079          return complete;
12080  
12081      }
12082  
12083      bool SectionTracker::isSectionTracker() const { return true; }
12084  
12085      SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {
12086          std::shared_ptr<SectionTracker> section;
12087  
12088          ITracker& currentTracker = ctx.currentTracker();
12089          if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
12090              assert( childTracker );
12091              assert( childTracker->isSectionTracker() );
12092              section = std::static_pointer_cast<SectionTracker>( childTracker );
12093          }
12094          else {
12095              section = std::make_shared<SectionTracker>( nameAndLocation, ctx, &currentTracker );
12096              currentTracker.addChild( section );
12097          }
12098          if( !ctx.completedCycle() )
12099              section->tryOpen();
12100          return *section;
12101      }
12102  
12103      void SectionTracker::tryOpen() {
12104          if( !isComplete() && (m_filters.empty() || m_filters[0].empty() ||  m_filters[0] == m_nameAndLocation.name ) )
12105              open();
12106      }
12107  
12108      void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) {
12109          if( !filters.empty() ) {
12110              m_filters.push_back(""); // Root - should never be consulted
12111              m_filters.push_back(""); // Test Case - not a section filter
12112              m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
12113          }
12114      }
12115      void SectionTracker::addNextFilters( std::vector<std::string> const& filters ) {
12116          if( filters.size() > 1 )
12117              m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() );
12118      }
12119  
12120  } // namespace TestCaseTracking
12121  
12122  using TestCaseTracking::ITracker;
12123  using TestCaseTracking::TrackerContext;
12124  using TestCaseTracking::SectionTracker;
12125  
12126  } // namespace Catch
12127  
12128  #if defined(__clang__)
12129  #    pragma clang diagnostic pop
12130  #endif
12131  // end catch_test_case_tracker.cpp
12132  // start catch_test_registry.cpp
12133  
12134  namespace Catch {
12135  
12136      auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker* {
12137          return new(std::nothrow) TestInvokerAsFunction( testAsFunction );
12138      }
12139  
12140      NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {}
12141  
12142      AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept {
12143          CATCH_TRY {
12144              getMutableRegistryHub()
12145                      .registerTest(
12146                          makeTestCase(
12147                              invoker,
12148                              extractClassName( classOrMethod ),
12149                              nameAndTags,
12150                              lineInfo));
12151          } CATCH_CATCH_ALL {
12152              // Do not throw when constructing global objects, instead register the exception to be processed later
12153              getMutableRegistryHub().registerStartupException();
12154          }
12155      }
12156  
12157      AutoReg::~AutoReg() = default;
12158  }
12159  // end catch_test_registry.cpp
12160  // start catch_test_spec.cpp
12161  
12162  #include <algorithm>
12163  #include <string>
12164  #include <vector>
12165  #include <memory>
12166  
12167  namespace Catch {
12168  
12169      TestSpec::Pattern::~Pattern() = default;
12170      TestSpec::NamePattern::~NamePattern() = default;
12171      TestSpec::TagPattern::~TagPattern() = default;
12172      TestSpec::ExcludedPattern::~ExcludedPattern() = default;
12173  
12174      TestSpec::NamePattern::NamePattern( std::string const& name )
12175      : m_wildcardPattern( toLower( name ), CaseSensitive::No )
12176      {}
12177      bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const {
12178          return m_wildcardPattern.matches( toLower( testCase.name ) );
12179      }
12180  
12181      TestSpec::TagPattern::TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
12182      bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const {
12183          return std::find(begin(testCase.lcaseTags),
12184                           end(testCase.lcaseTags),
12185                           m_tag) != end(testCase.lcaseTags);
12186      }
12187  
12188      TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
12189      bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
12190  
12191      bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const {
12192          // All patterns in a filter must match for the filter to be a match
12193          for( auto const& pattern : m_patterns ) {
12194              if( !pattern->matches( testCase ) )
12195                  return false;
12196          }
12197          return true;
12198      }
12199  
12200      bool TestSpec::hasFilters() const {
12201          return !m_filters.empty();
12202      }
12203      bool TestSpec::matches( TestCaseInfo const& testCase ) const {
12204          // A TestSpec matches if any filter matches
12205          for( auto const& filter : m_filters )
12206              if( filter.matches( testCase ) )
12207                  return true;
12208          return false;
12209      }
12210  }
12211  // end catch_test_spec.cpp
12212  // start catch_test_spec_parser.cpp
12213  
12214  namespace Catch {
12215  
12216      TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
12217  
12218      TestSpecParser& TestSpecParser::parse( std::string const& arg ) {
12219          m_mode = None;
12220          m_exclusion = false;
12221          m_start = std::string::npos;
12222          m_arg = m_tagAliases->expandAliases( arg );
12223          m_escapeChars.clear();
12224          for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
12225              visitChar( m_arg[m_pos] );
12226          if( m_mode == Name )
12227              addPattern<TestSpec::NamePattern>();
12228          return *this;
12229      }
12230      TestSpec TestSpecParser::testSpec() {
12231          addFilter();
12232          return m_testSpec;
12233      }
12234  
12235      void TestSpecParser::visitChar( char c ) {
12236          if( m_mode == None ) {
12237              switch( c ) {
12238              case ' ': return;
12239              case '~': m_exclusion = true; return;
12240              case '[': return startNewMode( Tag, ++m_pos );
12241              case '"': return startNewMode( QuotedName, ++m_pos );
12242              case '\\': return escape();
12243              default: startNewMode( Name, m_pos ); break;
12244              }
12245          }
12246          if( m_mode == Name ) {
12247              if( c == ',' ) {
12248                  addPattern<TestSpec::NamePattern>();
12249                  addFilter();
12250              }
12251              else if( c == '[' ) {
12252                  if( subString() == "exclude:" )
12253                      m_exclusion = true;
12254                  else
12255                      addPattern<TestSpec::NamePattern>();
12256                  startNewMode( Tag, ++m_pos );
12257              }
12258              else if( c == '\\' )
12259                  escape();
12260          }
12261          else if( m_mode == EscapedName )
12262              m_mode = Name;
12263          else if( m_mode == QuotedName && c == '"' )
12264              addPattern<TestSpec::NamePattern>();
12265          else if( m_mode == Tag && c == ']' )
12266              addPattern<TestSpec::TagPattern>();
12267      }
12268      void TestSpecParser::startNewMode( Mode mode, std::size_t start ) {
12269          m_mode = mode;
12270          m_start = start;
12271      }
12272      void TestSpecParser::escape() {
12273          if( m_mode == None )
12274              m_start = m_pos;
12275          m_mode = EscapedName;
12276          m_escapeChars.push_back( m_pos );
12277      }
12278      std::string TestSpecParser::subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
12279  
12280      void TestSpecParser::addFilter() {
12281          if( !m_currentFilter.m_patterns.empty() ) {
12282              m_testSpec.m_filters.push_back( m_currentFilter );
12283              m_currentFilter = TestSpec::Filter();
12284          }
12285      }
12286  
12287      TestSpec parseTestSpec( std::string const& arg ) {
12288          return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
12289      }
12290  
12291  } // namespace Catch
12292  // end catch_test_spec_parser.cpp
12293  // start catch_timer.cpp
12294  
12295  #include <chrono>
12296  
12297  static const uint64_t nanosecondsInSecond = 1000000000;
12298  
12299  namespace Catch {
12300  
12301      auto getCurrentNanosecondsSinceEpoch() -> uint64_t {
12302          return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
12303      }
12304  
12305      namespace {
12306          auto estimateClockResolution() -> uint64_t {
12307              uint64_t sum = 0;
12308              static const uint64_t iterations = 1000000;
12309  
12310              auto startTime = getCurrentNanosecondsSinceEpoch();
12311  
12312              for( std::size_t i = 0; i < iterations; ++i ) {
12313  
12314                  uint64_t ticks;
12315                  uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
12316                  do {
12317                      ticks = getCurrentNanosecondsSinceEpoch();
12318                  } while( ticks == baseTicks );
12319  
12320                  auto delta = ticks - baseTicks;
12321                  sum += delta;
12322  
12323                  // If we have been calibrating for over 3 seconds -- the clock
12324                  // is terrible and we should move on.
12325                  // TBD: How to signal that the measured resolution is probably wrong?
12326                  if (ticks > startTime + 3 * nanosecondsInSecond) {
12327                      return sum / ( i + 1u );
12328                  }
12329              }
12330  
12331              // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
12332              // - and potentially do more iterations if there's a high variance.
12333              return sum/iterations;
12334          }
12335      }
12336      auto getEstimatedClockResolution() -> uint64_t {
12337          static auto s_resolution = estimateClockResolution();
12338          return s_resolution;
12339      }
12340  
12341      void Timer::start() {
12342         m_nanoseconds = getCurrentNanosecondsSinceEpoch();
12343      }
12344      auto Timer::getElapsedNanoseconds() const -> uint64_t {
12345          return getCurrentNanosecondsSinceEpoch() - m_nanoseconds;
12346      }
12347      auto Timer::getElapsedMicroseconds() const -> uint64_t {
12348          return getElapsedNanoseconds()/1000;
12349      }
12350      auto Timer::getElapsedMilliseconds() const -> unsigned int {
12351          return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
12352      }
12353      auto Timer::getElapsedSeconds() const -> double {
12354          return getElapsedMicroseconds()/1000000.0;
12355      }
12356  
12357  } // namespace Catch
12358  // end catch_timer.cpp
12359  // start catch_tostring.cpp
12360  
12361  #if defined(__clang__)
12362  #    pragma clang diagnostic push
12363  #    pragma clang diagnostic ignored "-Wexit-time-destructors"
12364  #    pragma clang diagnostic ignored "-Wglobal-constructors"
12365  #endif
12366  
12367  // Enable specific decls locally
12368  #if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
12369  #define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
12370  #endif
12371  
12372  #include <cmath>
12373  #include <iomanip>
12374  
12375  namespace Catch {
12376  
12377  namespace Detail {
12378  
12379      const std::string unprintableString = "{?}";
12380  
12381      namespace {
12382          const int hexThreshold = 255;
12383  
12384          struct Endianness {
12385              enum Arch { Big, Little };
12386  
12387              static Arch which() {
12388                  union _{
12389                      int asInt;
12390                      char asChar[sizeof (int)];
12391                  } u;
12392  
12393                  u.asInt = 1;
12394                  return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
12395              }
12396          };
12397      }
12398  
12399      std::string rawMemoryToString( const void *object, std::size_t size ) {
12400          // Reverse order for little endian architectures
12401          int i = 0, end = static_cast<int>( size ), inc = 1;
12402          if( Endianness::which() == Endianness::Little ) {
12403              i = end-1;
12404              end = inc = -1;
12405          }
12406  
12407          unsigned char const *bytes = static_cast<unsigned char const *>(object);
12408          ReusableStringStream rss;
12409          rss << "0x" << std::setfill('0') << std::hex;
12410          for( ; i != end; i += inc )
12411               rss << std::setw(2) << static_cast<unsigned>(bytes[i]);
12412         return rss.str();
12413      }
12414  }
12415  
12416  template<typename T>
12417  std::string fpToString( T value, int precision ) {
12418      if (Catch::isnan(value)) {
12419          return "nan";
12420      }
12421  
12422      ReusableStringStream rss;
12423      rss << std::setprecision( precision )
12424          << std::fixed
12425          << value;
12426      std::string d = rss.str();
12427      std::size_t i = d.find_last_not_of( '0' );
12428      if( i != std::string::npos && i != d.size()-1 ) {
12429          if( d[i] == '.' )
12430              i++;
12431          d = d.substr( 0, i+1 );
12432      }
12433      return d;
12434  }
12435  
12436  //// ======================================================= ////
12437  //
12438  //   Out-of-line defs for full specialization of StringMaker
12439  //
12440  //// ======================================================= ////
12441  
12442  std::string StringMaker<std::string>::convert(const std::string& str) {
12443      if (!getCurrentContext().getConfig()->showInvisibles()) {
12444          return '"' + str + '"';
12445      }
12446  
12447      std::string s("\"");
12448      for (char c : str) {
12449          switch (c) {
12450          case '\n':
12451              s.append("\\n");
12452              break;
12453          case '\t':
12454              s.append("\\t");
12455              break;
12456          default:
12457              s.push_back(c);
12458              break;
12459          }
12460      }
12461      s.append("\"");
12462      return s;
12463  }
12464  
12465  #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
12466  std::string StringMaker<std::string_view>::convert(std::string_view str) {
12467      return ::Catch::Detail::stringify(std::string{ str });
12468  }
12469  #endif
12470  
12471  std::string StringMaker<char const*>::convert(char const* str) {
12472      if (str) {
12473          return ::Catch::Detail::stringify(std::string{ str });
12474      } else {
12475          return{ "{null string}" };
12476      }
12477  }
12478  std::string StringMaker<char*>::convert(char* str) {
12479      if (str) {
12480          return ::Catch::Detail::stringify(std::string{ str });
12481      } else {
12482          return{ "{null string}" };
12483      }
12484  }
12485  
12486  #ifdef CATCH_CONFIG_WCHAR
12487  std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
12488      std::string s;
12489      s.reserve(wstr.size());
12490      for (auto c : wstr) {
12491          s += (c <= 0xff) ? static_cast<char>(c) : '?';
12492      }
12493      return ::Catch::Detail::stringify(s);
12494  }
12495  
12496  # ifdef CATCH_CONFIG_CPP17_STRING_VIEW
12497  std::string StringMaker<std::wstring_view>::convert(std::wstring_view str) {
12498      return StringMaker<std::wstring>::convert(std::wstring(str));
12499  }
12500  # endif
12501  
12502  std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {
12503      if (str) {
12504          return ::Catch::Detail::stringify(std::wstring{ str });
12505      } else {
12506          return{ "{null string}" };
12507      }
12508  }
12509  std::string StringMaker<wchar_t *>::convert(wchar_t * str) {
12510      if (str) {
12511          return ::Catch::Detail::stringify(std::wstring{ str });
12512      } else {
12513          return{ "{null string}" };
12514      }
12515  }
12516  #endif
12517  
12518  std::string StringMaker<int>::convert(int value) {
12519      return ::Catch::Detail::stringify(static_cast<long long>(value));
12520  }
12521  std::string StringMaker<long>::convert(long value) {
12522      return ::Catch::Detail::stringify(static_cast<long long>(value));
12523  }
12524  std::string StringMaker<long long>::convert(long long value) {
12525      ReusableStringStream rss;
12526      rss << value;
12527      if (value > Detail::hexThreshold) {
12528          rss << " (0x" << std::hex << value << ')';
12529      }
12530      return rss.str();
12531  }
12532  
12533  std::string StringMaker<unsigned int>::convert(unsigned int value) {
12534      return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
12535  }
12536  std::string StringMaker<unsigned long>::convert(unsigned long value) {
12537      return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
12538  }
12539  std::string StringMaker<unsigned long long>::convert(unsigned long long value) {
12540      ReusableStringStream rss;
12541      rss << value;
12542      if (value > Detail::hexThreshold) {
12543          rss << " (0x" << std::hex << value << ')';
12544      }
12545      return rss.str();
12546  }
12547  
12548  std::string StringMaker<bool>::convert(bool b) {
12549      return b ? "true" : "false";
12550  }
12551  
12552  std::string StringMaker<signed char>::convert(signed char value) {
12553      if (value == '\r') {
12554          return "'\\r'";
12555      } else if (value == '\f') {
12556          return "'\\f'";
12557      } else if (value == '\n') {
12558          return "'\\n'";
12559      } else if (value == '\t') {
12560          return "'\\t'";
12561      } else if ('\0' <= value && value < ' ') {
12562          return ::Catch::Detail::stringify(static_cast<unsigned int>(value));
12563      } else {
12564          char chstr[] = "' '";
12565          chstr[1] = value;
12566          return chstr;
12567      }
12568  }
12569  std::string StringMaker<char>::convert(char c) {
12570      return ::Catch::Detail::stringify(static_cast<signed char>(c));
12571  }
12572  std::string StringMaker<unsigned char>::convert(unsigned char c) {
12573      return ::Catch::Detail::stringify(static_cast<char>(c));
12574  }
12575  
12576  std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) {
12577      return "nullptr";
12578  }
12579  
12580  std::string StringMaker<float>::convert(float value) {
12581      return fpToString(value, 5) + 'f';
12582  }
12583  std::string StringMaker<double>::convert(double value) {
12584      return fpToString(value, 10);
12585  }
12586  
12587  std::string ratio_string<std::atto>::symbol() { return "a"; }
12588  std::string ratio_string<std::femto>::symbol() { return "f"; }
12589  std::string ratio_string<std::pico>::symbol() { return "p"; }
12590  std::string ratio_string<std::nano>::symbol() { return "n"; }
12591  std::string ratio_string<std::micro>::symbol() { return "u"; }
12592  std::string ratio_string<std::milli>::symbol() { return "m"; }
12593  
12594  } // end namespace Catch
12595  
12596  #if defined(__clang__)
12597  #    pragma clang diagnostic pop
12598  #endif
12599  
12600  // end catch_tostring.cpp
12601  // start catch_totals.cpp
12602  
12603  namespace Catch {
12604  
12605      Counts Counts::operator - ( Counts const& other ) const {
12606          Counts diff;
12607          diff.passed = passed - other.passed;
12608          diff.failed = failed - other.failed;
12609          diff.failedButOk = failedButOk - other.failedButOk;
12610          return diff;
12611      }
12612  
12613      Counts& Counts::operator += ( Counts const& other ) {
12614          passed += other.passed;
12615          failed += other.failed;
12616          failedButOk += other.failedButOk;
12617          return *this;
12618      }
12619  
12620      std::size_t Counts::total() const {
12621          return passed + failed + failedButOk;
12622      }
12623      bool Counts::allPassed() const {
12624          return failed == 0 && failedButOk == 0;
12625      }
12626      bool Counts::allOk() const {
12627          return failed == 0;
12628      }
12629  
12630      Totals Totals::operator - ( Totals const& other ) const {
12631          Totals diff;
12632          diff.assertions = assertions - other.assertions;
12633          diff.testCases = testCases - other.testCases;
12634          return diff;
12635      }
12636  
12637      Totals& Totals::operator += ( Totals const& other ) {
12638          assertions += other.assertions;
12639          testCases += other.testCases;
12640          return *this;
12641      }
12642  
12643      Totals Totals::delta( Totals const& prevTotals ) const {
12644          Totals diff = *this - prevTotals;
12645          if( diff.assertions.failed > 0 )
12646              ++diff.testCases.failed;
12647          else if( diff.assertions.failedButOk > 0 )
12648              ++diff.testCases.failedButOk;
12649          else
12650              ++diff.testCases.passed;
12651          return diff;
12652      }
12653  
12654  }
12655  // end catch_totals.cpp
12656  // start catch_uncaught_exceptions.cpp
12657  
12658  #include <exception>
12659  
12660  namespace Catch {
12661      bool uncaught_exceptions() {
12662  #if defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
12663          return std::uncaught_exceptions() > 0;
12664  #else
12665          return std::uncaught_exception();
12666  #endif
12667    }
12668  } // end namespace Catch
12669  // end catch_uncaught_exceptions.cpp
12670  // start catch_version.cpp
12671  
12672  #include <ostream>
12673  
12674  namespace Catch {
12675  
12676      Version::Version
12677          (   unsigned int _majorVersion,
12678              unsigned int _minorVersion,
12679              unsigned int _patchNumber,
12680              char const * const _branchName,
12681              unsigned int _buildNumber )
12682      :   majorVersion( _majorVersion ),
12683          minorVersion( _minorVersion ),
12684          patchNumber( _patchNumber ),
12685          branchName( _branchName ),
12686          buildNumber( _buildNumber )
12687      {}
12688  
12689      std::ostream& operator << ( std::ostream& os, Version const& version ) {
12690          os  << version.majorVersion << '.'
12691              << version.minorVersion << '.'
12692              << version.patchNumber;
12693          // branchName is never null -> 0th char is \0 if it is empty
12694          if (version.branchName[0]) {
12695              os << '-' << version.branchName
12696                 << '.' << version.buildNumber;
12697          }
12698          return os;
12699      }
12700  
12701      Version const& libraryVersion() {
12702          static Version version( 2, 7, 2, "", 0 );
12703          return version;
12704      }
12705  
12706  }
12707  // end catch_version.cpp
12708  // start catch_wildcard_pattern.cpp
12709  
12710  #include <sstream>
12711  
12712  namespace Catch {
12713  
12714      WildcardPattern::WildcardPattern( std::string const& pattern,
12715                                        CaseSensitive::Choice caseSensitivity )
12716      :   m_caseSensitivity( caseSensitivity ),
12717          m_pattern( adjustCase( pattern ) )
12718      {
12719          if( startsWith( m_pattern, '*' ) ) {
12720              m_pattern = m_pattern.substr( 1 );
12721              m_wildcard = WildcardAtStart;
12722          }
12723          if( endsWith( m_pattern, '*' ) ) {
12724              m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
12725              m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
12726          }
12727      }
12728  
12729      bool WildcardPattern::matches( std::string const& str ) const {
12730          switch( m_wildcard ) {
12731              case NoWildcard:
12732                  return m_pattern == adjustCase( str );
12733              case WildcardAtStart:
12734                  return endsWith( adjustCase( str ), m_pattern );
12735              case WildcardAtEnd:
12736                  return startsWith( adjustCase( str ), m_pattern );
12737              case WildcardAtBothEnds:
12738                  return contains( adjustCase( str ), m_pattern );
12739              default:
12740                  CATCH_INTERNAL_ERROR( "Unknown enum" );
12741          }
12742      }
12743  
12744      std::string WildcardPattern::adjustCase( std::string const& str ) const {
12745          return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;
12746      }
12747  }
12748  // end catch_wildcard_pattern.cpp
12749  // start catch_xmlwriter.cpp
12750  
12751  #include <iomanip>
12752  
12753  using uchar = unsigned char;
12754  
12755  namespace Catch {
12756  
12757  namespace {
12758  
12759      size_t trailingBytes(unsigned char c) {
12760          if ((c & 0xE0) == 0xC0) {
12761              return 2;
12762          }
12763          if ((c & 0xF0) == 0xE0) {
12764              return 3;
12765          }
12766          if ((c & 0xF8) == 0xF0) {
12767              return 4;
12768          }
12769          CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
12770      }
12771  
12772      uint32_t headerValue(unsigned char c) {
12773          if ((c & 0xE0) == 0xC0) {
12774              return c & 0x1F;
12775          }
12776          if ((c & 0xF0) == 0xE0) {
12777              return c & 0x0F;
12778          }
12779          if ((c & 0xF8) == 0xF0) {
12780              return c & 0x07;
12781          }
12782          CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
12783      }
12784  
12785      void hexEscapeChar(std::ostream& os, unsigned char c) {
12786          std::ios_base::fmtflags f(os.flags());
12787          os << "\\x"
12788              << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
12789              << static_cast<int>(c);
12790          os.flags(f);
12791      }
12792  
12793  } // anonymous namespace
12794  
12795      XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )
12796      :   m_str( str ),
12797          m_forWhat( forWhat )
12798      {}
12799  
12800      void XmlEncode::encodeTo( std::ostream& os ) const {
12801          // Apostrophe escaping not necessary if we always use " to write attributes
12802          // (see: http://www.w3.org/TR/xml/#syntax)
12803  
12804          for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
12805              uchar c = m_str[idx];
12806              switch (c) {
12807              case '<':   os << "&lt;"; break;
12808              case '&':   os << "&amp;"; break;
12809  
12810              case '>':
12811                  // See: http://www.w3.org/TR/xml/#syntax
12812                  if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
12813                      os << "&gt;";
12814                  else
12815                      os << c;
12816                  break;
12817  
12818              case '\"':
12819                  if (m_forWhat == ForAttributes)
12820                      os << "&quot;";
12821                  else
12822                      os << c;
12823                  break;
12824  
12825              default:
12826                  // Check for control characters and invalid utf-8
12827  
12828                  // Escape control characters in standard ascii
12829                  // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
12830                  if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
12831                      hexEscapeChar(os, c);
12832                      break;
12833                  }
12834  
12835                  // Plain ASCII: Write it to stream
12836                  if (c < 0x7F) {
12837                      os << c;
12838                      break;
12839                  }
12840  
12841                  // UTF-8 territory
12842                  // Check if the encoding is valid and if it is not, hex escape bytes.
12843                  // Important: We do not check the exact decoded values for validity, only the encoding format
12844                  // First check that this bytes is a valid lead byte:
12845                  // This means that it is not encoded as 1111 1XXX
12846                  // Or as 10XX XXXX
12847                  if (c <  0xC0 ||
12848                      c >= 0xF8) {
12849                      hexEscapeChar(os, c);
12850                      break;
12851                  }
12852  
12853                  auto encBytes = trailingBytes(c);
12854                  // Are there enough bytes left to avoid accessing out-of-bounds memory?
12855                  if (idx + encBytes - 1 >= m_str.size()) {
12856                      hexEscapeChar(os, c);
12857                      break;
12858                  }
12859                  // The header is valid, check data
12860                  // The next encBytes bytes must together be a valid utf-8
12861                  // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)
12862                  bool valid = true;
12863                  uint32_t value = headerValue(c);
12864                  for (std::size_t n = 1; n < encBytes; ++n) {
12865                      uchar nc = m_str[idx + n];
12866                      valid &= ((nc & 0xC0) == 0x80);
12867                      value = (value << 6) | (nc & 0x3F);
12868                  }
12869  
12870                  if (
12871                      // Wrong bit pattern of following bytes
12872                      (!valid) ||
12873                      // Overlong encodings
12874                      (value < 0x80) ||
12875                      (0x80 <= value && value < 0x800   && encBytes > 2) ||
12876                      (0x800 < value && value < 0x10000 && encBytes > 3) ||
12877                      // Encoded value out of range
12878                      (value >= 0x110000)
12879                      ) {
12880                      hexEscapeChar(os, c);
12881                      break;
12882                  }
12883  
12884                  // If we got here, this is in fact a valid(ish) utf-8 sequence
12885                  for (std::size_t n = 0; n < encBytes; ++n) {
12886                      os << m_str[idx + n];
12887                  }
12888                  idx += encBytes - 1;
12889                  break;
12890              }
12891          }
12892      }
12893  
12894      std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
12895          xmlEncode.encodeTo( os );
12896          return os;
12897      }
12898  
12899      XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer )
12900      :   m_writer( writer )
12901      {}
12902  
12903      XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept
12904      :   m_writer( other.m_writer ){
12905          other.m_writer = nullptr;
12906      }
12907      XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept {
12908          if ( m_writer ) {
12909              m_writer->endElement();
12910          }
12911          m_writer = other.m_writer;
12912          other.m_writer = nullptr;
12913          return *this;
12914      }
12915  
12916      XmlWriter::ScopedElement::~ScopedElement() {
12917          if( m_writer )
12918              m_writer->endElement();
12919      }
12920  
12921      XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, bool indent ) {
12922          m_writer->writeText( text, indent );
12923          return *this;
12924      }
12925  
12926      XmlWriter::XmlWriter( std::ostream& os ) : m_os( os )
12927      {
12928          writeDeclaration();
12929      }
12930  
12931      XmlWriter::~XmlWriter() {
12932          while( !m_tags.empty() )
12933              endElement();
12934      }
12935  
12936      XmlWriter& XmlWriter::startElement( std::string const& name ) {
12937          ensureTagClosed();
12938          newlineIfNecessary();
12939          m_os << m_indent << '<' << name;
12940          m_tags.push_back( name );
12941          m_indent += "  ";
12942          m_tagIsOpen = true;
12943          return *this;
12944      }
12945  
12946      XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name ) {
12947          ScopedElement scoped( this );
12948          startElement( name );
12949          return scoped;
12950      }
12951  
12952      XmlWriter& XmlWriter::endElement() {
12953          newlineIfNecessary();
12954          m_indent = m_indent.substr( 0, m_indent.size()-2 );
12955          if( m_tagIsOpen ) {
12956              m_os << "/>";
12957              m_tagIsOpen = false;
12958          }
12959          else {
12960              m_os << m_indent << "</" << m_tags.back() << ">";
12961          }
12962          m_os << std::endl;
12963          m_tags.pop_back();
12964          return *this;
12965      }
12966  
12967      XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) {
12968          if( !name.empty() && !attribute.empty() )
12969              m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
12970          return *this;
12971      }
12972  
12973      XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) {
12974          m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
12975          return *this;
12976      }
12977  
12978      XmlWriter& XmlWriter::writeText( std::string const& text, bool indent ) {
12979          if( !text.empty() ){
12980              bool tagWasOpen = m_tagIsOpen;
12981              ensureTagClosed();
12982              if( tagWasOpen && indent )
12983                  m_os << m_indent;
12984              m_os << XmlEncode( text );
12985              m_needsNewline = true;
12986          }
12987          return *this;
12988      }
12989  
12990      XmlWriter& XmlWriter::writeComment( std::string const& text ) {
12991          ensureTagClosed();
12992          m_os << m_indent << "<!--" << text << "-->";
12993          m_needsNewline = true;
12994          return *this;
12995      }
12996  
12997      void XmlWriter::writeStylesheetRef( std::string const& url ) {
12998          m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
12999      }
13000  
13001      XmlWriter& XmlWriter::writeBlankLine() {
13002          ensureTagClosed();
13003          m_os << '\n';
13004          return *this;
13005      }
13006  
13007      void XmlWriter::ensureTagClosed() {
13008          if( m_tagIsOpen ) {
13009              m_os << ">" << std::endl;
13010              m_tagIsOpen = false;
13011          }
13012      }
13013  
13014      void XmlWriter::writeDeclaration() {
13015          m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
13016      }
13017  
13018      void XmlWriter::newlineIfNecessary() {
13019          if( m_needsNewline ) {
13020              m_os << std::endl;
13021              m_needsNewline = false;
13022          }
13023      }
13024  }
13025  // end catch_xmlwriter.cpp
13026  // start catch_reporter_bases.cpp
13027  
13028  #include <cstring>
13029  #include <cfloat>
13030  #include <cstdio>
13031  #include <cassert>
13032  #include <memory>
13033  
13034  namespace Catch {
13035      void prepareExpandedExpression(AssertionResult& result) {
13036          result.getExpandedExpression();
13037      }
13038  
13039      // Because formatting using c++ streams is stateful, drop down to C is required
13040      // Alternatively we could use stringstream, but its performance is... not good.
13041      std::string getFormattedDuration( double duration ) {
13042          // Max exponent + 1 is required to represent the whole part
13043          // + 1 for decimal point
13044          // + 3 for the 3 decimal places
13045          // + 1 for null terminator
13046          const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
13047          char buffer[maxDoubleSize];
13048  
13049          // Save previous errno, to prevent sprintf from overwriting it
13050          ErrnoGuard guard;
13051  #ifdef _MSC_VER
13052          sprintf_s(buffer, "%.3f", duration);
13053  #else
13054          std::sprintf(buffer, "%.3f", duration);
13055  #endif
13056          return std::string(buffer);
13057      }
13058  
13059      std::string serializeFilters( std::vector<std::string> const& container ) {
13060          ReusableStringStream oss;
13061          bool first = true;
13062          for (auto&& filter : container)
13063          {
13064              if (!first)
13065                  oss << ' ';
13066              else
13067                  first = false;
13068  
13069              oss << filter;
13070          }
13071          return oss.str();
13072      }
13073  
13074      TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)
13075          :StreamingReporterBase(_config) {}
13076  
13077      std::set<Verbosity> TestEventListenerBase::getSupportedVerbosities() {
13078          return { Verbosity::Quiet, Verbosity::Normal, Verbosity::High };
13079      }
13080  
13081      void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}
13082  
13083      bool TestEventListenerBase::assertionEnded(AssertionStats const &) {
13084          return false;
13085      }
13086  
13087  } // end namespace Catch
13088  // end catch_reporter_bases.cpp
13089  // start catch_reporter_compact.cpp
13090  
13091  namespace {
13092  
13093  #ifdef CATCH_PLATFORM_MAC
13094      const char* failedString() { return "FAILED"; }
13095      const char* passedString() { return "PASSED"; }
13096  #else
13097      const char* failedString() { return "failed"; }
13098      const char* passedString() { return "passed"; }
13099  #endif
13100  
13101      // Colour::LightGrey
13102      Catch::Colour::Code dimColour() { return Catch::Colour::FileName; }
13103  
13104      std::string bothOrAll( std::size_t count ) {
13105          return count == 1 ? std::string() :
13106                 count == 2 ? "both " : "all " ;
13107      }
13108  
13109  } // anon namespace
13110  
13111  namespace Catch {
13112  namespace {
13113  // Colour, message variants:
13114  // - white: No tests ran.
13115  // -   red: Failed [both/all] N test cases, failed [both/all] M assertions.
13116  // - white: Passed [both/all] N test cases (no assertions).
13117  // -   red: Failed N tests cases, failed M assertions.
13118  // - green: Passed [both/all] N tests cases with M assertions.
13119  void printTotals(std::ostream& out, const Totals& totals) {
13120      if (totals.testCases.total() == 0) {
13121          out << "No tests ran.";
13122      } else if (totals.testCases.failed == totals.testCases.total()) {
13123          Colour colour(Colour::ResultError);
13124          const std::string qualify_assertions_failed =
13125              totals.assertions.failed == totals.assertions.total() ?
13126              bothOrAll(totals.assertions.failed) : std::string();
13127          out <<
13128              "Failed " << bothOrAll(totals.testCases.failed)
13129              << pluralise(totals.testCases.failed, "test case") << ", "
13130              "failed " << qualify_assertions_failed <<
13131              pluralise(totals.assertions.failed, "assertion") << '.';
13132      } else if (totals.assertions.total() == 0) {
13133          out <<
13134              "Passed " << bothOrAll(totals.testCases.total())
13135              << pluralise(totals.testCases.total(), "test case")
13136              << " (no assertions).";
13137      } else if (totals.assertions.failed) {
13138          Colour colour(Colour::ResultError);
13139          out <<
13140              "Failed " << pluralise(totals.testCases.failed, "test case") << ", "
13141              "failed " << pluralise(totals.assertions.failed, "assertion") << '.';
13142      } else {
13143          Colour colour(Colour::ResultSuccess);
13144          out <<
13145              "Passed " << bothOrAll(totals.testCases.passed)
13146              << pluralise(totals.testCases.passed, "test case") <<
13147              " with " << pluralise(totals.assertions.passed, "assertion") << '.';
13148      }
13149  }
13150  
13151  // Implementation of CompactReporter formatting
13152  class AssertionPrinter {
13153  public:
13154      AssertionPrinter& operator= (AssertionPrinter const&) = delete;
13155      AssertionPrinter(AssertionPrinter const&) = delete;
13156      AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
13157          : stream(_stream)
13158          , result(_stats.assertionResult)
13159          , messages(_stats.infoMessages)
13160          , itMessage(_stats.infoMessages.begin())
13161          , printInfoMessages(_printInfoMessages) {}
13162  
13163      void print() {
13164          printSourceInfo();
13165  
13166          itMessage = messages.begin();
13167  
13168          switch (result.getResultType()) {
13169          case ResultWas::Ok:
13170              printResultType(Colour::ResultSuccess, passedString());
13171              printOriginalExpression();
13172              printReconstructedExpression();
13173              if (!result.hasExpression())
13174                  printRemainingMessages(Colour::None);
13175              else
13176                  printRemainingMessages();
13177              break;
13178          case ResultWas::ExpressionFailed:
13179              if (result.isOk())
13180                  printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok"));
13181              else
13182                  printResultType(Colour::Error, failedString());
13183              printOriginalExpression();
13184              printReconstructedExpression();
13185              printRemainingMessages();
13186              break;
13187          case ResultWas::ThrewException:
13188              printResultType(Colour::Error, failedString());
13189              printIssue("unexpected exception with message:");
13190              printMessage();
13191              printExpressionWas();
13192              printRemainingMessages();
13193              break;
13194          case ResultWas::FatalErrorCondition:
13195              printResultType(Colour::Error, failedString());
13196              printIssue("fatal error condition with message:");
13197              printMessage();
13198              printExpressionWas();
13199              printRemainingMessages();
13200              break;
13201          case ResultWas::DidntThrowException:
13202              printResultType(Colour::Error, failedString());
13203              printIssue("expected exception, got none");
13204              printExpressionWas();
13205              printRemainingMessages();
13206              break;
13207          case ResultWas::Info:
13208              printResultType(Colour::None, "info");
13209              printMessage();
13210              printRemainingMessages();
13211              break;
13212          case ResultWas::Warning:
13213              printResultType(Colour::None, "warning");
13214              printMessage();
13215              printRemainingMessages();
13216              break;
13217          case ResultWas::ExplicitFailure:
13218              printResultType(Colour::Error, failedString());
13219              printIssue("explicitly");
13220              printRemainingMessages(Colour::None);
13221              break;
13222              // These cases are here to prevent compiler warnings
13223          case ResultWas::Unknown:
13224          case ResultWas::FailureBit:
13225          case ResultWas::Exception:
13226              printResultType(Colour::Error, "** internal error **");
13227              break;
13228          }
13229      }
13230  
13231  private:
13232      void printSourceInfo() const {
13233          Colour colourGuard(Colour::FileName);
13234          stream << result.getSourceInfo() << ':';
13235      }
13236  
13237      void printResultType(Colour::Code colour, std::string const& passOrFail) const {
13238          if (!passOrFail.empty()) {
13239              {
13240                  Colour colourGuard(colour);
13241                  stream << ' ' << passOrFail;
13242              }
13243              stream << ':';
13244          }
13245      }
13246  
13247      void printIssue(std::string const& issue) const {
13248          stream << ' ' << issue;
13249      }
13250  
13251      void printExpressionWas() {
13252          if (result.hasExpression()) {
13253              stream << ';';
13254              {
13255                  Colour colour(dimColour());
13256                  stream << " expression was:";
13257              }
13258              printOriginalExpression();
13259          }
13260      }
13261  
13262      void printOriginalExpression() const {
13263          if (result.hasExpression()) {
13264              stream << ' ' << result.getExpression();
13265          }
13266      }
13267  
13268      void printReconstructedExpression() const {
13269          if (result.hasExpandedExpression()) {
13270              {
13271                  Colour colour(dimColour());
13272                  stream << " for: ";
13273              }
13274              stream << result.getExpandedExpression();
13275          }
13276      }
13277  
13278      void printMessage() {
13279          if (itMessage != messages.end()) {
13280              stream << " '" << itMessage->message << '\'';
13281              ++itMessage;
13282          }
13283      }
13284  
13285      void printRemainingMessages(Colour::Code colour = dimColour()) {
13286          if (itMessage == messages.end())
13287              return;
13288  
13289          // using messages.end() directly yields (or auto) compilation error:
13290          std::vector<MessageInfo>::const_iterator itEnd = messages.end();
13291          const std::size_t N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
13292  
13293          {
13294              Colour colourGuard(colour);
13295              stream << " with " << pluralise(N, "message") << ':';
13296          }
13297  
13298          for (; itMessage != itEnd; ) {
13299              // If this assertion is a warning ignore any INFO messages
13300              if (printInfoMessages || itMessage->type != ResultWas::Info) {
13301                  stream << " '" << itMessage->message << '\'';
13302                  if (++itMessage != itEnd) {
13303                      Colour colourGuard(dimColour());
13304                      stream << " and";
13305                  }
13306              }
13307          }
13308      }
13309  
13310  private:
13311      std::ostream& stream;
13312      AssertionResult const& result;
13313      std::vector<MessageInfo> messages;
13314      std::vector<MessageInfo>::const_iterator itMessage;
13315      bool printInfoMessages;
13316  };
13317  
13318  } // anon namespace
13319  
13320          std::string CompactReporter::getDescription() {
13321              return "Reports test results on a single line, suitable for IDEs";
13322          }
13323  
13324          ReporterPreferences CompactReporter::getPreferences() const {
13325              return m_reporterPrefs;
13326          }
13327  
13328          void CompactReporter::noMatchingTestCases( std::string const& spec ) {
13329              stream << "No test cases matched '" << spec << '\'' << std::endl;
13330          }
13331  
13332          void CompactReporter::assertionStarting( AssertionInfo const& ) {}
13333  
13334          bool CompactReporter::assertionEnded( AssertionStats const& _assertionStats ) {
13335              AssertionResult const& result = _assertionStats.assertionResult;
13336  
13337              bool printInfoMessages = true;
13338  
13339              // Drop out if result was successful and we're not printing those
13340              if( !m_config->includeSuccessfulResults() && result.isOk() ) {
13341                  if( result.getResultType() != ResultWas::Warning )
13342                      return false;
13343                  printInfoMessages = false;
13344              }
13345  
13346              AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
13347              printer.print();
13348  
13349              stream << std::endl;
13350              return true;
13351          }
13352  
13353          void CompactReporter::sectionEnded(SectionStats const& _sectionStats) {
13354              if (m_config->showDurations() == ShowDurations::Always) {
13355                  stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
13356              }
13357          }
13358  
13359          void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) {
13360              printTotals( stream, _testRunStats.totals );
13361              stream << '\n' << std::endl;
13362              StreamingReporterBase::testRunEnded( _testRunStats );
13363          }
13364  
13365          CompactReporter::~CompactReporter() {}
13366  
13367      CATCH_REGISTER_REPORTER( "compact", CompactReporter )
13368  
13369  } // end namespace Catch
13370  // end catch_reporter_compact.cpp
13371  // start catch_reporter_console.cpp
13372  
13373  #include <cfloat>
13374  #include <cstdio>
13375  
13376  #if defined(_MSC_VER)
13377  #pragma warning(push)
13378  #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
13379   // Note that 4062 (not all labels are handled
13380   // and default is missing) is enabled
13381  #endif
13382  
13383  namespace Catch {
13384  
13385  namespace {
13386  
13387  // Formatter impl for ConsoleReporter
13388  class ConsoleAssertionPrinter {
13389  public:
13390      ConsoleAssertionPrinter& operator= (ConsoleAssertionPrinter const&) = delete;
13391      ConsoleAssertionPrinter(ConsoleAssertionPrinter const&) = delete;
13392      ConsoleAssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
13393          : stream(_stream),
13394          stats(_stats),
13395          result(_stats.assertionResult),
13396          colour(Colour::None),
13397          message(result.getMessage()),
13398          messages(_stats.infoMessages),
13399          printInfoMessages(_printInfoMessages) {
13400          switch (result.getResultType()) {
13401          case ResultWas::Ok:
13402              colour = Colour::Success;
13403              passOrFail = "PASSED";
13404              //if( result.hasMessage() )
13405              if (_stats.infoMessages.size() == 1)
13406                  messageLabel = "with message";
13407              if (_stats.infoMessages.size() > 1)
13408                  messageLabel = "with messages";
13409              break;
13410          case ResultWas::ExpressionFailed:
13411              if (result.isOk()) {
13412                  colour = Colour::Success;
13413                  passOrFail = "FAILED - but was ok";
13414              } else {
13415                  colour = Colour::Error;
13416                  passOrFail = "error: FAILED";
13417              }
13418              if (_stats.infoMessages.size() == 1)
13419                  messageLabel = "with message";
13420              if (_stats.infoMessages.size() > 1)
13421                  messageLabel = "with messages";
13422              break;
13423          case ResultWas::ThrewException:
13424              colour = Colour::Error;
13425              passOrFail = "error: FAILED";
13426              messageLabel = "due to unexpected exception with ";
13427              if (_stats.infoMessages.size() == 1)
13428                  messageLabel += "message";
13429              if (_stats.infoMessages.size() > 1)
13430                  messageLabel += "messages";
13431              break;
13432          case ResultWas::FatalErrorCondition:
13433              colour = Colour::Error;
13434              passOrFail = "error: FAILED";
13435              messageLabel = "due to a fatal error condition";
13436              break;
13437          case ResultWas::DidntThrowException:
13438              colour = Colour::Error;
13439              passOrFail = "error: FAILED";
13440              messageLabel = "because no exception was thrown where one was expected";
13441              break;
13442          case ResultWas::Info:
13443              messageLabel = "info";
13444              break;
13445          case ResultWas::Warning:
13446              messageLabel = "warning";
13447              break;
13448          case ResultWas::ExplicitFailure:
13449              passOrFail = "FAILED";
13450              colour = Colour::Error;
13451              if (_stats.infoMessages.size() == 1)
13452                  messageLabel = "explicitly with message";
13453              if (_stats.infoMessages.size() > 1)
13454                  messageLabel = "explicitly with messages";
13455              break;
13456              // These cases are here to prevent compiler warnings
13457          case ResultWas::Unknown:
13458          case ResultWas::FailureBit:
13459          case ResultWas::Exception:
13460              passOrFail = "** internal error **";
13461              colour = Colour::Error;
13462              break;
13463          }
13464      }
13465  
13466      void print() const {
13467          printSourceInfo();
13468          if (stats.totals.assertions.total() > 0) {
13469              printResultType();
13470              printOriginalExpression();
13471              printReconstructedExpression();
13472          } else {
13473              stream << '\n';
13474          }
13475          printMessage();
13476      }
13477  
13478  private:
13479      void printResultType() const {
13480          if (!passOrFail.empty()) {
13481              Colour colourGuard(colour);
13482              stream << passOrFail << ": ";
13483          }
13484      }
13485      void printOriginalExpression() const {
13486          if (result.hasExpression()) {
13487              Colour colourGuard(Colour::OriginalExpression);
13488              stream << " ";
13489              stream << result.getExpressionInMacro();
13490              stream << ' ';
13491          }
13492      }
13493      void printReconstructedExpression() const {
13494          if (result.hasExpandedExpression()) {
13495              stream << "with expansion: ";
13496              Colour colourGuard(Colour::ReconstructedExpression);
13497              stream << result.getExpandedExpression() << '\n';
13498          }
13499      }
13500      void printMessage() const {
13501          if (!messageLabel.empty())
13502              stream << messageLabel << ':' << '\n';
13503          for (auto const& msg : messages) {
13504              // If this assertion is a warning ignore any INFO messages
13505              if (printInfoMessages || msg.type != ResultWas::Info)
13506                  stream << Column(msg.message).indent(2) << '\n';
13507          }
13508      }
13509      void printSourceInfo() const {
13510          Colour colourGuard(Colour::FileName);
13511          stream << result.getSourceInfo() << ": ";
13512      }
13513  
13514      std::ostream& stream;
13515      AssertionStats const& stats;
13516      AssertionResult const& result;
13517      Colour::Code colour;
13518      std::string passOrFail;
13519      std::string messageLabel;
13520      std::string message;
13521      std::vector<MessageInfo> messages;
13522      bool printInfoMessages;
13523  };
13524  
13525  std::size_t makeRatio(std::size_t number, std::size_t total) {
13526      std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0;
13527      return (ratio == 0 && number > 0) ? 1 : ratio;
13528  }
13529  
13530  std::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k) {
13531      if (i > j && i > k)
13532          return i;
13533      else if (j > k)
13534          return j;
13535      else
13536          return k;
13537  }
13538  
13539  struct ColumnInfo {
13540      enum Justification { Left, Right };
13541      std::string name;
13542      int width;
13543      Justification justification;
13544  };
13545  struct ColumnBreak {};
13546  struct RowBreak {};
13547  
13548  class Duration {
13549      enum class Unit {
13550          Auto,
13551          Nanoseconds,
13552          Microseconds,
13553          Milliseconds,
13554          Seconds,
13555          Minutes
13556      };
13557      static const uint64_t s_nanosecondsInAMicrosecond = 1000;
13558      static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond;
13559      static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;
13560      static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;
13561  
13562      uint64_t m_inNanoseconds;
13563      Unit m_units;
13564  
13565  public:
13566      explicit Duration(uint64_t inNanoseconds, Unit units = Unit::Auto)
13567          : m_inNanoseconds(inNanoseconds),
13568          m_units(units) {
13569          if (m_units == Unit::Auto) {
13570              if (m_inNanoseconds < s_nanosecondsInAMicrosecond)
13571                  m_units = Unit::Nanoseconds;
13572              else if (m_inNanoseconds < s_nanosecondsInAMillisecond)
13573                  m_units = Unit::Microseconds;
13574              else if (m_inNanoseconds < s_nanosecondsInASecond)
13575                  m_units = Unit::Milliseconds;
13576              else if (m_inNanoseconds < s_nanosecondsInAMinute)
13577                  m_units = Unit::Seconds;
13578              else
13579                  m_units = Unit::Minutes;
13580          }
13581  
13582      }
13583  
13584      auto value() const -> double {
13585          switch (m_units) {
13586          case Unit::Microseconds:
13587              return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond);
13588          case Unit::Milliseconds:
13589              return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond);
13590          case Unit::Seconds:
13591              return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond);
13592          case Unit::Minutes:
13593              return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute);
13594          default:
13595              return static_cast<double>(m_inNanoseconds);
13596          }
13597      }
13598      auto unitsAsString() const -> std::string {
13599          switch (m_units) {
13600          case Unit::Nanoseconds:
13601              return "ns";
13602          case Unit::Microseconds:
13603              return "us";
13604          case Unit::Milliseconds:
13605              return "ms";
13606          case Unit::Seconds:
13607              return "s";
13608          case Unit::Minutes:
13609              return "m";
13610          default:
13611              return "** internal error **";
13612          }
13613  
13614      }
13615      friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& {
13616          return os << duration.value() << " " << duration.unitsAsString();
13617      }
13618  };
13619  } // end anon namespace
13620  
13621  class TablePrinter {
13622      std::ostream& m_os;
13623      std::vector<ColumnInfo> m_columnInfos;
13624      std::ostringstream m_oss;
13625      int m_currentColumn = -1;
13626      bool m_isOpen = false;
13627  
13628  public:
13629      TablePrinter( std::ostream& os, std::vector<ColumnInfo> columnInfos )
13630      :   m_os( os ),
13631          m_columnInfos( std::move( columnInfos ) ) {}
13632  
13633      auto columnInfos() const -> std::vector<ColumnInfo> const& {
13634          return m_columnInfos;
13635      }
13636  
13637      void open() {
13638          if (!m_isOpen) {
13639              m_isOpen = true;
13640              *this << RowBreak();
13641              for (auto const& info : m_columnInfos)
13642                  *this << info.name << ColumnBreak();
13643              *this << RowBreak();
13644              m_os << Catch::getLineOfChars<'-'>() << "\n";
13645          }
13646      }
13647      void close() {
13648          if (m_isOpen) {
13649              *this << RowBreak();
13650              m_os << std::endl;
13651              m_isOpen = false;
13652          }
13653      }
13654  
13655      template<typename T>
13656      friend TablePrinter& operator << (TablePrinter& tp, T const& value) {
13657          tp.m_oss << value;
13658          return tp;
13659      }
13660  
13661      friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) {
13662          auto colStr = tp.m_oss.str();
13663          // This takes account of utf8 encodings
13664          auto strSize = Catch::StringRef(colStr).numberOfCharacters();
13665          tp.m_oss.str("");
13666          tp.open();
13667          if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) {
13668              tp.m_currentColumn = -1;
13669              tp.m_os << "\n";
13670          }
13671          tp.m_currentColumn++;
13672  
13673          auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
13674          auto padding = (strSize + 2 < static_cast<std::size_t>(colInfo.width))
13675              ? std::string(colInfo.width - (strSize + 2), ' ')
13676              : std::string();
13677          if (colInfo.justification == ColumnInfo::Left)
13678              tp.m_os << colStr << padding << " ";
13679          else
13680              tp.m_os << padding << colStr << " ";
13681          return tp;
13682      }
13683  
13684      friend TablePrinter& operator << (TablePrinter& tp, RowBreak) {
13685          if (tp.m_currentColumn > 0) {
13686              tp.m_os << "\n";
13687              tp.m_currentColumn = -1;
13688          }
13689          return tp;
13690      }
13691  };
13692  
13693  ConsoleReporter::ConsoleReporter(ReporterConfig const& config)
13694      : StreamingReporterBase(config),
13695      m_tablePrinter(new TablePrinter(config.stream(),
13696      {
13697          { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 32, ColumnInfo::Left },
13698          { "iters", 8, ColumnInfo::Right },
13699          { "elapsed ns", 14, ColumnInfo::Right },
13700          { "average", 14, ColumnInfo::Right }
13701      })) {}
13702  ConsoleReporter::~ConsoleReporter() = default;
13703  
13704  std::string ConsoleReporter::getDescription() {
13705      return "Reports test results as plain lines of text";
13706  }
13707  
13708  void ConsoleReporter::noMatchingTestCases(std::string const& spec) {
13709      stream << "No test cases matched '" << spec << '\'' << std::endl;
13710  }
13711  
13712  void ConsoleReporter::assertionStarting(AssertionInfo const&) {}
13713  
13714  bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {
13715      AssertionResult const& result = _assertionStats.assertionResult;
13716  
13717      bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
13718  
13719      // Drop out if result was successful but we're not printing them.
13720      if (!includeResults && result.getResultType() != ResultWas::Warning)
13721          return false;
13722  
13723      lazyPrint();
13724  
13725      ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults);
13726      printer.print();
13727      stream << std::endl;
13728      return true;
13729  }
13730  
13731  void ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) {
13732      m_headerPrinted = false;
13733      StreamingReporterBase::sectionStarting(_sectionInfo);
13734  }
13735  void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) {
13736      m_tablePrinter->close();
13737      if (_sectionStats.missingAssertions) {
13738          lazyPrint();
13739          Colour colour(Colour::ResultError);
13740          if (m_sectionStack.size() > 1)
13741              stream << "\nNo assertions in section";
13742          else
13743              stream << "\nNo assertions in test case";
13744          stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
13745      }
13746      if (m_config->showDurations() == ShowDurations::Always) {
13747          stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
13748      }
13749      if (m_headerPrinted) {
13750          m_headerPrinted = false;
13751      }
13752      StreamingReporterBase::sectionEnded(_sectionStats);
13753  }
13754  
13755  void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {
13756      lazyPrintWithoutClosingBenchmarkTable();
13757  
13758      auto nameCol = Column( info.name ).width( static_cast<std::size_t>( m_tablePrinter->columnInfos()[0].width - 2 ) );
13759  
13760      bool firstLine = true;
13761      for (auto line : nameCol) {
13762          if (!firstLine)
13763              (*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();
13764          else
13765              firstLine = false;
13766  
13767          (*m_tablePrinter) << line << ColumnBreak();
13768      }
13769  }
13770  void ConsoleReporter::benchmarkEnded(BenchmarkStats const& stats) {
13771      Duration average(stats.elapsedTimeInNanoseconds / stats.iterations);
13772      (*m_tablePrinter)
13773          << stats.iterations << ColumnBreak()
13774          << stats.elapsedTimeInNanoseconds << ColumnBreak()
13775          << average << ColumnBreak();
13776  }
13777  
13778  void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {
13779      m_tablePrinter->close();
13780      StreamingReporterBase::testCaseEnded(_testCaseStats);
13781      m_headerPrinted = false;
13782  }
13783  void ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats) {
13784      if (currentGroupInfo.used) {
13785          printSummaryDivider();
13786          stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
13787          printTotals(_testGroupStats.totals);
13788          stream << '\n' << std::endl;
13789      }
13790      StreamingReporterBase::testGroupEnded(_testGroupStats);
13791  }
13792  void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
13793      printTotalsDivider(_testRunStats.totals);
13794      printTotals(_testRunStats.totals);
13795      stream << std::endl;
13796      StreamingReporterBase::testRunEnded(_testRunStats);
13797  }
13798  void ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) {
13799      StreamingReporterBase::testRunStarting(_testInfo);
13800      printTestFilters();
13801  }
13802  
13803  void ConsoleReporter::lazyPrint() {
13804  
13805      m_tablePrinter->close();
13806      lazyPrintWithoutClosingBenchmarkTable();
13807  }
13808  
13809  void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() {
13810  
13811      if (!currentTestRunInfo.used)
13812          lazyPrintRunInfo();
13813      if (!currentGroupInfo.used)
13814          lazyPrintGroupInfo();
13815  
13816      if (!m_headerPrinted) {
13817          printTestCaseAndSectionHeader();
13818          m_headerPrinted = true;
13819      }
13820  }
13821  void ConsoleReporter::lazyPrintRunInfo() {
13822      stream << '\n' << getLineOfChars<'~'>() << '\n';
13823      Colour colour(Colour::SecondaryText);
13824      stream << currentTestRunInfo->name
13825          << " is a Catch v" << libraryVersion() << " host application.\n"
13826          << "Run with -? for options\n\n";
13827  
13828      if (m_config->rngSeed() != 0)
13829          stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
13830  
13831      currentTestRunInfo.used = true;
13832  }
13833  void ConsoleReporter::lazyPrintGroupInfo() {
13834      if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) {
13835          printClosedHeader("Group: " + currentGroupInfo->name);
13836          currentGroupInfo.used = true;
13837      }
13838  }
13839  void ConsoleReporter::printTestCaseAndSectionHeader() {
13840      assert(!m_sectionStack.empty());
13841      printOpenHeader(currentTestCaseInfo->name);
13842  
13843      if (m_sectionStack.size() > 1) {
13844          Colour colourGuard(Colour::Headers);
13845  
13846          auto
13847              it = m_sectionStack.begin() + 1, // Skip first section (test case)
13848              itEnd = m_sectionStack.end();
13849          for (; it != itEnd; ++it)
13850              printHeaderString(it->name, 2);
13851      }
13852  
13853      SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
13854  
13855      if (!lineInfo.empty()) {
13856          stream << getLineOfChars<'-'>() << '\n';
13857          Colour colourGuard(Colour::FileName);
13858          stream << lineInfo << ": in test " << m_sectionStack.back().name << ":";
13859      }
13860      stream << std::endl;
13861  }
13862  
13863  void ConsoleReporter::printClosedHeader(std::string const& _name) {
13864      printOpenHeader(_name);
13865      stream << getLineOfChars<'.'>() << '\n';
13866  }
13867  void ConsoleReporter::printOpenHeader(std::string const& _name) {
13868      stream << getLineOfChars<'-'>() << '\n';
13869      {
13870          Colour colourGuard(Colour::Headers);
13871          printHeaderString(_name);
13872      }
13873  }
13874  
13875  // if string has a : in first line will set indent to follow it on
13876  // subsequent lines
13877  void ConsoleReporter::printHeaderString(std::string const& _string, std::size_t indent) {
13878      std::size_t i = _string.find(": ");
13879      if (i != std::string::npos)
13880          i += 2;
13881      else
13882          i = 0;
13883      stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n';
13884  }
13885  
13886  struct SummaryColumn {
13887  
13888      SummaryColumn( std::string _label, Colour::Code _colour )
13889      :   label( std::move( _label ) ),
13890          colour( _colour ) {}
13891      SummaryColumn addRow( std::size_t count ) {
13892          ReusableStringStream rss;
13893          rss << count;
13894          std::string row = rss.str();
13895          for (auto& oldRow : rows) {
13896              while (oldRow.size() < row.size())
13897                  oldRow = ' ' + oldRow;
13898              while (oldRow.size() > row.size())
13899                  row = ' ' + row;
13900          }
13901          rows.push_back(row);
13902          return *this;
13903      }
13904  
13905      std::string label;
13906      Colour::Code colour;
13907      std::vector<std::string> rows;
13908  
13909  };
13910  
13911  void ConsoleReporter::printTotals( Totals const& totals ) {
13912      if (totals.testCases.total() == 0) {
13913          stream << Colour(Colour::Warning) << "No tests ran\n";
13914      } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) {
13915          stream << Colour(Colour::ResultSuccess) << "All tests passed";
13916          stream << " ("
13917              << pluralise(totals.assertions.passed, "assertion") << " in "
13918              << pluralise(totals.testCases.passed, "test case") << ')'
13919              << '\n';
13920      } else {
13921  
13922          std::vector<SummaryColumn> columns;
13923          columns.push_back(SummaryColumn("", Colour::None)
13924                            .addRow(totals.testCases.total())
13925                            .addRow(totals.assertions.total()));
13926          columns.push_back(SummaryColumn("passed", Colour::Success)
13927                            .addRow(totals.testCases.passed)
13928                            .addRow(totals.assertions.passed));
13929          columns.push_back(SummaryColumn("failed", Colour::ResultError)
13930                            .addRow(totals.testCases.failed)
13931                            .addRow(totals.assertions.failed));
13932          columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure)
13933                            .addRow(totals.testCases.failedButOk)
13934                            .addRow(totals.assertions.failedButOk));
13935  
13936          printSummaryRow("test cases", columns, 0);
13937          printSummaryRow("assertions", columns, 1);
13938      }
13939  }
13940  void ConsoleReporter::printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row) {
13941      for (auto col : cols) {
13942          std::string value = col.rows[row];
13943          if (col.label.empty()) {
13944              stream << label << ": ";
13945              if (value != "0")
13946                  stream << value;
13947              else
13948                  stream << Colour(Colour::Warning) << "- none -";
13949          } else if (value != "0") {
13950              stream << Colour(Colour::LightGrey) << " | ";
13951              stream << Colour(col.colour)
13952                  << value << ' ' << col.label;
13953          }
13954      }
13955      stream << '\n';
13956  }
13957  
13958  void ConsoleReporter::printTotalsDivider(Totals const& totals) {
13959      if (totals.testCases.total() > 0) {
13960          std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());
13961          std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());
13962          std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());
13963          while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
13964              findMax(failedRatio, failedButOkRatio, passedRatio)++;
13965          while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)
13966              findMax(failedRatio, failedButOkRatio, passedRatio)--;
13967  
13968          stream << Colour(Colour::Error) << std::string(failedRatio, '=');
13969          stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '=');
13970          if (totals.testCases.allPassed())
13971              stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '=');
13972          else
13973              stream << Colour(Colour::Success) << std::string(passedRatio, '=');
13974      } else {
13975          stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '=');
13976      }
13977      stream << '\n';
13978  }
13979  void ConsoleReporter::printSummaryDivider() {
13980      stream << getLineOfChars<'-'>() << '\n';
13981  }
13982  
13983  void ConsoleReporter::printTestFilters() {
13984      if (m_config->testSpec().hasFilters())
13985          stream << Colour(Colour::BrightYellow) << "Filters: " << serializeFilters( m_config->getTestsOrTags() ) << '\n';
13986  }
13987  
13988  CATCH_REGISTER_REPORTER("console", ConsoleReporter)
13989  
13990  } // end namespace Catch
13991  
13992  #if defined(_MSC_VER)
13993  #pragma warning(pop)
13994  #endif
13995  // end catch_reporter_console.cpp
13996  // start catch_reporter_junit.cpp
13997  
13998  #include <cassert>
13999  #include <sstream>
14000  #include <ctime>
14001  #include <algorithm>
14002  
14003  namespace Catch {
14004  
14005      namespace {
14006          std::string getCurrentTimestamp() {
14007              // Beware, this is not reentrant because of backward compatibility issues
14008              // Also, UTC only, again because of backward compatibility (%z is C++11)
14009              time_t rawtime;
14010              std::time(&rawtime);
14011              auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
14012  
14013  #ifdef _MSC_VER
14014              std::tm timeInfo = {};
14015              gmtime_s(&timeInfo, &rawtime);
14016  #else
14017              std::tm* timeInfo;
14018              timeInfo = std::gmtime(&rawtime);
14019  #endif
14020  
14021              char timeStamp[timeStampSize];
14022              const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
14023  
14024  #ifdef _MSC_VER
14025              std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
14026  #else
14027              std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
14028  #endif
14029              return std::string(timeStamp);
14030          }
14031  
14032          std::string fileNameTag(const std::vector<std::string> &tags) {
14033              auto it = std::find_if(begin(tags),
14034                                     end(tags),
14035                                     [] (std::string const& tag) {return tag.front() == '#'; });
14036              if (it != tags.end())
14037                  return it->substr(1);
14038              return std::string();
14039          }
14040      } // anonymous namespace
14041  
14042      JunitReporter::JunitReporter( ReporterConfig const& _config )
14043          :   CumulativeReporterBase( _config ),
14044              xml( _config.stream() )
14045          {
14046              m_reporterPrefs.shouldRedirectStdOut = true;
14047              m_reporterPrefs.shouldReportAllAssertions = true;
14048          }
14049  
14050      JunitReporter::~JunitReporter() {}
14051  
14052      std::string JunitReporter::getDescription() {
14053          return "Reports test results in an XML format that looks like Ant's junitreport target";
14054      }
14055  
14056      void JunitReporter::noMatchingTestCases( std::string const& /*spec*/ ) {}
14057  
14058      void JunitReporter::testRunStarting( TestRunInfo const& runInfo )  {
14059          CumulativeReporterBase::testRunStarting( runInfo );
14060          xml.startElement( "testsuites" );
14061      }
14062  
14063      void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) {
14064          suiteTimer.start();
14065          stdOutForSuite.clear();
14066          stdErrForSuite.clear();
14067          unexpectedExceptions = 0;
14068          CumulativeReporterBase::testGroupStarting( groupInfo );
14069      }
14070  
14071      void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) {
14072          m_okToFail = testCaseInfo.okToFail();
14073      }
14074  
14075      bool JunitReporter::assertionEnded( AssertionStats const& assertionStats ) {
14076          if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
14077              unexpectedExceptions++;
14078          return CumulativeReporterBase::assertionEnded( assertionStats );
14079      }
14080  
14081      void JunitReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
14082          stdOutForSuite += testCaseStats.stdOut;
14083          stdErrForSuite += testCaseStats.stdErr;
14084          CumulativeReporterBase::testCaseEnded( testCaseStats );
14085      }
14086  
14087      void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
14088          double suiteTime = suiteTimer.getElapsedSeconds();
14089          CumulativeReporterBase::testGroupEnded( testGroupStats );
14090          writeGroup( *m_testGroups.back(), suiteTime );
14091      }
14092  
14093      void JunitReporter::testRunEndedCumulative() {
14094          xml.endElement();
14095      }
14096  
14097      void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
14098          XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
14099  
14100          TestGroupStats const& stats = groupNode.value;
14101          xml.writeAttribute( "name", stats.groupInfo.name );
14102          xml.writeAttribute( "errors", unexpectedExceptions );
14103          xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
14104          xml.writeAttribute( "tests", stats.totals.assertions.total() );
14105          xml.writeAttribute( "hostname", "tbd" ); // !TBD
14106          if( m_config->showDurations() == ShowDurations::Never )
14107              xml.writeAttribute( "time", "" );
14108          else
14109              xml.writeAttribute( "time", suiteTime );
14110          xml.writeAttribute( "timestamp", getCurrentTimestamp() );
14111  
14112          // Write properties if there are any
14113          if (m_config->hasTestFilters() || m_config->rngSeed() != 0) {
14114              auto properties = xml.scopedElement("properties");
14115              if (m_config->hasTestFilters()) {
14116                  xml.scopedElement("property")
14117                      .writeAttribute("name", "filters")
14118                      .writeAttribute("value", serializeFilters(m_config->getTestsOrTags()));
14119              }
14120              if (m_config->rngSeed() != 0) {
14121                  xml.scopedElement("property")
14122                      .writeAttribute("name", "random-seed")
14123                      .writeAttribute("value", m_config->rngSeed());
14124              }
14125          }
14126  
14127          // Write test cases
14128          for( auto const& child : groupNode.children )
14129              writeTestCase( *child );
14130  
14131          xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), false );
14132          xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), false );
14133      }
14134  
14135      void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) {
14136          TestCaseStats const& stats = testCaseNode.value;
14137  
14138          // All test cases have exactly one section - which represents the
14139          // test case itself. That section may have 0-n nested sections
14140          assert( testCaseNode.children.size() == 1 );
14141          SectionNode const& rootSection = *testCaseNode.children.front();
14142  
14143          std::string className = stats.testInfo.className;
14144  
14145          if( className.empty() ) {
14146              className = fileNameTag(stats.testInfo.tags);
14147              if ( className.empty() )
14148                  className = "global";
14149          }
14150  
14151          if ( !m_config->name().empty() )
14152              className = m_config->name() + "." + className;
14153  
14154          writeSection( className, "", rootSection );
14155      }
14156  
14157      void JunitReporter::writeSection(  std::string const& className,
14158                          std::string const& rootName,
14159                          SectionNode const& sectionNode ) {
14160          std::string name = trim( sectionNode.stats.sectionInfo.name );
14161          if( !rootName.empty() )
14162              name = rootName + '/' + name;
14163  
14164          if( !sectionNode.assertions.empty() ||
14165              !sectionNode.stdOut.empty() ||
14166              !sectionNode.stdErr.empty() ) {
14167              XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
14168              if( className.empty() ) {
14169                  xml.writeAttribute( "classname", name );
14170                  xml.writeAttribute( "name", "root" );
14171              }
14172              else {
14173                  xml.writeAttribute( "classname", className );
14174                  xml.writeAttribute( "name", name );
14175              }
14176              xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) );
14177  
14178              writeAssertions( sectionNode );
14179  
14180              if( !sectionNode.stdOut.empty() )
14181                  xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
14182              if( !sectionNode.stdErr.empty() )
14183                  xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
14184          }
14185          for( auto const& childNode : sectionNode.childSections )
14186              if( className.empty() )
14187                  writeSection( name, "", *childNode );
14188              else
14189                  writeSection( className, name, *childNode );
14190      }
14191  
14192      void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {
14193          for( auto const& assertion : sectionNode.assertions )
14194              writeAssertion( assertion );
14195      }
14196  
14197      void JunitReporter::writeAssertion( AssertionStats const& stats ) {
14198          AssertionResult const& result = stats.assertionResult;
14199          if( !result.isOk() ) {
14200              std::string elementName;
14201              switch( result.getResultType() ) {
14202                  case ResultWas::ThrewException:
14203                  case ResultWas::FatalErrorCondition:
14204                      elementName = "error";
14205                      break;
14206                  case ResultWas::ExplicitFailure:
14207                      elementName = "failure";
14208                      break;
14209                  case ResultWas::ExpressionFailed:
14210                      elementName = "failure";
14211                      break;
14212                  case ResultWas::DidntThrowException:
14213                      elementName = "failure";
14214                      break;
14215  
14216                  // We should never see these here:
14217                  case ResultWas::Info:
14218                  case ResultWas::Warning:
14219                  case ResultWas::Ok:
14220                  case ResultWas::Unknown:
14221                  case ResultWas::FailureBit:
14222                  case ResultWas::Exception:
14223                      elementName = "internalError";
14224                      break;
14225              }
14226  
14227              XmlWriter::ScopedElement e = xml.scopedElement( elementName );
14228  
14229              xml.writeAttribute( "message", result.getExpandedExpression() );
14230              xml.writeAttribute( "type", result.getTestMacroName() );
14231  
14232              ReusableStringStream rss;
14233              if( !result.getMessage().empty() )
14234                  rss << result.getMessage() << '\n';
14235              for( auto const& msg : stats.infoMessages )
14236                  if( msg.type == ResultWas::Info )
14237                      rss << msg.message << '\n';
14238  
14239              rss << "at " << result.getSourceInfo();
14240              xml.writeText( rss.str(), false );
14241          }
14242      }
14243  
14244      CATCH_REGISTER_REPORTER( "junit", JunitReporter )
14245  
14246  } // end namespace Catch
14247  // end catch_reporter_junit.cpp
14248  // start catch_reporter_listening.cpp
14249  
14250  #include <cassert>
14251  
14252  namespace Catch {
14253  
14254      ListeningReporter::ListeningReporter() {
14255          // We will assume that listeners will always want all assertions
14256          m_preferences.shouldReportAllAssertions = true;
14257      }
14258  
14259      void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) {
14260          m_listeners.push_back( std::move( listener ) );
14261      }
14262  
14263      void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {
14264          assert(!m_reporter && "Listening reporter can wrap only 1 real reporter");
14265          m_reporter = std::move( reporter );
14266          m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;
14267      }
14268  
14269      ReporterPreferences ListeningReporter::getPreferences() const {
14270          return m_preferences;
14271      }
14272  
14273      std::set<Verbosity> ListeningReporter::getSupportedVerbosities() {
14274          return std::set<Verbosity>{ };
14275      }
14276  
14277      void ListeningReporter::noMatchingTestCases( std::string const& spec ) {
14278          for ( auto const& listener : m_listeners ) {
14279              listener->noMatchingTestCases( spec );
14280          }
14281          m_reporter->noMatchingTestCases( spec );
14282      }
14283  
14284      void ListeningReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {
14285          for ( auto const& listener : m_listeners ) {
14286              listener->benchmarkStarting( benchmarkInfo );
14287          }
14288          m_reporter->benchmarkStarting( benchmarkInfo );
14289      }
14290      void ListeningReporter::benchmarkEnded( BenchmarkStats const& benchmarkStats ) {
14291          for ( auto const& listener : m_listeners ) {
14292              listener->benchmarkEnded( benchmarkStats );
14293          }
14294          m_reporter->benchmarkEnded( benchmarkStats );
14295      }
14296  
14297      void ListeningReporter::testRunStarting( TestRunInfo const& testRunInfo ) {
14298          for ( auto const& listener : m_listeners ) {
14299              listener->testRunStarting( testRunInfo );
14300          }
14301          m_reporter->testRunStarting( testRunInfo );
14302      }
14303  
14304      void ListeningReporter::testGroupStarting( GroupInfo const& groupInfo ) {
14305          for ( auto const& listener : m_listeners ) {
14306              listener->testGroupStarting( groupInfo );
14307          }
14308          m_reporter->testGroupStarting( groupInfo );
14309      }
14310  
14311      void ListeningReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
14312          for ( auto const& listener : m_listeners ) {
14313              listener->testCaseStarting( testInfo );
14314          }
14315          m_reporter->testCaseStarting( testInfo );
14316      }
14317  
14318      void ListeningReporter::sectionStarting( SectionInfo const& sectionInfo ) {
14319          for ( auto const& listener : m_listeners ) {
14320              listener->sectionStarting( sectionInfo );
14321          }
14322          m_reporter->sectionStarting( sectionInfo );
14323      }
14324  
14325      void ListeningReporter::assertionStarting( AssertionInfo const& assertionInfo ) {
14326          for ( auto const& listener : m_listeners ) {
14327              listener->assertionStarting( assertionInfo );
14328          }
14329          m_reporter->assertionStarting( assertionInfo );
14330      }
14331  
14332      // The return value indicates if the messages buffer should be cleared:
14333      bool ListeningReporter::assertionEnded( AssertionStats const& assertionStats ) {
14334          for( auto const& listener : m_listeners ) {
14335              static_cast<void>( listener->assertionEnded( assertionStats ) );
14336          }
14337          return m_reporter->assertionEnded( assertionStats );
14338      }
14339  
14340      void ListeningReporter::sectionEnded( SectionStats const& sectionStats ) {
14341          for ( auto const& listener : m_listeners ) {
14342              listener->sectionEnded( sectionStats );
14343          }
14344          m_reporter->sectionEnded( sectionStats );
14345      }
14346  
14347      void ListeningReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
14348          for ( auto const& listener : m_listeners ) {
14349              listener->testCaseEnded( testCaseStats );
14350          }
14351          m_reporter->testCaseEnded( testCaseStats );
14352      }
14353  
14354      void ListeningReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
14355          for ( auto const& listener : m_listeners ) {
14356              listener->testGroupEnded( testGroupStats );
14357          }
14358          m_reporter->testGroupEnded( testGroupStats );
14359      }
14360  
14361      void ListeningReporter::testRunEnded( TestRunStats const& testRunStats ) {
14362          for ( auto const& listener : m_listeners ) {
14363              listener->testRunEnded( testRunStats );
14364          }
14365          m_reporter->testRunEnded( testRunStats );
14366      }
14367  
14368      void ListeningReporter::skipTest( TestCaseInfo const& testInfo ) {
14369          for ( auto const& listener : m_listeners ) {
14370              listener->skipTest( testInfo );
14371          }
14372          m_reporter->skipTest( testInfo );
14373      }
14374  
14375      bool ListeningReporter::isMulti() const {
14376          return true;
14377      }
14378  
14379  } // end namespace Catch
14380  // end catch_reporter_listening.cpp
14381  // start catch_reporter_xml.cpp
14382  
14383  #if defined(_MSC_VER)
14384  #pragma warning(push)
14385  #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
14386                                // Note that 4062 (not all labels are handled
14387                                // and default is missing) is enabled
14388  #endif
14389  
14390  namespace Catch {
14391      XmlReporter::XmlReporter( ReporterConfig const& _config )
14392      :   StreamingReporterBase( _config ),
14393          m_xml(_config.stream())
14394      {
14395          m_reporterPrefs.shouldRedirectStdOut = true;
14396          m_reporterPrefs.shouldReportAllAssertions = true;
14397      }
14398  
14399      XmlReporter::~XmlReporter() = default;
14400  
14401      std::string XmlReporter::getDescription() {
14402          return "Reports test results as an XML document";
14403      }
14404  
14405      std::string XmlReporter::getStylesheetRef() const {
14406          return std::string();
14407      }
14408  
14409      void XmlReporter::writeSourceInfo( SourceLineInfo const& sourceInfo ) {
14410          m_xml
14411              .writeAttribute( "filename", sourceInfo.file )
14412              .writeAttribute( "line", sourceInfo.line );
14413      }
14414  
14415      void XmlReporter::noMatchingTestCases( std::string const& s ) {
14416          StreamingReporterBase::noMatchingTestCases( s );
14417      }
14418  
14419      void XmlReporter::testRunStarting( TestRunInfo const& testInfo ) {
14420          StreamingReporterBase::testRunStarting( testInfo );
14421          std::string stylesheetRef = getStylesheetRef();
14422          if( !stylesheetRef.empty() )
14423              m_xml.writeStylesheetRef( stylesheetRef );
14424          m_xml.startElement( "Catch" );
14425          if( !m_config->name().empty() )
14426              m_xml.writeAttribute( "name", m_config->name() );
14427          if (m_config->testSpec().hasFilters())
14428              m_xml.writeAttribute( "filters", serializeFilters( m_config->getTestsOrTags() ) );
14429          if( m_config->rngSeed() != 0 )
14430              m_xml.scopedElement( "Randomness" )
14431                  .writeAttribute( "seed", m_config->rngSeed() );
14432      }
14433  
14434      void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) {
14435          StreamingReporterBase::testGroupStarting( groupInfo );
14436          m_xml.startElement( "Group" )
14437              .writeAttribute( "name", groupInfo.name );
14438      }
14439  
14440      void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
14441          StreamingReporterBase::testCaseStarting(testInfo);
14442          m_xml.startElement( "TestCase" )
14443              .writeAttribute( "name", trim( testInfo.name ) )
14444              .writeAttribute( "description", testInfo.description )
14445              .writeAttribute( "tags", testInfo.tagsAsString() );
14446  
14447          writeSourceInfo( testInfo.lineInfo );
14448  
14449          if ( m_config->showDurations() == ShowDurations::Always )
14450              m_testCaseTimer.start();
14451          m_xml.ensureTagClosed();
14452      }
14453  
14454      void XmlReporter::sectionStarting( SectionInfo const& sectionInfo ) {
14455          StreamingReporterBase::sectionStarting( sectionInfo );
14456          if( m_sectionDepth++ > 0 ) {
14457              m_xml.startElement( "Section" )
14458                  .writeAttribute( "name", trim( sectionInfo.name ) );
14459              writeSourceInfo( sectionInfo.lineInfo );
14460              m_xml.ensureTagClosed();
14461          }
14462      }
14463  
14464      void XmlReporter::assertionStarting( AssertionInfo const& ) { }
14465  
14466      bool XmlReporter::assertionEnded( AssertionStats const& assertionStats ) {
14467  
14468          AssertionResult const& result = assertionStats.assertionResult;
14469  
14470          bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
14471  
14472          if( includeResults || result.getResultType() == ResultWas::Warning ) {
14473              // Print any info messages in <Info> tags.
14474              for( auto const& msg : assertionStats.infoMessages ) {
14475                  if( msg.type == ResultWas::Info && includeResults ) {
14476                      m_xml.scopedElement( "Info" )
14477                              .writeText( msg.message );
14478                  } else if ( msg.type == ResultWas::Warning ) {
14479                      m_xml.scopedElement( "Warning" )
14480                              .writeText( msg.message );
14481                  }
14482              }
14483          }
14484  
14485          // Drop out if result was successful but we're not printing them.
14486          if( !includeResults && result.getResultType() != ResultWas::Warning )
14487              return true;
14488  
14489          // Print the expression if there is one.
14490          if( result.hasExpression() ) {
14491              m_xml.startElement( "Expression" )
14492                  .writeAttribute( "success", result.succeeded() )
14493                  .writeAttribute( "type", result.getTestMacroName() );
14494  
14495              writeSourceInfo( result.getSourceInfo() );
14496  
14497              m_xml.scopedElement( "Original" )
14498                  .writeText( result.getExpression() );
14499              m_xml.scopedElement( "Expanded" )
14500                  .writeText( result.getExpandedExpression() );
14501          }
14502  
14503          // And... Print a result applicable to each result type.
14504          switch( result.getResultType() ) {
14505              case ResultWas::ThrewException:
14506                  m_xml.startElement( "Exception" );
14507                  writeSourceInfo( result.getSourceInfo() );
14508                  m_xml.writeText( result.getMessage() );
14509                  m_xml.endElement();
14510                  break;
14511              case ResultWas::FatalErrorCondition:
14512                  m_xml.startElement( "FatalErrorCondition" );
14513                  writeSourceInfo( result.getSourceInfo() );
14514                  m_xml.writeText( result.getMessage() );
14515                  m_xml.endElement();
14516                  break;
14517              case ResultWas::Info:
14518                  m_xml.scopedElement( "Info" )
14519                      .writeText( result.getMessage() );
14520                  break;
14521              case ResultWas::Warning:
14522                  // Warning will already have been written
14523                  break;
14524              case ResultWas::ExplicitFailure:
14525                  m_xml.startElement( "Failure" );
14526                  writeSourceInfo( result.getSourceInfo() );
14527                  m_xml.writeText( result.getMessage() );
14528                  m_xml.endElement();
14529                  break;
14530              default:
14531                  break;
14532          }
14533  
14534          if( result.hasExpression() )
14535              m_xml.endElement();
14536  
14537          return true;
14538      }
14539  
14540      void XmlReporter::sectionEnded( SectionStats const& sectionStats ) {
14541          StreamingReporterBase::sectionEnded( sectionStats );
14542          if( --m_sectionDepth > 0 ) {
14543              XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
14544              e.writeAttribute( "successes", sectionStats.assertions.passed );
14545              e.writeAttribute( "failures", sectionStats.assertions.failed );
14546              e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
14547  
14548              if ( m_config->showDurations() == ShowDurations::Always )
14549                  e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
14550  
14551              m_xml.endElement();
14552          }
14553      }
14554  
14555      void XmlReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
14556          StreamingReporterBase::testCaseEnded( testCaseStats );
14557          XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
14558          e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
14559  
14560          if ( m_config->showDurations() == ShowDurations::Always )
14561              e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
14562  
14563          if( !testCaseStats.stdOut.empty() )
14564              m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false );
14565          if( !testCaseStats.stdErr.empty() )
14566              m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false );
14567  
14568          m_xml.endElement();
14569      }
14570  
14571      void XmlReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
14572          StreamingReporterBase::testGroupEnded( testGroupStats );
14573          // TODO: Check testGroupStats.aborting and act accordingly.
14574          m_xml.scopedElement( "OverallResults" )
14575              .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
14576              .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
14577              .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
14578          m_xml.endElement();
14579      }
14580  
14581      void XmlReporter::testRunEnded( TestRunStats const& testRunStats ) {
14582          StreamingReporterBase::testRunEnded( testRunStats );
14583          m_xml.scopedElement( "OverallResults" )
14584              .writeAttribute( "successes", testRunStats.totals.assertions.passed )
14585              .writeAttribute( "failures", testRunStats.totals.assertions.failed )
14586              .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
14587          m_xml.endElement();
14588      }
14589  
14590      CATCH_REGISTER_REPORTER( "xml", XmlReporter )
14591  
14592  } // end namespace Catch
14593  
14594  #if defined(_MSC_VER)
14595  #pragma warning(pop)
14596  #endif
14597  // end catch_reporter_xml.cpp
14598  
14599  namespace Catch {
14600      LeakDetector leakDetector;
14601  }
14602  
14603  #ifdef __clang__
14604  #pragma clang diagnostic pop
14605  #endif
14606  
14607  // end catch_impl.hpp
14608  #endif
14609  
14610  #ifdef CATCH_CONFIG_MAIN
14611  // start catch_default_main.hpp
14612  
14613  #ifndef __OBJC__
14614  
14615  #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
14616  // Standard C/C++ Win32 Unicode wmain entry point
14617  extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
14618  #else
14619  // Standard C/C++ main entry point
14620  int main (int argc, char * argv[]) {
14621  #endif
14622  
14623      return Catch::Session().run( argc, argv );
14624  }
14625  
14626  #else // __OBJC__
14627  
14628  // Objective-C entry point
14629  int main (int argc, char * const argv[]) {
14630  #if !CATCH_ARC_ENABLED
14631      NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
14632  #endif
14633  
14634      Catch::registerTestMethods();
14635      int result = Catch::Session().run( argc, (char**)argv );
14636  
14637  #if !CATCH_ARC_ENABLED
14638      [pool drain];
14639  #endif
14640  
14641      return result;
14642  }
14643  
14644  #endif // __OBJC__
14645  
14646  // end catch_default_main.hpp
14647  #endif
14648  
14649  #if !defined(CATCH_CONFIG_IMPL_ONLY)
14650  
14651  #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
14652  #  undef CLARA_CONFIG_MAIN
14653  #endif
14654  
14655  #if !defined(CATCH_CONFIG_DISABLE)
14656  //////
14657  // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
14658  #ifdef CATCH_CONFIG_PREFIX_ALL
14659  
14660  #define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
14661  #define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
14662  
14663  #define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
14664  #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
14665  #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
14666  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14667  #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
14668  #endif// CATCH_CONFIG_DISABLE_MATCHERS
14669  #define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
14670  
14671  #define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14672  #define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
14673  #define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14674  #define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14675  #define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
14676  
14677  #define CATCH_CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14678  #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
14679  #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
14680  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14681  #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
14682  #endif // CATCH_CONFIG_DISABLE_MATCHERS
14683  #define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14684  
14685  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14686  #define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
14687  
14688  #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
14689  #endif // CATCH_CONFIG_DISABLE_MATCHERS
14690  
14691  #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
14692  #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
14693  #define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE",__VA_ARGS__ )
14694  
14695  #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
14696  #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
14697  #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
14698  #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
14699  #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
14700  #define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
14701  #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
14702  #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14703  #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14704  
14705  #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
14706  
14707  #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
14708  #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
14709  #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
14710  #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
14711  #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
14712  #else
14713  #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
14714  #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
14715  #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
14716  #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
14717  #endif
14718  
14719  #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
14720  #define CATCH_STATIC_REQUIRE( ... )       static_assert(   __VA_ARGS__ ,      #__VA_ARGS__ );     CATCH_SUCCEED( #__VA_ARGS__ )
14721  #define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ )
14722  #else
14723  #define CATCH_STATIC_REQUIRE( ... )       CATCH_REQUIRE( __VA_ARGS__ )
14724  #define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ )
14725  #endif
14726  
14727  // "BDD-style" convenience wrappers
14728  #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
14729  #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
14730  #define CATCH_GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    Given: " << desc )
14731  #define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
14732  #define CATCH_WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     When: " << desc )
14733  #define CATCH_AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
14734  #define CATCH_THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc )
14735  #define CATCH_AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc )
14736  
14737  // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
14738  #else
14739  
14740  #define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__  )
14741  #define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
14742  
14743  #define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
14744  #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
14745  #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
14746  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14747  #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
14748  #endif // CATCH_CONFIG_DISABLE_MATCHERS
14749  #define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
14750  
14751  #define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14752  #define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
14753  #define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14754  #define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14755  #define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
14756  
14757  #define CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14758  #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
14759  #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
14760  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14761  #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
14762  #endif // CATCH_CONFIG_DISABLE_MATCHERS
14763  #define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14764  
14765  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14766  #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
14767  
14768  #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
14769  #endif // CATCH_CONFIG_DISABLE_MATCHERS
14770  
14771  #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
14772  #define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "UNSCOPED_INFO", msg )
14773  #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
14774  #define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ )
14775  
14776  #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
14777  #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
14778  #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
14779  #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
14780  #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
14781  #define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
14782  #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
14783  #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14784  #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14785  #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
14786  
14787  #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
14788  #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
14789  #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
14790  #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
14791  #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
14792  #else
14793  #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
14794  #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
14795  #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
14796  #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
14797  #endif
14798  
14799  #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
14800  #define STATIC_REQUIRE( ... )       static_assert(   __VA_ARGS__,  #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ )
14801  #define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" )
14802  #else
14803  #define STATIC_REQUIRE( ... )       REQUIRE( __VA_ARGS__ )
14804  #define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ )
14805  #endif
14806  
14807  #endif
14808  
14809  #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
14810  
14811  // "BDD-style" convenience wrappers
14812  #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
14813  #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
14814  
14815  #define GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    Given: " << desc )
14816  #define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
14817  #define WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     When: " << desc )
14818  #define AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
14819  #define THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc )
14820  #define AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc )
14821  
14822  using Catch::Detail::Approx;
14823  
14824  #else // CATCH_CONFIG_DISABLE
14825  
14826  //////
14827  // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
14828  #ifdef CATCH_CONFIG_PREFIX_ALL
14829  
14830  #define CATCH_REQUIRE( ... )        (void)(0)
14831  #define CATCH_REQUIRE_FALSE( ... )  (void)(0)
14832  
14833  #define CATCH_REQUIRE_THROWS( ... ) (void)(0)
14834  #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
14835  #define CATCH_REQUIRE_THROWS_WITH( expr, matcher )     (void)(0)
14836  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14837  #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
14838  #endif// CATCH_CONFIG_DISABLE_MATCHERS
14839  #define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)
14840  
14841  #define CATCH_CHECK( ... )         (void)(0)
14842  #define CATCH_CHECK_FALSE( ... )   (void)(0)
14843  #define CATCH_CHECKED_IF( ... )    if (__VA_ARGS__)
14844  #define CATCH_CHECKED_ELSE( ... )  if (!(__VA_ARGS__))
14845  #define CATCH_CHECK_NOFAIL( ... )  (void)(0)
14846  
14847  #define CATCH_CHECK_THROWS( ... )  (void)(0)
14848  #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
14849  #define CATCH_CHECK_THROWS_WITH( expr, matcher )     (void)(0)
14850  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14851  #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
14852  #endif // CATCH_CONFIG_DISABLE_MATCHERS
14853  #define CATCH_CHECK_NOTHROW( ... ) (void)(0)
14854  
14855  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14856  #define CATCH_CHECK_THAT( arg, matcher )   (void)(0)
14857  
14858  #define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
14859  #endif // CATCH_CONFIG_DISABLE_MATCHERS
14860  
14861  #define CATCH_INFO( msg )    (void)(0)
14862  #define CATCH_WARN( msg )    (void)(0)
14863  #define CATCH_CAPTURE( msg ) (void)(0)
14864  
14865  #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
14866  #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
14867  #define CATCH_METHOD_AS_TEST_CASE( method, ... )
14868  #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
14869  #define CATCH_SECTION( ... )
14870  #define CATCH_DYNAMIC_SECTION( ... )
14871  #define CATCH_FAIL( ... ) (void)(0)
14872  #define CATCH_FAIL_CHECK( ... ) (void)(0)
14873  #define CATCH_SUCCEED( ... ) (void)(0)
14874  
14875  #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
14876  
14877  #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
14878  #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) )
14879  #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className )
14880  #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
14881  #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
14882  #else
14883  #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) ) )
14884  #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className ) )
14885  #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
14886  #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
14887  #endif
14888  
14889  // "BDD-style" convenience wrappers
14890  #define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
14891  #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
14892  #define CATCH_GIVEN( desc )
14893  #define CATCH_AND_GIVEN( desc )
14894  #define CATCH_WHEN( desc )
14895  #define CATCH_AND_WHEN( desc )
14896  #define CATCH_THEN( desc )
14897  #define CATCH_AND_THEN( desc )
14898  
14899  #define CATCH_STATIC_REQUIRE( ... )       (void)(0)
14900  #define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0)
14901  
14902  // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
14903  #else
14904  
14905  #define REQUIRE( ... )       (void)(0)
14906  #define REQUIRE_FALSE( ... ) (void)(0)
14907  
14908  #define REQUIRE_THROWS( ... ) (void)(0)
14909  #define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
14910  #define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
14911  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14912  #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
14913  #endif // CATCH_CONFIG_DISABLE_MATCHERS
14914  #define REQUIRE_NOTHROW( ... ) (void)(0)
14915  
14916  #define CHECK( ... ) (void)(0)
14917  #define CHECK_FALSE( ... ) (void)(0)
14918  #define CHECKED_IF( ... ) if (__VA_ARGS__)
14919  #define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
14920  #define CHECK_NOFAIL( ... ) (void)(0)
14921  
14922  #define CHECK_THROWS( ... )  (void)(0)
14923  #define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
14924  #define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
14925  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14926  #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
14927  #endif // CATCH_CONFIG_DISABLE_MATCHERS
14928  #define CHECK_NOTHROW( ... ) (void)(0)
14929  
14930  #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14931  #define CHECK_THAT( arg, matcher ) (void)(0)
14932  
14933  #define REQUIRE_THAT( arg, matcher ) (void)(0)
14934  #endif // CATCH_CONFIG_DISABLE_MATCHERS
14935  
14936  #define INFO( msg ) (void)(0)
14937  #define WARN( msg ) (void)(0)
14938  #define CAPTURE( msg ) (void)(0)
14939  
14940  #define TEST_CASE( ... )  INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
14941  #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
14942  #define METHOD_AS_TEST_CASE( method, ... )
14943  #define REGISTER_TEST_CASE( Function, ... ) (void)(0)
14944  #define SECTION( ... )
14945  #define DYNAMIC_SECTION( ... )
14946  #define FAIL( ... ) (void)(0)
14947  #define FAIL_CHECK( ... ) (void)(0)
14948  #define SUCCEED( ... ) (void)(0)
14949  #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
14950  
14951  #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
14952  #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) )
14953  #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className )
14954  #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
14955  #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
14956  #else
14957  #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) ) )
14958  #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className ) )
14959  #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
14960  #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
14961  #endif
14962  
14963  #define STATIC_REQUIRE( ... )       (void)(0)
14964  #define STATIC_REQUIRE_FALSE( ... ) (void)(0)
14965  
14966  #endif
14967  
14968  #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
14969  
14970  // "BDD-style" convenience wrappers
14971  #define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) )
14972  #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
14973  
14974  #define GIVEN( desc )
14975  #define AND_GIVEN( desc )
14976  #define WHEN( desc )
14977  #define AND_WHEN( desc )
14978  #define THEN( desc )
14979  #define AND_THEN( desc )
14980  
14981  using Catch::Detail::Approx;
14982  
14983  #endif
14984  
14985  #endif // ! CATCH_CONFIG_IMPL_ONLY
14986  
14987  // start catch_reenable_warnings.h
14988  
14989  
14990  #ifdef __clang__
14991  #    ifdef __ICC // icpc defines the __clang__ macro
14992  #        pragma warning(pop)
14993  #    else
14994  #        pragma clang diagnostic pop
14995  #    endif
14996  #elif defined __GNUC__
14997  #    pragma GCC diagnostic pop
14998  #endif
14999  
15000  // end catch_reenable_warnings.h
15001  // end catch.hpp
15002  #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
15003