Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

17878 rindas
638KB

  1. /*
  2. * Catch v2.13.3
  3. * Generated: 2020-10-31 18:20:31.045274
  4. * ----------------------------------------------------------
  5. * This file has been merged from multiple headers. Please don't edit it directly
  6. * Copyright (c) 2020 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. #define CATCH_VERSION_MAJOR 2
  15. #define CATCH_VERSION_MINOR 13
  16. #define CATCH_VERSION_PATCH 3
  17. #ifdef __clang__
  18. # pragma clang system_header
  19. #elif defined __GNUC__
  20. # pragma GCC system_header
  21. #endif
  22. // start catch_suppress_warnings.h
  23. #ifdef __clang__
  24. # ifdef __ICC // icpc defines the __clang__ macro
  25. # pragma warning(push)
  26. # pragma warning(disable: 161 1682)
  27. # else // __ICC
  28. # pragma clang diagnostic push
  29. # pragma clang diagnostic ignored "-Wpadded"
  30. # pragma clang diagnostic ignored "-Wswitch-enum"
  31. # pragma clang diagnostic ignored "-Wcovered-switch-default"
  32. # endif
  33. #elif defined __GNUC__
  34. // Because REQUIREs trigger GCC's -Wparentheses, and because still
  35. // supported version of g++ have only buggy support for _Pragmas,
  36. // Wparentheses have to be suppressed globally.
  37. # pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details
  38. # pragma GCC diagnostic push
  39. # pragma GCC diagnostic ignored "-Wunused-variable"
  40. # pragma GCC diagnostic ignored "-Wpadded"
  41. #endif
  42. // end catch_suppress_warnings.h
  43. #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
  44. # define CATCH_IMPL
  45. # define CATCH_CONFIG_ALL_PARTS
  46. #endif
  47. // In the impl file, we want to have access to all parts of the headers
  48. // Can also be used to sanely support PCHs
  49. #if defined(CATCH_CONFIG_ALL_PARTS)
  50. # define CATCH_CONFIG_EXTERNAL_INTERFACES
  51. # if defined(CATCH_CONFIG_DISABLE_MATCHERS)
  52. # undef CATCH_CONFIG_DISABLE_MATCHERS
  53. # endif
  54. # if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
  55. # define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
  56. # endif
  57. #endif
  58. #if !defined(CATCH_CONFIG_IMPL_ONLY)
  59. // start catch_platform.h
  60. #ifdef __APPLE__
  61. # include <TargetConditionals.h>
  62. # if TARGET_OS_OSX == 1
  63. # define CATCH_PLATFORM_MAC
  64. # elif TARGET_OS_IPHONE == 1
  65. # define CATCH_PLATFORM_IPHONE
  66. # endif
  67. #elif defined(linux) || defined(__linux) || defined(__linux__)
  68. # define CATCH_PLATFORM_LINUX
  69. #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
  70. # define CATCH_PLATFORM_WINDOWS
  71. #endif
  72. // end catch_platform.h
  73. #ifdef CATCH_IMPL
  74. # ifndef CLARA_CONFIG_MAIN
  75. # define CLARA_CONFIG_MAIN_NOT_DEFINED
  76. # define CLARA_CONFIG_MAIN
  77. # endif
  78. #endif
  79. // start catch_user_interfaces.h
  80. namespace Catch {
  81. unsigned int rngSeed();
  82. }
  83. // end catch_user_interfaces.h
  84. // start catch_tag_alias_autoregistrar.h
  85. // start catch_common.h
  86. // start catch_compiler_capabilities.h
  87. // Detect a number of compiler features - by compiler
  88. // The following features are defined:
  89. //
  90. // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
  91. // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
  92. // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
  93. // CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
  94. // ****************
  95. // Note to maintainers: if new toggles are added please document them
  96. // in configuration.md, too
  97. // ****************
  98. // In general each macro has a _NO_<feature name> form
  99. // (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
  100. // Many features, at point of detection, define an _INTERNAL_ macro, so they
  101. // can be combined, en-mass, with the _NO_ forms later.
  102. #ifdef __cplusplus
  103. # if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
  104. # define CATCH_CPP14_OR_GREATER
  105. # endif
  106. # if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
  107. # define CATCH_CPP17_OR_GREATER
  108. # endif
  109. #endif
  110. // We have to avoid both ICC and Clang, because they try to mask themselves
  111. // as gcc, and we want only GCC in this block
  112. #if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__)
  113. # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" )
  114. # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" )
  115. # define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__)
  116. #endif
  117. #if defined(__clang__)
  118. # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" )
  119. # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" )
  120. // As of this writing, IBM XL's implementation of __builtin_constant_p has a bug
  121. // which results in calls to destructors being emitted for each temporary,
  122. // without a matching initialization. In practice, this can result in something
  123. // like `std::string::~string` being called on an uninitialized value.
  124. //
  125. // For example, this code will likely segfault under IBM XL:
  126. // ```
  127. // REQUIRE(std::string("12") + "34" == "1234")
  128. // ```
  129. //
  130. // Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented.
  131. # if !defined(__ibmxl__) && !defined(__CUDACC__)
  132. # define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */
  133. # endif
  134. # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  135. _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
  136. _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
  137. # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
  138. _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
  139. # define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
  140. _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
  141. # define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
  142. _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" )
  143. # define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
  144. _Pragma( "clang diagnostic ignored \"-Wunused-template\"" )
  145. #endif // __clang__
  146. ////////////////////////////////////////////////////////////////////////////////
  147. // Assume that non-Windows platforms support posix signals by default
  148. #if !defined(CATCH_PLATFORM_WINDOWS)
  149. #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
  150. #endif
  151. ////////////////////////////////////////////////////////////////////////////////
  152. // We know some environments not to support full POSIX signals
  153. #if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
  154. #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
  155. #endif
  156. #ifdef __OS400__
  157. # define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
  158. # define CATCH_CONFIG_COLOUR_NONE
  159. #endif
  160. ////////////////////////////////////////////////////////////////////////////////
  161. // Android somehow still does not support std::to_string
  162. #if defined(__ANDROID__)
  163. # define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
  164. # define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE
  165. #endif
  166. ////////////////////////////////////////////////////////////////////////////////
  167. // Not all Windows environments support SEH properly
  168. #if defined(__MINGW32__)
  169. # define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
  170. #endif
  171. ////////////////////////////////////////////////////////////////////////////////
  172. // PS4
  173. #if defined(__ORBIS__)
  174. # define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
  175. #endif
  176. ////////////////////////////////////////////////////////////////////////////////
  177. // Cygwin
  178. #ifdef __CYGWIN__
  179. // Required for some versions of Cygwin to declare gettimeofday
  180. // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
  181. # define _BSD_SOURCE
  182. // some versions of cygwin (most) do not support std::to_string. Use the libstd check.
  183. // https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
  184. # if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
  185. && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
  186. # define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
  187. # endif
  188. #endif // __CYGWIN__
  189. ////////////////////////////////////////////////////////////////////////////////
  190. // Visual C++
  191. #if defined(_MSC_VER)
  192. # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
  193. # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) )
  194. // Universal Windows platform does not support SEH
  195. // Or console colours (or console at all...)
  196. # if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
  197. # define CATCH_CONFIG_COLOUR_NONE
  198. # else
  199. # define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
  200. # endif
  201. // MSVC traditional preprocessor needs some workaround for __VA_ARGS__
  202. // _MSVC_TRADITIONAL == 0 means new conformant preprocessor
  203. // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
  204. # if !defined(__clang__) // Handle Clang masquerading for msvc
  205. # if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
  206. # define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  207. # endif // MSVC_TRADITIONAL
  208. # endif // __clang__
  209. #endif // _MSC_VER
  210. #if defined(_REENTRANT) || defined(_MSC_VER)
  211. // Enable async processing, as -pthread is specified or no additional linking is required
  212. # define CATCH_INTERNAL_CONFIG_USE_ASYNC
  213. #endif // _MSC_VER
  214. ////////////////////////////////////////////////////////////////////////////////
  215. // Check if we are compiled with -fno-exceptions or equivalent
  216. #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
  217. # define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
  218. #endif
  219. ////////////////////////////////////////////////////////////////////////////////
  220. // DJGPP
  221. #ifdef __DJGPP__
  222. # define CATCH_INTERNAL_CONFIG_NO_WCHAR
  223. #endif // __DJGPP__
  224. ////////////////////////////////////////////////////////////////////////////////
  225. // Embarcadero C++Build
  226. #if defined(__BORLANDC__)
  227. #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN
  228. #endif
  229. ////////////////////////////////////////////////////////////////////////////////
  230. // Use of __COUNTER__ is suppressed during code analysis in
  231. // CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
  232. // handled by it.
  233. // Otherwise all supported compilers support COUNTER macro,
  234. // but user still might want to turn it off
  235. #if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
  236. #define CATCH_INTERNAL_CONFIG_COUNTER
  237. #endif
  238. ////////////////////////////////////////////////////////////////////////////////
  239. // RTX is a special version of Windows that is real time.
  240. // This means that it is detected as Windows, but does not provide
  241. // the same set of capabilities as real Windows does.
  242. #if defined(UNDER_RTSS) || defined(RTX64_BUILD)
  243. #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
  244. #define CATCH_INTERNAL_CONFIG_NO_ASYNC
  245. #define CATCH_CONFIG_COLOUR_NONE
  246. #endif
  247. #if !defined(_GLIBCXX_USE_C99_MATH_TR1)
  248. #define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER
  249. #endif
  250. // Various stdlib support checks that require __has_include
  251. #if defined(__has_include)
  252. // Check if string_view is available and usable
  253. #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
  254. # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
  255. #endif
  256. // Check if optional is available and usable
  257. # if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
  258. # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
  259. # endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
  260. // Check if byte is available and usable
  261. # if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
  262. # include <cstddef>
  263. # if __cpp_lib_byte > 0
  264. # define CATCH_INTERNAL_CONFIG_CPP17_BYTE
  265. # endif
  266. # endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
  267. // Check if variant is available and usable
  268. # if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
  269. # if defined(__clang__) && (__clang_major__ < 8)
  270. // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
  271. // fix should be in clang 8, workaround in libstdc++ 8.2
  272. # include <ciso646>
  273. # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
  274. # define CATCH_CONFIG_NO_CPP17_VARIANT
  275. # else
  276. # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
  277. # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
  278. # else
  279. # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
  280. # endif // defined(__clang__) && (__clang_major__ < 8)
  281. # endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
  282. #endif // defined(__has_include)
  283. #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
  284. # define CATCH_CONFIG_COUNTER
  285. #endif
  286. #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)
  287. # define CATCH_CONFIG_WINDOWS_SEH
  288. #endif
  289. // This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
  290. #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)
  291. # define CATCH_CONFIG_POSIX_SIGNALS
  292. #endif
  293. // This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.
  294. #if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
  295. # define CATCH_CONFIG_WCHAR
  296. #endif
  297. #if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
  298. # define CATCH_CONFIG_CPP11_TO_STRING
  299. #endif
  300. #if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL)
  301. # define CATCH_CONFIG_CPP17_OPTIONAL
  302. #endif
  303. #if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
  304. # define CATCH_CONFIG_CPP17_STRING_VIEW
  305. #endif
  306. #if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
  307. # define CATCH_CONFIG_CPP17_VARIANT
  308. #endif
  309. #if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE)
  310. # define CATCH_CONFIG_CPP17_BYTE
  311. #endif
  312. #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
  313. # define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
  314. #endif
  315. #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)
  316. # define CATCH_CONFIG_NEW_CAPTURE
  317. #endif
  318. #if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  319. # define CATCH_CONFIG_DISABLE_EXCEPTIONS
  320. #endif
  321. #if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN)
  322. # define CATCH_CONFIG_POLYFILL_ISNAN
  323. #endif
  324. #if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC)
  325. # define CATCH_CONFIG_USE_ASYNC
  326. #endif
  327. #if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE)
  328. # define CATCH_CONFIG_ANDROID_LOGWRITE
  329. #endif
  330. #if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
  331. # define CATCH_CONFIG_GLOBAL_NEXTAFTER
  332. #endif
  333. // Even if we do not think the compiler has that warning, we still have
  334. // to provide a macro that can be used by the code.
  335. #if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION)
  336. # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
  337. #endif
  338. #if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION)
  339. # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
  340. #endif
  341. #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
  342. # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
  343. #endif
  344. #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
  345. # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
  346. #endif
  347. #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
  348. # define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
  349. #endif
  350. #if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)
  351. # define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
  352. #endif
  353. // The goal of this macro is to avoid evaluation of the arguments, but
  354. // still have the compiler warn on problems inside...
  355. #if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN)
  356. # define CATCH_INTERNAL_IGNORE_BUT_WARN(...)
  357. #endif
  358. #if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)
  359. # undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
  360. #elif defined(__clang__) && (__clang_major__ < 5)
  361. # undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
  362. #endif
  363. #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS)
  364. # define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
  365. #endif
  366. #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  367. #define CATCH_TRY if ((true))
  368. #define CATCH_CATCH_ALL if ((false))
  369. #define CATCH_CATCH_ANON(type) if ((false))
  370. #else
  371. #define CATCH_TRY try
  372. #define CATCH_CATCH_ALL catch (...)
  373. #define CATCH_CATCH_ANON(type) catch (type)
  374. #endif
  375. #if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)
  376. #define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  377. #endif
  378. // end catch_compiler_capabilities.h
  379. #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
  380. #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
  381. #ifdef CATCH_CONFIG_COUNTER
  382. # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
  383. #else
  384. # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
  385. #endif
  386. #include <iosfwd>
  387. #include <string>
  388. #include <cstdint>
  389. // We need a dummy global operator<< so we can bring it into Catch namespace later
  390. struct Catch_global_namespace_dummy {};
  391. std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
  392. namespace Catch {
  393. struct CaseSensitive { enum Choice {
  394. Yes,
  395. No
  396. }; };
  397. class NonCopyable {
  398. NonCopyable( NonCopyable const& ) = delete;
  399. NonCopyable( NonCopyable && ) = delete;
  400. NonCopyable& operator = ( NonCopyable const& ) = delete;
  401. NonCopyable& operator = ( NonCopyable && ) = delete;
  402. protected:
  403. NonCopyable();
  404. virtual ~NonCopyable();
  405. };
  406. struct SourceLineInfo {
  407. SourceLineInfo() = delete;
  408. SourceLineInfo( char const* _file, std::size_t _line ) noexcept
  409. : file( _file ),
  410. line( _line )
  411. {}
  412. SourceLineInfo( SourceLineInfo const& other ) = default;
  413. SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
  414. SourceLineInfo( SourceLineInfo&& ) noexcept = default;
  415. SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default;
  416. bool empty() const noexcept { return file[0] == '\0'; }
  417. bool operator == ( SourceLineInfo const& other ) const noexcept;
  418. bool operator < ( SourceLineInfo const& other ) const noexcept;
  419. char const* file;
  420. std::size_t line;
  421. };
  422. std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
  423. // Bring in operator<< from global namespace into Catch namespace
  424. // This is necessary because the overload of operator<< above makes
  425. // lookup stop at namespace Catch
  426. using ::operator<<;
  427. // Use this in variadic streaming macros to allow
  428. // >> +StreamEndStop
  429. // as well as
  430. // >> stuff +StreamEndStop
  431. struct StreamEndStop {
  432. std::string operator+() const;
  433. };
  434. template<typename T>
  435. T const& operator + ( T const& value, StreamEndStop ) {
  436. return value;
  437. }
  438. }
  439. #define CATCH_INTERNAL_LINEINFO \
  440. ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
  441. // end catch_common.h
  442. namespace Catch {
  443. struct RegistrarForTagAliases {
  444. RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
  445. };
  446. } // end namespace Catch
  447. #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
  448. CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
  449. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  450. namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
  451. CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
  452. // end catch_tag_alias_autoregistrar.h
  453. // start catch_test_registry.h
  454. // start catch_interfaces_testcase.h
  455. #include <vector>
  456. namespace Catch {
  457. class TestSpec;
  458. struct ITestInvoker {
  459. virtual void invoke () const = 0;
  460. virtual ~ITestInvoker();
  461. };
  462. class TestCase;
  463. struct IConfig;
  464. struct ITestCaseRegistry {
  465. virtual ~ITestCaseRegistry();
  466. virtual std::vector<TestCase> const& getAllTests() const = 0;
  467. virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
  468. };
  469. bool isThrowSafe( TestCase const& testCase, IConfig const& config );
  470. bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
  471. std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
  472. std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
  473. }
  474. // end catch_interfaces_testcase.h
  475. // start catch_stringref.h
  476. #include <cstddef>
  477. #include <string>
  478. #include <iosfwd>
  479. #include <cassert>
  480. namespace Catch {
  481. /// A non-owning string class (similar to the forthcoming std::string_view)
  482. /// Note that, because a StringRef may be a substring of another string,
  483. /// it may not be null terminated.
  484. class StringRef {
  485. public:
  486. using size_type = std::size_t;
  487. using const_iterator = const char*;
  488. private:
  489. static constexpr char const* const s_empty = "";
  490. char const* m_start = s_empty;
  491. size_type m_size = 0;
  492. public: // construction
  493. constexpr StringRef() noexcept = default;
  494. StringRef( char const* rawChars ) noexcept;
  495. constexpr StringRef( char const* rawChars, size_type size ) noexcept
  496. : m_start( rawChars ),
  497. m_size( size )
  498. {}
  499. StringRef( std::string const& stdString ) noexcept
  500. : m_start( stdString.c_str() ),
  501. m_size( stdString.size() )
  502. {}
  503. explicit operator std::string() const {
  504. return std::string(m_start, m_size);
  505. }
  506. public: // operators
  507. auto operator == ( StringRef const& other ) const noexcept -> bool;
  508. auto operator != (StringRef const& other) const noexcept -> bool {
  509. return !(*this == other);
  510. }
  511. auto operator[] ( size_type index ) const noexcept -> char {
  512. assert(index < m_size);
  513. return m_start[index];
  514. }
  515. public: // named queries
  516. constexpr auto empty() const noexcept -> bool {
  517. return m_size == 0;
  518. }
  519. constexpr auto size() const noexcept -> size_type {
  520. return m_size;
  521. }
  522. // Returns the current start pointer. If the StringRef is not
  523. // null-terminated, throws std::domain_exception
  524. auto c_str() const -> char const*;
  525. public: // substrings and searches
  526. // Returns a substring of [start, start + length).
  527. // If start + length > size(), then the substring is [start, size()).
  528. // If start > size(), then the substring is empty.
  529. auto substr( size_type start, size_type length ) const noexcept -> StringRef;
  530. // Returns the current start pointer. May not be null-terminated.
  531. auto data() const noexcept -> char const*;
  532. constexpr auto isNullTerminated() const noexcept -> bool {
  533. return m_start[m_size] == '\0';
  534. }
  535. public: // iterators
  536. constexpr const_iterator begin() const { return m_start; }
  537. constexpr const_iterator end() const { return m_start + m_size; }
  538. };
  539. auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
  540. auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
  541. constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
  542. return StringRef( rawChars, size );
  543. }
  544. } // namespace Catch
  545. constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
  546. return Catch::StringRef( rawChars, size );
  547. }
  548. // end catch_stringref.h
  549. // start catch_preprocessor.hpp
  550. #define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__
  551. #define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))
  552. #define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))
  553. #define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__)))
  554. #define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__)))
  555. #define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__)))
  556. #ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  557. #define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__
  558. // MSVC needs more evaluations
  559. #define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__)))
  560. #define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__))
  561. #else
  562. #define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__)
  563. #endif
  564. #define CATCH_REC_END(...)
  565. #define CATCH_REC_OUT
  566. #define CATCH_EMPTY()
  567. #define CATCH_DEFER(id) id CATCH_EMPTY()
  568. #define CATCH_REC_GET_END2() 0, CATCH_REC_END
  569. #define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2
  570. #define CATCH_REC_GET_END(...) CATCH_REC_GET_END1
  571. #define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT
  572. #define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0)
  573. #define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next)
  574. #define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
  575. #define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ )
  576. #define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
  577. #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__ )
  578. #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__ )
  579. #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__ )
  580. // Applies the function macro `f` to each of the remaining parameters, inserts commas between the results,
  581. // and passes userdata as the first parameter to each invocation,
  582. // e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c)
  583. #define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
  584. #define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
  585. #define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
  586. #define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__
  587. #define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
  588. #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
  589. #define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__)
  590. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  591. #define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__
  592. #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param))
  593. #else
  594. // MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
  595. #define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__)
  596. #define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__
  597. #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1)
  598. #endif
  599. #define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__
  600. #define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name)
  601. #define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)
  602. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  603. #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>())
  604. #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
  605. #else
  606. #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>()))
  607. #define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
  608. #endif
  609. #define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\
  610. CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__)
  611. #define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0)
  612. #define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1)
  613. #define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2)
  614. #define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3)
  615. #define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4)
  616. #define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5)
  617. #define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6)
  618. #define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7)
  619. #define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8)
  620. #define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9)
  621. #define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10)
  622. #define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
  623. #define INTERNAL_CATCH_TYPE_GEN\
  624. template<typename...> struct TypeList {};\
  625. template<typename...Ts>\
  626. constexpr auto get_wrapper() noexcept -> TypeList<Ts...> { return {}; }\
  627. template<template<typename...> class...> struct TemplateTypeList{};\
  628. template<template<typename...> class...Cs>\
  629. constexpr auto get_wrapper() noexcept -> TemplateTypeList<Cs...> { return {}; }\
  630. template<typename...>\
  631. struct append;\
  632. template<typename...>\
  633. struct rewrap;\
  634. template<template<typename...> class, typename...>\
  635. struct create;\
  636. template<template<typename...> class, typename>\
  637. struct convert;\
  638. \
  639. template<typename T> \
  640. struct append<T> { using type = T; };\
  641. template< template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2, typename...Rest>\
  642. struct append<L1<E1...>, L2<E2...>, Rest...> { using type = typename append<L1<E1...,E2...>, Rest...>::type; };\
  643. template< template<typename...> class L1, typename...E1, typename...Rest>\
  644. struct append<L1<E1...>, TypeList<mpl_::na>, Rest...> { using type = L1<E1...>; };\
  645. \
  646. template< template<typename...> class Container, template<typename...> class List, typename...elems>\
  647. struct rewrap<TemplateTypeList<Container>, List<elems...>> { using type = TypeList<Container<elems...>>; };\
  648. template< template<typename...> class Container, template<typename...> class List, class...Elems, typename...Elements>\
  649. struct rewrap<TemplateTypeList<Container>, List<Elems...>, Elements...> { using type = typename append<TypeList<Container<Elems...>>, typename rewrap<TemplateTypeList<Container>, Elements...>::type>::type; };\
  650. \
  651. template<template <typename...> class Final, template< typename...> class...Containers, typename...Types>\
  652. struct create<Final, TemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<TemplateTypeList<Containers>, Types...>::type...>::type; };\
  653. template<template <typename...> class Final, template <typename...> class List, typename...Ts>\
  654. struct convert<Final, List<Ts...>> { using type = typename append<Final<>,TypeList<Ts>...>::type; };
  655. #define INTERNAL_CATCH_NTTP_1(signature, ...)\
  656. template<INTERNAL_CATCH_REMOVE_PARENS(signature)> struct Nttp{};\
  657. template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
  658. constexpr auto get_wrapper() noexcept -> Nttp<__VA_ARGS__> { return {}; } \
  659. template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...> struct NttpTemplateTypeList{};\
  660. template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Cs>\
  661. constexpr auto get_wrapper() noexcept -> NttpTemplateTypeList<Cs...> { return {}; } \
  662. \
  663. template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature)>\
  664. struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>> { using type = TypeList<Container<__VA_ARGS__>>; };\
  665. template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature), typename...Elements>\
  666. struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>, Elements...> { using type = typename append<TypeList<Container<__VA_ARGS__>>, typename rewrap<NttpTemplateTypeList<Container>, Elements...>::type>::type; };\
  667. template<template <typename...> class Final, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Containers, typename...Types>\
  668. struct create<Final, NttpTemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<NttpTemplateTypeList<Containers>, Types...>::type...>::type; };
  669. #define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName)
  670. #define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature)\
  671. template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
  672. static void TestName()
  673. #define INTERNAL_CATCH_DECLARE_SIG_TEST_X(TestName, signature, ...)\
  674. template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
  675. static void TestName()
  676. #define INTERNAL_CATCH_DEFINE_SIG_TEST0(TestName)
  677. #define INTERNAL_CATCH_DEFINE_SIG_TEST1(TestName, signature)\
  678. template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
  679. static void TestName()
  680. #define INTERNAL_CATCH_DEFINE_SIG_TEST_X(TestName, signature,...)\
  681. template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
  682. static void TestName()
  683. #define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature)\
  684. template<typename Type>\
  685. void reg_test(TypeList<Type>, Catch::NameAndTags nameAndTags)\
  686. {\
  687. Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<Type>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
  688. }
  689. #define INTERNAL_CATCH_NTTP_REGISTER(TestFunc, signature, ...)\
  690. template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
  691. void reg_test(Nttp<__VA_ARGS__>, Catch::NameAndTags nameAndTags)\
  692. {\
  693. Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<__VA_ARGS__>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\
  694. }
  695. #define INTERNAL_CATCH_NTTP_REGISTER_METHOD0(TestName, signature, ...)\
  696. template<typename Type>\
  697. void reg_test(TypeList<Type>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
  698. {\
  699. Catch::AutoReg( Catch::makeTestInvoker(&TestName<Type>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
  700. }
  701. #define INTERNAL_CATCH_NTTP_REGISTER_METHOD(TestName, signature, ...)\
  702. template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
  703. void reg_test(Nttp<__VA_ARGS__>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\
  704. {\
  705. Catch::AutoReg( Catch::makeTestInvoker(&TestName<__VA_ARGS__>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\
  706. }
  707. #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0(TestName, ClassName)
  708. #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1(TestName, ClassName, signature)\
  709. template<typename TestType> \
  710. struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<TestType> { \
  711. void test();\
  712. }
  713. #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X(TestName, ClassName, signature, ...)\
  714. template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
  715. struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<__VA_ARGS__> { \
  716. void test();\
  717. }
  718. #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0(TestName)
  719. #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1(TestName, signature)\
  720. template<typename TestType> \
  721. void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<TestType>::test()
  722. #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X(TestName, signature, ...)\
  723. template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \
  724. void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<__VA_ARGS__>::test()
  725. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  726. #define INTERNAL_CATCH_NTTP_0
  727. #define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__),INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_0)
  728. #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__)
  729. #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__)
  730. #define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__)
  731. #define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__)
  732. #define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__)
  733. #define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__)
  734. #define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__)
  735. #else
  736. #define INTERNAL_CATCH_NTTP_0(signature)
  737. #define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1,INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_0)( __VA_ARGS__))
  738. #define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__))
  739. #define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__))
  740. #define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__))
  741. #define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__))
  742. #define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__))
  743. #define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( "dummy", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__))
  744. #define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__))
  745. #endif
  746. // end catch_preprocessor.hpp
  747. // start catch_meta.hpp
  748. #include <type_traits>
  749. namespace Catch {
  750. template<typename T>
  751. struct always_false : std::false_type {};
  752. template <typename> struct true_given : std::true_type {};
  753. struct is_callable_tester {
  754. template <typename Fun, typename... Args>
  755. true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
  756. template <typename...>
  757. std::false_type static test(...);
  758. };
  759. template <typename T>
  760. struct is_callable;
  761. template <typename Fun, typename... Args>
  762. struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};
  763. #if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
  764. // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
  765. // replaced with std::invoke_result here.
  766. template <typename Func, typename... U>
  767. using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U...>>>;
  768. #else
  769. // Keep ::type here because we still support C++11
  770. template <typename Func, typename... U>
  771. using FunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U...)>::type>::type>::type;
  772. #endif
  773. } // namespace Catch
  774. namespace mpl_{
  775. struct na;
  776. }
  777. // end catch_meta.hpp
  778. namespace Catch {
  779. template<typename C>
  780. class TestInvokerAsMethod : public ITestInvoker {
  781. void (C::*m_testAsMethod)();
  782. public:
  783. TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}
  784. void invoke() const override {
  785. C obj;
  786. (obj.*m_testAsMethod)();
  787. }
  788. };
  789. auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;
  790. template<typename C>
  791. auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {
  792. return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod );
  793. }
  794. struct NameAndTags {
  795. NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;
  796. StringRef name;
  797. StringRef tags;
  798. };
  799. struct AutoReg : NonCopyable {
  800. AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;
  801. ~AutoReg();
  802. };
  803. } // end namespace Catch
  804. #if defined(CATCH_CONFIG_DISABLE)
  805. #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
  806. static void TestName()
  807. #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
  808. namespace{ \
  809. struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
  810. void test(); \
  811. }; \
  812. } \
  813. void TestName::test()
  814. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( TestName, TestFunc, Name, Tags, Signature, ... ) \
  815. INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))
  816. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
  817. namespace{ \
  818. namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
  819. INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
  820. } \
  821. } \
  822. INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
  823. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  824. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
  825. INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_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, typename TestType, __VA_ARGS__ )
  826. #else
  827. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \
  828. INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_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, typename TestType, __VA_ARGS__ ) )
  829. #endif
  830. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  831. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
  832. INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_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, Signature, __VA_ARGS__ )
  833. #else
  834. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \
  835. INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_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, Signature, __VA_ARGS__ ) )
  836. #endif
  837. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  838. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
  839. INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_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, typename T, __VA_ARGS__ )
  840. #else
  841. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \
  842. INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_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, typename T, __VA_ARGS__ ) )
  843. #endif
  844. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  845. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
  846. INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_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, Signature, __VA_ARGS__ )
  847. #else
  848. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \
  849. INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_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, Signature, __VA_ARGS__ ) )
  850. #endif
  851. #endif
  852. ///////////////////////////////////////////////////////////////////////////////
  853. #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
  854. static void TestName(); \
  855. CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
  856. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  857. namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
  858. CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
  859. static void TestName()
  860. #define INTERNAL_CATCH_TESTCASE( ... ) \
  861. INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
  862. ///////////////////////////////////////////////////////////////////////////////
  863. #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
  864. CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
  865. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  866. namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
  867. CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
  868. ///////////////////////////////////////////////////////////////////////////////
  869. #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
  870. CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
  871. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  872. namespace{ \
  873. struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
  874. void test(); \
  875. }; \
  876. Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
  877. } \
  878. CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
  879. void TestName::test()
  880. #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
  881. INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
  882. ///////////////////////////////////////////////////////////////////////////////
  883. #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
  884. CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
  885. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  886. Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
  887. CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
  888. ///////////////////////////////////////////////////////////////////////////////
  889. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ... )\
  890. CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
  891. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  892. CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
  893. CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
  894. INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
  895. namespace {\
  896. namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
  897. INTERNAL_CATCH_TYPE_GEN\
  898. INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
  899. INTERNAL_CATCH_NTTP_REG_GEN(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))\
  900. template<typename...Types> \
  901. struct TestName{\
  902. TestName(){\
  903. int index = 0; \
  904. constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
  905. using expander = int[];\
  906. (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
  907. }\
  908. };\
  909. static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
  910. TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
  911. return 0;\
  912. }();\
  913. }\
  914. }\
  915. CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
  916. INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))
  917. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  918. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
  919. 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, typename TestType, __VA_ARGS__ )
  920. #else
  921. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
  922. 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, typename TestType, __VA_ARGS__ ) )
  923. #endif
  924. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  925. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
  926. 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, Signature, __VA_ARGS__ )
  927. #else
  928. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \
  929. 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, Signature, __VA_ARGS__ ) )
  930. #endif
  931. #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \
  932. CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
  933. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  934. CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
  935. CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
  936. template<typename TestType> static void TestFuncName(); \
  937. namespace {\
  938. namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
  939. INTERNAL_CATCH_TYPE_GEN \
  940. INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature)) \
  941. template<typename... Types> \
  942. struct TestName { \
  943. void reg_tests() { \
  944. int index = 0; \
  945. using expander = int[]; \
  946. constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
  947. constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
  948. constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
  949. (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++)... };/* NOLINT */\
  950. } \
  951. }; \
  952. static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
  953. using TestInit = typename create<TestName, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type; \
  954. TestInit t; \
  955. t.reg_tests(); \
  956. return 0; \
  957. }(); \
  958. } \
  959. } \
  960. CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
  961. template<typename TestType> \
  962. static void TestFuncName()
  963. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  964. #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
  965. 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, typename T,__VA_ARGS__)
  966. #else
  967. #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
  968. 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, typename T, __VA_ARGS__ ) )
  969. #endif
  970. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  971. #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
  972. 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, Signature, __VA_ARGS__)
  973. #else
  974. #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\
  975. 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, Signature, __VA_ARGS__ ) )
  976. #endif
  977. #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\
  978. CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
  979. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  980. CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
  981. template<typename TestType> static void TestFunc(); \
  982. namespace {\
  983. namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
  984. INTERNAL_CATCH_TYPE_GEN\
  985. template<typename... Types> \
  986. struct TestName { \
  987. void reg_tests() { \
  988. int index = 0; \
  989. using expander = int[]; \
  990. (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */\
  991. } \
  992. };\
  993. static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
  994. using TestInit = typename convert<TestName, TmplList>::type; \
  995. TestInit t; \
  996. t.reg_tests(); \
  997. return 0; \
  998. }(); \
  999. }}\
  1000. CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
  1001. template<typename TestType> \
  1002. static void TestFunc()
  1003. #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \
  1004. INTERNAL_CATCH_TEMPLATE_LIST_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, TmplList )
  1005. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
  1006. CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
  1007. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  1008. CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
  1009. CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
  1010. namespace {\
  1011. namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
  1012. INTERNAL_CATCH_TYPE_GEN\
  1013. INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
  1014. INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
  1015. INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\
  1016. template<typename...Types> \
  1017. struct TestNameClass{\
  1018. TestNameClass(){\
  1019. int index = 0; \
  1020. constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
  1021. using expander = int[];\
  1022. (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
  1023. }\
  1024. };\
  1025. static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
  1026. TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\
  1027. return 0;\
  1028. }();\
  1029. }\
  1030. }\
  1031. CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
  1032. INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
  1033. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  1034. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
  1035. 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, typename T, __VA_ARGS__ )
  1036. #else
  1037. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
  1038. 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, typename T, __VA_ARGS__ ) )
  1039. #endif
  1040. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  1041. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
  1042. 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, Signature, __VA_ARGS__ )
  1043. #else
  1044. #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \
  1045. 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, Signature, __VA_ARGS__ ) )
  1046. #endif
  1047. #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\
  1048. CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
  1049. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  1050. CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
  1051. CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
  1052. template<typename TestType> \
  1053. struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
  1054. void test();\
  1055. };\
  1056. namespace {\
  1057. namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) {\
  1058. INTERNAL_CATCH_TYPE_GEN \
  1059. INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
  1060. template<typename...Types>\
  1061. struct TestNameClass{\
  1062. void reg_tests(){\
  1063. int index = 0;\
  1064. using expander = int[];\
  1065. constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
  1066. constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
  1067. constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
  1068. (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++)... };/* NOLINT */ \
  1069. }\
  1070. };\
  1071. static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
  1072. using TestInit = typename create<TestNameClass, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type;\
  1073. TestInit t;\
  1074. t.reg_tests();\
  1075. return 0;\
  1076. }(); \
  1077. }\
  1078. }\
  1079. CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
  1080. template<typename TestType> \
  1081. void TestName<TestType>::test()
  1082. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  1083. #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
  1084. 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, typename T, __VA_ARGS__ )
  1085. #else
  1086. #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
  1087. 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, typename T,__VA_ARGS__ ) )
  1088. #endif
  1089. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  1090. #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
  1091. 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, Signature, __VA_ARGS__ )
  1092. #else
  1093. #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\
  1094. 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, Signature,__VA_ARGS__ ) )
  1095. #endif
  1096. #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
  1097. CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
  1098. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  1099. CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
  1100. template<typename TestType> \
  1101. struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
  1102. void test();\
  1103. };\
  1104. namespace {\
  1105. namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
  1106. INTERNAL_CATCH_TYPE_GEN\
  1107. template<typename...Types>\
  1108. struct TestNameClass{\
  1109. void reg_tests(){\
  1110. int index = 0;\
  1111. using expander = int[];\
  1112. (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */ \
  1113. }\
  1114. };\
  1115. static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
  1116. using TestInit = typename convert<TestNameClass, TmplList>::type;\
  1117. TestInit t;\
  1118. t.reg_tests();\
  1119. return 0;\
  1120. }(); \
  1121. }}\
  1122. CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
  1123. template<typename TestType> \
  1124. void TestName<TestType>::test()
  1125. #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \
  1126. INTERNAL_CATCH_TEMPLATE_LIST_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, TmplList )
  1127. // end catch_test_registry.h
  1128. // start catch_capture.hpp
  1129. // start catch_assertionhandler.h
  1130. // start catch_assertioninfo.h
  1131. // start catch_result_type.h
  1132. namespace Catch {
  1133. // ResultWas::OfType enum
  1134. struct ResultWas { enum OfType {
  1135. Unknown = -1,
  1136. Ok = 0,
  1137. Info = 1,
  1138. Warning = 2,
  1139. FailureBit = 0x10,
  1140. ExpressionFailed = FailureBit | 1,
  1141. ExplicitFailure = FailureBit | 2,
  1142. Exception = 0x100 | FailureBit,
  1143. ThrewException = Exception | 1,
  1144. DidntThrowException = Exception | 2,
  1145. FatalErrorCondition = 0x200 | FailureBit
  1146. }; };
  1147. bool isOk( ResultWas::OfType resultType );
  1148. bool isJustInfo( int flags );
  1149. // ResultDisposition::Flags enum
  1150. struct ResultDisposition { enum Flags {
  1151. Normal = 0x01,
  1152. ContinueOnFailure = 0x02, // Failures fail test, but execution continues
  1153. FalseTest = 0x04, // Prefix expression with !
  1154. SuppressFail = 0x08 // Failures are reported but do not fail the test
  1155. }; };
  1156. ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs );
  1157. bool shouldContinueOnFailure( int flags );
  1158. inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
  1159. bool shouldSuppressFailure( int flags );
  1160. } // end namespace Catch
  1161. // end catch_result_type.h
  1162. namespace Catch {
  1163. struct AssertionInfo
  1164. {
  1165. StringRef macroName;
  1166. SourceLineInfo lineInfo;
  1167. StringRef capturedExpression;
  1168. ResultDisposition::Flags resultDisposition;
  1169. // We want to delete this constructor but a compiler bug in 4.8 means
  1170. // the struct is then treated as non-aggregate
  1171. //AssertionInfo() = delete;
  1172. };
  1173. } // end namespace Catch
  1174. // end catch_assertioninfo.h
  1175. // start catch_decomposer.h
  1176. // start catch_tostring.h
  1177. #include <vector>
  1178. #include <cstddef>
  1179. #include <type_traits>
  1180. #include <string>
  1181. // start catch_stream.h
  1182. #include <iosfwd>
  1183. #include <cstddef>
  1184. #include <ostream>
  1185. namespace Catch {
  1186. std::ostream& cout();
  1187. std::ostream& cerr();
  1188. std::ostream& clog();
  1189. class StringRef;
  1190. struct IStream {
  1191. virtual ~IStream();
  1192. virtual std::ostream& stream() const = 0;
  1193. };
  1194. auto makeStream( StringRef const &filename ) -> IStream const*;
  1195. class ReusableStringStream : NonCopyable {
  1196. std::size_t m_index;
  1197. std::ostream* m_oss;
  1198. public:
  1199. ReusableStringStream();
  1200. ~ReusableStringStream();
  1201. auto str() const -> std::string;
  1202. template<typename T>
  1203. auto operator << ( T const& value ) -> ReusableStringStream& {
  1204. *m_oss << value;
  1205. return *this;
  1206. }
  1207. auto get() -> std::ostream& { return *m_oss; }
  1208. };
  1209. }
  1210. // end catch_stream.h
  1211. // start catch_interfaces_enum_values_registry.h
  1212. #include <vector>
  1213. namespace Catch {
  1214. namespace Detail {
  1215. struct EnumInfo {
  1216. StringRef m_name;
  1217. std::vector<std::pair<int, StringRef>> m_values;
  1218. ~EnumInfo();
  1219. StringRef lookup( int value ) const;
  1220. };
  1221. } // namespace Detail
  1222. struct IMutableEnumValuesRegistry {
  1223. virtual ~IMutableEnumValuesRegistry();
  1224. virtual Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values ) = 0;
  1225. template<typename E>
  1226. Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list<E> values ) {
  1227. static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int");
  1228. std::vector<int> intValues;
  1229. intValues.reserve( values.size() );
  1230. for( auto enumValue : values )
  1231. intValues.push_back( static_cast<int>( enumValue ) );
  1232. return registerEnum( enumName, allEnums, intValues );
  1233. }
  1234. };
  1235. } // Catch
  1236. // end catch_interfaces_enum_values_registry.h
  1237. #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
  1238. #include <string_view>
  1239. #endif
  1240. #ifdef __OBJC__
  1241. // start catch_objc_arc.hpp
  1242. #import <Foundation/Foundation.h>
  1243. #ifdef __has_feature
  1244. #define CATCH_ARC_ENABLED __has_feature(objc_arc)
  1245. #else
  1246. #define CATCH_ARC_ENABLED 0
  1247. #endif
  1248. void arcSafeRelease( NSObject* obj );
  1249. id performOptionalSelector( id obj, SEL sel );
  1250. #if !CATCH_ARC_ENABLED
  1251. inline void arcSafeRelease( NSObject* obj ) {
  1252. [obj release];
  1253. }
  1254. inline id performOptionalSelector( id obj, SEL sel ) {
  1255. if( [obj respondsToSelector: sel] )
  1256. return [obj performSelector: sel];
  1257. return nil;
  1258. }
  1259. #define CATCH_UNSAFE_UNRETAINED
  1260. #define CATCH_ARC_STRONG
  1261. #else
  1262. inline void arcSafeRelease( NSObject* ){}
  1263. inline id performOptionalSelector( id obj, SEL sel ) {
  1264. #ifdef __clang__
  1265. #pragma clang diagnostic push
  1266. #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
  1267. #endif
  1268. if( [obj respondsToSelector: sel] )
  1269. return [obj performSelector: sel];
  1270. #ifdef __clang__
  1271. #pragma clang diagnostic pop
  1272. #endif
  1273. return nil;
  1274. }
  1275. #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
  1276. #define CATCH_ARC_STRONG __strong
  1277. #endif
  1278. // end catch_objc_arc.hpp
  1279. #endif
  1280. #ifdef _MSC_VER
  1281. #pragma warning(push)
  1282. #pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
  1283. #endif
  1284. namespace Catch {
  1285. namespace Detail {
  1286. extern const std::string unprintableString;
  1287. std::string rawMemoryToString( const void *object, std::size_t size );
  1288. template<typename T>
  1289. std::string rawMemoryToString( const T& object ) {
  1290. return rawMemoryToString( &object, sizeof(object) );
  1291. }
  1292. template<typename T>
  1293. class IsStreamInsertable {
  1294. template<typename Stream, typename U>
  1295. static auto test(int)
  1296. -> decltype(std::declval<Stream&>() << std::declval<U>(), std::true_type());
  1297. template<typename, typename>
  1298. static auto test(...)->std::false_type;
  1299. public:
  1300. static const bool value = decltype(test<std::ostream, const T&>(0))::value;
  1301. };
  1302. template<typename E>
  1303. std::string convertUnknownEnumToString( E e );
  1304. template<typename T>
  1305. typename std::enable_if<
  1306. !std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value,
  1307. std::string>::type convertUnstreamable( T const& ) {
  1308. return Detail::unprintableString;
  1309. }
  1310. template<typename T>
  1311. typename std::enable_if<
  1312. !std::is_enum<T>::value && std::is_base_of<std::exception, T>::value,
  1313. std::string>::type convertUnstreamable(T const& ex) {
  1314. return ex.what();
  1315. }
  1316. template<typename T>
  1317. typename std::enable_if<
  1318. std::is_enum<T>::value
  1319. , std::string>::type convertUnstreamable( T const& value ) {
  1320. return convertUnknownEnumToString( value );
  1321. }
  1322. #if defined(_MANAGED)
  1323. //! Convert a CLR string to a utf8 std::string
  1324. template<typename T>
  1325. std::string clrReferenceToString( T^ ref ) {
  1326. if (ref == nullptr)
  1327. return std::string("null");
  1328. auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
  1329. cli::pin_ptr<System::Byte> p = &bytes[0];
  1330. return std::string(reinterpret_cast<char const *>(p), bytes->Length);
  1331. }
  1332. #endif
  1333. } // namespace Detail
  1334. // If we decide for C++14, change these to enable_if_ts
  1335. template <typename T, typename = void>
  1336. struct StringMaker {
  1337. template <typename Fake = T>
  1338. static
  1339. typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
  1340. convert(const Fake& value) {
  1341. ReusableStringStream rss;
  1342. // NB: call using the function-like syntax to avoid ambiguity with
  1343. // user-defined templated operator<< under clang.
  1344. rss.operator<<(value);
  1345. return rss.str();
  1346. }
  1347. template <typename Fake = T>
  1348. static
  1349. typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
  1350. convert( const Fake& value ) {
  1351. #if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
  1352. return Detail::convertUnstreamable(value);
  1353. #else
  1354. return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
  1355. #endif
  1356. }
  1357. };
  1358. namespace Detail {
  1359. // This function dispatches all stringification requests inside of Catch.
  1360. // Should be preferably called fully qualified, like ::Catch::Detail::stringify
  1361. template <typename T>
  1362. std::string stringify(const T& e) {
  1363. return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);
  1364. }
  1365. template<typename E>
  1366. std::string convertUnknownEnumToString( E e ) {
  1367. return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));
  1368. }
  1369. #if defined(_MANAGED)
  1370. template <typename T>
  1371. std::string stringify( T^ e ) {
  1372. return ::Catch::StringMaker<T^>::convert(e);
  1373. }
  1374. #endif
  1375. } // namespace Detail
  1376. // Some predefined specializations
  1377. template<>
  1378. struct StringMaker<std::string> {
  1379. static std::string convert(const std::string& str);
  1380. };
  1381. #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
  1382. template<>
  1383. struct StringMaker<std::string_view> {
  1384. static std::string convert(std::string_view str);
  1385. };
  1386. #endif
  1387. template<>
  1388. struct StringMaker<char const *> {
  1389. static std::string convert(char const * str);
  1390. };
  1391. template<>
  1392. struct StringMaker<char *> {
  1393. static std::string convert(char * str);
  1394. };
  1395. #ifdef CATCH_CONFIG_WCHAR
  1396. template<>
  1397. struct StringMaker<std::wstring> {
  1398. static std::string convert(const std::wstring& wstr);
  1399. };
  1400. # ifdef CATCH_CONFIG_CPP17_STRING_VIEW
  1401. template<>
  1402. struct StringMaker<std::wstring_view> {
  1403. static std::string convert(std::wstring_view str);
  1404. };
  1405. # endif
  1406. template<>
  1407. struct StringMaker<wchar_t const *> {
  1408. static std::string convert(wchar_t const * str);
  1409. };
  1410. template<>
  1411. struct StringMaker<wchar_t *> {
  1412. static std::string convert(wchar_t * str);
  1413. };
  1414. #endif
  1415. // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
  1416. // while keeping string semantics?
  1417. template<int SZ>
  1418. struct StringMaker<char[SZ]> {
  1419. static std::string convert(char const* str) {
  1420. return ::Catch::Detail::stringify(std::string{ str });
  1421. }
  1422. };
  1423. template<int SZ>
  1424. struct StringMaker<signed char[SZ]> {
  1425. static std::string convert(signed char const* str) {
  1426. return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
  1427. }
  1428. };
  1429. template<int SZ>
  1430. struct StringMaker<unsigned char[SZ]> {
  1431. static std::string convert(unsigned char const* str) {
  1432. return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
  1433. }
  1434. };
  1435. #if defined(CATCH_CONFIG_CPP17_BYTE)
  1436. template<>
  1437. struct StringMaker<std::byte> {
  1438. static std::string convert(std::byte value);
  1439. };
  1440. #endif // defined(CATCH_CONFIG_CPP17_BYTE)
  1441. template<>
  1442. struct StringMaker<int> {
  1443. static std::string convert(int value);
  1444. };
  1445. template<>
  1446. struct StringMaker<long> {
  1447. static std::string convert(long value);
  1448. };
  1449. template<>
  1450. struct StringMaker<long long> {
  1451. static std::string convert(long long value);
  1452. };
  1453. template<>
  1454. struct StringMaker<unsigned int> {
  1455. static std::string convert(unsigned int value);
  1456. };
  1457. template<>
  1458. struct StringMaker<unsigned long> {
  1459. static std::string convert(unsigned long value);
  1460. };
  1461. template<>
  1462. struct StringMaker<unsigned long long> {
  1463. static std::string convert(unsigned long long value);
  1464. };
  1465. template<>
  1466. struct StringMaker<bool> {
  1467. static std::string convert(bool b);
  1468. };
  1469. template<>
  1470. struct StringMaker<char> {
  1471. static std::string convert(char c);
  1472. };
  1473. template<>
  1474. struct StringMaker<signed char> {
  1475. static std::string convert(signed char c);
  1476. };
  1477. template<>
  1478. struct StringMaker<unsigned char> {
  1479. static std::string convert(unsigned char c);
  1480. };
  1481. template<>
  1482. struct StringMaker<std::nullptr_t> {
  1483. static std::string convert(std::nullptr_t);
  1484. };
  1485. template<>
  1486. struct StringMaker<float> {
  1487. static std::string convert(float value);
  1488. static int precision;
  1489. };
  1490. template<>
  1491. struct StringMaker<double> {
  1492. static std::string convert(double value);
  1493. static int precision;
  1494. };
  1495. template <typename T>
  1496. struct StringMaker<T*> {
  1497. template <typename U>
  1498. static std::string convert(U* p) {
  1499. if (p) {
  1500. return ::Catch::Detail::rawMemoryToString(p);
  1501. } else {
  1502. return "nullptr";
  1503. }
  1504. }
  1505. };
  1506. template <typename R, typename C>
  1507. struct StringMaker<R C::*> {
  1508. static std::string convert(R C::* p) {
  1509. if (p) {
  1510. return ::Catch::Detail::rawMemoryToString(p);
  1511. } else {
  1512. return "nullptr";
  1513. }
  1514. }
  1515. };
  1516. #if defined(_MANAGED)
  1517. template <typename T>
  1518. struct StringMaker<T^> {
  1519. static std::string convert( T^ ref ) {
  1520. return ::Catch::Detail::clrReferenceToString(ref);
  1521. }
  1522. };
  1523. #endif
  1524. namespace Detail {
  1525. template<typename InputIterator, typename Sentinel = InputIterator>
  1526. std::string rangeToString(InputIterator first, Sentinel last) {
  1527. ReusableStringStream rss;
  1528. rss << "{ ";
  1529. if (first != last) {
  1530. rss << ::Catch::Detail::stringify(*first);
  1531. for (++first; first != last; ++first)
  1532. rss << ", " << ::Catch::Detail::stringify(*first);
  1533. }
  1534. rss << " }";
  1535. return rss.str();
  1536. }
  1537. }
  1538. #ifdef __OBJC__
  1539. template<>
  1540. struct StringMaker<NSString*> {
  1541. static std::string convert(NSString * nsstring) {
  1542. if (!nsstring)
  1543. return "nil";
  1544. return std::string("@") + [nsstring UTF8String];
  1545. }
  1546. };
  1547. template<>
  1548. struct StringMaker<NSObject*> {
  1549. static std::string convert(NSObject* nsObject) {
  1550. return ::Catch::Detail::stringify([nsObject description]);
  1551. }
  1552. };
  1553. namespace Detail {
  1554. inline std::string stringify( NSString* nsstring ) {
  1555. return StringMaker<NSString*>::convert( nsstring );
  1556. }
  1557. } // namespace Detail
  1558. #endif // __OBJC__
  1559. } // namespace Catch
  1560. //////////////////////////////////////////////////////
  1561. // Separate std-lib types stringification, so it can be selectively enabled
  1562. // This means that we do not bring in
  1563. #if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
  1564. # define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
  1565. # define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
  1566. # define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
  1567. # define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
  1568. # define CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
  1569. #endif
  1570. // Separate std::pair specialization
  1571. #if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
  1572. #include <utility>
  1573. namespace Catch {
  1574. template<typename T1, typename T2>
  1575. struct StringMaker<std::pair<T1, T2> > {
  1576. static std::string convert(const std::pair<T1, T2>& pair) {
  1577. ReusableStringStream rss;
  1578. rss << "{ "
  1579. << ::Catch::Detail::stringify(pair.first)
  1580. << ", "
  1581. << ::Catch::Detail::stringify(pair.second)
  1582. << " }";
  1583. return rss.str();
  1584. }
  1585. };
  1586. }
  1587. #endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
  1588. #if defined(CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_OPTIONAL)
  1589. #include <optional>
  1590. namespace Catch {
  1591. template<typename T>
  1592. struct StringMaker<std::optional<T> > {
  1593. static std::string convert(const std::optional<T>& optional) {
  1594. ReusableStringStream rss;
  1595. if (optional.has_value()) {
  1596. rss << ::Catch::Detail::stringify(*optional);
  1597. } else {
  1598. rss << "{ }";
  1599. }
  1600. return rss.str();
  1601. }
  1602. };
  1603. }
  1604. #endif // CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
  1605. // Separate std::tuple specialization
  1606. #if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
  1607. #include <tuple>
  1608. namespace Catch {
  1609. namespace Detail {
  1610. template<
  1611. typename Tuple,
  1612. std::size_t N = 0,
  1613. bool = (N < std::tuple_size<Tuple>::value)
  1614. >
  1615. struct TupleElementPrinter {
  1616. static void print(const Tuple& tuple, std::ostream& os) {
  1617. os << (N ? ", " : " ")
  1618. << ::Catch::Detail::stringify(std::get<N>(tuple));
  1619. TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
  1620. }
  1621. };
  1622. template<
  1623. typename Tuple,
  1624. std::size_t N
  1625. >
  1626. struct TupleElementPrinter<Tuple, N, false> {
  1627. static void print(const Tuple&, std::ostream&) {}
  1628. };
  1629. }
  1630. template<typename ...Types>
  1631. struct StringMaker<std::tuple<Types...>> {
  1632. static std::string convert(const std::tuple<Types...>& tuple) {
  1633. ReusableStringStream rss;
  1634. rss << '{';
  1635. Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
  1636. rss << " }";
  1637. return rss.str();
  1638. }
  1639. };
  1640. }
  1641. #endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
  1642. #if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
  1643. #include <variant>
  1644. namespace Catch {
  1645. template<>
  1646. struct StringMaker<std::monostate> {
  1647. static std::string convert(const std::monostate&) {
  1648. return "{ }";
  1649. }
  1650. };
  1651. template<typename... Elements>
  1652. struct StringMaker<std::variant<Elements...>> {
  1653. static std::string convert(const std::variant<Elements...>& variant) {
  1654. if (variant.valueless_by_exception()) {
  1655. return "{valueless variant}";
  1656. } else {
  1657. return std::visit(
  1658. [](const auto& value) {
  1659. return ::Catch::Detail::stringify(value);
  1660. },
  1661. variant
  1662. );
  1663. }
  1664. }
  1665. };
  1666. }
  1667. #endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
  1668. namespace Catch {
  1669. // Import begin/ end from std here
  1670. using std::begin;
  1671. using std::end;
  1672. namespace detail {
  1673. template <typename...>
  1674. struct void_type {
  1675. using type = void;
  1676. };
  1677. template <typename T, typename = void>
  1678. struct is_range_impl : std::false_type {
  1679. };
  1680. template <typename T>
  1681. struct is_range_impl<T, typename void_type<decltype(begin(std::declval<T>()))>::type> : std::true_type {
  1682. };
  1683. } // namespace detail
  1684. template <typename T>
  1685. struct is_range : detail::is_range_impl<T> {
  1686. };
  1687. #if defined(_MANAGED) // Managed types are never ranges
  1688. template <typename T>
  1689. struct is_range<T^> {
  1690. static const bool value = false;
  1691. };
  1692. #endif
  1693. template<typename Range>
  1694. std::string rangeToString( Range const& range ) {
  1695. return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
  1696. }
  1697. // Handle vector<bool> specially
  1698. template<typename Allocator>
  1699. std::string rangeToString( std::vector<bool, Allocator> const& v ) {
  1700. ReusableStringStream rss;
  1701. rss << "{ ";
  1702. bool first = true;
  1703. for( bool b : v ) {
  1704. if( first )
  1705. first = false;
  1706. else
  1707. rss << ", ";
  1708. rss << ::Catch::Detail::stringify( b );
  1709. }
  1710. rss << " }";
  1711. return rss.str();
  1712. }
  1713. template<typename R>
  1714. struct StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {
  1715. static std::string convert( R const& range ) {
  1716. return rangeToString( range );
  1717. }
  1718. };
  1719. template <typename T, int SZ>
  1720. struct StringMaker<T[SZ]> {
  1721. static std::string convert(T const(&arr)[SZ]) {
  1722. return rangeToString(arr);
  1723. }
  1724. };
  1725. } // namespace Catch
  1726. // Separate std::chrono::duration specialization
  1727. #if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
  1728. #include <ctime>
  1729. #include <ratio>
  1730. #include <chrono>
  1731. namespace Catch {
  1732. template <class Ratio>
  1733. struct ratio_string {
  1734. static std::string symbol();
  1735. };
  1736. template <class Ratio>
  1737. std::string ratio_string<Ratio>::symbol() {
  1738. Catch::ReusableStringStream rss;
  1739. rss << '[' << Ratio::num << '/'
  1740. << Ratio::den << ']';
  1741. return rss.str();
  1742. }
  1743. template <>
  1744. struct ratio_string<std::atto> {
  1745. static std::string symbol();
  1746. };
  1747. template <>
  1748. struct ratio_string<std::femto> {
  1749. static std::string symbol();
  1750. };
  1751. template <>
  1752. struct ratio_string<std::pico> {
  1753. static std::string symbol();
  1754. };
  1755. template <>
  1756. struct ratio_string<std::nano> {
  1757. static std::string symbol();
  1758. };
  1759. template <>
  1760. struct ratio_string<std::micro> {
  1761. static std::string symbol();
  1762. };
  1763. template <>
  1764. struct ratio_string<std::milli> {
  1765. static std::string symbol();
  1766. };
  1767. ////////////
  1768. // std::chrono::duration specializations
  1769. template<typename Value, typename Ratio>
  1770. struct StringMaker<std::chrono::duration<Value, Ratio>> {
  1771. static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
  1772. ReusableStringStream rss;
  1773. rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
  1774. return rss.str();
  1775. }
  1776. };
  1777. template<typename Value>
  1778. struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
  1779. static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
  1780. ReusableStringStream rss;
  1781. rss << duration.count() << " s";
  1782. return rss.str();
  1783. }
  1784. };
  1785. template<typename Value>
  1786. struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
  1787. static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
  1788. ReusableStringStream rss;
  1789. rss << duration.count() << " m";
  1790. return rss.str();
  1791. }
  1792. };
  1793. template<typename Value>
  1794. struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
  1795. static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
  1796. ReusableStringStream rss;
  1797. rss << duration.count() << " h";
  1798. return rss.str();
  1799. }
  1800. };
  1801. ////////////
  1802. // std::chrono::time_point specialization
  1803. // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
  1804. template<typename Clock, typename Duration>
  1805. struct StringMaker<std::chrono::time_point<Clock, Duration>> {
  1806. static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {
  1807. return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
  1808. }
  1809. };
  1810. // std::chrono::time_point<system_clock> specialization
  1811. template<typename Duration>
  1812. struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
  1813. static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
  1814. auto converted = std::chrono::system_clock::to_time_t(time_point);
  1815. #ifdef _MSC_VER
  1816. std::tm timeInfo = {};
  1817. gmtime_s(&timeInfo, &converted);
  1818. #else
  1819. std::tm* timeInfo = std::gmtime(&converted);
  1820. #endif
  1821. auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
  1822. char timeStamp[timeStampSize];
  1823. const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
  1824. #ifdef _MSC_VER
  1825. std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
  1826. #else
  1827. std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
  1828. #endif
  1829. return std::string(timeStamp);
  1830. }
  1831. };
  1832. }
  1833. #endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
  1834. #define INTERNAL_CATCH_REGISTER_ENUM( enumName, ... ) \
  1835. namespace Catch { \
  1836. template<> struct StringMaker<enumName> { \
  1837. static std::string convert( enumName value ) { \
  1838. static const auto& enumInfo = ::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum( #enumName, #__VA_ARGS__, { __VA_ARGS__ } ); \
  1839. return static_cast<std::string>(enumInfo.lookup( static_cast<int>( value ) )); \
  1840. } \
  1841. }; \
  1842. }
  1843. #define CATCH_REGISTER_ENUM( enumName, ... ) INTERNAL_CATCH_REGISTER_ENUM( enumName, __VA_ARGS__ )
  1844. #ifdef _MSC_VER
  1845. #pragma warning(pop)
  1846. #endif
  1847. // end catch_tostring.h
  1848. #include <iosfwd>
  1849. #ifdef _MSC_VER
  1850. #pragma warning(push)
  1851. #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
  1852. #pragma warning(disable:4018) // more "signed/unsigned mismatch"
  1853. #pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
  1854. #pragma warning(disable:4180) // qualifier applied to function type has no meaning
  1855. #pragma warning(disable:4800) // Forcing result to true or false
  1856. #endif
  1857. namespace Catch {
  1858. struct ITransientExpression {
  1859. auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
  1860. auto getResult() const -> bool { return m_result; }
  1861. virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
  1862. ITransientExpression( bool isBinaryExpression, bool result )
  1863. : m_isBinaryExpression( isBinaryExpression ),
  1864. m_result( result )
  1865. {}
  1866. // We don't actually need a virtual destructor, but many static analysers
  1867. // complain if it's not here :-(
  1868. virtual ~ITransientExpression();
  1869. bool m_isBinaryExpression;
  1870. bool m_result;
  1871. };
  1872. void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
  1873. template<typename LhsT, typename RhsT>
  1874. class BinaryExpr : public ITransientExpression {
  1875. LhsT m_lhs;
  1876. StringRef m_op;
  1877. RhsT m_rhs;
  1878. void streamReconstructedExpression( std::ostream &os ) const override {
  1879. formatReconstructedExpression
  1880. ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
  1881. }
  1882. public:
  1883. BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
  1884. : ITransientExpression{ true, comparisonResult },
  1885. m_lhs( lhs ),
  1886. m_op( op ),
  1887. m_rhs( rhs )
  1888. {}
  1889. template<typename T>
  1890. auto operator && ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
  1891. static_assert(always_false<T>::value,
  1892. "chained comparisons are not supported inside assertions, "
  1893. "wrap the expression inside parentheses, or decompose it");
  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. template<typename T>
  1902. auto operator == ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
  1903. static_assert(always_false<T>::value,
  1904. "chained comparisons are not supported inside assertions, "
  1905. "wrap the expression inside parentheses, or decompose it");
  1906. }
  1907. template<typename T>
  1908. auto operator != ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
  1909. static_assert(always_false<T>::value,
  1910. "chained comparisons are not supported inside assertions, "
  1911. "wrap the expression inside parentheses, or decompose it");
  1912. }
  1913. template<typename T>
  1914. auto operator > ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
  1915. static_assert(always_false<T>::value,
  1916. "chained comparisons are not supported inside assertions, "
  1917. "wrap the expression inside parentheses, or decompose it");
  1918. }
  1919. template<typename T>
  1920. auto operator < ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
  1921. static_assert(always_false<T>::value,
  1922. "chained comparisons are not supported inside assertions, "
  1923. "wrap the expression inside parentheses, or decompose it");
  1924. }
  1925. template<typename T>
  1926. auto operator >= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
  1927. static_assert(always_false<T>::value,
  1928. "chained comparisons are not supported inside assertions, "
  1929. "wrap the expression inside parentheses, or decompose it");
  1930. }
  1931. template<typename T>
  1932. auto operator <= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
  1933. static_assert(always_false<T>::value,
  1934. "chained comparisons are not supported inside assertions, "
  1935. "wrap the expression inside parentheses, or decompose it");
  1936. }
  1937. };
  1938. template<typename LhsT>
  1939. class UnaryExpr : public ITransientExpression {
  1940. LhsT m_lhs;
  1941. void streamReconstructedExpression( std::ostream &os ) const override {
  1942. os << Catch::Detail::stringify( m_lhs );
  1943. }
  1944. public:
  1945. explicit UnaryExpr( LhsT lhs )
  1946. : ITransientExpression{ false, static_cast<bool>(lhs) },
  1947. m_lhs( lhs )
  1948. {}
  1949. };
  1950. // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
  1951. template<typename LhsT, typename RhsT>
  1952. auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }
  1953. template<typename T>
  1954. auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
  1955. template<typename T>
  1956. auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
  1957. template<typename T>
  1958. auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
  1959. template<typename T>
  1960. auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
  1961. template<typename LhsT, typename RhsT>
  1962. auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }
  1963. template<typename T>
  1964. auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
  1965. template<typename T>
  1966. auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
  1967. template<typename T>
  1968. auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
  1969. template<typename T>
  1970. auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
  1971. template<typename LhsT>
  1972. class ExprLhs {
  1973. LhsT m_lhs;
  1974. public:
  1975. explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
  1976. template<typename RhsT>
  1977. auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
  1978. return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs };
  1979. }
  1980. auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
  1981. return { m_lhs == rhs, m_lhs, "==", rhs };
  1982. }
  1983. template<typename RhsT>
  1984. auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
  1985. return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs };
  1986. }
  1987. auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
  1988. return { m_lhs != rhs, m_lhs, "!=", rhs };
  1989. }
  1990. template<typename RhsT>
  1991. auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
  1992. return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs };
  1993. }
  1994. template<typename RhsT>
  1995. auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
  1996. return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs };
  1997. }
  1998. template<typename RhsT>
  1999. auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
  2000. return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs };
  2001. }
  2002. template<typename RhsT>
  2003. auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
  2004. return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs };
  2005. }
  2006. template <typename RhsT>
  2007. auto operator | (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
  2008. return { static_cast<bool>(m_lhs | rhs), m_lhs, "|", rhs };
  2009. }
  2010. template <typename RhsT>
  2011. auto operator & (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
  2012. return { static_cast<bool>(m_lhs & rhs), m_lhs, "&", rhs };
  2013. }
  2014. template <typename RhsT>
  2015. auto operator ^ (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
  2016. return { static_cast<bool>(m_lhs ^ rhs), m_lhs, "^", rhs };
  2017. }
  2018. template<typename RhsT>
  2019. auto operator && ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
  2020. static_assert(always_false<RhsT>::value,
  2021. "operator&& is not supported inside assertions, "
  2022. "wrap the expression inside parentheses, or decompose it");
  2023. }
  2024. template<typename RhsT>
  2025. auto operator || ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
  2026. static_assert(always_false<RhsT>::value,
  2027. "operator|| is not supported inside assertions, "
  2028. "wrap the expression inside parentheses, or decompose it");
  2029. }
  2030. auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
  2031. return UnaryExpr<LhsT>{ m_lhs };
  2032. }
  2033. };
  2034. void handleExpression( ITransientExpression const& expr );
  2035. template<typename T>
  2036. void handleExpression( ExprLhs<T> const& expr ) {
  2037. handleExpression( expr.makeUnaryExpr() );
  2038. }
  2039. struct Decomposer {
  2040. template<typename T>
  2041. auto operator <= ( T const& lhs ) -> ExprLhs<T const&> {
  2042. return ExprLhs<T const&>{ lhs };
  2043. }
  2044. auto operator <=( bool value ) -> ExprLhs<bool> {
  2045. return ExprLhs<bool>{ value };
  2046. }
  2047. };
  2048. } // end namespace Catch
  2049. #ifdef _MSC_VER
  2050. #pragma warning(pop)
  2051. #endif
  2052. // end catch_decomposer.h
  2053. // start catch_interfaces_capture.h
  2054. #include <string>
  2055. #include <chrono>
  2056. namespace Catch {
  2057. class AssertionResult;
  2058. struct AssertionInfo;
  2059. struct SectionInfo;
  2060. struct SectionEndInfo;
  2061. struct MessageInfo;
  2062. struct MessageBuilder;
  2063. struct Counts;
  2064. struct AssertionReaction;
  2065. struct SourceLineInfo;
  2066. struct ITransientExpression;
  2067. struct IGeneratorTracker;
  2068. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  2069. struct BenchmarkInfo;
  2070. template <typename Duration = std::chrono::duration<double, std::nano>>
  2071. struct BenchmarkStats;
  2072. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  2073. struct IResultCapture {
  2074. virtual ~IResultCapture();
  2075. virtual bool sectionStarted( SectionInfo const& sectionInfo,
  2076. Counts& assertions ) = 0;
  2077. virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
  2078. virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
  2079. virtual auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
  2080. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  2081. virtual void benchmarkPreparing( std::string const& name ) = 0;
  2082. virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
  2083. virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0;
  2084. virtual void benchmarkFailed( std::string const& error ) = 0;
  2085. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  2086. virtual void pushScopedMessage( MessageInfo const& message ) = 0;
  2087. virtual void popScopedMessage( MessageInfo const& message ) = 0;
  2088. virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0;
  2089. virtual void handleFatalErrorCondition( StringRef message ) = 0;
  2090. virtual void handleExpr
  2091. ( AssertionInfo const& info,
  2092. ITransientExpression const& expr,
  2093. AssertionReaction& reaction ) = 0;
  2094. virtual void handleMessage
  2095. ( AssertionInfo const& info,
  2096. ResultWas::OfType resultType,
  2097. StringRef const& message,
  2098. AssertionReaction& reaction ) = 0;
  2099. virtual void handleUnexpectedExceptionNotThrown
  2100. ( AssertionInfo const& info,
  2101. AssertionReaction& reaction ) = 0;
  2102. virtual void handleUnexpectedInflightException
  2103. ( AssertionInfo const& info,
  2104. std::string const& message,
  2105. AssertionReaction& reaction ) = 0;
  2106. virtual void handleIncomplete
  2107. ( AssertionInfo const& info ) = 0;
  2108. virtual void handleNonExpr
  2109. ( AssertionInfo const &info,
  2110. ResultWas::OfType resultType,
  2111. AssertionReaction &reaction ) = 0;
  2112. virtual bool lastAssertionPassed() = 0;
  2113. virtual void assertionPassed() = 0;
  2114. // Deprecated, do not use:
  2115. virtual std::string getCurrentTestName() const = 0;
  2116. virtual const AssertionResult* getLastResult() const = 0;
  2117. virtual void exceptionEarlyReported() = 0;
  2118. };
  2119. IResultCapture& getResultCapture();
  2120. }
  2121. // end catch_interfaces_capture.h
  2122. namespace Catch {
  2123. struct TestFailureException{};
  2124. struct AssertionResultData;
  2125. struct IResultCapture;
  2126. class RunContext;
  2127. class LazyExpression {
  2128. friend class AssertionHandler;
  2129. friend struct AssertionStats;
  2130. friend class RunContext;
  2131. ITransientExpression const* m_transientExpression = nullptr;
  2132. bool m_isNegated;
  2133. public:
  2134. LazyExpression( bool isNegated );
  2135. LazyExpression( LazyExpression const& other );
  2136. LazyExpression& operator = ( LazyExpression const& ) = delete;
  2137. explicit operator bool() const;
  2138. friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&;
  2139. };
  2140. struct AssertionReaction {
  2141. bool shouldDebugBreak = false;
  2142. bool shouldThrow = false;
  2143. };
  2144. class AssertionHandler {
  2145. AssertionInfo m_assertionInfo;
  2146. AssertionReaction m_reaction;
  2147. bool m_completed = false;
  2148. IResultCapture& m_resultCapture;
  2149. public:
  2150. AssertionHandler
  2151. ( StringRef const& macroName,
  2152. SourceLineInfo const& lineInfo,
  2153. StringRef capturedExpression,
  2154. ResultDisposition::Flags resultDisposition );
  2155. ~AssertionHandler() {
  2156. if ( !m_completed ) {
  2157. m_resultCapture.handleIncomplete( m_assertionInfo );
  2158. }
  2159. }
  2160. template<typename T>
  2161. void handleExpr( ExprLhs<T> const& expr ) {
  2162. handleExpr( expr.makeUnaryExpr() );
  2163. }
  2164. void handleExpr( ITransientExpression const& expr );
  2165. void handleMessage(ResultWas::OfType resultType, StringRef const& message);
  2166. void handleExceptionThrownAsExpected();
  2167. void handleUnexpectedExceptionNotThrown();
  2168. void handleExceptionNotThrownAsExpected();
  2169. void handleThrowingCallSkipped();
  2170. void handleUnexpectedInflightException();
  2171. void complete();
  2172. void setCompleted();
  2173. // query
  2174. auto allowThrows() const -> bool;
  2175. };
  2176. void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString );
  2177. } // namespace Catch
  2178. // end catch_assertionhandler.h
  2179. // start catch_message.h
  2180. #include <string>
  2181. #include <vector>
  2182. namespace Catch {
  2183. struct MessageInfo {
  2184. MessageInfo( StringRef const& _macroName,
  2185. SourceLineInfo const& _lineInfo,
  2186. ResultWas::OfType _type );
  2187. StringRef macroName;
  2188. std::string message;
  2189. SourceLineInfo lineInfo;
  2190. ResultWas::OfType type;
  2191. unsigned int sequence;
  2192. bool operator == ( MessageInfo const& other ) const;
  2193. bool operator < ( MessageInfo const& other ) const;
  2194. private:
  2195. static unsigned int globalCount;
  2196. };
  2197. struct MessageStream {
  2198. template<typename T>
  2199. MessageStream& operator << ( T const& value ) {
  2200. m_stream << value;
  2201. return *this;
  2202. }
  2203. ReusableStringStream m_stream;
  2204. };
  2205. struct MessageBuilder : MessageStream {
  2206. MessageBuilder( StringRef const& macroName,
  2207. SourceLineInfo const& lineInfo,
  2208. ResultWas::OfType type );
  2209. template<typename T>
  2210. MessageBuilder& operator << ( T const& value ) {
  2211. m_stream << value;
  2212. return *this;
  2213. }
  2214. MessageInfo m_info;
  2215. };
  2216. class ScopedMessage {
  2217. public:
  2218. explicit ScopedMessage( MessageBuilder const& builder );
  2219. ScopedMessage( ScopedMessage& duplicate ) = delete;
  2220. ScopedMessage( ScopedMessage&& old );
  2221. ~ScopedMessage();
  2222. MessageInfo m_info;
  2223. bool m_moved;
  2224. };
  2225. class Capturer {
  2226. std::vector<MessageInfo> m_messages;
  2227. IResultCapture& m_resultCapture = getResultCapture();
  2228. size_t m_captured = 0;
  2229. public:
  2230. Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
  2231. ~Capturer();
  2232. void captureValue( size_t index, std::string const& value );
  2233. template<typename T>
  2234. void captureValues( size_t index, T const& value ) {
  2235. captureValue( index, Catch::Detail::stringify( value ) );
  2236. }
  2237. template<typename T, typename... Ts>
  2238. void captureValues( size_t index, T const& value, Ts const&... values ) {
  2239. captureValue( index, Catch::Detail::stringify(value) );
  2240. captureValues( index+1, values... );
  2241. }
  2242. };
  2243. } // end namespace Catch
  2244. // end catch_message.h
  2245. #if !defined(CATCH_CONFIG_DISABLE)
  2246. #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
  2247. #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
  2248. #else
  2249. #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
  2250. #endif
  2251. #if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  2252. ///////////////////////////////////////////////////////////////////////////////
  2253. // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
  2254. // macros.
  2255. #define INTERNAL_CATCH_TRY
  2256. #define INTERNAL_CATCH_CATCH( capturer )
  2257. #else // CATCH_CONFIG_FAST_COMPILE
  2258. #define INTERNAL_CATCH_TRY try
  2259. #define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); }
  2260. #endif
  2261. #define INTERNAL_CATCH_REACT( handler ) handler.complete();
  2262. ///////////////////////////////////////////////////////////////////////////////
  2263. #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
  2264. do { \
  2265. CATCH_INTERNAL_IGNORE_BUT_WARN(__VA_ARGS__); \
  2266. Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
  2267. INTERNAL_CATCH_TRY { \
  2268. CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
  2269. CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
  2270. catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
  2271. CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
  2272. } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
  2273. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  2274. } while( (void)0, (false) && static_cast<bool>( !!(__VA_ARGS__) ) )
  2275. ///////////////////////////////////////////////////////////////////////////////
  2276. #define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
  2277. INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
  2278. if( Catch::getResultCapture().lastAssertionPassed() )
  2279. ///////////////////////////////////////////////////////////////////////////////
  2280. #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
  2281. INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
  2282. if( !Catch::getResultCapture().lastAssertionPassed() )
  2283. ///////////////////////////////////////////////////////////////////////////////
  2284. #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
  2285. do { \
  2286. Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
  2287. try { \
  2288. static_cast<void>(__VA_ARGS__); \
  2289. catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
  2290. } \
  2291. catch( ... ) { \
  2292. catchAssertionHandler.handleUnexpectedInflightException(); \
  2293. } \
  2294. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  2295. } while( false )
  2296. ///////////////////////////////////////////////////////////////////////////////
  2297. #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
  2298. do { \
  2299. Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
  2300. if( catchAssertionHandler.allowThrows() ) \
  2301. try { \
  2302. static_cast<void>(__VA_ARGS__); \
  2303. catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
  2304. } \
  2305. catch( ... ) { \
  2306. catchAssertionHandler.handleExceptionThrownAsExpected(); \
  2307. } \
  2308. else \
  2309. catchAssertionHandler.handleThrowingCallSkipped(); \
  2310. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  2311. } while( false )
  2312. ///////////////////////////////////////////////////////////////////////////////
  2313. #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
  2314. do { \
  2315. Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
  2316. if( catchAssertionHandler.allowThrows() ) \
  2317. try { \
  2318. static_cast<void>(expr); \
  2319. catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
  2320. } \
  2321. catch( exceptionType const& ) { \
  2322. catchAssertionHandler.handleExceptionThrownAsExpected(); \
  2323. } \
  2324. catch( ... ) { \
  2325. catchAssertionHandler.handleUnexpectedInflightException(); \
  2326. } \
  2327. else \
  2328. catchAssertionHandler.handleThrowingCallSkipped(); \
  2329. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  2330. } while( false )
  2331. ///////////////////////////////////////////////////////////////////////////////
  2332. #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
  2333. do { \
  2334. Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
  2335. catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
  2336. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  2337. } while( false )
  2338. ///////////////////////////////////////////////////////////////////////////////
  2339. #define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
  2340. auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \
  2341. varName.captureValues( 0, __VA_ARGS__ )
  2342. ///////////////////////////////////////////////////////////////////////////////
  2343. #define INTERNAL_CATCH_INFO( macroName, log ) \
  2344. Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
  2345. ///////////////////////////////////////////////////////////////////////////////
  2346. #define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \
  2347. Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )
  2348. ///////////////////////////////////////////////////////////////////////////////
  2349. // Although this is matcher-based, it can be used with just a string
  2350. #define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
  2351. do { \
  2352. Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
  2353. if( catchAssertionHandler.allowThrows() ) \
  2354. try { \
  2355. static_cast<void>(__VA_ARGS__); \
  2356. catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
  2357. } \
  2358. catch( ... ) { \
  2359. Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \
  2360. } \
  2361. else \
  2362. catchAssertionHandler.handleThrowingCallSkipped(); \
  2363. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  2364. } while( false )
  2365. #endif // CATCH_CONFIG_DISABLE
  2366. // end catch_capture.hpp
  2367. // start catch_section.h
  2368. // start catch_section_info.h
  2369. // start catch_totals.h
  2370. #include <cstddef>
  2371. namespace Catch {
  2372. struct Counts {
  2373. Counts operator - ( Counts const& other ) const;
  2374. Counts& operator += ( Counts const& other );
  2375. std::size_t total() const;
  2376. bool allPassed() const;
  2377. bool allOk() const;
  2378. std::size_t passed = 0;
  2379. std::size_t failed = 0;
  2380. std::size_t failedButOk = 0;
  2381. };
  2382. struct Totals {
  2383. Totals operator - ( Totals const& other ) const;
  2384. Totals& operator += ( Totals const& other );
  2385. Totals delta( Totals const& prevTotals ) const;
  2386. int error = 0;
  2387. Counts assertions;
  2388. Counts testCases;
  2389. };
  2390. }
  2391. // end catch_totals.h
  2392. #include <string>
  2393. namespace Catch {
  2394. struct SectionInfo {
  2395. SectionInfo
  2396. ( SourceLineInfo const& _lineInfo,
  2397. std::string const& _name );
  2398. // Deprecated
  2399. SectionInfo
  2400. ( SourceLineInfo const& _lineInfo,
  2401. std::string const& _name,
  2402. std::string const& ) : SectionInfo( _lineInfo, _name ) {}
  2403. std::string name;
  2404. std::string description; // !Deprecated: this will always be empty
  2405. SourceLineInfo lineInfo;
  2406. };
  2407. struct SectionEndInfo {
  2408. SectionInfo sectionInfo;
  2409. Counts prevAssertions;
  2410. double durationInSeconds;
  2411. };
  2412. } // end namespace Catch
  2413. // end catch_section_info.h
  2414. // start catch_timer.h
  2415. #include <cstdint>
  2416. namespace Catch {
  2417. auto getCurrentNanosecondsSinceEpoch() -> uint64_t;
  2418. auto getEstimatedClockResolution() -> uint64_t;
  2419. class Timer {
  2420. uint64_t m_nanoseconds = 0;
  2421. public:
  2422. void start();
  2423. auto getElapsedNanoseconds() const -> uint64_t;
  2424. auto getElapsedMicroseconds() const -> uint64_t;
  2425. auto getElapsedMilliseconds() const -> unsigned int;
  2426. auto getElapsedSeconds() const -> double;
  2427. };
  2428. } // namespace Catch
  2429. // end catch_timer.h
  2430. #include <string>
  2431. namespace Catch {
  2432. class Section : NonCopyable {
  2433. public:
  2434. Section( SectionInfo const& info );
  2435. ~Section();
  2436. // This indicates whether the section should be executed or not
  2437. explicit operator bool() const;
  2438. private:
  2439. SectionInfo m_info;
  2440. std::string m_name;
  2441. Counts m_assertions;
  2442. bool m_sectionIncluded;
  2443. Timer m_timer;
  2444. };
  2445. } // end namespace Catch
  2446. #define INTERNAL_CATCH_SECTION( ... ) \
  2447. CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
  2448. CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
  2449. if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
  2450. CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
  2451. #define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
  2452. CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
  2453. CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
  2454. if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \
  2455. CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
  2456. // end catch_section.h
  2457. // start catch_interfaces_exception.h
  2458. // start catch_interfaces_registry_hub.h
  2459. #include <string>
  2460. #include <memory>
  2461. namespace Catch {
  2462. class TestCase;
  2463. struct ITestCaseRegistry;
  2464. struct IExceptionTranslatorRegistry;
  2465. struct IExceptionTranslator;
  2466. struct IReporterRegistry;
  2467. struct IReporterFactory;
  2468. struct ITagAliasRegistry;
  2469. struct IMutableEnumValuesRegistry;
  2470. class StartupExceptionRegistry;
  2471. using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
  2472. struct IRegistryHub {
  2473. virtual ~IRegistryHub();
  2474. virtual IReporterRegistry const& getReporterRegistry() const = 0;
  2475. virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
  2476. virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
  2477. virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0;
  2478. virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
  2479. };
  2480. struct IMutableRegistryHub {
  2481. virtual ~IMutableRegistryHub();
  2482. virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0;
  2483. virtual void registerListener( IReporterFactoryPtr const& factory ) = 0;
  2484. virtual void registerTest( TestCase const& testInfo ) = 0;
  2485. virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
  2486. virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
  2487. virtual void registerStartupException() noexcept = 0;
  2488. virtual IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() = 0;
  2489. };
  2490. IRegistryHub const& getRegistryHub();
  2491. IMutableRegistryHub& getMutableRegistryHub();
  2492. void cleanUp();
  2493. std::string translateActiveException();
  2494. }
  2495. // end catch_interfaces_registry_hub.h
  2496. #if defined(CATCH_CONFIG_DISABLE)
  2497. #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \
  2498. static std::string translatorName( signature )
  2499. #endif
  2500. #include <exception>
  2501. #include <string>
  2502. #include <vector>
  2503. namespace Catch {
  2504. using exceptionTranslateFunction = std::string(*)();
  2505. struct IExceptionTranslator;
  2506. using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;
  2507. struct IExceptionTranslator {
  2508. virtual ~IExceptionTranslator();
  2509. virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
  2510. };
  2511. struct IExceptionTranslatorRegistry {
  2512. virtual ~IExceptionTranslatorRegistry();
  2513. virtual std::string translateActiveException() const = 0;
  2514. };
  2515. class ExceptionTranslatorRegistrar {
  2516. template<typename T>
  2517. class ExceptionTranslator : public IExceptionTranslator {
  2518. public:
  2519. ExceptionTranslator( std::string(*translateFunction)( T& ) )
  2520. : m_translateFunction( translateFunction )
  2521. {}
  2522. std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override {
  2523. #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  2524. return "";
  2525. #else
  2526. try {
  2527. if( it == itEnd )
  2528. std::rethrow_exception(std::current_exception());
  2529. else
  2530. return (*it)->translate( it+1, itEnd );
  2531. }
  2532. catch( T& ex ) {
  2533. return m_translateFunction( ex );
  2534. }
  2535. #endif
  2536. }
  2537. protected:
  2538. std::string(*m_translateFunction)( T& );
  2539. };
  2540. public:
  2541. template<typename T>
  2542. ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
  2543. getMutableRegistryHub().registerTranslator
  2544. ( new ExceptionTranslator<T>( translateFunction ) );
  2545. }
  2546. };
  2547. }
  2548. ///////////////////////////////////////////////////////////////////////////////
  2549. #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
  2550. static std::string translatorName( signature ); \
  2551. CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
  2552. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  2553. namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \
  2554. CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
  2555. static std::string translatorName( signature )
  2556. #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
  2557. // end catch_interfaces_exception.h
  2558. // start catch_approx.h
  2559. #include <type_traits>
  2560. namespace Catch {
  2561. namespace Detail {
  2562. class Approx {
  2563. private:
  2564. bool equalityComparisonImpl(double other) const;
  2565. // Validates the new margin (margin >= 0)
  2566. // out-of-line to avoid including stdexcept in the header
  2567. void setMargin(double margin);
  2568. // Validates the new epsilon (0 < epsilon < 1)
  2569. // out-of-line to avoid including stdexcept in the header
  2570. void setEpsilon(double epsilon);
  2571. public:
  2572. explicit Approx ( double value );
  2573. static Approx custom();
  2574. Approx operator-() const;
  2575. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2576. Approx operator()( T const& value ) {
  2577. Approx approx( static_cast<double>(value) );
  2578. approx.m_epsilon = m_epsilon;
  2579. approx.m_margin = m_margin;
  2580. approx.m_scale = m_scale;
  2581. return approx;
  2582. }
  2583. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2584. explicit Approx( T const& value ): Approx(static_cast<double>(value))
  2585. {}
  2586. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2587. friend bool operator == ( const T& lhs, Approx const& rhs ) {
  2588. auto lhs_v = static_cast<double>(lhs);
  2589. return rhs.equalityComparisonImpl(lhs_v);
  2590. }
  2591. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2592. friend bool operator == ( Approx const& lhs, const T& rhs ) {
  2593. return operator==( rhs, lhs );
  2594. }
  2595. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2596. friend bool operator != ( T const& lhs, Approx const& rhs ) {
  2597. return !operator==( lhs, rhs );
  2598. }
  2599. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2600. friend bool operator != ( Approx const& lhs, T const& rhs ) {
  2601. return !operator==( rhs, lhs );
  2602. }
  2603. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2604. friend bool operator <= ( T const& lhs, Approx const& rhs ) {
  2605. return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;
  2606. }
  2607. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2608. friend bool operator <= ( Approx const& lhs, T const& rhs ) {
  2609. return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
  2610. }
  2611. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2612. friend bool operator >= ( T const& lhs, Approx const& rhs ) {
  2613. return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;
  2614. }
  2615. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2616. friend bool operator >= ( Approx const& lhs, T const& rhs ) {
  2617. return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
  2618. }
  2619. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2620. Approx& epsilon( T const& newEpsilon ) {
  2621. double epsilonAsDouble = static_cast<double>(newEpsilon);
  2622. setEpsilon(epsilonAsDouble);
  2623. return *this;
  2624. }
  2625. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2626. Approx& margin( T const& newMargin ) {
  2627. double marginAsDouble = static_cast<double>(newMargin);
  2628. setMargin(marginAsDouble);
  2629. return *this;
  2630. }
  2631. template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  2632. Approx& scale( T const& newScale ) {
  2633. m_scale = static_cast<double>(newScale);
  2634. return *this;
  2635. }
  2636. std::string toString() const;
  2637. private:
  2638. double m_epsilon;
  2639. double m_margin;
  2640. double m_scale;
  2641. double m_value;
  2642. };
  2643. } // end namespace Detail
  2644. namespace literals {
  2645. Detail::Approx operator "" _a(long double val);
  2646. Detail::Approx operator "" _a(unsigned long long val);
  2647. } // end namespace literals
  2648. template<>
  2649. struct StringMaker<Catch::Detail::Approx> {
  2650. static std::string convert(Catch::Detail::Approx const& value);
  2651. };
  2652. } // end namespace Catch
  2653. // end catch_approx.h
  2654. // start catch_string_manip.h
  2655. #include <string>
  2656. #include <iosfwd>
  2657. #include <vector>
  2658. namespace Catch {
  2659. bool startsWith( std::string const& s, std::string const& prefix );
  2660. bool startsWith( std::string const& s, char prefix );
  2661. bool endsWith( std::string const& s, std::string const& suffix );
  2662. bool endsWith( std::string const& s, char suffix );
  2663. bool contains( std::string const& s, std::string const& infix );
  2664. void toLowerInPlace( std::string& s );
  2665. std::string toLower( std::string const& s );
  2666. //! Returns a new string without whitespace at the start/end
  2667. std::string trim( std::string const& str );
  2668. //! Returns a substring of the original ref without whitespace. Beware lifetimes!
  2669. StringRef trim(StringRef ref);
  2670. // !!! Be aware, returns refs into original string - make sure original string outlives them
  2671. std::vector<StringRef> splitStringRef( StringRef str, char delimiter );
  2672. bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
  2673. struct pluralise {
  2674. pluralise( std::size_t count, std::string const& label );
  2675. friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
  2676. std::size_t m_count;
  2677. std::string m_label;
  2678. };
  2679. }
  2680. // end catch_string_manip.h
  2681. #ifndef CATCH_CONFIG_DISABLE_MATCHERS
  2682. // start catch_capture_matchers.h
  2683. // start catch_matchers.h
  2684. #include <string>
  2685. #include <vector>
  2686. namespace Catch {
  2687. namespace Matchers {
  2688. namespace Impl {
  2689. template<typename ArgT> struct MatchAllOf;
  2690. template<typename ArgT> struct MatchAnyOf;
  2691. template<typename ArgT> struct MatchNotOf;
  2692. class MatcherUntypedBase {
  2693. public:
  2694. MatcherUntypedBase() = default;
  2695. MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
  2696. MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete;
  2697. std::string toString() const;
  2698. protected:
  2699. virtual ~MatcherUntypedBase();
  2700. virtual std::string describe() const = 0;
  2701. mutable std::string m_cachedToString;
  2702. };
  2703. #ifdef __clang__
  2704. # pragma clang diagnostic push
  2705. # pragma clang diagnostic ignored "-Wnon-virtual-dtor"
  2706. #endif
  2707. template<typename ObjectT>
  2708. struct MatcherMethod {
  2709. virtual bool match( ObjectT const& arg ) const = 0;
  2710. };
  2711. #if defined(__OBJC__)
  2712. // Hack to fix Catch GH issue #1661. Could use id for generic Object support.
  2713. // use of const for Object pointers is very uncommon and under ARC it causes some kind of signature mismatch that breaks compilation
  2714. template<>
  2715. struct MatcherMethod<NSString*> {
  2716. virtual bool match( NSString* arg ) const = 0;
  2717. };
  2718. #endif
  2719. #ifdef __clang__
  2720. # pragma clang diagnostic pop
  2721. #endif
  2722. template<typename T>
  2723. struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
  2724. MatchAllOf<T> operator && ( MatcherBase const& other ) const;
  2725. MatchAnyOf<T> operator || ( MatcherBase const& other ) const;
  2726. MatchNotOf<T> operator ! () const;
  2727. };
  2728. template<typename ArgT>
  2729. struct MatchAllOf : MatcherBase<ArgT> {
  2730. bool match( ArgT const& arg ) const override {
  2731. for( auto matcher : m_matchers ) {
  2732. if (!matcher->match(arg))
  2733. return false;
  2734. }
  2735. return true;
  2736. }
  2737. std::string describe() const override {
  2738. std::string description;
  2739. description.reserve( 4 + m_matchers.size()*32 );
  2740. description += "( ";
  2741. bool first = true;
  2742. for( auto matcher : m_matchers ) {
  2743. if( first )
  2744. first = false;
  2745. else
  2746. description += " and ";
  2747. description += matcher->toString();
  2748. }
  2749. description += " )";
  2750. return description;
  2751. }
  2752. MatchAllOf<ArgT> operator && ( MatcherBase<ArgT> const& other ) {
  2753. auto copy(*this);
  2754. copy.m_matchers.push_back( &other );
  2755. return copy;
  2756. }
  2757. std::vector<MatcherBase<ArgT> const*> m_matchers;
  2758. };
  2759. template<typename ArgT>
  2760. struct MatchAnyOf : MatcherBase<ArgT> {
  2761. bool match( ArgT const& arg ) const override {
  2762. for( auto matcher : m_matchers ) {
  2763. if (matcher->match(arg))
  2764. return true;
  2765. }
  2766. return false;
  2767. }
  2768. std::string describe() const override {
  2769. std::string description;
  2770. description.reserve( 4 + m_matchers.size()*32 );
  2771. description += "( ";
  2772. bool first = true;
  2773. for( auto matcher : m_matchers ) {
  2774. if( first )
  2775. first = false;
  2776. else
  2777. description += " or ";
  2778. description += matcher->toString();
  2779. }
  2780. description += " )";
  2781. return description;
  2782. }
  2783. MatchAnyOf<ArgT> operator || ( MatcherBase<ArgT> const& other ) {
  2784. auto copy(*this);
  2785. copy.m_matchers.push_back( &other );
  2786. return copy;
  2787. }
  2788. std::vector<MatcherBase<ArgT> const*> m_matchers;
  2789. };
  2790. template<typename ArgT>
  2791. struct MatchNotOf : MatcherBase<ArgT> {
  2792. MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
  2793. bool match( ArgT const& arg ) const override {
  2794. return !m_underlyingMatcher.match( arg );
  2795. }
  2796. std::string describe() const override {
  2797. return "not " + m_underlyingMatcher.toString();
  2798. }
  2799. MatcherBase<ArgT> const& m_underlyingMatcher;
  2800. };
  2801. template<typename T>
  2802. MatchAllOf<T> MatcherBase<T>::operator && ( MatcherBase const& other ) const {
  2803. return MatchAllOf<T>() && *this && other;
  2804. }
  2805. template<typename T>
  2806. MatchAnyOf<T> MatcherBase<T>::operator || ( MatcherBase const& other ) const {
  2807. return MatchAnyOf<T>() || *this || other;
  2808. }
  2809. template<typename T>
  2810. MatchNotOf<T> MatcherBase<T>::operator ! () const {
  2811. return MatchNotOf<T>( *this );
  2812. }
  2813. } // namespace Impl
  2814. } // namespace Matchers
  2815. using namespace Matchers;
  2816. using Matchers::Impl::MatcherBase;
  2817. } // namespace Catch
  2818. // end catch_matchers.h
  2819. // start catch_matchers_exception.hpp
  2820. namespace Catch {
  2821. namespace Matchers {
  2822. namespace Exception {
  2823. class ExceptionMessageMatcher : public MatcherBase<std::exception> {
  2824. std::string m_message;
  2825. public:
  2826. ExceptionMessageMatcher(std::string const& message):
  2827. m_message(message)
  2828. {}
  2829. bool match(std::exception const& ex) const override;
  2830. std::string describe() const override;
  2831. };
  2832. } // namespace Exception
  2833. Exception::ExceptionMessageMatcher Message(std::string const& message);
  2834. } // namespace Matchers
  2835. } // namespace Catch
  2836. // end catch_matchers_exception.hpp
  2837. // start catch_matchers_floating.h
  2838. namespace Catch {
  2839. namespace Matchers {
  2840. namespace Floating {
  2841. enum class FloatingPointKind : uint8_t;
  2842. struct WithinAbsMatcher : MatcherBase<double> {
  2843. WithinAbsMatcher(double target, double margin);
  2844. bool match(double const& matchee) const override;
  2845. std::string describe() const override;
  2846. private:
  2847. double m_target;
  2848. double m_margin;
  2849. };
  2850. struct WithinUlpsMatcher : MatcherBase<double> {
  2851. WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType);
  2852. bool match(double const& matchee) const override;
  2853. std::string describe() const override;
  2854. private:
  2855. double m_target;
  2856. uint64_t m_ulps;
  2857. FloatingPointKind m_type;
  2858. };
  2859. // Given IEEE-754 format for floats and doubles, we can assume
  2860. // that float -> double promotion is lossless. Given this, we can
  2861. // assume that if we do the standard relative comparison of
  2862. // |lhs - rhs| <= epsilon * max(fabs(lhs), fabs(rhs)), then we get
  2863. // the same result if we do this for floats, as if we do this for
  2864. // doubles that were promoted from floats.
  2865. struct WithinRelMatcher : MatcherBase<double> {
  2866. WithinRelMatcher(double target, double epsilon);
  2867. bool match(double const& matchee) const override;
  2868. std::string describe() const override;
  2869. private:
  2870. double m_target;
  2871. double m_epsilon;
  2872. };
  2873. } // namespace Floating
  2874. // The following functions create the actual matcher objects.
  2875. // This allows the types to be inferred
  2876. Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);
  2877. Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);
  2878. Floating::WithinAbsMatcher WithinAbs(double target, double margin);
  2879. Floating::WithinRelMatcher WithinRel(double target, double eps);
  2880. // defaults epsilon to 100*numeric_limits<double>::epsilon()
  2881. Floating::WithinRelMatcher WithinRel(double target);
  2882. Floating::WithinRelMatcher WithinRel(float target, float eps);
  2883. // defaults epsilon to 100*numeric_limits<float>::epsilon()
  2884. Floating::WithinRelMatcher WithinRel(float target);
  2885. } // namespace Matchers
  2886. } // namespace Catch
  2887. // end catch_matchers_floating.h
  2888. // start catch_matchers_generic.hpp
  2889. #include <functional>
  2890. #include <string>
  2891. namespace Catch {
  2892. namespace Matchers {
  2893. namespace Generic {
  2894. namespace Detail {
  2895. std::string finalizeDescription(const std::string& desc);
  2896. }
  2897. template <typename T>
  2898. class PredicateMatcher : public MatcherBase<T> {
  2899. std::function<bool(T const&)> m_predicate;
  2900. std::string m_description;
  2901. public:
  2902. PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr)
  2903. :m_predicate(std::move(elem)),
  2904. m_description(Detail::finalizeDescription(descr))
  2905. {}
  2906. bool match( T const& item ) const override {
  2907. return m_predicate(item);
  2908. }
  2909. std::string describe() const override {
  2910. return m_description;
  2911. }
  2912. };
  2913. } // namespace Generic
  2914. // The following functions create the actual matcher objects.
  2915. // The user has to explicitly specify type to the function, because
  2916. // inferring std::function<bool(T const&)> is hard (but possible) and
  2917. // requires a lot of TMP.
  2918. template<typename T>
  2919. Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") {
  2920. return Generic::PredicateMatcher<T>(predicate, description);
  2921. }
  2922. } // namespace Matchers
  2923. } // namespace Catch
  2924. // end catch_matchers_generic.hpp
  2925. // start catch_matchers_string.h
  2926. #include <string>
  2927. namespace Catch {
  2928. namespace Matchers {
  2929. namespace StdString {
  2930. struct CasedString
  2931. {
  2932. CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );
  2933. std::string adjustString( std::string const& str ) const;
  2934. std::string caseSensitivitySuffix() const;
  2935. CaseSensitive::Choice m_caseSensitivity;
  2936. std::string m_str;
  2937. };
  2938. struct StringMatcherBase : MatcherBase<std::string> {
  2939. StringMatcherBase( std::string const& operation, CasedString const& comparator );
  2940. std::string describe() const override;
  2941. CasedString m_comparator;
  2942. std::string m_operation;
  2943. };
  2944. struct EqualsMatcher : StringMatcherBase {
  2945. EqualsMatcher( CasedString const& comparator );
  2946. bool match( std::string const& source ) const override;
  2947. };
  2948. struct ContainsMatcher : StringMatcherBase {
  2949. ContainsMatcher( CasedString const& comparator );
  2950. bool match( std::string const& source ) const override;
  2951. };
  2952. struct StartsWithMatcher : StringMatcherBase {
  2953. StartsWithMatcher( CasedString const& comparator );
  2954. bool match( std::string const& source ) const override;
  2955. };
  2956. struct EndsWithMatcher : StringMatcherBase {
  2957. EndsWithMatcher( CasedString const& comparator );
  2958. bool match( std::string const& source ) const override;
  2959. };
  2960. struct RegexMatcher : MatcherBase<std::string> {
  2961. RegexMatcher( std::string regex, CaseSensitive::Choice caseSensitivity );
  2962. bool match( std::string const& matchee ) const override;
  2963. std::string describe() const override;
  2964. private:
  2965. std::string m_regex;
  2966. CaseSensitive::Choice m_caseSensitivity;
  2967. };
  2968. } // namespace StdString
  2969. // The following functions create the actual matcher objects.
  2970. // This allows the types to be inferred
  2971. StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
  2972. StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
  2973. StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
  2974. StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
  2975. StdString::RegexMatcher Matches( std::string const& regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
  2976. } // namespace Matchers
  2977. } // namespace Catch
  2978. // end catch_matchers_string.h
  2979. // start catch_matchers_vector.h
  2980. #include <algorithm>
  2981. namespace Catch {
  2982. namespace Matchers {
  2983. namespace Vector {
  2984. template<typename T, typename Alloc>
  2985. struct ContainsElementMatcher : MatcherBase<std::vector<T, Alloc>> {
  2986. ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
  2987. bool match(std::vector<T, Alloc> const &v) const override {
  2988. for (auto const& el : v) {
  2989. if (el == m_comparator) {
  2990. return true;
  2991. }
  2992. }
  2993. return false;
  2994. }
  2995. std::string describe() const override {
  2996. return "Contains: " + ::Catch::Detail::stringify( m_comparator );
  2997. }
  2998. T const& m_comparator;
  2999. };
  3000. template<typename T, typename AllocComp, typename AllocMatch>
  3001. struct ContainsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
  3002. ContainsMatcher(std::vector<T, AllocComp> const &comparator) : m_comparator( comparator ) {}
  3003. bool match(std::vector<T, AllocMatch> const &v) const override {
  3004. // !TBD: see note in EqualsMatcher
  3005. if (m_comparator.size() > v.size())
  3006. return false;
  3007. for (auto const& comparator : m_comparator) {
  3008. auto present = false;
  3009. for (const auto& el : v) {
  3010. if (el == comparator) {
  3011. present = true;
  3012. break;
  3013. }
  3014. }
  3015. if (!present) {
  3016. return false;
  3017. }
  3018. }
  3019. return true;
  3020. }
  3021. std::string describe() const override {
  3022. return "Contains: " + ::Catch::Detail::stringify( m_comparator );
  3023. }
  3024. std::vector<T, AllocComp> const& m_comparator;
  3025. };
  3026. template<typename T, typename AllocComp, typename AllocMatch>
  3027. struct EqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
  3028. EqualsMatcher(std::vector<T, AllocComp> const &comparator) : m_comparator( comparator ) {}
  3029. bool match(std::vector<T, AllocMatch> const &v) const override {
  3030. // !TBD: This currently works if all elements can be compared using !=
  3031. // - a more general approach would be via a compare template that defaults
  3032. // to using !=. but could be specialised for, e.g. std::vector<T, Alloc> etc
  3033. // - then just call that directly
  3034. if (m_comparator.size() != v.size())
  3035. return false;
  3036. for (std::size_t i = 0; i < v.size(); ++i)
  3037. if (m_comparator[i] != v[i])
  3038. return false;
  3039. return true;
  3040. }
  3041. std::string describe() const override {
  3042. return "Equals: " + ::Catch::Detail::stringify( m_comparator );
  3043. }
  3044. std::vector<T, AllocComp> const& m_comparator;
  3045. };
  3046. template<typename T, typename AllocComp, typename AllocMatch>
  3047. struct ApproxMatcher : MatcherBase<std::vector<T, AllocMatch>> {
  3048. ApproxMatcher(std::vector<T, AllocComp> const& comparator) : m_comparator( comparator ) {}
  3049. bool match(std::vector<T, AllocMatch> const &v) const override {
  3050. if (m_comparator.size() != v.size())
  3051. return false;
  3052. for (std::size_t i = 0; i < v.size(); ++i)
  3053. if (m_comparator[i] != approx(v[i]))
  3054. return false;
  3055. return true;
  3056. }
  3057. std::string describe() const override {
  3058. return "is approx: " + ::Catch::Detail::stringify( m_comparator );
  3059. }
  3060. template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  3061. ApproxMatcher& epsilon( T const& newEpsilon ) {
  3062. approx.epsilon(newEpsilon);
  3063. return *this;
  3064. }
  3065. template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  3066. ApproxMatcher& margin( T const& newMargin ) {
  3067. approx.margin(newMargin);
  3068. return *this;
  3069. }
  3070. template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  3071. ApproxMatcher& scale( T const& newScale ) {
  3072. approx.scale(newScale);
  3073. return *this;
  3074. }
  3075. std::vector<T, AllocComp> const& m_comparator;
  3076. mutable Catch::Detail::Approx approx = Catch::Detail::Approx::custom();
  3077. };
  3078. template<typename T, typename AllocComp, typename AllocMatch>
  3079. struct UnorderedEqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
  3080. UnorderedEqualsMatcher(std::vector<T, AllocComp> const& target) : m_target(target) {}
  3081. bool match(std::vector<T, AllocMatch> const& vec) const override {
  3082. if (m_target.size() != vec.size()) {
  3083. return false;
  3084. }
  3085. return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());
  3086. }
  3087. std::string describe() const override {
  3088. return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
  3089. }
  3090. private:
  3091. std::vector<T, AllocComp> const& m_target;
  3092. };
  3093. } // namespace Vector
  3094. // The following functions create the actual matcher objects.
  3095. // This allows the types to be inferred
  3096. template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
  3097. Vector::ContainsMatcher<T, AllocComp, AllocMatch> Contains( std::vector<T, AllocComp> const& comparator ) {
  3098. return Vector::ContainsMatcher<T, AllocComp, AllocMatch>( comparator );
  3099. }
  3100. template<typename T, typename Alloc = std::allocator<T>>
  3101. Vector::ContainsElementMatcher<T, Alloc> VectorContains( T const& comparator ) {
  3102. return Vector::ContainsElementMatcher<T, Alloc>( comparator );
  3103. }
  3104. template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
  3105. Vector::EqualsMatcher<T, AllocComp, AllocMatch> Equals( std::vector<T, AllocComp> const& comparator ) {
  3106. return Vector::EqualsMatcher<T, AllocComp, AllocMatch>( comparator );
  3107. }
  3108. template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
  3109. Vector::ApproxMatcher<T, AllocComp, AllocMatch> Approx( std::vector<T, AllocComp> const& comparator ) {
  3110. return Vector::ApproxMatcher<T, AllocComp, AllocMatch>( comparator );
  3111. }
  3112. template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
  3113. Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch> UnorderedEquals(std::vector<T, AllocComp> const& target) {
  3114. return Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch>( target );
  3115. }
  3116. } // namespace Matchers
  3117. } // namespace Catch
  3118. // end catch_matchers_vector.h
  3119. namespace Catch {
  3120. template<typename ArgT, typename MatcherT>
  3121. class MatchExpr : public ITransientExpression {
  3122. ArgT const& m_arg;
  3123. MatcherT m_matcher;
  3124. StringRef m_matcherString;
  3125. public:
  3126. MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString )
  3127. : ITransientExpression{ true, matcher.match( arg ) },
  3128. m_arg( arg ),
  3129. m_matcher( matcher ),
  3130. m_matcherString( matcherString )
  3131. {}
  3132. void streamReconstructedExpression( std::ostream &os ) const override {
  3133. auto matcherAsString = m_matcher.toString();
  3134. os << Catch::Detail::stringify( m_arg ) << ' ';
  3135. if( matcherAsString == Detail::unprintableString )
  3136. os << m_matcherString;
  3137. else
  3138. os << matcherAsString;
  3139. }
  3140. };
  3141. using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
  3142. void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString );
  3143. template<typename ArgT, typename MatcherT>
  3144. auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString ) -> MatchExpr<ArgT, MatcherT> {
  3145. return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );
  3146. }
  3147. } // namespace Catch
  3148. ///////////////////////////////////////////////////////////////////////////////
  3149. #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
  3150. do { \
  3151. Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
  3152. INTERNAL_CATCH_TRY { \
  3153. catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \
  3154. } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
  3155. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  3156. } while( false )
  3157. ///////////////////////////////////////////////////////////////////////////////
  3158. #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
  3159. do { \
  3160. Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
  3161. if( catchAssertionHandler.allowThrows() ) \
  3162. try { \
  3163. static_cast<void>(__VA_ARGS__ ); \
  3164. catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
  3165. } \
  3166. catch( exceptionType const& ex ) { \
  3167. catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \
  3168. } \
  3169. catch( ... ) { \
  3170. catchAssertionHandler.handleUnexpectedInflightException(); \
  3171. } \
  3172. else \
  3173. catchAssertionHandler.handleThrowingCallSkipped(); \
  3174. INTERNAL_CATCH_REACT( catchAssertionHandler ) \
  3175. } while( false )
  3176. // end catch_capture_matchers.h
  3177. #endif
  3178. // start catch_generators.hpp
  3179. // start catch_interfaces_generatortracker.h
  3180. #include <memory>
  3181. namespace Catch {
  3182. namespace Generators {
  3183. class GeneratorUntypedBase {
  3184. public:
  3185. GeneratorUntypedBase() = default;
  3186. virtual ~GeneratorUntypedBase();
  3187. // Attempts to move the generator to the next element
  3188. //
  3189. // Returns true iff the move succeeded (and a valid element
  3190. // can be retrieved).
  3191. virtual bool next() = 0;
  3192. };
  3193. using GeneratorBasePtr = std::unique_ptr<GeneratorUntypedBase>;
  3194. } // namespace Generators
  3195. struct IGeneratorTracker {
  3196. virtual ~IGeneratorTracker();
  3197. virtual auto hasGenerator() const -> bool = 0;
  3198. virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;
  3199. virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0;
  3200. };
  3201. } // namespace Catch
  3202. // end catch_interfaces_generatortracker.h
  3203. // start catch_enforce.h
  3204. #include <exception>
  3205. namespace Catch {
  3206. #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  3207. template <typename Ex>
  3208. [[noreturn]]
  3209. void throw_exception(Ex const& e) {
  3210. throw e;
  3211. }
  3212. #else // ^^ Exceptions are enabled // Exceptions are disabled vv
  3213. [[noreturn]]
  3214. void throw_exception(std::exception const& e);
  3215. #endif
  3216. [[noreturn]]
  3217. void throw_logic_error(std::string const& msg);
  3218. [[noreturn]]
  3219. void throw_domain_error(std::string const& msg);
  3220. [[noreturn]]
  3221. void throw_runtime_error(std::string const& msg);
  3222. } // namespace Catch;
  3223. #define CATCH_MAKE_MSG(...) \
  3224. (Catch::ReusableStringStream() << __VA_ARGS__).str()
  3225. #define CATCH_INTERNAL_ERROR(...) \
  3226. Catch::throw_logic_error(CATCH_MAKE_MSG( CATCH_INTERNAL_LINEINFO << ": Internal Catch2 error: " << __VA_ARGS__))
  3227. #define CATCH_ERROR(...) \
  3228. Catch::throw_domain_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
  3229. #define CATCH_RUNTIME_ERROR(...) \
  3230. Catch::throw_runtime_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
  3231. #define CATCH_ENFORCE( condition, ... ) \
  3232. do{ if( !(condition) ) CATCH_ERROR( __VA_ARGS__ ); } while(false)
  3233. // end catch_enforce.h
  3234. #include <memory>
  3235. #include <vector>
  3236. #include <cassert>
  3237. #include <utility>
  3238. #include <exception>
  3239. namespace Catch {
  3240. class GeneratorException : public std::exception {
  3241. const char* const m_msg = "";
  3242. public:
  3243. GeneratorException(const char* msg):
  3244. m_msg(msg)
  3245. {}
  3246. const char* what() const noexcept override final;
  3247. };
  3248. namespace Generators {
  3249. // !TBD move this into its own location?
  3250. namespace pf{
  3251. template<typename T, typename... Args>
  3252. std::unique_ptr<T> make_unique( Args&&... args ) {
  3253. return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
  3254. }
  3255. }
  3256. template<typename T>
  3257. struct IGenerator : GeneratorUntypedBase {
  3258. virtual ~IGenerator() = default;
  3259. // Returns the current element of the generator
  3260. //
  3261. // \Precondition The generator is either freshly constructed,
  3262. // or the last call to `next()` returned true
  3263. virtual T const& get() const = 0;
  3264. using type = T;
  3265. };
  3266. template<typename T>
  3267. class SingleValueGenerator final : public IGenerator<T> {
  3268. T m_value;
  3269. public:
  3270. SingleValueGenerator(T&& value) : m_value(std::move(value)) {}
  3271. T const& get() const override {
  3272. return m_value;
  3273. }
  3274. bool next() override {
  3275. return false;
  3276. }
  3277. };
  3278. template<typename T>
  3279. class FixedValuesGenerator final : public IGenerator<T> {
  3280. static_assert(!std::is_same<T, bool>::value,
  3281. "FixedValuesGenerator does not support bools because of std::vector<bool>"
  3282. "specialization, use SingleValue Generator instead.");
  3283. std::vector<T> m_values;
  3284. size_t m_idx = 0;
  3285. public:
  3286. FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {}
  3287. T const& get() const override {
  3288. return m_values[m_idx];
  3289. }
  3290. bool next() override {
  3291. ++m_idx;
  3292. return m_idx < m_values.size();
  3293. }
  3294. };
  3295. template <typename T>
  3296. class GeneratorWrapper final {
  3297. std::unique_ptr<IGenerator<T>> m_generator;
  3298. public:
  3299. GeneratorWrapper(std::unique_ptr<IGenerator<T>> generator):
  3300. m_generator(std::move(generator))
  3301. {}
  3302. T const& get() const {
  3303. return m_generator->get();
  3304. }
  3305. bool next() {
  3306. return m_generator->next();
  3307. }
  3308. };
  3309. template <typename T>
  3310. GeneratorWrapper<T> value(T&& value) {
  3311. return GeneratorWrapper<T>(pf::make_unique<SingleValueGenerator<T>>(std::forward<T>(value)));
  3312. }
  3313. template <typename T>
  3314. GeneratorWrapper<T> values(std::initializer_list<T> values) {
  3315. return GeneratorWrapper<T>(pf::make_unique<FixedValuesGenerator<T>>(values));
  3316. }
  3317. template<typename T>
  3318. class Generators : public IGenerator<T> {
  3319. std::vector<GeneratorWrapper<T>> m_generators;
  3320. size_t m_current = 0;
  3321. void populate(GeneratorWrapper<T>&& generator) {
  3322. m_generators.emplace_back(std::move(generator));
  3323. }
  3324. void populate(T&& val) {
  3325. m_generators.emplace_back(value(std::forward<T>(val)));
  3326. }
  3327. template<typename U>
  3328. void populate(U&& val) {
  3329. populate(T(std::forward<U>(val)));
  3330. }
  3331. template<typename U, typename... Gs>
  3332. void populate(U&& valueOrGenerator, Gs &&... moreGenerators) {
  3333. populate(std::forward<U>(valueOrGenerator));
  3334. populate(std::forward<Gs>(moreGenerators)...);
  3335. }
  3336. public:
  3337. template <typename... Gs>
  3338. Generators(Gs &&... moreGenerators) {
  3339. m_generators.reserve(sizeof...(Gs));
  3340. populate(std::forward<Gs>(moreGenerators)...);
  3341. }
  3342. T const& get() const override {
  3343. return m_generators[m_current].get();
  3344. }
  3345. bool next() override {
  3346. if (m_current >= m_generators.size()) {
  3347. return false;
  3348. }
  3349. const bool current_status = m_generators[m_current].next();
  3350. if (!current_status) {
  3351. ++m_current;
  3352. }
  3353. return m_current < m_generators.size();
  3354. }
  3355. };
  3356. template<typename... Ts>
  3357. GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std::tuple<typename std::decay<Ts>::type...>> tuples ) {
  3358. return values<std::tuple<Ts...>>( tuples );
  3359. }
  3360. // Tag type to signal that a generator sequence should convert arguments to a specific type
  3361. template <typename T>
  3362. struct as {};
  3363. template<typename T, typename... Gs>
  3364. auto makeGenerators( GeneratorWrapper<T>&& generator, Gs &&... moreGenerators ) -> Generators<T> {
  3365. return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...);
  3366. }
  3367. template<typename T>
  3368. auto makeGenerators( GeneratorWrapper<T>&& generator ) -> Generators<T> {
  3369. return Generators<T>(std::move(generator));
  3370. }
  3371. template<typename T, typename... Gs>
  3372. auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generators<T> {
  3373. return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );
  3374. }
  3375. template<typename T, typename U, typename... Gs>
  3376. auto makeGenerators( as<T>, U&& val, Gs &&... moreGenerators ) -> Generators<T> {
  3377. return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );
  3378. }
  3379. auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
  3380. template<typename L>
  3381. // Note: The type after -> is weird, because VS2015 cannot parse
  3382. // the expression used in the typedef inside, when it is in
  3383. // return type. Yeah.
  3384. auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) {
  3385. using UnderlyingType = typename decltype(generatorExpression())::type;
  3386. IGeneratorTracker& tracker = acquireGeneratorTracker( generatorName, lineInfo );
  3387. if (!tracker.hasGenerator()) {
  3388. tracker.setGenerator(pf::make_unique<Generators<UnderlyingType>>(generatorExpression()));
  3389. }
  3390. auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() );
  3391. return generator.get();
  3392. }
  3393. } // namespace Generators
  3394. } // namespace Catch
  3395. #define GENERATE( ... ) \
  3396. Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
  3397. CATCH_INTERNAL_LINEINFO, \
  3398. [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
  3399. #define GENERATE_COPY( ... ) \
  3400. Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
  3401. CATCH_INTERNAL_LINEINFO, \
  3402. [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
  3403. #define GENERATE_REF( ... ) \
  3404. Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
  3405. CATCH_INTERNAL_LINEINFO, \
  3406. [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
  3407. // end catch_generators.hpp
  3408. // start catch_generators_generic.hpp
  3409. namespace Catch {
  3410. namespace Generators {
  3411. template <typename T>
  3412. class TakeGenerator : public IGenerator<T> {
  3413. GeneratorWrapper<T> m_generator;
  3414. size_t m_returned = 0;
  3415. size_t m_target;
  3416. public:
  3417. TakeGenerator(size_t target, GeneratorWrapper<T>&& generator):
  3418. m_generator(std::move(generator)),
  3419. m_target(target)
  3420. {
  3421. assert(target != 0 && "Empty generators are not allowed");
  3422. }
  3423. T const& get() const override {
  3424. return m_generator.get();
  3425. }
  3426. bool next() override {
  3427. ++m_returned;
  3428. if (m_returned >= m_target) {
  3429. return false;
  3430. }
  3431. const auto success = m_generator.next();
  3432. // If the underlying generator does not contain enough values
  3433. // then we cut short as well
  3434. if (!success) {
  3435. m_returned = m_target;
  3436. }
  3437. return success;
  3438. }
  3439. };
  3440. template <typename T>
  3441. GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T>&& generator) {
  3442. return GeneratorWrapper<T>(pf::make_unique<TakeGenerator<T>>(target, std::move(generator)));
  3443. }
  3444. template <typename T, typename Predicate>
  3445. class FilterGenerator : public IGenerator<T> {
  3446. GeneratorWrapper<T> m_generator;
  3447. Predicate m_predicate;
  3448. public:
  3449. template <typename P = Predicate>
  3450. FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator):
  3451. m_generator(std::move(generator)),
  3452. m_predicate(std::forward<P>(pred))
  3453. {
  3454. if (!m_predicate(m_generator.get())) {
  3455. // It might happen that there are no values that pass the
  3456. // filter. In that case we throw an exception.
  3457. auto has_initial_value = next();
  3458. if (!has_initial_value) {
  3459. Catch::throw_exception(GeneratorException("No valid value found in filtered generator"));
  3460. }
  3461. }
  3462. }
  3463. T const& get() const override {
  3464. return m_generator.get();
  3465. }
  3466. bool next() override {
  3467. bool success = m_generator.next();
  3468. if (!success) {
  3469. return false;
  3470. }
  3471. while (!m_predicate(m_generator.get()) && (success = m_generator.next()) == true);
  3472. return success;
  3473. }
  3474. };
  3475. template <typename T, typename Predicate>
  3476. GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& generator) {
  3477. return GeneratorWrapper<T>(std::unique_ptr<IGenerator<T>>(pf::make_unique<FilterGenerator<T, Predicate>>(std::forward<Predicate>(pred), std::move(generator))));
  3478. }
  3479. template <typename T>
  3480. class RepeatGenerator : public IGenerator<T> {
  3481. static_assert(!std::is_same<T, bool>::value,
  3482. "RepeatGenerator currently does not support bools"
  3483. "because of std::vector<bool> specialization");
  3484. GeneratorWrapper<T> m_generator;
  3485. mutable std::vector<T> m_returned;
  3486. size_t m_target_repeats;
  3487. size_t m_current_repeat = 0;
  3488. size_t m_repeat_index = 0;
  3489. public:
  3490. RepeatGenerator(size_t repeats, GeneratorWrapper<T>&& generator):
  3491. m_generator(std::move(generator)),
  3492. m_target_repeats(repeats)
  3493. {
  3494. assert(m_target_repeats > 0 && "Repeat generator must repeat at least once");
  3495. }
  3496. T const& get() const override {
  3497. if (m_current_repeat == 0) {
  3498. m_returned.push_back(m_generator.get());
  3499. return m_returned.back();
  3500. }
  3501. return m_returned[m_repeat_index];
  3502. }
  3503. bool next() override {
  3504. // There are 2 basic cases:
  3505. // 1) We are still reading the generator
  3506. // 2) We are reading our own cache
  3507. // In the first case, we need to poke the underlying generator.
  3508. // If it happily moves, we are left in that state, otherwise it is time to start reading from our cache
  3509. if (m_current_repeat == 0) {
  3510. const auto success = m_generator.next();
  3511. if (!success) {
  3512. ++m_current_repeat;
  3513. }
  3514. return m_current_repeat < m_target_repeats;
  3515. }
  3516. // In the second case, we need to move indices forward and check that we haven't run up against the end
  3517. ++m_repeat_index;
  3518. if (m_repeat_index == m_returned.size()) {
  3519. m_repeat_index = 0;
  3520. ++m_current_repeat;
  3521. }
  3522. return m_current_repeat < m_target_repeats;
  3523. }
  3524. };
  3525. template <typename T>
  3526. GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T>&& generator) {
  3527. return GeneratorWrapper<T>(pf::make_unique<RepeatGenerator<T>>(repeats, std::move(generator)));
  3528. }
  3529. template <typename T, typename U, typename Func>
  3530. class MapGenerator : public IGenerator<T> {
  3531. // TBD: provide static assert for mapping function, for friendly error message
  3532. GeneratorWrapper<U> m_generator;
  3533. Func m_function;
  3534. // To avoid returning dangling reference, we have to save the values
  3535. T m_cache;
  3536. public:
  3537. template <typename F2 = Func>
  3538. MapGenerator(F2&& function, GeneratorWrapper<U>&& generator) :
  3539. m_generator(std::move(generator)),
  3540. m_function(std::forward<F2>(function)),
  3541. m_cache(m_function(m_generator.get()))
  3542. {}
  3543. T const& get() const override {
  3544. return m_cache;
  3545. }
  3546. bool next() override {
  3547. const auto success = m_generator.next();
  3548. if (success) {
  3549. m_cache = m_function(m_generator.get());
  3550. }
  3551. return success;
  3552. }
  3553. };
  3554. template <typename Func, typename U, typename T = FunctionReturnType<Func, U>>
  3555. GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
  3556. return GeneratorWrapper<T>(
  3557. pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
  3558. );
  3559. }
  3560. template <typename T, typename U, typename Func>
  3561. GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
  3562. return GeneratorWrapper<T>(
  3563. pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
  3564. );
  3565. }
  3566. template <typename T>
  3567. class ChunkGenerator final : public IGenerator<std::vector<T>> {
  3568. std::vector<T> m_chunk;
  3569. size_t m_chunk_size;
  3570. GeneratorWrapper<T> m_generator;
  3571. bool m_used_up = false;
  3572. public:
  3573. ChunkGenerator(size_t size, GeneratorWrapper<T> generator) :
  3574. m_chunk_size(size), m_generator(std::move(generator))
  3575. {
  3576. m_chunk.reserve(m_chunk_size);
  3577. if (m_chunk_size != 0) {
  3578. m_chunk.push_back(m_generator.get());
  3579. for (size_t i = 1; i < m_chunk_size; ++i) {
  3580. if (!m_generator.next()) {
  3581. Catch::throw_exception(GeneratorException("Not enough values to initialize the first chunk"));
  3582. }
  3583. m_chunk.push_back(m_generator.get());
  3584. }
  3585. }
  3586. }
  3587. std::vector<T> const& get() const override {
  3588. return m_chunk;
  3589. }
  3590. bool next() override {
  3591. m_chunk.clear();
  3592. for (size_t idx = 0; idx < m_chunk_size; ++idx) {
  3593. if (!m_generator.next()) {
  3594. return false;
  3595. }
  3596. m_chunk.push_back(m_generator.get());
  3597. }
  3598. return true;
  3599. }
  3600. };
  3601. template <typename T>
  3602. GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper<T>&& generator) {
  3603. return GeneratorWrapper<std::vector<T>>(
  3604. pf::make_unique<ChunkGenerator<T>>(size, std::move(generator))
  3605. );
  3606. }
  3607. } // namespace Generators
  3608. } // namespace Catch
  3609. // end catch_generators_generic.hpp
  3610. // start catch_generators_specific.hpp
  3611. // start catch_context.h
  3612. #include <memory>
  3613. namespace Catch {
  3614. struct IResultCapture;
  3615. struct IRunner;
  3616. struct IConfig;
  3617. struct IMutableContext;
  3618. using IConfigPtr = std::shared_ptr<IConfig const>;
  3619. struct IContext
  3620. {
  3621. virtual ~IContext();
  3622. virtual IResultCapture* getResultCapture() = 0;
  3623. virtual IRunner* getRunner() = 0;
  3624. virtual IConfigPtr const& getConfig() const = 0;
  3625. };
  3626. struct IMutableContext : IContext
  3627. {
  3628. virtual ~IMutableContext();
  3629. virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
  3630. virtual void setRunner( IRunner* runner ) = 0;
  3631. virtual void setConfig( IConfigPtr const& config ) = 0;
  3632. private:
  3633. static IMutableContext *currentContext;
  3634. friend IMutableContext& getCurrentMutableContext();
  3635. friend void cleanUpContext();
  3636. static void createContext();
  3637. };
  3638. inline IMutableContext& getCurrentMutableContext()
  3639. {
  3640. if( !IMutableContext::currentContext )
  3641. IMutableContext::createContext();
  3642. // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
  3643. return *IMutableContext::currentContext;
  3644. }
  3645. inline IContext& getCurrentContext()
  3646. {
  3647. return getCurrentMutableContext();
  3648. }
  3649. void cleanUpContext();
  3650. class SimplePcg32;
  3651. SimplePcg32& rng();
  3652. }
  3653. // end catch_context.h
  3654. // start catch_interfaces_config.h
  3655. // start catch_option.hpp
  3656. namespace Catch {
  3657. // An optional type
  3658. template<typename T>
  3659. class Option {
  3660. public:
  3661. Option() : nullableValue( nullptr ) {}
  3662. Option( T const& _value )
  3663. : nullableValue( new( storage ) T( _value ) )
  3664. {}
  3665. Option( Option const& _other )
  3666. : nullableValue( _other ? new( storage ) T( *_other ) : nullptr )
  3667. {}
  3668. ~Option() {
  3669. reset();
  3670. }
  3671. Option& operator= ( Option const& _other ) {
  3672. if( &_other != this ) {
  3673. reset();
  3674. if( _other )
  3675. nullableValue = new( storage ) T( *_other );
  3676. }
  3677. return *this;
  3678. }
  3679. Option& operator = ( T const& _value ) {
  3680. reset();
  3681. nullableValue = new( storage ) T( _value );
  3682. return *this;
  3683. }
  3684. void reset() {
  3685. if( nullableValue )
  3686. nullableValue->~T();
  3687. nullableValue = nullptr;
  3688. }
  3689. T& operator*() { return *nullableValue; }
  3690. T const& operator*() const { return *nullableValue; }
  3691. T* operator->() { return nullableValue; }
  3692. const T* operator->() const { return nullableValue; }
  3693. T valueOr( T const& defaultValue ) const {
  3694. return nullableValue ? *nullableValue : defaultValue;
  3695. }
  3696. bool some() const { return nullableValue != nullptr; }
  3697. bool none() const { return nullableValue == nullptr; }
  3698. bool operator !() const { return nullableValue == nullptr; }
  3699. explicit operator bool() const {
  3700. return some();
  3701. }
  3702. private:
  3703. T *nullableValue;
  3704. alignas(alignof(T)) char storage[sizeof(T)];
  3705. };
  3706. } // end namespace Catch
  3707. // end catch_option.hpp
  3708. #include <chrono>
  3709. #include <iosfwd>
  3710. #include <string>
  3711. #include <vector>
  3712. #include <memory>
  3713. namespace Catch {
  3714. enum class Verbosity {
  3715. Quiet = 0,
  3716. Normal,
  3717. High
  3718. };
  3719. struct WarnAbout { enum What {
  3720. Nothing = 0x00,
  3721. NoAssertions = 0x01,
  3722. NoTests = 0x02
  3723. }; };
  3724. struct ShowDurations { enum OrNot {
  3725. DefaultForReporter,
  3726. Always,
  3727. Never
  3728. }; };
  3729. struct RunTests { enum InWhatOrder {
  3730. InDeclarationOrder,
  3731. InLexicographicalOrder,
  3732. InRandomOrder
  3733. }; };
  3734. struct UseColour { enum YesOrNo {
  3735. Auto,
  3736. Yes,
  3737. No
  3738. }; };
  3739. struct WaitForKeypress { enum When {
  3740. Never,
  3741. BeforeStart = 1,
  3742. BeforeExit = 2,
  3743. BeforeStartAndExit = BeforeStart | BeforeExit
  3744. }; };
  3745. class TestSpec;
  3746. struct IConfig : NonCopyable {
  3747. virtual ~IConfig();
  3748. virtual bool allowThrows() const = 0;
  3749. virtual std::ostream& stream() const = 0;
  3750. virtual std::string name() const = 0;
  3751. virtual bool includeSuccessfulResults() const = 0;
  3752. virtual bool shouldDebugBreak() const = 0;
  3753. virtual bool warnAboutMissingAssertions() const = 0;
  3754. virtual bool warnAboutNoTests() const = 0;
  3755. virtual int abortAfter() const = 0;
  3756. virtual bool showInvisibles() const = 0;
  3757. virtual ShowDurations::OrNot showDurations() const = 0;
  3758. virtual double minDuration() const = 0;
  3759. virtual TestSpec const& testSpec() const = 0;
  3760. virtual bool hasTestFilters() const = 0;
  3761. virtual std::vector<std::string> const& getTestsOrTags() const = 0;
  3762. virtual RunTests::InWhatOrder runOrder() const = 0;
  3763. virtual unsigned int rngSeed() const = 0;
  3764. virtual UseColour::YesOrNo useColour() const = 0;
  3765. virtual std::vector<std::string> const& getSectionsToRun() const = 0;
  3766. virtual Verbosity verbosity() const = 0;
  3767. virtual bool benchmarkNoAnalysis() const = 0;
  3768. virtual int benchmarkSamples() const = 0;
  3769. virtual double benchmarkConfidenceInterval() const = 0;
  3770. virtual unsigned int benchmarkResamples() const = 0;
  3771. virtual std::chrono::milliseconds benchmarkWarmupTime() const = 0;
  3772. };
  3773. using IConfigPtr = std::shared_ptr<IConfig const>;
  3774. }
  3775. // end catch_interfaces_config.h
  3776. // start catch_random_number_generator.h
  3777. #include <cstdint>
  3778. namespace Catch {
  3779. // This is a simple implementation of C++11 Uniform Random Number
  3780. // Generator. It does not provide all operators, because Catch2
  3781. // does not use it, but it should behave as expected inside stdlib's
  3782. // distributions.
  3783. // The implementation is based on the PCG family (http://pcg-random.org)
  3784. class SimplePcg32 {
  3785. using state_type = std::uint64_t;
  3786. public:
  3787. using result_type = std::uint32_t;
  3788. static constexpr result_type (min)() {
  3789. return 0;
  3790. }
  3791. static constexpr result_type (max)() {
  3792. return static_cast<result_type>(-1);
  3793. }
  3794. // Provide some default initial state for the default constructor
  3795. SimplePcg32():SimplePcg32(0xed743cc4U) {}
  3796. explicit SimplePcg32(result_type seed_);
  3797. void seed(result_type seed_);
  3798. void discard(uint64_t skip);
  3799. result_type operator()();
  3800. private:
  3801. friend bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
  3802. friend bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
  3803. // In theory we also need operator<< and operator>>
  3804. // In practice we do not use them, so we will skip them for now
  3805. std::uint64_t m_state;
  3806. // This part of the state determines which "stream" of the numbers
  3807. // is chosen -- we take it as a constant for Catch2, so we only
  3808. // need to deal with seeding the main state.
  3809. // Picked by reading 8 bytes from `/dev/random` :-)
  3810. static const std::uint64_t s_inc = (0x13ed0cc53f939476ULL << 1ULL) | 1ULL;
  3811. };
  3812. } // end namespace Catch
  3813. // end catch_random_number_generator.h
  3814. #include <random>
  3815. namespace Catch {
  3816. namespace Generators {
  3817. template <typename Float>
  3818. class RandomFloatingGenerator final : public IGenerator<Float> {
  3819. Catch::SimplePcg32& m_rng;
  3820. std::uniform_real_distribution<Float> m_dist;
  3821. Float m_current_number;
  3822. public:
  3823. RandomFloatingGenerator(Float a, Float b):
  3824. m_rng(rng()),
  3825. m_dist(a, b) {
  3826. static_cast<void>(next());
  3827. }
  3828. Float const& get() const override {
  3829. return m_current_number;
  3830. }
  3831. bool next() override {
  3832. m_current_number = m_dist(m_rng);
  3833. return true;
  3834. }
  3835. };
  3836. template <typename Integer>
  3837. class RandomIntegerGenerator final : public IGenerator<Integer> {
  3838. Catch::SimplePcg32& m_rng;
  3839. std::uniform_int_distribution<Integer> m_dist;
  3840. Integer m_current_number;
  3841. public:
  3842. RandomIntegerGenerator(Integer a, Integer b):
  3843. m_rng(rng()),
  3844. m_dist(a, b) {
  3845. static_cast<void>(next());
  3846. }
  3847. Integer const& get() const override {
  3848. return m_current_number;
  3849. }
  3850. bool next() override {
  3851. m_current_number = m_dist(m_rng);
  3852. return true;
  3853. }
  3854. };
  3855. // TODO: Ideally this would be also constrained against the various char types,
  3856. // but I don't expect users to run into that in practice.
  3857. template <typename T>
  3858. typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value,
  3859. GeneratorWrapper<T>>::type
  3860. random(T a, T b) {
  3861. return GeneratorWrapper<T>(
  3862. pf::make_unique<RandomIntegerGenerator<T>>(a, b)
  3863. );
  3864. }
  3865. template <typename T>
  3866. typename std::enable_if<std::is_floating_point<T>::value,
  3867. GeneratorWrapper<T>>::type
  3868. random(T a, T b) {
  3869. return GeneratorWrapper<T>(
  3870. pf::make_unique<RandomFloatingGenerator<T>>(a, b)
  3871. );
  3872. }
  3873. template <typename T>
  3874. class RangeGenerator final : public IGenerator<T> {
  3875. T m_current;
  3876. T m_end;
  3877. T m_step;
  3878. bool m_positive;
  3879. public:
  3880. RangeGenerator(T const& start, T const& end, T const& step):
  3881. m_current(start),
  3882. m_end(end),
  3883. m_step(step),
  3884. m_positive(m_step > T(0))
  3885. {
  3886. assert(m_current != m_end && "Range start and end cannot be equal");
  3887. assert(m_step != T(0) && "Step size cannot be zero");
  3888. assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && "Step moves away from end");
  3889. }
  3890. RangeGenerator(T const& start, T const& end):
  3891. RangeGenerator(start, end, (start < end) ? T(1) : T(-1))
  3892. {}
  3893. T const& get() const override {
  3894. return m_current;
  3895. }
  3896. bool next() override {
  3897. m_current += m_step;
  3898. return (m_positive) ? (m_current < m_end) : (m_current > m_end);
  3899. }
  3900. };
  3901. template <typename T>
  3902. GeneratorWrapper<T> range(T const& start, T const& end, T const& step) {
  3903. static_assert(std::is_arithmetic<T>::value && !std::is_same<T, bool>::value, "Type must be numeric");
  3904. return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end, step));
  3905. }
  3906. template <typename T>
  3907. GeneratorWrapper<T> range(T const& start, T const& end) {
  3908. static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
  3909. return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end));
  3910. }
  3911. template <typename T>
  3912. class IteratorGenerator final : public IGenerator<T> {
  3913. static_assert(!std::is_same<T, bool>::value,
  3914. "IteratorGenerator currently does not support bools"
  3915. "because of std::vector<bool> specialization");
  3916. std::vector<T> m_elems;
  3917. size_t m_current = 0;
  3918. public:
  3919. template <typename InputIterator, typename InputSentinel>
  3920. IteratorGenerator(InputIterator first, InputSentinel last):m_elems(first, last) {
  3921. if (m_elems.empty()) {
  3922. Catch::throw_exception(GeneratorException("IteratorGenerator received no valid values"));
  3923. }
  3924. }
  3925. T const& get() const override {
  3926. return m_elems[m_current];
  3927. }
  3928. bool next() override {
  3929. ++m_current;
  3930. return m_current != m_elems.size();
  3931. }
  3932. };
  3933. template <typename InputIterator,
  3934. typename InputSentinel,
  3935. typename ResultType = typename std::iterator_traits<InputIterator>::value_type>
  3936. GeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) {
  3937. return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(from, to));
  3938. }
  3939. template <typename Container,
  3940. typename ResultType = typename Container::value_type>
  3941. GeneratorWrapper<ResultType> from_range(Container const& cnt) {
  3942. return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(cnt.begin(), cnt.end()));
  3943. }
  3944. } // namespace Generators
  3945. } // namespace Catch
  3946. // end catch_generators_specific.hpp
  3947. // These files are included here so the single_include script doesn't put them
  3948. // in the conditionally compiled sections
  3949. // start catch_test_case_info.h
  3950. #include <string>
  3951. #include <vector>
  3952. #include <memory>
  3953. #ifdef __clang__
  3954. #pragma clang diagnostic push
  3955. #pragma clang diagnostic ignored "-Wpadded"
  3956. #endif
  3957. namespace Catch {
  3958. struct ITestInvoker;
  3959. struct TestCaseInfo {
  3960. enum SpecialProperties{
  3961. None = 0,
  3962. IsHidden = 1 << 1,
  3963. ShouldFail = 1 << 2,
  3964. MayFail = 1 << 3,
  3965. Throws = 1 << 4,
  3966. NonPortable = 1 << 5,
  3967. Benchmark = 1 << 6
  3968. };
  3969. TestCaseInfo( std::string const& _name,
  3970. std::string const& _className,
  3971. std::string const& _description,
  3972. std::vector<std::string> const& _tags,
  3973. SourceLineInfo const& _lineInfo );
  3974. friend void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags );
  3975. bool isHidden() const;
  3976. bool throws() const;
  3977. bool okToFail() const;
  3978. bool expectedToFail() const;
  3979. std::string tagsAsString() const;
  3980. std::string name;
  3981. std::string className;
  3982. std::string description;
  3983. std::vector<std::string> tags;
  3984. std::vector<std::string> lcaseTags;
  3985. SourceLineInfo lineInfo;
  3986. SpecialProperties properties;
  3987. };
  3988. class TestCase : public TestCaseInfo {
  3989. public:
  3990. TestCase( ITestInvoker* testCase, TestCaseInfo&& info );
  3991. TestCase withName( std::string const& _newName ) const;
  3992. void invoke() const;
  3993. TestCaseInfo const& getTestCaseInfo() const;
  3994. bool operator == ( TestCase const& other ) const;
  3995. bool operator < ( TestCase const& other ) const;
  3996. private:
  3997. std::shared_ptr<ITestInvoker> test;
  3998. };
  3999. TestCase makeTestCase( ITestInvoker* testCase,
  4000. std::string const& className,
  4001. NameAndTags const& nameAndTags,
  4002. SourceLineInfo const& lineInfo );
  4003. }
  4004. #ifdef __clang__
  4005. #pragma clang diagnostic pop
  4006. #endif
  4007. // end catch_test_case_info.h
  4008. // start catch_interfaces_runner.h
  4009. namespace Catch {
  4010. struct IRunner {
  4011. virtual ~IRunner();
  4012. virtual bool aborting() const = 0;
  4013. };
  4014. }
  4015. // end catch_interfaces_runner.h
  4016. #ifdef __OBJC__
  4017. // start catch_objc.hpp
  4018. #import <objc/runtime.h>
  4019. #include <string>
  4020. // NB. Any general catch headers included here must be included
  4021. // in catch.hpp first to make sure they are included by the single
  4022. // header for non obj-usage
  4023. ///////////////////////////////////////////////////////////////////////////////
  4024. // This protocol is really only here for (self) documenting purposes, since
  4025. // all its methods are optional.
  4026. @protocol OcFixture
  4027. @optional
  4028. -(void) setUp;
  4029. -(void) tearDown;
  4030. @end
  4031. namespace Catch {
  4032. class OcMethod : public ITestInvoker {
  4033. public:
  4034. OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
  4035. virtual void invoke() const {
  4036. id obj = [[m_cls alloc] init];
  4037. performOptionalSelector( obj, @selector(setUp) );
  4038. performOptionalSelector( obj, m_sel );
  4039. performOptionalSelector( obj, @selector(tearDown) );
  4040. arcSafeRelease( obj );
  4041. }
  4042. private:
  4043. virtual ~OcMethod() {}
  4044. Class m_cls;
  4045. SEL m_sel;
  4046. };
  4047. namespace Detail{
  4048. inline std::string getAnnotation( Class cls,
  4049. std::string const& annotationName,
  4050. std::string const& testCaseName ) {
  4051. NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
  4052. SEL sel = NSSelectorFromString( selStr );
  4053. arcSafeRelease( selStr );
  4054. id value = performOptionalSelector( cls, sel );
  4055. if( value )
  4056. return [(NSString*)value UTF8String];
  4057. return "";
  4058. }
  4059. }
  4060. inline std::size_t registerTestMethods() {
  4061. std::size_t noTestMethods = 0;
  4062. int noClasses = objc_getClassList( nullptr, 0 );
  4063. Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
  4064. objc_getClassList( classes, noClasses );
  4065. for( int c = 0; c < noClasses; c++ ) {
  4066. Class cls = classes[c];
  4067. {
  4068. u_int count;
  4069. Method* methods = class_copyMethodList( cls, &count );
  4070. for( u_int m = 0; m < count ; m++ ) {
  4071. SEL selector = method_getName(methods[m]);
  4072. std::string methodName = sel_getName(selector);
  4073. if( startsWith( methodName, "Catch_TestCase_" ) ) {
  4074. std::string testCaseName = methodName.substr( 15 );
  4075. std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
  4076. std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
  4077. const char* className = class_getName( cls );
  4078. getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo("",0) ) );
  4079. noTestMethods++;
  4080. }
  4081. }
  4082. free(methods);
  4083. }
  4084. }
  4085. return noTestMethods;
  4086. }
  4087. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  4088. namespace Matchers {
  4089. namespace Impl {
  4090. namespace NSStringMatchers {
  4091. struct StringHolder : MatcherBase<NSString*>{
  4092. StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
  4093. StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
  4094. StringHolder() {
  4095. arcSafeRelease( m_substr );
  4096. }
  4097. bool match( NSString* str ) const override {
  4098. return false;
  4099. }
  4100. NSString* CATCH_ARC_STRONG m_substr;
  4101. };
  4102. struct Equals : StringHolder {
  4103. Equals( NSString* substr ) : StringHolder( substr ){}
  4104. bool match( NSString* str ) const override {
  4105. return (str != nil || m_substr == nil ) &&
  4106. [str isEqualToString:m_substr];
  4107. }
  4108. std::string describe() const override {
  4109. return "equals string: " + Catch::Detail::stringify( m_substr );
  4110. }
  4111. };
  4112. struct Contains : StringHolder {
  4113. Contains( NSString* substr ) : StringHolder( substr ){}
  4114. bool match( NSString* str ) const override {
  4115. return (str != nil || m_substr == nil ) &&
  4116. [str rangeOfString:m_substr].location != NSNotFound;
  4117. }
  4118. std::string describe() const override {
  4119. return "contains string: " + Catch::Detail::stringify( m_substr );
  4120. }
  4121. };
  4122. struct StartsWith : StringHolder {
  4123. StartsWith( NSString* substr ) : StringHolder( substr ){}
  4124. bool match( NSString* str ) const override {
  4125. return (str != nil || m_substr == nil ) &&
  4126. [str rangeOfString:m_substr].location == 0;
  4127. }
  4128. std::string describe() const override {
  4129. return "starts with: " + Catch::Detail::stringify( m_substr );
  4130. }
  4131. };
  4132. struct EndsWith : StringHolder {
  4133. EndsWith( NSString* substr ) : StringHolder( substr ){}
  4134. bool match( NSString* str ) const override {
  4135. return (str != nil || m_substr == nil ) &&
  4136. [str rangeOfString:m_substr].location == [str length] - [m_substr length];
  4137. }
  4138. std::string describe() const override {
  4139. return "ends with: " + Catch::Detail::stringify( m_substr );
  4140. }
  4141. };
  4142. } // namespace NSStringMatchers
  4143. } // namespace Impl
  4144. inline Impl::NSStringMatchers::Equals
  4145. Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
  4146. inline Impl::NSStringMatchers::Contains
  4147. Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
  4148. inline Impl::NSStringMatchers::StartsWith
  4149. StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
  4150. inline Impl::NSStringMatchers::EndsWith
  4151. EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
  4152. } // namespace Matchers
  4153. using namespace Matchers;
  4154. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  4155. } // namespace Catch
  4156. ///////////////////////////////////////////////////////////////////////////////
  4157. #define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix
  4158. #define OC_TEST_CASE2( name, desc, uniqueSuffix ) \
  4159. +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \
  4160. { \
  4161. return @ name; \
  4162. } \
  4163. +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \
  4164. { \
  4165. return @ desc; \
  4166. } \
  4167. -(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix )
  4168. #define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ )
  4169. // end catch_objc.hpp
  4170. #endif
  4171. // Benchmarking needs the externally-facing parts of reporters to work
  4172. #if defined(CATCH_CONFIG_EXTERNAL_INTERFACES) || defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  4173. // start catch_external_interfaces.h
  4174. // start catch_reporter_bases.hpp
  4175. // start catch_interfaces_reporter.h
  4176. // start catch_config.hpp
  4177. // start catch_test_spec_parser.h
  4178. #ifdef __clang__
  4179. #pragma clang diagnostic push
  4180. #pragma clang diagnostic ignored "-Wpadded"
  4181. #endif
  4182. // start catch_test_spec.h
  4183. #ifdef __clang__
  4184. #pragma clang diagnostic push
  4185. #pragma clang diagnostic ignored "-Wpadded"
  4186. #endif
  4187. // start catch_wildcard_pattern.h
  4188. namespace Catch
  4189. {
  4190. class WildcardPattern {
  4191. enum WildcardPosition {
  4192. NoWildcard = 0,
  4193. WildcardAtStart = 1,
  4194. WildcardAtEnd = 2,
  4195. WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
  4196. };
  4197. public:
  4198. WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity );
  4199. virtual ~WildcardPattern() = default;
  4200. virtual bool matches( std::string const& str ) const;
  4201. private:
  4202. std::string normaliseString( std::string const& str ) const;
  4203. CaseSensitive::Choice m_caseSensitivity;
  4204. WildcardPosition m_wildcard = NoWildcard;
  4205. std::string m_pattern;
  4206. };
  4207. }
  4208. // end catch_wildcard_pattern.h
  4209. #include <string>
  4210. #include <vector>
  4211. #include <memory>
  4212. namespace Catch {
  4213. struct IConfig;
  4214. class TestSpec {
  4215. class Pattern {
  4216. public:
  4217. explicit Pattern( std::string const& name );
  4218. virtual ~Pattern();
  4219. virtual bool matches( TestCaseInfo const& testCase ) const = 0;
  4220. std::string const& name() const;
  4221. private:
  4222. std::string const m_name;
  4223. };
  4224. using PatternPtr = std::shared_ptr<Pattern>;
  4225. class NamePattern : public Pattern {
  4226. public:
  4227. explicit NamePattern( std::string const& name, std::string const& filterString );
  4228. bool matches( TestCaseInfo const& testCase ) const override;
  4229. private:
  4230. WildcardPattern m_wildcardPattern;
  4231. };
  4232. class TagPattern : public Pattern {
  4233. public:
  4234. explicit TagPattern( std::string const& tag, std::string const& filterString );
  4235. bool matches( TestCaseInfo const& testCase ) const override;
  4236. private:
  4237. std::string m_tag;
  4238. };
  4239. class ExcludedPattern : public Pattern {
  4240. public:
  4241. explicit ExcludedPattern( PatternPtr const& underlyingPattern );
  4242. bool matches( TestCaseInfo const& testCase ) const override;
  4243. private:
  4244. PatternPtr m_underlyingPattern;
  4245. };
  4246. struct Filter {
  4247. std::vector<PatternPtr> m_patterns;
  4248. bool matches( TestCaseInfo const& testCase ) const;
  4249. std::string name() const;
  4250. };
  4251. public:
  4252. struct FilterMatch {
  4253. std::string name;
  4254. std::vector<TestCase const*> tests;
  4255. };
  4256. using Matches = std::vector<FilterMatch>;
  4257. using vectorStrings = std::vector<std::string>;
  4258. bool hasFilters() const;
  4259. bool matches( TestCaseInfo const& testCase ) const;
  4260. Matches matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const;
  4261. const vectorStrings & getInvalidArgs() const;
  4262. private:
  4263. std::vector<Filter> m_filters;
  4264. std::vector<std::string> m_invalidArgs;
  4265. friend class TestSpecParser;
  4266. };
  4267. }
  4268. #ifdef __clang__
  4269. #pragma clang diagnostic pop
  4270. #endif
  4271. // end catch_test_spec.h
  4272. // start catch_interfaces_tag_alias_registry.h
  4273. #include <string>
  4274. namespace Catch {
  4275. struct TagAlias;
  4276. struct ITagAliasRegistry {
  4277. virtual ~ITagAliasRegistry();
  4278. // Nullptr if not present
  4279. virtual TagAlias const* find( std::string const& alias ) const = 0;
  4280. virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
  4281. static ITagAliasRegistry const& get();
  4282. };
  4283. } // end namespace Catch
  4284. // end catch_interfaces_tag_alias_registry.h
  4285. namespace Catch {
  4286. class TestSpecParser {
  4287. enum Mode{ None, Name, QuotedName, Tag, EscapedName };
  4288. Mode m_mode = None;
  4289. Mode lastMode = None;
  4290. bool m_exclusion = false;
  4291. std::size_t m_pos = 0;
  4292. std::size_t m_realPatternPos = 0;
  4293. std::string m_arg;
  4294. std::string m_substring;
  4295. std::string m_patternName;
  4296. std::vector<std::size_t> m_escapeChars;
  4297. TestSpec::Filter m_currentFilter;
  4298. TestSpec m_testSpec;
  4299. ITagAliasRegistry const* m_tagAliases = nullptr;
  4300. public:
  4301. TestSpecParser( ITagAliasRegistry const& tagAliases );
  4302. TestSpecParser& parse( std::string const& arg );
  4303. TestSpec testSpec();
  4304. private:
  4305. bool visitChar( char c );
  4306. void startNewMode( Mode mode );
  4307. bool processNoneChar( char c );
  4308. void processNameChar( char c );
  4309. bool processOtherChar( char c );
  4310. void endMode();
  4311. void escape();
  4312. bool isControlChar( char c ) const;
  4313. void saveLastMode();
  4314. void revertBackToLastMode();
  4315. void addFilter();
  4316. bool separate();
  4317. // Handles common preprocessing of the pattern for name/tag patterns
  4318. std::string preprocessPattern();
  4319. // Adds the current pattern as a test name
  4320. void addNamePattern();
  4321. // Adds the current pattern as a tag
  4322. void addTagPattern();
  4323. inline void addCharToPattern(char c) {
  4324. m_substring += c;
  4325. m_patternName += c;
  4326. m_realPatternPos++;
  4327. }
  4328. };
  4329. TestSpec parseTestSpec( std::string const& arg );
  4330. } // namespace Catch
  4331. #ifdef __clang__
  4332. #pragma clang diagnostic pop
  4333. #endif
  4334. // end catch_test_spec_parser.h
  4335. // Libstdc++ doesn't like incomplete classes for unique_ptr
  4336. #include <memory>
  4337. #include <vector>
  4338. #include <string>
  4339. #ifndef CATCH_CONFIG_CONSOLE_WIDTH
  4340. #define CATCH_CONFIG_CONSOLE_WIDTH 80
  4341. #endif
  4342. namespace Catch {
  4343. struct IStream;
  4344. struct ConfigData {
  4345. bool listTests = false;
  4346. bool listTags = false;
  4347. bool listReporters = false;
  4348. bool listTestNamesOnly = false;
  4349. bool showSuccessfulTests = false;
  4350. bool shouldDebugBreak = false;
  4351. bool noThrow = false;
  4352. bool showHelp = false;
  4353. bool showInvisibles = false;
  4354. bool filenamesAsTags = false;
  4355. bool libIdentify = false;
  4356. int abortAfter = -1;
  4357. unsigned int rngSeed = 0;
  4358. bool benchmarkNoAnalysis = false;
  4359. unsigned int benchmarkSamples = 100;
  4360. double benchmarkConfidenceInterval = 0.95;
  4361. unsigned int benchmarkResamples = 100000;
  4362. std::chrono::milliseconds::rep benchmarkWarmupTime = 100;
  4363. Verbosity verbosity = Verbosity::Normal;
  4364. WarnAbout::What warnings = WarnAbout::Nothing;
  4365. ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;
  4366. double minDuration = -1;
  4367. RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;
  4368. UseColour::YesOrNo useColour = UseColour::Auto;
  4369. WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
  4370. std::string outputFilename;
  4371. std::string name;
  4372. std::string processName;
  4373. #ifndef CATCH_CONFIG_DEFAULT_REPORTER
  4374. #define CATCH_CONFIG_DEFAULT_REPORTER "console"
  4375. #endif
  4376. std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER;
  4377. #undef CATCH_CONFIG_DEFAULT_REPORTER
  4378. std::vector<std::string> testsOrTags;
  4379. std::vector<std::string> sectionsToRun;
  4380. };
  4381. class Config : public IConfig {
  4382. public:
  4383. Config() = default;
  4384. Config( ConfigData const& data );
  4385. virtual ~Config() = default;
  4386. std::string const& getFilename() const;
  4387. bool listTests() const;
  4388. bool listTestNamesOnly() const;
  4389. bool listTags() const;
  4390. bool listReporters() const;
  4391. std::string getProcessName() const;
  4392. std::string const& getReporterName() const;
  4393. std::vector<std::string> const& getTestsOrTags() const override;
  4394. std::vector<std::string> const& getSectionsToRun() const override;
  4395. TestSpec const& testSpec() const override;
  4396. bool hasTestFilters() const override;
  4397. bool showHelp() const;
  4398. // IConfig interface
  4399. bool allowThrows() const override;
  4400. std::ostream& stream() const override;
  4401. std::string name() const override;
  4402. bool includeSuccessfulResults() const override;
  4403. bool warnAboutMissingAssertions() const override;
  4404. bool warnAboutNoTests() const override;
  4405. ShowDurations::OrNot showDurations() const override;
  4406. double minDuration() const override;
  4407. RunTests::InWhatOrder runOrder() const override;
  4408. unsigned int rngSeed() const override;
  4409. UseColour::YesOrNo useColour() const override;
  4410. bool shouldDebugBreak() const override;
  4411. int abortAfter() const override;
  4412. bool showInvisibles() const override;
  4413. Verbosity verbosity() const override;
  4414. bool benchmarkNoAnalysis() const override;
  4415. int benchmarkSamples() const override;
  4416. double benchmarkConfidenceInterval() const override;
  4417. unsigned int benchmarkResamples() const override;
  4418. std::chrono::milliseconds benchmarkWarmupTime() const override;
  4419. private:
  4420. IStream const* openStream();
  4421. ConfigData m_data;
  4422. std::unique_ptr<IStream const> m_stream;
  4423. TestSpec m_testSpec;
  4424. bool m_hasTestFilters = false;
  4425. };
  4426. } // end namespace Catch
  4427. // end catch_config.hpp
  4428. // start catch_assertionresult.h
  4429. #include <string>
  4430. namespace Catch {
  4431. struct AssertionResultData
  4432. {
  4433. AssertionResultData() = delete;
  4434. AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression );
  4435. std::string message;
  4436. mutable std::string reconstructedExpression;
  4437. LazyExpression lazyExpression;
  4438. ResultWas::OfType resultType;
  4439. std::string reconstructExpression() const;
  4440. };
  4441. class AssertionResult {
  4442. public:
  4443. AssertionResult() = delete;
  4444. AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
  4445. bool isOk() const;
  4446. bool succeeded() const;
  4447. ResultWas::OfType getResultType() const;
  4448. bool hasExpression() const;
  4449. bool hasMessage() const;
  4450. std::string getExpression() const;
  4451. std::string getExpressionInMacro() const;
  4452. bool hasExpandedExpression() const;
  4453. std::string getExpandedExpression() const;
  4454. std::string getMessage() const;
  4455. SourceLineInfo getSourceInfo() const;
  4456. StringRef getTestMacroName() const;
  4457. //protected:
  4458. AssertionInfo m_info;
  4459. AssertionResultData m_resultData;
  4460. };
  4461. } // end namespace Catch
  4462. // end catch_assertionresult.h
  4463. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  4464. // start catch_estimate.hpp
  4465. // Statistics estimates
  4466. namespace Catch {
  4467. namespace Benchmark {
  4468. template <typename Duration>
  4469. struct Estimate {
  4470. Duration point;
  4471. Duration lower_bound;
  4472. Duration upper_bound;
  4473. double confidence_interval;
  4474. template <typename Duration2>
  4475. operator Estimate<Duration2>() const {
  4476. return { point, lower_bound, upper_bound, confidence_interval };
  4477. }
  4478. };
  4479. } // namespace Benchmark
  4480. } // namespace Catch
  4481. // end catch_estimate.hpp
  4482. // start catch_outlier_classification.hpp
  4483. // Outlier information
  4484. namespace Catch {
  4485. namespace Benchmark {
  4486. struct OutlierClassification {
  4487. int samples_seen = 0;
  4488. int low_severe = 0; // more than 3 times IQR below Q1
  4489. int low_mild = 0; // 1.5 to 3 times IQR below Q1
  4490. int high_mild = 0; // 1.5 to 3 times IQR above Q3
  4491. int high_severe = 0; // more than 3 times IQR above Q3
  4492. int total() const {
  4493. return low_severe + low_mild + high_mild + high_severe;
  4494. }
  4495. };
  4496. } // namespace Benchmark
  4497. } // namespace Catch
  4498. // end catch_outlier_classification.hpp
  4499. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  4500. #include <string>
  4501. #include <iosfwd>
  4502. #include <map>
  4503. #include <set>
  4504. #include <memory>
  4505. #include <algorithm>
  4506. namespace Catch {
  4507. struct ReporterConfig {
  4508. explicit ReporterConfig( IConfigPtr const& _fullConfig );
  4509. ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream );
  4510. std::ostream& stream() const;
  4511. IConfigPtr fullConfig() const;
  4512. private:
  4513. std::ostream* m_stream;
  4514. IConfigPtr m_fullConfig;
  4515. };
  4516. struct ReporterPreferences {
  4517. bool shouldRedirectStdOut = false;
  4518. bool shouldReportAllAssertions = false;
  4519. };
  4520. template<typename T>
  4521. struct LazyStat : Option<T> {
  4522. LazyStat& operator=( T const& _value ) {
  4523. Option<T>::operator=( _value );
  4524. used = false;
  4525. return *this;
  4526. }
  4527. void reset() {
  4528. Option<T>::reset();
  4529. used = false;
  4530. }
  4531. bool used = false;
  4532. };
  4533. struct TestRunInfo {
  4534. TestRunInfo( std::string const& _name );
  4535. std::string name;
  4536. };
  4537. struct GroupInfo {
  4538. GroupInfo( std::string const& _name,
  4539. std::size_t _groupIndex,
  4540. std::size_t _groupsCount );
  4541. std::string name;
  4542. std::size_t groupIndex;
  4543. std::size_t groupsCounts;
  4544. };
  4545. struct AssertionStats {
  4546. AssertionStats( AssertionResult const& _assertionResult,
  4547. std::vector<MessageInfo> const& _infoMessages,
  4548. Totals const& _totals );
  4549. AssertionStats( AssertionStats const& ) = default;
  4550. AssertionStats( AssertionStats && ) = default;
  4551. AssertionStats& operator = ( AssertionStats const& ) = delete;
  4552. AssertionStats& operator = ( AssertionStats && ) = delete;
  4553. virtual ~AssertionStats();
  4554. AssertionResult assertionResult;
  4555. std::vector<MessageInfo> infoMessages;
  4556. Totals totals;
  4557. };
  4558. struct SectionStats {
  4559. SectionStats( SectionInfo const& _sectionInfo,
  4560. Counts const& _assertions,
  4561. double _durationInSeconds,
  4562. bool _missingAssertions );
  4563. SectionStats( SectionStats const& ) = default;
  4564. SectionStats( SectionStats && ) = default;
  4565. SectionStats& operator = ( SectionStats const& ) = default;
  4566. SectionStats& operator = ( SectionStats && ) = default;
  4567. virtual ~SectionStats();
  4568. SectionInfo sectionInfo;
  4569. Counts assertions;
  4570. double durationInSeconds;
  4571. bool missingAssertions;
  4572. };
  4573. struct TestCaseStats {
  4574. TestCaseStats( TestCaseInfo const& _testInfo,
  4575. Totals const& _totals,
  4576. std::string const& _stdOut,
  4577. std::string const& _stdErr,
  4578. bool _aborting );
  4579. TestCaseStats( TestCaseStats const& ) = default;
  4580. TestCaseStats( TestCaseStats && ) = default;
  4581. TestCaseStats& operator = ( TestCaseStats const& ) = default;
  4582. TestCaseStats& operator = ( TestCaseStats && ) = default;
  4583. virtual ~TestCaseStats();
  4584. TestCaseInfo testInfo;
  4585. Totals totals;
  4586. std::string stdOut;
  4587. std::string stdErr;
  4588. bool aborting;
  4589. };
  4590. struct TestGroupStats {
  4591. TestGroupStats( GroupInfo const& _groupInfo,
  4592. Totals const& _totals,
  4593. bool _aborting );
  4594. TestGroupStats( GroupInfo const& _groupInfo );
  4595. TestGroupStats( TestGroupStats const& ) = default;
  4596. TestGroupStats( TestGroupStats && ) = default;
  4597. TestGroupStats& operator = ( TestGroupStats const& ) = default;
  4598. TestGroupStats& operator = ( TestGroupStats && ) = default;
  4599. virtual ~TestGroupStats();
  4600. GroupInfo groupInfo;
  4601. Totals totals;
  4602. bool aborting;
  4603. };
  4604. struct TestRunStats {
  4605. TestRunStats( TestRunInfo const& _runInfo,
  4606. Totals const& _totals,
  4607. bool _aborting );
  4608. TestRunStats( TestRunStats const& ) = default;
  4609. TestRunStats( TestRunStats && ) = default;
  4610. TestRunStats& operator = ( TestRunStats const& ) = default;
  4611. TestRunStats& operator = ( TestRunStats && ) = default;
  4612. virtual ~TestRunStats();
  4613. TestRunInfo runInfo;
  4614. Totals totals;
  4615. bool aborting;
  4616. };
  4617. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  4618. struct BenchmarkInfo {
  4619. std::string name;
  4620. double estimatedDuration;
  4621. int iterations;
  4622. int samples;
  4623. unsigned int resamples;
  4624. double clockResolution;
  4625. double clockCost;
  4626. };
  4627. template <class Duration>
  4628. struct BenchmarkStats {
  4629. BenchmarkInfo info;
  4630. std::vector<Duration> samples;
  4631. Benchmark::Estimate<Duration> mean;
  4632. Benchmark::Estimate<Duration> standardDeviation;
  4633. Benchmark::OutlierClassification outliers;
  4634. double outlierVariance;
  4635. template <typename Duration2>
  4636. operator BenchmarkStats<Duration2>() const {
  4637. std::vector<Duration2> samples2;
  4638. samples2.reserve(samples.size());
  4639. std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
  4640. return {
  4641. info,
  4642. std::move(samples2),
  4643. mean,
  4644. standardDeviation,
  4645. outliers,
  4646. outlierVariance,
  4647. };
  4648. }
  4649. };
  4650. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  4651. struct IStreamingReporter {
  4652. virtual ~IStreamingReporter() = default;
  4653. // Implementing class must also provide the following static methods:
  4654. // static std::string getDescription();
  4655. // static std::set<Verbosity> getSupportedVerbosities()
  4656. virtual ReporterPreferences getPreferences() const = 0;
  4657. virtual void noMatchingTestCases( std::string const& spec ) = 0;
  4658. virtual void reportInvalidArguments(std::string const&) {}
  4659. virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
  4660. virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
  4661. virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
  4662. virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
  4663. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  4664. virtual void benchmarkPreparing( std::string const& ) {}
  4665. virtual void benchmarkStarting( BenchmarkInfo const& ) {}
  4666. virtual void benchmarkEnded( BenchmarkStats<> const& ) {}
  4667. virtual void benchmarkFailed( std::string const& ) {}
  4668. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  4669. virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
  4670. // The return value indicates if the messages buffer should be cleared:
  4671. virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
  4672. virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
  4673. virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
  4674. virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
  4675. virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
  4676. virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
  4677. // Default empty implementation provided
  4678. virtual void fatalErrorEncountered( StringRef name );
  4679. virtual bool isMulti() const;
  4680. };
  4681. using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>;
  4682. struct IReporterFactory {
  4683. virtual ~IReporterFactory();
  4684. virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0;
  4685. virtual std::string getDescription() const = 0;
  4686. };
  4687. using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
  4688. struct IReporterRegistry {
  4689. using FactoryMap = std::map<std::string, IReporterFactoryPtr>;
  4690. using Listeners = std::vector<IReporterFactoryPtr>;
  4691. virtual ~IReporterRegistry();
  4692. virtual IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const = 0;
  4693. virtual FactoryMap const& getFactories() const = 0;
  4694. virtual Listeners const& getListeners() const = 0;
  4695. };
  4696. } // end namespace Catch
  4697. // end catch_interfaces_reporter.h
  4698. #include <algorithm>
  4699. #include <cstring>
  4700. #include <cfloat>
  4701. #include <cstdio>
  4702. #include <cassert>
  4703. #include <memory>
  4704. #include <ostream>
  4705. namespace Catch {
  4706. void prepareExpandedExpression(AssertionResult& result);
  4707. // Returns double formatted as %.3f (format expected on output)
  4708. std::string getFormattedDuration( double duration );
  4709. //! Should the reporter show
  4710. bool shouldShowDuration( IConfig const& config, double duration );
  4711. std::string serializeFilters( std::vector<std::string> const& container );
  4712. template<typename DerivedT>
  4713. struct StreamingReporterBase : IStreamingReporter {
  4714. StreamingReporterBase( ReporterConfig const& _config )
  4715. : m_config( _config.fullConfig() ),
  4716. stream( _config.stream() )
  4717. {
  4718. m_reporterPrefs.shouldRedirectStdOut = false;
  4719. if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
  4720. CATCH_ERROR( "Verbosity level not supported by this reporter" );
  4721. }
  4722. ReporterPreferences getPreferences() const override {
  4723. return m_reporterPrefs;
  4724. }
  4725. static std::set<Verbosity> getSupportedVerbosities() {
  4726. return { Verbosity::Normal };
  4727. }
  4728. ~StreamingReporterBase() override = default;
  4729. void noMatchingTestCases(std::string const&) override {}
  4730. void reportInvalidArguments(std::string const&) override {}
  4731. void testRunStarting(TestRunInfo const& _testRunInfo) override {
  4732. currentTestRunInfo = _testRunInfo;
  4733. }
  4734. void testGroupStarting(GroupInfo const& _groupInfo) override {
  4735. currentGroupInfo = _groupInfo;
  4736. }
  4737. void testCaseStarting(TestCaseInfo const& _testInfo) override {
  4738. currentTestCaseInfo = _testInfo;
  4739. }
  4740. void sectionStarting(SectionInfo const& _sectionInfo) override {
  4741. m_sectionStack.push_back(_sectionInfo);
  4742. }
  4743. void sectionEnded(SectionStats const& /* _sectionStats */) override {
  4744. m_sectionStack.pop_back();
  4745. }
  4746. void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {
  4747. currentTestCaseInfo.reset();
  4748. }
  4749. void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override {
  4750. currentGroupInfo.reset();
  4751. }
  4752. void testRunEnded(TestRunStats const& /* _testRunStats */) override {
  4753. currentTestCaseInfo.reset();
  4754. currentGroupInfo.reset();
  4755. currentTestRunInfo.reset();
  4756. }
  4757. void skipTest(TestCaseInfo const&) override {
  4758. // Don't do anything with this by default.
  4759. // It can optionally be overridden in the derived class.
  4760. }
  4761. IConfigPtr m_config;
  4762. std::ostream& stream;
  4763. LazyStat<TestRunInfo> currentTestRunInfo;
  4764. LazyStat<GroupInfo> currentGroupInfo;
  4765. LazyStat<TestCaseInfo> currentTestCaseInfo;
  4766. std::vector<SectionInfo> m_sectionStack;
  4767. ReporterPreferences m_reporterPrefs;
  4768. };
  4769. template<typename DerivedT>
  4770. struct CumulativeReporterBase : IStreamingReporter {
  4771. template<typename T, typename ChildNodeT>
  4772. struct Node {
  4773. explicit Node( T const& _value ) : value( _value ) {}
  4774. virtual ~Node() {}
  4775. using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;
  4776. T value;
  4777. ChildNodes children;
  4778. };
  4779. struct SectionNode {
  4780. explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}
  4781. virtual ~SectionNode() = default;
  4782. bool operator == (SectionNode const& other) const {
  4783. return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
  4784. }
  4785. bool operator == (std::shared_ptr<SectionNode> const& other) const {
  4786. return operator==(*other);
  4787. }
  4788. SectionStats stats;
  4789. using ChildSections = std::vector<std::shared_ptr<SectionNode>>;
  4790. using Assertions = std::vector<AssertionStats>;
  4791. ChildSections childSections;
  4792. Assertions assertions;
  4793. std::string stdOut;
  4794. std::string stdErr;
  4795. };
  4796. struct BySectionInfo {
  4797. BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
  4798. BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
  4799. bool operator() (std::shared_ptr<SectionNode> const& node) const {
  4800. return ((node->stats.sectionInfo.name == m_other.name) &&
  4801. (node->stats.sectionInfo.lineInfo == m_other.lineInfo));
  4802. }
  4803. void operator=(BySectionInfo const&) = delete;
  4804. private:
  4805. SectionInfo const& m_other;
  4806. };
  4807. using TestCaseNode = Node<TestCaseStats, SectionNode>;
  4808. using TestGroupNode = Node<TestGroupStats, TestCaseNode>;
  4809. using TestRunNode = Node<TestRunStats, TestGroupNode>;
  4810. CumulativeReporterBase( ReporterConfig const& _config )
  4811. : m_config( _config.fullConfig() ),
  4812. stream( _config.stream() )
  4813. {
  4814. m_reporterPrefs.shouldRedirectStdOut = false;
  4815. if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
  4816. CATCH_ERROR( "Verbosity level not supported by this reporter" );
  4817. }
  4818. ~CumulativeReporterBase() override = default;
  4819. ReporterPreferences getPreferences() const override {
  4820. return m_reporterPrefs;
  4821. }
  4822. static std::set<Verbosity> getSupportedVerbosities() {
  4823. return { Verbosity::Normal };
  4824. }
  4825. void testRunStarting( TestRunInfo const& ) override {}
  4826. void testGroupStarting( GroupInfo const& ) override {}
  4827. void testCaseStarting( TestCaseInfo const& ) override {}
  4828. void sectionStarting( SectionInfo const& sectionInfo ) override {
  4829. SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
  4830. std::shared_ptr<SectionNode> node;
  4831. if( m_sectionStack.empty() ) {
  4832. if( !m_rootSection )
  4833. m_rootSection = std::make_shared<SectionNode>( incompleteStats );
  4834. node = m_rootSection;
  4835. }
  4836. else {
  4837. SectionNode& parentNode = *m_sectionStack.back();
  4838. auto it =
  4839. std::find_if( parentNode.childSections.begin(),
  4840. parentNode.childSections.end(),
  4841. BySectionInfo( sectionInfo ) );
  4842. if( it == parentNode.childSections.end() ) {
  4843. node = std::make_shared<SectionNode>( incompleteStats );
  4844. parentNode.childSections.push_back( node );
  4845. }
  4846. else
  4847. node = *it;
  4848. }
  4849. m_sectionStack.push_back( node );
  4850. m_deepestSection = std::move(node);
  4851. }
  4852. void assertionStarting(AssertionInfo const&) override {}
  4853. bool assertionEnded(AssertionStats const& assertionStats) override {
  4854. assert(!m_sectionStack.empty());
  4855. // AssertionResult holds a pointer to a temporary DecomposedExpression,
  4856. // which getExpandedExpression() calls to build the expression string.
  4857. // Our section stack copy of the assertionResult will likely outlive the
  4858. // temporary, so it must be expanded or discarded now to avoid calling
  4859. // a destroyed object later.
  4860. prepareExpandedExpression(const_cast<AssertionResult&>( assertionStats.assertionResult ) );
  4861. SectionNode& sectionNode = *m_sectionStack.back();
  4862. sectionNode.assertions.push_back(assertionStats);
  4863. return true;
  4864. }
  4865. void sectionEnded(SectionStats const& sectionStats) override {
  4866. assert(!m_sectionStack.empty());
  4867. SectionNode& node = *m_sectionStack.back();
  4868. node.stats = sectionStats;
  4869. m_sectionStack.pop_back();
  4870. }
  4871. void testCaseEnded(TestCaseStats const& testCaseStats) override {
  4872. auto node = std::make_shared<TestCaseNode>(testCaseStats);
  4873. assert(m_sectionStack.size() == 0);
  4874. node->children.push_back(m_rootSection);
  4875. m_testCases.push_back(node);
  4876. m_rootSection.reset();
  4877. assert(m_deepestSection);
  4878. m_deepestSection->stdOut = testCaseStats.stdOut;
  4879. m_deepestSection->stdErr = testCaseStats.stdErr;
  4880. }
  4881. void testGroupEnded(TestGroupStats const& testGroupStats) override {
  4882. auto node = std::make_shared<TestGroupNode>(testGroupStats);
  4883. node->children.swap(m_testCases);
  4884. m_testGroups.push_back(node);
  4885. }
  4886. void testRunEnded(TestRunStats const& testRunStats) override {
  4887. auto node = std::make_shared<TestRunNode>(testRunStats);
  4888. node->children.swap(m_testGroups);
  4889. m_testRuns.push_back(node);
  4890. testRunEndedCumulative();
  4891. }
  4892. virtual void testRunEndedCumulative() = 0;
  4893. void skipTest(TestCaseInfo const&) override {}
  4894. IConfigPtr m_config;
  4895. std::ostream& stream;
  4896. std::vector<AssertionStats> m_assertions;
  4897. std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;
  4898. std::vector<std::shared_ptr<TestCaseNode>> m_testCases;
  4899. std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;
  4900. std::vector<std::shared_ptr<TestRunNode>> m_testRuns;
  4901. std::shared_ptr<SectionNode> m_rootSection;
  4902. std::shared_ptr<SectionNode> m_deepestSection;
  4903. std::vector<std::shared_ptr<SectionNode>> m_sectionStack;
  4904. ReporterPreferences m_reporterPrefs;
  4905. };
  4906. template<char C>
  4907. char const* getLineOfChars() {
  4908. static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
  4909. if( !*line ) {
  4910. std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
  4911. line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
  4912. }
  4913. return line;
  4914. }
  4915. struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> {
  4916. TestEventListenerBase( ReporterConfig const& _config );
  4917. static std::set<Verbosity> getSupportedVerbosities();
  4918. void assertionStarting(AssertionInfo const&) override;
  4919. bool assertionEnded(AssertionStats const&) override;
  4920. };
  4921. } // end namespace Catch
  4922. // end catch_reporter_bases.hpp
  4923. // start catch_console_colour.h
  4924. namespace Catch {
  4925. struct Colour {
  4926. enum Code {
  4927. None = 0,
  4928. White,
  4929. Red,
  4930. Green,
  4931. Blue,
  4932. Cyan,
  4933. Yellow,
  4934. Grey,
  4935. Bright = 0x10,
  4936. BrightRed = Bright | Red,
  4937. BrightGreen = Bright | Green,
  4938. LightGrey = Bright | Grey,
  4939. BrightWhite = Bright | White,
  4940. BrightYellow = Bright | Yellow,
  4941. // By intention
  4942. FileName = LightGrey,
  4943. Warning = BrightYellow,
  4944. ResultError = BrightRed,
  4945. ResultSuccess = BrightGreen,
  4946. ResultExpectedFailure = Warning,
  4947. Error = BrightRed,
  4948. Success = Green,
  4949. OriginalExpression = Cyan,
  4950. ReconstructedExpression = BrightYellow,
  4951. SecondaryText = LightGrey,
  4952. Headers = White
  4953. };
  4954. // Use constructed object for RAII guard
  4955. Colour( Code _colourCode );
  4956. Colour( Colour&& other ) noexcept;
  4957. Colour& operator=( Colour&& other ) noexcept;
  4958. ~Colour();
  4959. // Use static method for one-shot changes
  4960. static void use( Code _colourCode );
  4961. private:
  4962. bool m_moved = false;
  4963. };
  4964. std::ostream& operator << ( std::ostream& os, Colour const& );
  4965. } // end namespace Catch
  4966. // end catch_console_colour.h
  4967. // start catch_reporter_registrars.hpp
  4968. namespace Catch {
  4969. template<typename T>
  4970. class ReporterRegistrar {
  4971. class ReporterFactory : public IReporterFactory {
  4972. IStreamingReporterPtr create( ReporterConfig const& config ) const override {
  4973. return std::unique_ptr<T>( new T( config ) );
  4974. }
  4975. std::string getDescription() const override {
  4976. return T::getDescription();
  4977. }
  4978. };
  4979. public:
  4980. explicit ReporterRegistrar( std::string const& name ) {
  4981. getMutableRegistryHub().registerReporter( name, std::make_shared<ReporterFactory>() );
  4982. }
  4983. };
  4984. template<typename T>
  4985. class ListenerRegistrar {
  4986. class ListenerFactory : public IReporterFactory {
  4987. IStreamingReporterPtr create( ReporterConfig const& config ) const override {
  4988. return std::unique_ptr<T>( new T( config ) );
  4989. }
  4990. std::string getDescription() const override {
  4991. return std::string();
  4992. }
  4993. };
  4994. public:
  4995. ListenerRegistrar() {
  4996. getMutableRegistryHub().registerListener( std::make_shared<ListenerFactory>() );
  4997. }
  4998. };
  4999. }
  5000. #if !defined(CATCH_CONFIG_DISABLE)
  5001. #define CATCH_REGISTER_REPORTER( name, reporterType ) \
  5002. CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
  5003. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  5004. namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \
  5005. CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
  5006. #define CATCH_REGISTER_LISTENER( listenerType ) \
  5007. CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
  5008. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  5009. namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \
  5010. CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
  5011. #else // CATCH_CONFIG_DISABLE
  5012. #define CATCH_REGISTER_REPORTER(name, reporterType)
  5013. #define CATCH_REGISTER_LISTENER(listenerType)
  5014. #endif // CATCH_CONFIG_DISABLE
  5015. // end catch_reporter_registrars.hpp
  5016. // Allow users to base their work off existing reporters
  5017. // start catch_reporter_compact.h
  5018. namespace Catch {
  5019. struct CompactReporter : StreamingReporterBase<CompactReporter> {
  5020. using StreamingReporterBase::StreamingReporterBase;
  5021. ~CompactReporter() override;
  5022. static std::string getDescription();
  5023. void noMatchingTestCases(std::string const& spec) override;
  5024. void assertionStarting(AssertionInfo const&) override;
  5025. bool assertionEnded(AssertionStats const& _assertionStats) override;
  5026. void sectionEnded(SectionStats const& _sectionStats) override;
  5027. void testRunEnded(TestRunStats const& _testRunStats) override;
  5028. };
  5029. } // end namespace Catch
  5030. // end catch_reporter_compact.h
  5031. // start catch_reporter_console.h
  5032. #if defined(_MSC_VER)
  5033. #pragma warning(push)
  5034. #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
  5035. // Note that 4062 (not all labels are handled
  5036. // and default is missing) is enabled
  5037. #endif
  5038. namespace Catch {
  5039. // Fwd decls
  5040. struct SummaryColumn;
  5041. class TablePrinter;
  5042. struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> {
  5043. std::unique_ptr<TablePrinter> m_tablePrinter;
  5044. ConsoleReporter(ReporterConfig const& config);
  5045. ~ConsoleReporter() override;
  5046. static std::string getDescription();
  5047. void noMatchingTestCases(std::string const& spec) override;
  5048. void reportInvalidArguments(std::string const&arg) override;
  5049. void assertionStarting(AssertionInfo const&) override;
  5050. bool assertionEnded(AssertionStats const& _assertionStats) override;
  5051. void sectionStarting(SectionInfo const& _sectionInfo) override;
  5052. void sectionEnded(SectionStats const& _sectionStats) override;
  5053. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  5054. void benchmarkPreparing(std::string const& name) override;
  5055. void benchmarkStarting(BenchmarkInfo const& info) override;
  5056. void benchmarkEnded(BenchmarkStats<> const& stats) override;
  5057. void benchmarkFailed(std::string const& error) override;
  5058. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  5059. void testCaseEnded(TestCaseStats const& _testCaseStats) override;
  5060. void testGroupEnded(TestGroupStats const& _testGroupStats) override;
  5061. void testRunEnded(TestRunStats const& _testRunStats) override;
  5062. void testRunStarting(TestRunInfo const& _testRunInfo) override;
  5063. private:
  5064. void lazyPrint();
  5065. void lazyPrintWithoutClosingBenchmarkTable();
  5066. void lazyPrintRunInfo();
  5067. void lazyPrintGroupInfo();
  5068. void printTestCaseAndSectionHeader();
  5069. void printClosedHeader(std::string const& _name);
  5070. void printOpenHeader(std::string const& _name);
  5071. // if string has a : in first line will set indent to follow it on
  5072. // subsequent lines
  5073. void printHeaderString(std::string const& _string, std::size_t indent = 0);
  5074. void printTotals(Totals const& totals);
  5075. void printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row);
  5076. void printTotalsDivider(Totals const& totals);
  5077. void printSummaryDivider();
  5078. void printTestFilters();
  5079. private:
  5080. bool m_headerPrinted = false;
  5081. };
  5082. } // end namespace Catch
  5083. #if defined(_MSC_VER)
  5084. #pragma warning(pop)
  5085. #endif
  5086. // end catch_reporter_console.h
  5087. // start catch_reporter_junit.h
  5088. // start catch_xmlwriter.h
  5089. #include <vector>
  5090. namespace Catch {
  5091. enum class XmlFormatting {
  5092. None = 0x00,
  5093. Indent = 0x01,
  5094. Newline = 0x02,
  5095. };
  5096. XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs);
  5097. XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs);
  5098. class XmlEncode {
  5099. public:
  5100. enum ForWhat { ForTextNodes, ForAttributes };
  5101. XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes );
  5102. void encodeTo( std::ostream& os ) const;
  5103. friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );
  5104. private:
  5105. std::string m_str;
  5106. ForWhat m_forWhat;
  5107. };
  5108. class XmlWriter {
  5109. public:
  5110. class ScopedElement {
  5111. public:
  5112. ScopedElement( XmlWriter* writer, XmlFormatting fmt );
  5113. ScopedElement( ScopedElement&& other ) noexcept;
  5114. ScopedElement& operator=( ScopedElement&& other ) noexcept;
  5115. ~ScopedElement();
  5116. ScopedElement& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent );
  5117. template<typename T>
  5118. ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
  5119. m_writer->writeAttribute( name, attribute );
  5120. return *this;
  5121. }
  5122. private:
  5123. mutable XmlWriter* m_writer = nullptr;
  5124. XmlFormatting m_fmt;
  5125. };
  5126. XmlWriter( std::ostream& os = Catch::cout() );
  5127. ~XmlWriter();
  5128. XmlWriter( XmlWriter const& ) = delete;
  5129. XmlWriter& operator=( XmlWriter const& ) = delete;
  5130. XmlWriter& startElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
  5131. ScopedElement scopedElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
  5132. XmlWriter& endElement(XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
  5133. XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );
  5134. XmlWriter& writeAttribute( std::string const& name, bool attribute );
  5135. template<typename T>
  5136. XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
  5137. ReusableStringStream rss;
  5138. rss << attribute;
  5139. return writeAttribute( name, rss.str() );
  5140. }
  5141. XmlWriter& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
  5142. XmlWriter& writeComment(std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
  5143. void writeStylesheetRef( std::string const& url );
  5144. XmlWriter& writeBlankLine();
  5145. void ensureTagClosed();
  5146. private:
  5147. void applyFormatting(XmlFormatting fmt);
  5148. void writeDeclaration();
  5149. void newlineIfNecessary();
  5150. bool m_tagIsOpen = false;
  5151. bool m_needsNewline = false;
  5152. std::vector<std::string> m_tags;
  5153. std::string m_indent;
  5154. std::ostream& m_os;
  5155. };
  5156. }
  5157. // end catch_xmlwriter.h
  5158. namespace Catch {
  5159. class JunitReporter : public CumulativeReporterBase<JunitReporter> {
  5160. public:
  5161. JunitReporter(ReporterConfig const& _config);
  5162. ~JunitReporter() override;
  5163. static std::string getDescription();
  5164. void noMatchingTestCases(std::string const& /*spec*/) override;
  5165. void testRunStarting(TestRunInfo const& runInfo) override;
  5166. void testGroupStarting(GroupInfo const& groupInfo) override;
  5167. void testCaseStarting(TestCaseInfo const& testCaseInfo) override;
  5168. bool assertionEnded(AssertionStats const& assertionStats) override;
  5169. void testCaseEnded(TestCaseStats const& testCaseStats) override;
  5170. void testGroupEnded(TestGroupStats const& testGroupStats) override;
  5171. void testRunEndedCumulative() override;
  5172. void writeGroup(TestGroupNode const& groupNode, double suiteTime);
  5173. void writeTestCase(TestCaseNode const& testCaseNode);
  5174. void writeSection(std::string const& className,
  5175. std::string const& rootName,
  5176. SectionNode const& sectionNode);
  5177. void writeAssertions(SectionNode const& sectionNode);
  5178. void writeAssertion(AssertionStats const& stats);
  5179. XmlWriter xml;
  5180. Timer suiteTimer;
  5181. std::string stdOutForSuite;
  5182. std::string stdErrForSuite;
  5183. unsigned int unexpectedExceptions = 0;
  5184. bool m_okToFail = false;
  5185. };
  5186. } // end namespace Catch
  5187. // end catch_reporter_junit.h
  5188. // start catch_reporter_xml.h
  5189. namespace Catch {
  5190. class XmlReporter : public StreamingReporterBase<XmlReporter> {
  5191. public:
  5192. XmlReporter(ReporterConfig const& _config);
  5193. ~XmlReporter() override;
  5194. static std::string getDescription();
  5195. virtual std::string getStylesheetRef() const;
  5196. void writeSourceInfo(SourceLineInfo const& sourceInfo);
  5197. public: // StreamingReporterBase
  5198. void noMatchingTestCases(std::string const& s) override;
  5199. void testRunStarting(TestRunInfo const& testInfo) override;
  5200. void testGroupStarting(GroupInfo const& groupInfo) override;
  5201. void testCaseStarting(TestCaseInfo const& testInfo) override;
  5202. void sectionStarting(SectionInfo const& sectionInfo) override;
  5203. void assertionStarting(AssertionInfo const&) override;
  5204. bool assertionEnded(AssertionStats const& assertionStats) override;
  5205. void sectionEnded(SectionStats const& sectionStats) override;
  5206. void testCaseEnded(TestCaseStats const& testCaseStats) override;
  5207. void testGroupEnded(TestGroupStats const& testGroupStats) override;
  5208. void testRunEnded(TestRunStats const& testRunStats) override;
  5209. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  5210. void benchmarkPreparing(std::string const& name) override;
  5211. void benchmarkStarting(BenchmarkInfo const&) override;
  5212. void benchmarkEnded(BenchmarkStats<> const&) override;
  5213. void benchmarkFailed(std::string const&) override;
  5214. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  5215. private:
  5216. Timer m_testCaseTimer;
  5217. XmlWriter m_xml;
  5218. int m_sectionDepth = 0;
  5219. };
  5220. } // end namespace Catch
  5221. // end catch_reporter_xml.h
  5222. // end catch_external_interfaces.h
  5223. #endif
  5224. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  5225. // start catch_benchmarking_all.hpp
  5226. // A proxy header that includes all of the benchmarking headers to allow
  5227. // concise include of the benchmarking features. You should prefer the
  5228. // individual includes in standard use.
  5229. // start catch_benchmark.hpp
  5230. // Benchmark
  5231. // start catch_chronometer.hpp
  5232. // User-facing chronometer
  5233. // start catch_clock.hpp
  5234. // Clocks
  5235. #include <chrono>
  5236. #include <ratio>
  5237. namespace Catch {
  5238. namespace Benchmark {
  5239. template <typename Clock>
  5240. using ClockDuration = typename Clock::duration;
  5241. template <typename Clock>
  5242. using FloatDuration = std::chrono::duration<double, typename Clock::period>;
  5243. template <typename Clock>
  5244. using TimePoint = typename Clock::time_point;
  5245. using default_clock = std::chrono::steady_clock;
  5246. template <typename Clock>
  5247. struct now {
  5248. TimePoint<Clock> operator()() const {
  5249. return Clock::now();
  5250. }
  5251. };
  5252. using fp_seconds = std::chrono::duration<double, std::ratio<1>>;
  5253. } // namespace Benchmark
  5254. } // namespace Catch
  5255. // end catch_clock.hpp
  5256. // start catch_optimizer.hpp
  5257. // Hinting the optimizer
  5258. #if defined(_MSC_VER)
  5259. # include <atomic> // atomic_thread_fence
  5260. #endif
  5261. namespace Catch {
  5262. namespace Benchmark {
  5263. #if defined(__GNUC__) || defined(__clang__)
  5264. template <typename T>
  5265. inline void keep_memory(T* p) {
  5266. asm volatile("" : : "g"(p) : "memory");
  5267. }
  5268. inline void keep_memory() {
  5269. asm volatile("" : : : "memory");
  5270. }
  5271. namespace Detail {
  5272. inline void optimizer_barrier() { keep_memory(); }
  5273. } // namespace Detail
  5274. #elif defined(_MSC_VER)
  5275. #pragma optimize("", off)
  5276. template <typename T>
  5277. inline void keep_memory(T* p) {
  5278. // thanks @milleniumbug
  5279. *reinterpret_cast<char volatile*>(p) = *reinterpret_cast<char const volatile*>(p);
  5280. }
  5281. // TODO equivalent keep_memory()
  5282. #pragma optimize("", on)
  5283. namespace Detail {
  5284. inline void optimizer_barrier() {
  5285. std::atomic_thread_fence(std::memory_order_seq_cst);
  5286. }
  5287. } // namespace Detail
  5288. #endif
  5289. template <typename T>
  5290. inline void deoptimize_value(T&& x) {
  5291. keep_memory(&x);
  5292. }
  5293. template <typename Fn, typename... Args>
  5294. inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<!std::is_same<void, decltype(fn(args...))>::value>::type {
  5295. deoptimize_value(std::forward<Fn>(fn) (std::forward<Args...>(args...)));
  5296. }
  5297. template <typename Fn, typename... Args>
  5298. inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<std::is_same<void, decltype(fn(args...))>::value>::type {
  5299. std::forward<Fn>(fn) (std::forward<Args...>(args...));
  5300. }
  5301. } // namespace Benchmark
  5302. } // namespace Catch
  5303. // end catch_optimizer.hpp
  5304. // start catch_complete_invoke.hpp
  5305. // Invoke with a special case for void
  5306. #include <type_traits>
  5307. #include <utility>
  5308. namespace Catch {
  5309. namespace Benchmark {
  5310. namespace Detail {
  5311. template <typename T>
  5312. struct CompleteType { using type = T; };
  5313. template <>
  5314. struct CompleteType<void> { struct type {}; };
  5315. template <typename T>
  5316. using CompleteType_t = typename CompleteType<T>::type;
  5317. template <typename Result>
  5318. struct CompleteInvoker {
  5319. template <typename Fun, typename... Args>
  5320. static Result invoke(Fun&& fun, Args&&... args) {
  5321. return std::forward<Fun>(fun)(std::forward<Args>(args)...);
  5322. }
  5323. };
  5324. template <>
  5325. struct CompleteInvoker<void> {
  5326. template <typename Fun, typename... Args>
  5327. static CompleteType_t<void> invoke(Fun&& fun, Args&&... args) {
  5328. std::forward<Fun>(fun)(std::forward<Args>(args)...);
  5329. return {};
  5330. }
  5331. };
  5332. // invoke and not return void :(
  5333. template <typename Fun, typename... Args>
  5334. CompleteType_t<FunctionReturnType<Fun, Args...>> complete_invoke(Fun&& fun, Args&&... args) {
  5335. return CompleteInvoker<FunctionReturnType<Fun, Args...>>::invoke(std::forward<Fun>(fun), std::forward<Args>(args)...);
  5336. }
  5337. const std::string benchmarkErrorMsg = "a benchmark failed to run successfully";
  5338. } // namespace Detail
  5339. template <typename Fun>
  5340. Detail::CompleteType_t<FunctionReturnType<Fun>> user_code(Fun&& fun) {
  5341. CATCH_TRY{
  5342. return Detail::complete_invoke(std::forward<Fun>(fun));
  5343. } CATCH_CATCH_ALL{
  5344. getResultCapture().benchmarkFailed(translateActiveException());
  5345. CATCH_RUNTIME_ERROR(Detail::benchmarkErrorMsg);
  5346. }
  5347. }
  5348. } // namespace Benchmark
  5349. } // namespace Catch
  5350. // end catch_complete_invoke.hpp
  5351. namespace Catch {
  5352. namespace Benchmark {
  5353. namespace Detail {
  5354. struct ChronometerConcept {
  5355. virtual void start() = 0;
  5356. virtual void finish() = 0;
  5357. virtual ~ChronometerConcept() = default;
  5358. };
  5359. template <typename Clock>
  5360. struct ChronometerModel final : public ChronometerConcept {
  5361. void start() override { started = Clock::now(); }
  5362. void finish() override { finished = Clock::now(); }
  5363. ClockDuration<Clock> elapsed() const { return finished - started; }
  5364. TimePoint<Clock> started;
  5365. TimePoint<Clock> finished;
  5366. };
  5367. } // namespace Detail
  5368. struct Chronometer {
  5369. public:
  5370. template <typename Fun>
  5371. void measure(Fun&& fun) { measure(std::forward<Fun>(fun), is_callable<Fun(int)>()); }
  5372. int runs() const { return k; }
  5373. Chronometer(Detail::ChronometerConcept& meter, int k)
  5374. : impl(&meter)
  5375. , k(k) {}
  5376. private:
  5377. template <typename Fun>
  5378. void measure(Fun&& fun, std::false_type) {
  5379. measure([&fun](int) { return fun(); }, std::true_type());
  5380. }
  5381. template <typename Fun>
  5382. void measure(Fun&& fun, std::true_type) {
  5383. Detail::optimizer_barrier();
  5384. impl->start();
  5385. for (int i = 0; i < k; ++i) invoke_deoptimized(fun, i);
  5386. impl->finish();
  5387. Detail::optimizer_barrier();
  5388. }
  5389. Detail::ChronometerConcept* impl;
  5390. int k;
  5391. };
  5392. } // namespace Benchmark
  5393. } // namespace Catch
  5394. // end catch_chronometer.hpp
  5395. // start catch_environment.hpp
  5396. // Environment information
  5397. namespace Catch {
  5398. namespace Benchmark {
  5399. template <typename Duration>
  5400. struct EnvironmentEstimate {
  5401. Duration mean;
  5402. OutlierClassification outliers;
  5403. template <typename Duration2>
  5404. operator EnvironmentEstimate<Duration2>() const {
  5405. return { mean, outliers };
  5406. }
  5407. };
  5408. template <typename Clock>
  5409. struct Environment {
  5410. using clock_type = Clock;
  5411. EnvironmentEstimate<FloatDuration<Clock>> clock_resolution;
  5412. EnvironmentEstimate<FloatDuration<Clock>> clock_cost;
  5413. };
  5414. } // namespace Benchmark
  5415. } // namespace Catch
  5416. // end catch_environment.hpp
  5417. // start catch_execution_plan.hpp
  5418. // Execution plan
  5419. // start catch_benchmark_function.hpp
  5420. // Dumb std::function implementation for consistent call overhead
  5421. #include <cassert>
  5422. #include <type_traits>
  5423. #include <utility>
  5424. #include <memory>
  5425. namespace Catch {
  5426. namespace Benchmark {
  5427. namespace Detail {
  5428. template <typename T>
  5429. using Decay = typename std::decay<T>::type;
  5430. template <typename T, typename U>
  5431. struct is_related
  5432. : std::is_same<Decay<T>, Decay<U>> {};
  5433. /// We need to reinvent std::function because every piece of code that might add overhead
  5434. /// in a measurement context needs to have consistent performance characteristics so that we
  5435. /// can account for it in the measurement.
  5436. /// Implementations of std::function with optimizations that aren't always applicable, like
  5437. /// small buffer optimizations, are not uncommon.
  5438. /// This is effectively an implementation of std::function without any such optimizations;
  5439. /// it may be slow, but it is consistently slow.
  5440. struct BenchmarkFunction {
  5441. private:
  5442. struct callable {
  5443. virtual void call(Chronometer meter) const = 0;
  5444. virtual callable* clone() const = 0;
  5445. virtual ~callable() = default;
  5446. };
  5447. template <typename Fun>
  5448. struct model : public callable {
  5449. model(Fun&& fun) : fun(std::move(fun)) {}
  5450. model(Fun const& fun) : fun(fun) {}
  5451. model<Fun>* clone() const override { return new model<Fun>(*this); }
  5452. void call(Chronometer meter) const override {
  5453. call(meter, is_callable<Fun(Chronometer)>());
  5454. }
  5455. void call(Chronometer meter, std::true_type) const {
  5456. fun(meter);
  5457. }
  5458. void call(Chronometer meter, std::false_type) const {
  5459. meter.measure(fun);
  5460. }
  5461. Fun fun;
  5462. };
  5463. struct do_nothing { void operator()() const {} };
  5464. template <typename T>
  5465. BenchmarkFunction(model<T>* c) : f(c) {}
  5466. public:
  5467. BenchmarkFunction()
  5468. : f(new model<do_nothing>{ {} }) {}
  5469. template <typename Fun,
  5470. typename std::enable_if<!is_related<Fun, BenchmarkFunction>::value, int>::type = 0>
  5471. BenchmarkFunction(Fun&& fun)
  5472. : f(new model<typename std::decay<Fun>::type>(std::forward<Fun>(fun))) {}
  5473. BenchmarkFunction(BenchmarkFunction&& that)
  5474. : f(std::move(that.f)) {}
  5475. BenchmarkFunction(BenchmarkFunction const& that)
  5476. : f(that.f->clone()) {}
  5477. BenchmarkFunction& operator=(BenchmarkFunction&& that) {
  5478. f = std::move(that.f);
  5479. return *this;
  5480. }
  5481. BenchmarkFunction& operator=(BenchmarkFunction const& that) {
  5482. f.reset(that.f->clone());
  5483. return *this;
  5484. }
  5485. void operator()(Chronometer meter) const { f->call(meter); }
  5486. private:
  5487. std::unique_ptr<callable> f;
  5488. };
  5489. } // namespace Detail
  5490. } // namespace Benchmark
  5491. } // namespace Catch
  5492. // end catch_benchmark_function.hpp
  5493. // start catch_repeat.hpp
  5494. // repeat algorithm
  5495. #include <type_traits>
  5496. #include <utility>
  5497. namespace Catch {
  5498. namespace Benchmark {
  5499. namespace Detail {
  5500. template <typename Fun>
  5501. struct repeater {
  5502. void operator()(int k) const {
  5503. for (int i = 0; i < k; ++i) {
  5504. fun();
  5505. }
  5506. }
  5507. Fun fun;
  5508. };
  5509. template <typename Fun>
  5510. repeater<typename std::decay<Fun>::type> repeat(Fun&& fun) {
  5511. return { std::forward<Fun>(fun) };
  5512. }
  5513. } // namespace Detail
  5514. } // namespace Benchmark
  5515. } // namespace Catch
  5516. // end catch_repeat.hpp
  5517. // start catch_run_for_at_least.hpp
  5518. // Run a function for a minimum amount of time
  5519. // start catch_measure.hpp
  5520. // Measure
  5521. // start catch_timing.hpp
  5522. // Timing
  5523. #include <tuple>
  5524. #include <type_traits>
  5525. namespace Catch {
  5526. namespace Benchmark {
  5527. template <typename Duration, typename Result>
  5528. struct Timing {
  5529. Duration elapsed;
  5530. Result result;
  5531. int iterations;
  5532. };
  5533. template <typename Clock, typename Func, typename... Args>
  5534. using TimingOf = Timing<ClockDuration<Clock>, Detail::CompleteType_t<FunctionReturnType<Func, Args...>>>;
  5535. } // namespace Benchmark
  5536. } // namespace Catch
  5537. // end catch_timing.hpp
  5538. #include <utility>
  5539. namespace Catch {
  5540. namespace Benchmark {
  5541. namespace Detail {
  5542. template <typename Clock, typename Fun, typename... Args>
  5543. TimingOf<Clock, Fun, Args...> measure(Fun&& fun, Args&&... args) {
  5544. auto start = Clock::now();
  5545. auto&& r = Detail::complete_invoke(fun, std::forward<Args>(args)...);
  5546. auto end = Clock::now();
  5547. auto delta = end - start;
  5548. return { delta, std::forward<decltype(r)>(r), 1 };
  5549. }
  5550. } // namespace Detail
  5551. } // namespace Benchmark
  5552. } // namespace Catch
  5553. // end catch_measure.hpp
  5554. #include <utility>
  5555. #include <type_traits>
  5556. namespace Catch {
  5557. namespace Benchmark {
  5558. namespace Detail {
  5559. template <typename Clock, typename Fun>
  5560. TimingOf<Clock, Fun, int> measure_one(Fun&& fun, int iters, std::false_type) {
  5561. return Detail::measure<Clock>(fun, iters);
  5562. }
  5563. template <typename Clock, typename Fun>
  5564. TimingOf<Clock, Fun, Chronometer> measure_one(Fun&& fun, int iters, std::true_type) {
  5565. Detail::ChronometerModel<Clock> meter;
  5566. auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters));
  5567. return { meter.elapsed(), std::move(result), iters };
  5568. }
  5569. template <typename Clock, typename Fun>
  5570. using run_for_at_least_argument_t = typename std::conditional<is_callable<Fun(Chronometer)>::value, Chronometer, int>::type;
  5571. struct optimized_away_error : std::exception {
  5572. const char* what() const noexcept override {
  5573. return "could not measure benchmark, maybe it was optimized away";
  5574. }
  5575. };
  5576. template <typename Clock, typename Fun>
  5577. TimingOf<Clock, Fun, run_for_at_least_argument_t<Clock, Fun>> run_for_at_least(ClockDuration<Clock> how_long, int seed, Fun&& fun) {
  5578. auto iters = seed;
  5579. while (iters < (1 << 30)) {
  5580. auto&& Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>());
  5581. if (Timing.elapsed >= how_long) {
  5582. return { Timing.elapsed, std::move(Timing.result), iters };
  5583. }
  5584. iters *= 2;
  5585. }
  5586. throw optimized_away_error{};
  5587. }
  5588. } // namespace Detail
  5589. } // namespace Benchmark
  5590. } // namespace Catch
  5591. // end catch_run_for_at_least.hpp
  5592. #include <algorithm>
  5593. namespace Catch {
  5594. namespace Benchmark {
  5595. template <typename Duration>
  5596. struct ExecutionPlan {
  5597. int iterations_per_sample;
  5598. Duration estimated_duration;
  5599. Detail::BenchmarkFunction benchmark;
  5600. Duration warmup_time;
  5601. int warmup_iterations;
  5602. template <typename Duration2>
  5603. operator ExecutionPlan<Duration2>() const {
  5604. return { iterations_per_sample, estimated_duration, benchmark, warmup_time, warmup_iterations };
  5605. }
  5606. template <typename Clock>
  5607. std::vector<FloatDuration<Clock>> run(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
  5608. // warmup a bit
  5609. Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_iterations, Detail::repeat(now<Clock>{}));
  5610. std::vector<FloatDuration<Clock>> times;
  5611. times.reserve(cfg.benchmarkSamples());
  5612. std::generate_n(std::back_inserter(times), cfg.benchmarkSamples(), [this, env] {
  5613. Detail::ChronometerModel<Clock> model;
  5614. this->benchmark(Chronometer(model, iterations_per_sample));
  5615. auto sample_time = model.elapsed() - env.clock_cost.mean;
  5616. if (sample_time < FloatDuration<Clock>::zero()) sample_time = FloatDuration<Clock>::zero();
  5617. return sample_time / iterations_per_sample;
  5618. });
  5619. return times;
  5620. }
  5621. };
  5622. } // namespace Benchmark
  5623. } // namespace Catch
  5624. // end catch_execution_plan.hpp
  5625. // start catch_estimate_clock.hpp
  5626. // Environment measurement
  5627. // start catch_stats.hpp
  5628. // Statistical analysis tools
  5629. #include <algorithm>
  5630. #include <functional>
  5631. #include <vector>
  5632. #include <iterator>
  5633. #include <numeric>
  5634. #include <tuple>
  5635. #include <cmath>
  5636. #include <utility>
  5637. #include <cstddef>
  5638. #include <random>
  5639. namespace Catch {
  5640. namespace Benchmark {
  5641. namespace Detail {
  5642. using sample = std::vector<double>;
  5643. double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last);
  5644. template <typename Iterator>
  5645. OutlierClassification classify_outliers(Iterator first, Iterator last) {
  5646. std::vector<double> copy(first, last);
  5647. auto q1 = weighted_average_quantile(1, 4, copy.begin(), copy.end());
  5648. auto q3 = weighted_average_quantile(3, 4, copy.begin(), copy.end());
  5649. auto iqr = q3 - q1;
  5650. auto los = q1 - (iqr * 3.);
  5651. auto lom = q1 - (iqr * 1.5);
  5652. auto him = q3 + (iqr * 1.5);
  5653. auto his = q3 + (iqr * 3.);
  5654. OutlierClassification o;
  5655. for (; first != last; ++first) {
  5656. auto&& t = *first;
  5657. if (t < los) ++o.low_severe;
  5658. else if (t < lom) ++o.low_mild;
  5659. else if (t > his) ++o.high_severe;
  5660. else if (t > him) ++o.high_mild;
  5661. ++o.samples_seen;
  5662. }
  5663. return o;
  5664. }
  5665. template <typename Iterator>
  5666. double mean(Iterator first, Iterator last) {
  5667. auto count = last - first;
  5668. double sum = std::accumulate(first, last, 0.);
  5669. return sum / count;
  5670. }
  5671. template <typename URng, typename Iterator, typename Estimator>
  5672. sample resample(URng& rng, int resamples, Iterator first, Iterator last, Estimator& estimator) {
  5673. auto n = last - first;
  5674. std::uniform_int_distribution<decltype(n)> dist(0, n - 1);
  5675. sample out;
  5676. out.reserve(resamples);
  5677. std::generate_n(std::back_inserter(out), resamples, [n, first, &estimator, &dist, &rng] {
  5678. std::vector<double> resampled;
  5679. resampled.reserve(n);
  5680. std::generate_n(std::back_inserter(resampled), n, [first, &dist, &rng] { return first[dist(rng)]; });
  5681. return estimator(resampled.begin(), resampled.end());
  5682. });
  5683. std::sort(out.begin(), out.end());
  5684. return out;
  5685. }
  5686. template <typename Estimator, typename Iterator>
  5687. sample jackknife(Estimator&& estimator, Iterator first, Iterator last) {
  5688. auto n = last - first;
  5689. auto second = std::next(first);
  5690. sample results;
  5691. results.reserve(n);
  5692. for (auto it = first; it != last; ++it) {
  5693. std::iter_swap(it, first);
  5694. results.push_back(estimator(second, last));
  5695. }
  5696. return results;
  5697. }
  5698. inline double normal_cdf(double x) {
  5699. return std::erfc(-x / std::sqrt(2.0)) / 2.0;
  5700. }
  5701. double erfc_inv(double x);
  5702. double normal_quantile(double p);
  5703. template <typename Iterator, typename Estimator>
  5704. Estimate<double> bootstrap(double confidence_level, Iterator first, Iterator last, sample const& resample, Estimator&& estimator) {
  5705. auto n_samples = last - first;
  5706. double point = estimator(first, last);
  5707. // Degenerate case with a single sample
  5708. if (n_samples == 1) return { point, point, point, confidence_level };
  5709. sample jack = jackknife(estimator, first, last);
  5710. double jack_mean = mean(jack.begin(), jack.end());
  5711. double sum_squares, sum_cubes;
  5712. std::tie(sum_squares, sum_cubes) = std::accumulate(jack.begin(), jack.end(), std::make_pair(0., 0.), [jack_mean](std::pair<double, double> sqcb, double x) -> std::pair<double, double> {
  5713. auto d = jack_mean - x;
  5714. auto d2 = d * d;
  5715. auto d3 = d2 * d;
  5716. return { sqcb.first + d2, sqcb.second + d3 };
  5717. });
  5718. double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5));
  5719. int n = static_cast<int>(resample.size());
  5720. double prob_n = std::count_if(resample.begin(), resample.end(), [point](double x) { return x < point; }) / (double)n;
  5721. // degenerate case with uniform samples
  5722. if (prob_n == 0) return { point, point, point, confidence_level };
  5723. double bias = normal_quantile(prob_n);
  5724. double z1 = normal_quantile((1. - confidence_level) / 2.);
  5725. auto cumn = [n](double x) -> int {
  5726. return std::lround(normal_cdf(x) * n); };
  5727. auto a = [bias, accel](double b) { return bias + b / (1. - accel * b); };
  5728. double b1 = bias + z1;
  5729. double b2 = bias - z1;
  5730. double a1 = a(b1);
  5731. double a2 = a(b2);
  5732. auto lo = std::max(cumn(a1), 0);
  5733. auto hi = std::min(cumn(a2), n - 1);
  5734. return { point, resample[lo], resample[hi], confidence_level };
  5735. }
  5736. double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n);
  5737. struct bootstrap_analysis {
  5738. Estimate<double> mean;
  5739. Estimate<double> standard_deviation;
  5740. double outlier_variance;
  5741. };
  5742. bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last);
  5743. } // namespace Detail
  5744. } // namespace Benchmark
  5745. } // namespace Catch
  5746. // end catch_stats.hpp
  5747. #include <algorithm>
  5748. #include <iterator>
  5749. #include <tuple>
  5750. #include <vector>
  5751. #include <cmath>
  5752. namespace Catch {
  5753. namespace Benchmark {
  5754. namespace Detail {
  5755. template <typename Clock>
  5756. std::vector<double> resolution(int k) {
  5757. std::vector<TimePoint<Clock>> times;
  5758. times.reserve(k + 1);
  5759. std::generate_n(std::back_inserter(times), k + 1, now<Clock>{});
  5760. std::vector<double> deltas;
  5761. deltas.reserve(k);
  5762. std::transform(std::next(times.begin()), times.end(), times.begin(),
  5763. std::back_inserter(deltas),
  5764. [](TimePoint<Clock> a, TimePoint<Clock> b) { return static_cast<double>((a - b).count()); });
  5765. return deltas;
  5766. }
  5767. const auto warmup_iterations = 10000;
  5768. const auto warmup_time = std::chrono::milliseconds(100);
  5769. const auto minimum_ticks = 1000;
  5770. const auto warmup_seed = 10000;
  5771. const auto clock_resolution_estimation_time = std::chrono::milliseconds(500);
  5772. const auto clock_cost_estimation_time_limit = std::chrono::seconds(1);
  5773. const auto clock_cost_estimation_tick_limit = 100000;
  5774. const auto clock_cost_estimation_time = std::chrono::milliseconds(10);
  5775. const auto clock_cost_estimation_iterations = 10000;
  5776. template <typename Clock>
  5777. int warmup() {
  5778. return run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_seed, &resolution<Clock>)
  5779. .iterations;
  5780. }
  5781. template <typename Clock>
  5782. EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_resolution(int iterations) {
  5783. auto r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_resolution_estimation_time), iterations, &resolution<Clock>)
  5784. .result;
  5785. return {
  5786. FloatDuration<Clock>(mean(r.begin(), r.end())),
  5787. classify_outliers(r.begin(), r.end()),
  5788. };
  5789. }
  5790. template <typename Clock>
  5791. EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_cost(FloatDuration<Clock> resolution) {
  5792. auto time_limit = std::min(resolution * clock_cost_estimation_tick_limit, FloatDuration<Clock>(clock_cost_estimation_time_limit));
  5793. auto time_clock = [](int k) {
  5794. return Detail::measure<Clock>([k] {
  5795. for (int i = 0; i < k; ++i) {
  5796. volatile auto ignored = Clock::now();
  5797. (void)ignored;
  5798. }
  5799. }).elapsed;
  5800. };
  5801. time_clock(1);
  5802. int iters = clock_cost_estimation_iterations;
  5803. auto&& r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_cost_estimation_time), iters, time_clock);
  5804. std::vector<double> times;
  5805. int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed));
  5806. times.reserve(nsamples);
  5807. std::generate_n(std::back_inserter(times), nsamples, [time_clock, &r] {
  5808. return static_cast<double>((time_clock(r.iterations) / r.iterations).count());
  5809. });
  5810. return {
  5811. FloatDuration<Clock>(mean(times.begin(), times.end())),
  5812. classify_outliers(times.begin(), times.end()),
  5813. };
  5814. }
  5815. template <typename Clock>
  5816. Environment<FloatDuration<Clock>> measure_environment() {
  5817. static Environment<FloatDuration<Clock>>* env = nullptr;
  5818. if (env) {
  5819. return *env;
  5820. }
  5821. auto iters = Detail::warmup<Clock>();
  5822. auto resolution = Detail::estimate_clock_resolution<Clock>(iters);
  5823. auto cost = Detail::estimate_clock_cost<Clock>(resolution.mean);
  5824. env = new Environment<FloatDuration<Clock>>{ resolution, cost };
  5825. return *env;
  5826. }
  5827. } // namespace Detail
  5828. } // namespace Benchmark
  5829. } // namespace Catch
  5830. // end catch_estimate_clock.hpp
  5831. // start catch_analyse.hpp
  5832. // Run and analyse one benchmark
  5833. // start catch_sample_analysis.hpp
  5834. // Benchmark results
  5835. #include <algorithm>
  5836. #include <vector>
  5837. #include <string>
  5838. #include <iterator>
  5839. namespace Catch {
  5840. namespace Benchmark {
  5841. template <typename Duration>
  5842. struct SampleAnalysis {
  5843. std::vector<Duration> samples;
  5844. Estimate<Duration> mean;
  5845. Estimate<Duration> standard_deviation;
  5846. OutlierClassification outliers;
  5847. double outlier_variance;
  5848. template <typename Duration2>
  5849. operator SampleAnalysis<Duration2>() const {
  5850. std::vector<Duration2> samples2;
  5851. samples2.reserve(samples.size());
  5852. std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });
  5853. return {
  5854. std::move(samples2),
  5855. mean,
  5856. standard_deviation,
  5857. outliers,
  5858. outlier_variance,
  5859. };
  5860. }
  5861. };
  5862. } // namespace Benchmark
  5863. } // namespace Catch
  5864. // end catch_sample_analysis.hpp
  5865. #include <algorithm>
  5866. #include <iterator>
  5867. #include <vector>
  5868. namespace Catch {
  5869. namespace Benchmark {
  5870. namespace Detail {
  5871. template <typename Duration, typename Iterator>
  5872. SampleAnalysis<Duration> analyse(const IConfig &cfg, Environment<Duration>, Iterator first, Iterator last) {
  5873. if (!cfg.benchmarkNoAnalysis()) {
  5874. std::vector<double> samples;
  5875. samples.reserve(last - first);
  5876. std::transform(first, last, std::back_inserter(samples), [](Duration d) { return d.count(); });
  5877. auto analysis = Catch::Benchmark::Detail::analyse_samples(cfg.benchmarkConfidenceInterval(), cfg.benchmarkResamples(), samples.begin(), samples.end());
  5878. auto outliers = Catch::Benchmark::Detail::classify_outliers(samples.begin(), samples.end());
  5879. auto wrap_estimate = [](Estimate<double> e) {
  5880. return Estimate<Duration> {
  5881. Duration(e.point),
  5882. Duration(e.lower_bound),
  5883. Duration(e.upper_bound),
  5884. e.confidence_interval,
  5885. };
  5886. };
  5887. std::vector<Duration> samples2;
  5888. samples2.reserve(samples.size());
  5889. std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](double d) { return Duration(d); });
  5890. return {
  5891. std::move(samples2),
  5892. wrap_estimate(analysis.mean),
  5893. wrap_estimate(analysis.standard_deviation),
  5894. outliers,
  5895. analysis.outlier_variance,
  5896. };
  5897. } else {
  5898. std::vector<Duration> samples;
  5899. samples.reserve(last - first);
  5900. Duration mean = Duration(0);
  5901. int i = 0;
  5902. for (auto it = first; it < last; ++it, ++i) {
  5903. samples.push_back(Duration(*it));
  5904. mean += Duration(*it);
  5905. }
  5906. mean /= i;
  5907. return {
  5908. std::move(samples),
  5909. Estimate<Duration>{mean, mean, mean, 0.0},
  5910. Estimate<Duration>{Duration(0), Duration(0), Duration(0), 0.0},
  5911. OutlierClassification{},
  5912. 0.0
  5913. };
  5914. }
  5915. }
  5916. } // namespace Detail
  5917. } // namespace Benchmark
  5918. } // namespace Catch
  5919. // end catch_analyse.hpp
  5920. #include <algorithm>
  5921. #include <functional>
  5922. #include <string>
  5923. #include <vector>
  5924. #include <cmath>
  5925. namespace Catch {
  5926. namespace Benchmark {
  5927. struct Benchmark {
  5928. Benchmark(std::string &&name)
  5929. : name(std::move(name)) {}
  5930. template <class FUN>
  5931. Benchmark(std::string &&name, FUN &&func)
  5932. : fun(std::move(func)), name(std::move(name)) {}
  5933. template <typename Clock>
  5934. ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
  5935. auto min_time = env.clock_resolution.mean * Detail::minimum_ticks;
  5936. auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(cfg.benchmarkWarmupTime()));
  5937. auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun);
  5938. int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed));
  5939. return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(cfg.benchmarkWarmupTime()), Detail::warmup_iterations };
  5940. }
  5941. template <typename Clock = default_clock>
  5942. void run() {
  5943. IConfigPtr cfg = getCurrentContext().getConfig();
  5944. auto env = Detail::measure_environment<Clock>();
  5945. getResultCapture().benchmarkPreparing(name);
  5946. CATCH_TRY{
  5947. auto plan = user_code([&] {
  5948. return prepare<Clock>(*cfg, env);
  5949. });
  5950. BenchmarkInfo info {
  5951. name,
  5952. plan.estimated_duration.count(),
  5953. plan.iterations_per_sample,
  5954. cfg->benchmarkSamples(),
  5955. cfg->benchmarkResamples(),
  5956. env.clock_resolution.mean.count(),
  5957. env.clock_cost.mean.count()
  5958. };
  5959. getResultCapture().benchmarkStarting(info);
  5960. auto samples = user_code([&] {
  5961. return plan.template run<Clock>(*cfg, env);
  5962. });
  5963. auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end());
  5964. BenchmarkStats<FloatDuration<Clock>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };
  5965. getResultCapture().benchmarkEnded(stats);
  5966. } CATCH_CATCH_ALL{
  5967. if (translateActiveException() != Detail::benchmarkErrorMsg) // benchmark errors have been reported, otherwise rethrow.
  5968. std::rethrow_exception(std::current_exception());
  5969. }
  5970. }
  5971. // sets lambda to be used in fun *and* executes benchmark!
  5972. template <typename Fun,
  5973. typename std::enable_if<!Detail::is_related<Fun, Benchmark>::value, int>::type = 0>
  5974. Benchmark & operator=(Fun func) {
  5975. fun = Detail::BenchmarkFunction(func);
  5976. run();
  5977. return *this;
  5978. }
  5979. explicit operator bool() {
  5980. return true;
  5981. }
  5982. private:
  5983. Detail::BenchmarkFunction fun;
  5984. std::string name;
  5985. };
  5986. }
  5987. } // namespace Catch
  5988. #define INTERNAL_CATCH_GET_1_ARG(arg1, arg2, ...) arg1
  5989. #define INTERNAL_CATCH_GET_2_ARG(arg1, arg2, ...) arg2
  5990. #define INTERNAL_CATCH_BENCHMARK(BenchmarkName, name, benchmarkIndex)\
  5991. if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
  5992. BenchmarkName = [&](int benchmarkIndex)
  5993. #define INTERNAL_CATCH_BENCHMARK_ADVANCED(BenchmarkName, name)\
  5994. if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \
  5995. BenchmarkName = [&]
  5996. // end catch_benchmark.hpp
  5997. // start catch_constructor.hpp
  5998. // Constructor and destructor helpers
  5999. #include <type_traits>
  6000. namespace Catch {
  6001. namespace Benchmark {
  6002. namespace Detail {
  6003. template <typename T, bool Destruct>
  6004. struct ObjectStorage
  6005. {
  6006. using TStorage = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
  6007. ObjectStorage() : data() {}
  6008. ObjectStorage(const ObjectStorage& other)
  6009. {
  6010. new(&data) T(other.stored_object());
  6011. }
  6012. ObjectStorage(ObjectStorage&& other)
  6013. {
  6014. new(&data) T(std::move(other.stored_object()));
  6015. }
  6016. ~ObjectStorage() { destruct_on_exit<T>(); }
  6017. template <typename... Args>
  6018. void construct(Args&&... args)
  6019. {
  6020. new (&data) T(std::forward<Args>(args)...);
  6021. }
  6022. template <bool AllowManualDestruction = !Destruct>
  6023. typename std::enable_if<AllowManualDestruction>::type destruct()
  6024. {
  6025. stored_object().~T();
  6026. }
  6027. private:
  6028. // If this is a constructor benchmark, destruct the underlying object
  6029. template <typename U>
  6030. void destruct_on_exit(typename std::enable_if<Destruct, U>::type* = 0) { destruct<true>(); }
  6031. // Otherwise, don't
  6032. template <typename U>
  6033. void destruct_on_exit(typename std::enable_if<!Destruct, U>::type* = 0) { }
  6034. T& stored_object() {
  6035. return *static_cast<T*>(static_cast<void*>(&data));
  6036. }
  6037. T const& stored_object() const {
  6038. return *static_cast<T*>(static_cast<void*>(&data));
  6039. }
  6040. TStorage data;
  6041. };
  6042. }
  6043. template <typename T>
  6044. using storage_for = Detail::ObjectStorage<T, true>;
  6045. template <typename T>
  6046. using destructable_object = Detail::ObjectStorage<T, false>;
  6047. }
  6048. }
  6049. // end catch_constructor.hpp
  6050. // end catch_benchmarking_all.hpp
  6051. #endif
  6052. #endif // ! CATCH_CONFIG_IMPL_ONLY
  6053. #ifdef CATCH_IMPL
  6054. // start catch_impl.hpp
  6055. #ifdef __clang__
  6056. #pragma clang diagnostic push
  6057. #pragma clang diagnostic ignored "-Wweak-vtables"
  6058. #endif
  6059. // Keep these here for external reporters
  6060. // start catch_test_case_tracker.h
  6061. #include <string>
  6062. #include <vector>
  6063. #include <memory>
  6064. namespace Catch {
  6065. namespace TestCaseTracking {
  6066. struct NameAndLocation {
  6067. std::string name;
  6068. SourceLineInfo location;
  6069. NameAndLocation( std::string const& _name, SourceLineInfo const& _location );
  6070. friend bool operator==(NameAndLocation const& lhs, NameAndLocation const& rhs) {
  6071. return lhs.name == rhs.name
  6072. && lhs.location == rhs.location;
  6073. }
  6074. };
  6075. class ITracker;
  6076. using ITrackerPtr = std::shared_ptr<ITracker>;
  6077. class ITracker {
  6078. NameAndLocation m_nameAndLocation;
  6079. public:
  6080. ITracker(NameAndLocation const& nameAndLoc) :
  6081. m_nameAndLocation(nameAndLoc)
  6082. {}
  6083. // static queries
  6084. NameAndLocation const& nameAndLocation() const {
  6085. return m_nameAndLocation;
  6086. }
  6087. virtual ~ITracker();
  6088. // dynamic queries
  6089. virtual bool isComplete() const = 0; // Successfully completed or failed
  6090. virtual bool isSuccessfullyCompleted() const = 0;
  6091. virtual bool isOpen() const = 0; // Started but not complete
  6092. virtual bool hasChildren() const = 0;
  6093. virtual bool hasStarted() const = 0;
  6094. virtual ITracker& parent() = 0;
  6095. // actions
  6096. virtual void close() = 0; // Successfully complete
  6097. virtual void fail() = 0;
  6098. virtual void markAsNeedingAnotherRun() = 0;
  6099. virtual void addChild( ITrackerPtr const& child ) = 0;
  6100. virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0;
  6101. virtual void openChild() = 0;
  6102. // Debug/ checking
  6103. virtual bool isSectionTracker() const = 0;
  6104. virtual bool isGeneratorTracker() const = 0;
  6105. };
  6106. class TrackerContext {
  6107. enum RunState {
  6108. NotStarted,
  6109. Executing,
  6110. CompletedCycle
  6111. };
  6112. ITrackerPtr m_rootTracker;
  6113. ITracker* m_currentTracker = nullptr;
  6114. RunState m_runState = NotStarted;
  6115. public:
  6116. ITracker& startRun();
  6117. void endRun();
  6118. void startCycle();
  6119. void completeCycle();
  6120. bool completedCycle() const;
  6121. ITracker& currentTracker();
  6122. void setCurrentTracker( ITracker* tracker );
  6123. };
  6124. class TrackerBase : public ITracker {
  6125. protected:
  6126. enum CycleState {
  6127. NotStarted,
  6128. Executing,
  6129. ExecutingChildren,
  6130. NeedsAnotherRun,
  6131. CompletedSuccessfully,
  6132. Failed
  6133. };
  6134. using Children = std::vector<ITrackerPtr>;
  6135. TrackerContext& m_ctx;
  6136. ITracker* m_parent;
  6137. Children m_children;
  6138. CycleState m_runState = NotStarted;
  6139. public:
  6140. TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
  6141. bool isComplete() const override;
  6142. bool isSuccessfullyCompleted() const override;
  6143. bool isOpen() const override;
  6144. bool hasChildren() const override;
  6145. bool hasStarted() const override {
  6146. return m_runState != NotStarted;
  6147. }
  6148. void addChild( ITrackerPtr const& child ) override;
  6149. ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override;
  6150. ITracker& parent() override;
  6151. void openChild() override;
  6152. bool isSectionTracker() const override;
  6153. bool isGeneratorTracker() const override;
  6154. void open();
  6155. void close() override;
  6156. void fail() override;
  6157. void markAsNeedingAnotherRun() override;
  6158. private:
  6159. void moveToParent();
  6160. void moveToThis();
  6161. };
  6162. class SectionTracker : public TrackerBase {
  6163. std::vector<std::string> m_filters;
  6164. std::string m_trimmed_name;
  6165. public:
  6166. SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
  6167. bool isSectionTracker() const override;
  6168. bool isComplete() const override;
  6169. static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation );
  6170. void tryOpen();
  6171. void addInitialFilters( std::vector<std::string> const& filters );
  6172. void addNextFilters( std::vector<std::string> const& filters );
  6173. //! Returns filters active in this tracker
  6174. std::vector<std::string> const& getFilters() const;
  6175. //! Returns whitespace-trimmed name of the tracked section
  6176. std::string const& trimmedName() const;
  6177. };
  6178. } // namespace TestCaseTracking
  6179. using TestCaseTracking::ITracker;
  6180. using TestCaseTracking::TrackerContext;
  6181. using TestCaseTracking::SectionTracker;
  6182. } // namespace Catch
  6183. // end catch_test_case_tracker.h
  6184. // start catch_leak_detector.h
  6185. namespace Catch {
  6186. struct LeakDetector {
  6187. LeakDetector();
  6188. ~LeakDetector();
  6189. };
  6190. }
  6191. // end catch_leak_detector.h
  6192. // Cpp files will be included in the single-header file here
  6193. // start catch_stats.cpp
  6194. // Statistical analysis tools
  6195. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  6196. #include <cassert>
  6197. #include <random>
  6198. #if defined(CATCH_CONFIG_USE_ASYNC)
  6199. #include <future>
  6200. #endif
  6201. namespace {
  6202. double erf_inv(double x) {
  6203. // Code accompanying the article "Approximating the erfinv function" in GPU Computing Gems, Volume 2
  6204. double w, p;
  6205. w = -log((1.0 - x) * (1.0 + x));
  6206. if (w < 6.250000) {
  6207. w = w - 3.125000;
  6208. p = -3.6444120640178196996e-21;
  6209. p = -1.685059138182016589e-19 + p * w;
  6210. p = 1.2858480715256400167e-18 + p * w;
  6211. p = 1.115787767802518096e-17 + p * w;
  6212. p = -1.333171662854620906e-16 + p * w;
  6213. p = 2.0972767875968561637e-17 + p * w;
  6214. p = 6.6376381343583238325e-15 + p * w;
  6215. p = -4.0545662729752068639e-14 + p * w;
  6216. p = -8.1519341976054721522e-14 + p * w;
  6217. p = 2.6335093153082322977e-12 + p * w;
  6218. p = -1.2975133253453532498e-11 + p * w;
  6219. p = -5.4154120542946279317e-11 + p * w;
  6220. p = 1.051212273321532285e-09 + p * w;
  6221. p = -4.1126339803469836976e-09 + p * w;
  6222. p = -2.9070369957882005086e-08 + p * w;
  6223. p = 4.2347877827932403518e-07 + p * w;
  6224. p = -1.3654692000834678645e-06 + p * w;
  6225. p = -1.3882523362786468719e-05 + p * w;
  6226. p = 0.0001867342080340571352 + p * w;
  6227. p = -0.00074070253416626697512 + p * w;
  6228. p = -0.0060336708714301490533 + p * w;
  6229. p = 0.24015818242558961693 + p * w;
  6230. p = 1.6536545626831027356 + p * w;
  6231. } else if (w < 16.000000) {
  6232. w = sqrt(w) - 3.250000;
  6233. p = 2.2137376921775787049e-09;
  6234. p = 9.0756561938885390979e-08 + p * w;
  6235. p = -2.7517406297064545428e-07 + p * w;
  6236. p = 1.8239629214389227755e-08 + p * w;
  6237. p = 1.5027403968909827627e-06 + p * w;
  6238. p = -4.013867526981545969e-06 + p * w;
  6239. p = 2.9234449089955446044e-06 + p * w;
  6240. p = 1.2475304481671778723e-05 + p * w;
  6241. p = -4.7318229009055733981e-05 + p * w;
  6242. p = 6.8284851459573175448e-05 + p * w;
  6243. p = 2.4031110387097893999e-05 + p * w;
  6244. p = -0.0003550375203628474796 + p * w;
  6245. p = 0.00095328937973738049703 + p * w;
  6246. p = -0.0016882755560235047313 + p * w;
  6247. p = 0.0024914420961078508066 + p * w;
  6248. p = -0.0037512085075692412107 + p * w;
  6249. p = 0.005370914553590063617 + p * w;
  6250. p = 1.0052589676941592334 + p * w;
  6251. p = 3.0838856104922207635 + p * w;
  6252. } else {
  6253. w = sqrt(w) - 5.000000;
  6254. p = -2.7109920616438573243e-11;
  6255. p = -2.5556418169965252055e-10 + p * w;
  6256. p = 1.5076572693500548083e-09 + p * w;
  6257. p = -3.7894654401267369937e-09 + p * w;
  6258. p = 7.6157012080783393804e-09 + p * w;
  6259. p = -1.4960026627149240478e-08 + p * w;
  6260. p = 2.9147953450901080826e-08 + p * w;
  6261. p = -6.7711997758452339498e-08 + p * w;
  6262. p = 2.2900482228026654717e-07 + p * w;
  6263. p = -9.9298272942317002539e-07 + p * w;
  6264. p = 4.5260625972231537039e-06 + p * w;
  6265. p = -1.9681778105531670567e-05 + p * w;
  6266. p = 7.5995277030017761139e-05 + p * w;
  6267. p = -0.00021503011930044477347 + p * w;
  6268. p = -0.00013871931833623122026 + p * w;
  6269. p = 1.0103004648645343977 + p * w;
  6270. p = 4.8499064014085844221 + p * w;
  6271. }
  6272. return p * x;
  6273. }
  6274. double standard_deviation(std::vector<double>::iterator first, std::vector<double>::iterator last) {
  6275. auto m = Catch::Benchmark::Detail::mean(first, last);
  6276. double variance = std::accumulate(first, last, 0., [m](double a, double b) {
  6277. double diff = b - m;
  6278. return a + diff * diff;
  6279. }) / (last - first);
  6280. return std::sqrt(variance);
  6281. }
  6282. }
  6283. namespace Catch {
  6284. namespace Benchmark {
  6285. namespace Detail {
  6286. double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last) {
  6287. auto count = last - first;
  6288. double idx = (count - 1) * k / static_cast<double>(q);
  6289. int j = static_cast<int>(idx);
  6290. double g = idx - j;
  6291. std::nth_element(first, first + j, last);
  6292. auto xj = first[j];
  6293. if (g == 0) return xj;
  6294. auto xj1 = *std::min_element(first + (j + 1), last);
  6295. return xj + g * (xj1 - xj);
  6296. }
  6297. double erfc_inv(double x) {
  6298. return erf_inv(1.0 - x);
  6299. }
  6300. double normal_quantile(double p) {
  6301. static const double ROOT_TWO = std::sqrt(2.0);
  6302. double result = 0.0;
  6303. assert(p >= 0 && p <= 1);
  6304. if (p < 0 || p > 1) {
  6305. return result;
  6306. }
  6307. result = -erfc_inv(2.0 * p);
  6308. // result *= normal distribution standard deviation (1.0) * sqrt(2)
  6309. result *= /*sd * */ ROOT_TWO;
  6310. // result += normal disttribution mean (0)
  6311. return result;
  6312. }
  6313. double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n) {
  6314. double sb = stddev.point;
  6315. double mn = mean.point / n;
  6316. double mg_min = mn / 2.;
  6317. double sg = std::min(mg_min / 4., sb / std::sqrt(n));
  6318. double sg2 = sg * sg;
  6319. double sb2 = sb * sb;
  6320. auto c_max = [n, mn, sb2, sg2](double x) -> double {
  6321. double k = mn - x;
  6322. double d = k * k;
  6323. double nd = n * d;
  6324. double k0 = -n * nd;
  6325. double k1 = sb2 - n * sg2 + nd;
  6326. double det = k1 * k1 - 4 * sg2 * k0;
  6327. return (int)(-2. * k0 / (k1 + std::sqrt(det)));
  6328. };
  6329. auto var_out = [n, sb2, sg2](double c) {
  6330. double nc = n - c;
  6331. return (nc / n) * (sb2 - nc * sg2);
  6332. };
  6333. return std::min(var_out(1), var_out(std::min(c_max(0.), c_max(mg_min)))) / sb2;
  6334. }
  6335. bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last) {
  6336. CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
  6337. CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
  6338. static std::random_device entropy;
  6339. CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
  6340. auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++
  6341. auto mean = &Detail::mean<std::vector<double>::iterator>;
  6342. auto stddev = &standard_deviation;
  6343. #if defined(CATCH_CONFIG_USE_ASYNC)
  6344. auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
  6345. auto seed = entropy();
  6346. return std::async(std::launch::async, [=] {
  6347. std::mt19937 rng(seed);
  6348. auto resampled = resample(rng, n_resamples, first, last, f);
  6349. return bootstrap(confidence_level, first, last, resampled, f);
  6350. });
  6351. };
  6352. auto mean_future = Estimate(mean);
  6353. auto stddev_future = Estimate(stddev);
  6354. auto mean_estimate = mean_future.get();
  6355. auto stddev_estimate = stddev_future.get();
  6356. #else
  6357. auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
  6358. auto seed = entropy();
  6359. std::mt19937 rng(seed);
  6360. auto resampled = resample(rng, n_resamples, first, last, f);
  6361. return bootstrap(confidence_level, first, last, resampled, f);
  6362. };
  6363. auto mean_estimate = Estimate(mean);
  6364. auto stddev_estimate = Estimate(stddev);
  6365. #endif // CATCH_USE_ASYNC
  6366. double outlier_variance = Detail::outlier_variance(mean_estimate, stddev_estimate, n);
  6367. return { mean_estimate, stddev_estimate, outlier_variance };
  6368. }
  6369. } // namespace Detail
  6370. } // namespace Benchmark
  6371. } // namespace Catch
  6372. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  6373. // end catch_stats.cpp
  6374. // start catch_approx.cpp
  6375. #include <cmath>
  6376. #include <limits>
  6377. namespace {
  6378. // Performs equivalent check of std::fabs(lhs - rhs) <= margin
  6379. // But without the subtraction to allow for INFINITY in comparison
  6380. bool marginComparison(double lhs, double rhs, double margin) {
  6381. return (lhs + margin >= rhs) && (rhs + margin >= lhs);
  6382. }
  6383. }
  6384. namespace Catch {
  6385. namespace Detail {
  6386. Approx::Approx ( double value )
  6387. : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
  6388. m_margin( 0.0 ),
  6389. m_scale( 0.0 ),
  6390. m_value( value )
  6391. {}
  6392. Approx Approx::custom() {
  6393. return Approx( 0 );
  6394. }
  6395. Approx Approx::operator-() const {
  6396. auto temp(*this);
  6397. temp.m_value = -temp.m_value;
  6398. return temp;
  6399. }
  6400. std::string Approx::toString() const {
  6401. ReusableStringStream rss;
  6402. rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
  6403. return rss.str();
  6404. }
  6405. bool Approx::equalityComparisonImpl(const double other) const {
  6406. // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
  6407. // Thanks to Richard Harris for his help refining the scaled margin value
  6408. return marginComparison(m_value, other, m_margin)
  6409. || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(std::isinf(m_value)? 0 : m_value)));
  6410. }
  6411. void Approx::setMargin(double newMargin) {
  6412. CATCH_ENFORCE(newMargin >= 0,
  6413. "Invalid Approx::margin: " << newMargin << '.'
  6414. << " Approx::Margin has to be non-negative.");
  6415. m_margin = newMargin;
  6416. }
  6417. void Approx::setEpsilon(double newEpsilon) {
  6418. CATCH_ENFORCE(newEpsilon >= 0 && newEpsilon <= 1.0,
  6419. "Invalid Approx::epsilon: " << newEpsilon << '.'
  6420. << " Approx::epsilon has to be in [0, 1]");
  6421. m_epsilon = newEpsilon;
  6422. }
  6423. } // end namespace Detail
  6424. namespace literals {
  6425. Detail::Approx operator "" _a(long double val) {
  6426. return Detail::Approx(val);
  6427. }
  6428. Detail::Approx operator "" _a(unsigned long long val) {
  6429. return Detail::Approx(val);
  6430. }
  6431. } // end namespace literals
  6432. std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
  6433. return value.toString();
  6434. }
  6435. } // end namespace Catch
  6436. // end catch_approx.cpp
  6437. // start catch_assertionhandler.cpp
  6438. // start catch_debugger.h
  6439. namespace Catch {
  6440. bool isDebuggerActive();
  6441. }
  6442. #ifdef CATCH_PLATFORM_MAC
  6443. #if defined(__i386__) || defined(__x86_64__)
  6444. #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
  6445. #elif defined(__aarch64__)
  6446. #define CATCH_TRAP() __asm__(".inst 0xd4200000")
  6447. #endif
  6448. #elif defined(CATCH_PLATFORM_IPHONE)
  6449. // use inline assembler
  6450. #if defined(__i386__) || defined(__x86_64__)
  6451. #define CATCH_TRAP() __asm__("int $3")
  6452. #elif defined(__aarch64__)
  6453. #define CATCH_TRAP() __asm__(".inst 0xd4200000")
  6454. #elif defined(__arm__) && !defined(__thumb__)
  6455. #define CATCH_TRAP() __asm__(".inst 0xe7f001f0")
  6456. #elif defined(__arm__) && defined(__thumb__)
  6457. #define CATCH_TRAP() __asm__(".inst 0xde01")
  6458. #endif
  6459. #elif defined(CATCH_PLATFORM_LINUX)
  6460. // If we can use inline assembler, do it because this allows us to break
  6461. // directly at the location of the failing check instead of breaking inside
  6462. // raise() called from it, i.e. one stack frame below.
  6463. #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
  6464. #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
  6465. #else // Fall back to the generic way.
  6466. #include <signal.h>
  6467. #define CATCH_TRAP() raise(SIGTRAP)
  6468. #endif
  6469. #elif defined(_MSC_VER)
  6470. #define CATCH_TRAP() __debugbreak()
  6471. #elif defined(__MINGW32__)
  6472. extern "C" __declspec(dllimport) void __stdcall DebugBreak();
  6473. #define CATCH_TRAP() DebugBreak()
  6474. #endif
  6475. #ifndef CATCH_BREAK_INTO_DEBUGGER
  6476. #ifdef CATCH_TRAP
  6477. #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }()
  6478. #else
  6479. #define CATCH_BREAK_INTO_DEBUGGER() []{}()
  6480. #endif
  6481. #endif
  6482. // end catch_debugger.h
  6483. // start catch_run_context.h
  6484. // start catch_fatal_condition.h
  6485. // start catch_windows_h_proxy.h
  6486. #if defined(CATCH_PLATFORM_WINDOWS)
  6487. #if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
  6488. # define CATCH_DEFINED_NOMINMAX
  6489. # define NOMINMAX
  6490. #endif
  6491. #if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
  6492. # define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
  6493. # define WIN32_LEAN_AND_MEAN
  6494. #endif
  6495. #ifdef __AFXDLL
  6496. #include <AfxWin.h>
  6497. #else
  6498. #include <windows.h>
  6499. #endif
  6500. #ifdef CATCH_DEFINED_NOMINMAX
  6501. # undef NOMINMAX
  6502. #endif
  6503. #ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
  6504. # undef WIN32_LEAN_AND_MEAN
  6505. #endif
  6506. #endif // defined(CATCH_PLATFORM_WINDOWS)
  6507. // end catch_windows_h_proxy.h
  6508. #if defined( CATCH_CONFIG_WINDOWS_SEH )
  6509. namespace Catch {
  6510. struct FatalConditionHandler {
  6511. static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
  6512. FatalConditionHandler();
  6513. static void reset();
  6514. ~FatalConditionHandler();
  6515. private:
  6516. static bool isSet;
  6517. static ULONG guaranteeSize;
  6518. static PVOID exceptionHandlerHandle;
  6519. };
  6520. } // namespace Catch
  6521. #elif defined ( CATCH_CONFIG_POSIX_SIGNALS )
  6522. #include <signal.h>
  6523. namespace Catch {
  6524. struct FatalConditionHandler {
  6525. static bool isSet;
  6526. static struct sigaction oldSigActions[];
  6527. static stack_t oldSigStack;
  6528. static char altStackMem[];
  6529. static void handleSignal( int sig );
  6530. FatalConditionHandler();
  6531. ~FatalConditionHandler();
  6532. static void reset();
  6533. };
  6534. } // namespace Catch
  6535. #else
  6536. namespace Catch {
  6537. struct FatalConditionHandler {
  6538. void reset();
  6539. };
  6540. }
  6541. #endif
  6542. // end catch_fatal_condition.h
  6543. #include <string>
  6544. namespace Catch {
  6545. struct IMutableContext;
  6546. ///////////////////////////////////////////////////////////////////////////
  6547. class RunContext : public IResultCapture, public IRunner {
  6548. public:
  6549. RunContext( RunContext const& ) = delete;
  6550. RunContext& operator =( RunContext const& ) = delete;
  6551. explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr&& reporter );
  6552. ~RunContext() override;
  6553. void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount );
  6554. void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount );
  6555. Totals runTest(TestCase const& testCase);
  6556. IConfigPtr config() const;
  6557. IStreamingReporter& reporter() const;
  6558. public: // IResultCapture
  6559. // Assertion handlers
  6560. void handleExpr
  6561. ( AssertionInfo const& info,
  6562. ITransientExpression const& expr,
  6563. AssertionReaction& reaction ) override;
  6564. void handleMessage
  6565. ( AssertionInfo const& info,
  6566. ResultWas::OfType resultType,
  6567. StringRef const& message,
  6568. AssertionReaction& reaction ) override;
  6569. void handleUnexpectedExceptionNotThrown
  6570. ( AssertionInfo const& info,
  6571. AssertionReaction& reaction ) override;
  6572. void handleUnexpectedInflightException
  6573. ( AssertionInfo const& info,
  6574. std::string const& message,
  6575. AssertionReaction& reaction ) override;
  6576. void handleIncomplete
  6577. ( AssertionInfo const& info ) override;
  6578. void handleNonExpr
  6579. ( AssertionInfo const &info,
  6580. ResultWas::OfType resultType,
  6581. AssertionReaction &reaction ) override;
  6582. bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override;
  6583. void sectionEnded( SectionEndInfo const& endInfo ) override;
  6584. void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
  6585. auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
  6586. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  6587. void benchmarkPreparing( std::string const& name ) override;
  6588. void benchmarkStarting( BenchmarkInfo const& info ) override;
  6589. void benchmarkEnded( BenchmarkStats<> const& stats ) override;
  6590. void benchmarkFailed( std::string const& error ) override;
  6591. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  6592. void pushScopedMessage( MessageInfo const& message ) override;
  6593. void popScopedMessage( MessageInfo const& message ) override;
  6594. void emplaceUnscopedMessage( MessageBuilder const& builder ) override;
  6595. std::string getCurrentTestName() const override;
  6596. const AssertionResult* getLastResult() const override;
  6597. void exceptionEarlyReported() override;
  6598. void handleFatalErrorCondition( StringRef message ) override;
  6599. bool lastAssertionPassed() override;
  6600. void assertionPassed() override;
  6601. public:
  6602. // !TBD We need to do this another way!
  6603. bool aborting() const final;
  6604. private:
  6605. void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr );
  6606. void invokeActiveTestCase();
  6607. void resetAssertionInfo();
  6608. bool testForMissingAssertions( Counts& assertions );
  6609. void assertionEnded( AssertionResult const& result );
  6610. void reportExpr
  6611. ( AssertionInfo const &info,
  6612. ResultWas::OfType resultType,
  6613. ITransientExpression const *expr,
  6614. bool negated );
  6615. void populateReaction( AssertionReaction& reaction );
  6616. private:
  6617. void handleUnfinishedSections();
  6618. TestRunInfo m_runInfo;
  6619. IMutableContext& m_context;
  6620. TestCase const* m_activeTestCase = nullptr;
  6621. ITracker* m_testCaseTracker = nullptr;
  6622. Option<AssertionResult> m_lastResult;
  6623. IConfigPtr m_config;
  6624. Totals m_totals;
  6625. IStreamingReporterPtr m_reporter;
  6626. std::vector<MessageInfo> m_messages;
  6627. std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */
  6628. AssertionInfo m_lastAssertionInfo;
  6629. std::vector<SectionEndInfo> m_unfinishedSections;
  6630. std::vector<ITracker*> m_activeSections;
  6631. TrackerContext m_trackerContext;
  6632. bool m_lastAssertionPassed = false;
  6633. bool m_shouldReportUnexpected = true;
  6634. bool m_includeSuccessfulResults;
  6635. };
  6636. void seedRng(IConfig const& config);
  6637. unsigned int rngSeed();
  6638. } // end namespace Catch
  6639. // end catch_run_context.h
  6640. namespace Catch {
  6641. namespace {
  6642. auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
  6643. expr.streamReconstructedExpression( os );
  6644. return os;
  6645. }
  6646. }
  6647. LazyExpression::LazyExpression( bool isNegated )
  6648. : m_isNegated( isNegated )
  6649. {}
  6650. LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {}
  6651. LazyExpression::operator bool() const {
  6652. return m_transientExpression != nullptr;
  6653. }
  6654. auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& {
  6655. if( lazyExpr.m_isNegated )
  6656. os << "!";
  6657. if( lazyExpr ) {
  6658. if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() )
  6659. os << "(" << *lazyExpr.m_transientExpression << ")";
  6660. else
  6661. os << *lazyExpr.m_transientExpression;
  6662. }
  6663. else {
  6664. os << "{** error - unchecked empty expression requested **}";
  6665. }
  6666. return os;
  6667. }
  6668. AssertionHandler::AssertionHandler
  6669. ( StringRef const& macroName,
  6670. SourceLineInfo const& lineInfo,
  6671. StringRef capturedExpression,
  6672. ResultDisposition::Flags resultDisposition )
  6673. : m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },
  6674. m_resultCapture( getResultCapture() )
  6675. {}
  6676. void AssertionHandler::handleExpr( ITransientExpression const& expr ) {
  6677. m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );
  6678. }
  6679. void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) {
  6680. m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction );
  6681. }
  6682. auto AssertionHandler::allowThrows() const -> bool {
  6683. return getCurrentContext().getConfig()->allowThrows();
  6684. }
  6685. void AssertionHandler::complete() {
  6686. setCompleted();
  6687. if( m_reaction.shouldDebugBreak ) {
  6688. // If you find your debugger stopping you here then go one level up on the
  6689. // call-stack for the code that caused it (typically a failed assertion)
  6690. // (To go back to the test and change execution, jump over the throw, next)
  6691. CATCH_BREAK_INTO_DEBUGGER();
  6692. }
  6693. if (m_reaction.shouldThrow) {
  6694. #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  6695. throw Catch::TestFailureException();
  6696. #else
  6697. CATCH_ERROR( "Test failure requires aborting test!" );
  6698. #endif
  6699. }
  6700. }
  6701. void AssertionHandler::setCompleted() {
  6702. m_completed = true;
  6703. }
  6704. void AssertionHandler::handleUnexpectedInflightException() {
  6705. m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction );
  6706. }
  6707. void AssertionHandler::handleExceptionThrownAsExpected() {
  6708. m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
  6709. }
  6710. void AssertionHandler::handleExceptionNotThrownAsExpected() {
  6711. m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
  6712. }
  6713. void AssertionHandler::handleUnexpectedExceptionNotThrown() {
  6714. m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction );
  6715. }
  6716. void AssertionHandler::handleThrowingCallSkipped() {
  6717. m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
  6718. }
  6719. // This is the overload that takes a string and infers the Equals matcher from it
  6720. // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
  6721. void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString ) {
  6722. handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );
  6723. }
  6724. } // namespace Catch
  6725. // end catch_assertionhandler.cpp
  6726. // start catch_assertionresult.cpp
  6727. namespace Catch {
  6728. AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression):
  6729. lazyExpression(_lazyExpression),
  6730. resultType(_resultType) {}
  6731. std::string AssertionResultData::reconstructExpression() const {
  6732. if( reconstructedExpression.empty() ) {
  6733. if( lazyExpression ) {
  6734. ReusableStringStream rss;
  6735. rss << lazyExpression;
  6736. reconstructedExpression = rss.str();
  6737. }
  6738. }
  6739. return reconstructedExpression;
  6740. }
  6741. AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
  6742. : m_info( info ),
  6743. m_resultData( data )
  6744. {}
  6745. // Result was a success
  6746. bool AssertionResult::succeeded() const {
  6747. return Catch::isOk( m_resultData.resultType );
  6748. }
  6749. // Result was a success, or failure is suppressed
  6750. bool AssertionResult::isOk() const {
  6751. return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
  6752. }
  6753. ResultWas::OfType AssertionResult::getResultType() const {
  6754. return m_resultData.resultType;
  6755. }
  6756. bool AssertionResult::hasExpression() const {
  6757. return !m_info.capturedExpression.empty();
  6758. }
  6759. bool AssertionResult::hasMessage() const {
  6760. return !m_resultData.message.empty();
  6761. }
  6762. std::string AssertionResult::getExpression() const {
  6763. // Possibly overallocating by 3 characters should be basically free
  6764. std::string expr; expr.reserve(m_info.capturedExpression.size() + 3);
  6765. if (isFalseTest(m_info.resultDisposition)) {
  6766. expr += "!(";
  6767. }
  6768. expr += m_info.capturedExpression;
  6769. if (isFalseTest(m_info.resultDisposition)) {
  6770. expr += ')';
  6771. }
  6772. return expr;
  6773. }
  6774. std::string AssertionResult::getExpressionInMacro() const {
  6775. std::string expr;
  6776. if( m_info.macroName.empty() )
  6777. expr = static_cast<std::string>(m_info.capturedExpression);
  6778. else {
  6779. expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
  6780. expr += m_info.macroName;
  6781. expr += "( ";
  6782. expr += m_info.capturedExpression;
  6783. expr += " )";
  6784. }
  6785. return expr;
  6786. }
  6787. bool AssertionResult::hasExpandedExpression() const {
  6788. return hasExpression() && getExpandedExpression() != getExpression();
  6789. }
  6790. std::string AssertionResult::getExpandedExpression() const {
  6791. std::string expr = m_resultData.reconstructExpression();
  6792. return expr.empty()
  6793. ? getExpression()
  6794. : expr;
  6795. }
  6796. std::string AssertionResult::getMessage() const {
  6797. return m_resultData.message;
  6798. }
  6799. SourceLineInfo AssertionResult::getSourceInfo() const {
  6800. return m_info.lineInfo;
  6801. }
  6802. StringRef AssertionResult::getTestMacroName() const {
  6803. return m_info.macroName;
  6804. }
  6805. } // end namespace Catch
  6806. // end catch_assertionresult.cpp
  6807. // start catch_capture_matchers.cpp
  6808. namespace Catch {
  6809. using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
  6810. // This is the general overload that takes a any string matcher
  6811. // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
  6812. // the Equals matcher (so the header does not mention matchers)
  6813. void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString ) {
  6814. std::string exceptionMessage = Catch::translateActiveException();
  6815. MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );
  6816. handler.handleExpr( expr );
  6817. }
  6818. } // namespace Catch
  6819. // end catch_capture_matchers.cpp
  6820. // start catch_commandline.cpp
  6821. // start catch_commandline.h
  6822. // start catch_clara.h
  6823. // Use Catch's value for console width (store Clara's off to the side, if present)
  6824. #ifdef CLARA_CONFIG_CONSOLE_WIDTH
  6825. #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
  6826. #undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
  6827. #endif
  6828. #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1
  6829. #ifdef __clang__
  6830. #pragma clang diagnostic push
  6831. #pragma clang diagnostic ignored "-Wweak-vtables"
  6832. #pragma clang diagnostic ignored "-Wexit-time-destructors"
  6833. #pragma clang diagnostic ignored "-Wshadow"
  6834. #endif
  6835. // start clara.hpp
  6836. // Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
  6837. //
  6838. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  6839. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6840. //
  6841. // See https://github.com/philsquared/Clara for more details
  6842. // Clara v1.1.5
  6843. #ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
  6844. #define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80
  6845. #endif
  6846. #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
  6847. #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH
  6848. #endif
  6849. #ifndef CLARA_CONFIG_OPTIONAL_TYPE
  6850. #ifdef __has_include
  6851. #if __has_include(<optional>) && __cplusplus >= 201703L
  6852. #include <optional>
  6853. #define CLARA_CONFIG_OPTIONAL_TYPE std::optional
  6854. #endif
  6855. #endif
  6856. #endif
  6857. // ----------- #included from clara_textflow.hpp -----------
  6858. // TextFlowCpp
  6859. //
  6860. // A single-header library for wrapping and laying out basic text, by Phil Nash
  6861. //
  6862. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  6863. // file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6864. //
  6865. // This project is hosted at https://github.com/philsquared/textflowcpp
  6866. #include <cassert>
  6867. #include <ostream>
  6868. #include <sstream>
  6869. #include <vector>
  6870. #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
  6871. #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80
  6872. #endif
  6873. namespace Catch {
  6874. namespace clara {
  6875. namespace TextFlow {
  6876. inline auto isWhitespace(char c) -> bool {
  6877. static std::string chars = " \t\n\r";
  6878. return chars.find(c) != std::string::npos;
  6879. }
  6880. inline auto isBreakableBefore(char c) -> bool {
  6881. static std::string chars = "[({<|";
  6882. return chars.find(c) != std::string::npos;
  6883. }
  6884. inline auto isBreakableAfter(char c) -> bool {
  6885. static std::string chars = "])}>.,:;*+-=&/\\";
  6886. return chars.find(c) != std::string::npos;
  6887. }
  6888. class Columns;
  6889. class Column {
  6890. std::vector<std::string> m_strings;
  6891. size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
  6892. size_t m_indent = 0;
  6893. size_t m_initialIndent = std::string::npos;
  6894. public:
  6895. class iterator {
  6896. friend Column;
  6897. Column const& m_column;
  6898. size_t m_stringIndex = 0;
  6899. size_t m_pos = 0;
  6900. size_t m_len = 0;
  6901. size_t m_end = 0;
  6902. bool m_suffix = false;
  6903. iterator(Column const& column, size_t stringIndex)
  6904. : m_column(column),
  6905. m_stringIndex(stringIndex) {}
  6906. auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
  6907. auto isBoundary(size_t at) const -> bool {
  6908. assert(at > 0);
  6909. assert(at <= line().size());
  6910. return at == line().size() ||
  6911. (isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) ||
  6912. isBreakableBefore(line()[at]) ||
  6913. isBreakableAfter(line()[at - 1]);
  6914. }
  6915. void calcLength() {
  6916. assert(m_stringIndex < m_column.m_strings.size());
  6917. m_suffix = false;
  6918. auto width = m_column.m_width - indent();
  6919. m_end = m_pos;
  6920. if (line()[m_pos] == '\n') {
  6921. ++m_end;
  6922. }
  6923. while (m_end < line().size() && line()[m_end] != '\n')
  6924. ++m_end;
  6925. if (m_end < m_pos + width) {
  6926. m_len = m_end - m_pos;
  6927. } else {
  6928. size_t len = width;
  6929. while (len > 0 && !isBoundary(m_pos + len))
  6930. --len;
  6931. while (len > 0 && isWhitespace(line()[m_pos + len - 1]))
  6932. --len;
  6933. if (len > 0) {
  6934. m_len = len;
  6935. } else {
  6936. m_suffix = true;
  6937. m_len = width - 1;
  6938. }
  6939. }
  6940. }
  6941. auto indent() const -> size_t {
  6942. auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
  6943. return initial == std::string::npos ? m_column.m_indent : initial;
  6944. }
  6945. auto addIndentAndSuffix(std::string const &plain) const -> std::string {
  6946. return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain);
  6947. }
  6948. public:
  6949. using difference_type = std::ptrdiff_t;
  6950. using value_type = std::string;
  6951. using pointer = value_type * ;
  6952. using reference = value_type & ;
  6953. using iterator_category = std::forward_iterator_tag;
  6954. explicit iterator(Column const& column) : m_column(column) {
  6955. assert(m_column.m_width > m_column.m_indent);
  6956. assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent);
  6957. calcLength();
  6958. if (m_len == 0)
  6959. m_stringIndex++; // Empty string
  6960. }
  6961. auto operator *() const -> std::string {
  6962. assert(m_stringIndex < m_column.m_strings.size());
  6963. assert(m_pos <= m_end);
  6964. return addIndentAndSuffix(line().substr(m_pos, m_len));
  6965. }
  6966. auto operator ++() -> iterator& {
  6967. m_pos += m_len;
  6968. if (m_pos < line().size() && line()[m_pos] == '\n')
  6969. m_pos += 1;
  6970. else
  6971. while (m_pos < line().size() && isWhitespace(line()[m_pos]))
  6972. ++m_pos;
  6973. if (m_pos == line().size()) {
  6974. m_pos = 0;
  6975. ++m_stringIndex;
  6976. }
  6977. if (m_stringIndex < m_column.m_strings.size())
  6978. calcLength();
  6979. return *this;
  6980. }
  6981. auto operator ++(int) -> iterator {
  6982. iterator prev(*this);
  6983. operator++();
  6984. return prev;
  6985. }
  6986. auto operator ==(iterator const& other) const -> bool {
  6987. return
  6988. m_pos == other.m_pos &&
  6989. m_stringIndex == other.m_stringIndex &&
  6990. &m_column == &other.m_column;
  6991. }
  6992. auto operator !=(iterator const& other) const -> bool {
  6993. return !operator==(other);
  6994. }
  6995. };
  6996. using const_iterator = iterator;
  6997. explicit Column(std::string const& text) { m_strings.push_back(text); }
  6998. auto width(size_t newWidth) -> Column& {
  6999. assert(newWidth > 0);
  7000. m_width = newWidth;
  7001. return *this;
  7002. }
  7003. auto indent(size_t newIndent) -> Column& {
  7004. m_indent = newIndent;
  7005. return *this;
  7006. }
  7007. auto initialIndent(size_t newIndent) -> Column& {
  7008. m_initialIndent = newIndent;
  7009. return *this;
  7010. }
  7011. auto width() const -> size_t { return m_width; }
  7012. auto begin() const -> iterator { return iterator(*this); }
  7013. auto end() const -> iterator { return { *this, m_strings.size() }; }
  7014. inline friend std::ostream& operator << (std::ostream& os, Column const& col) {
  7015. bool first = true;
  7016. for (auto line : col) {
  7017. if (first)
  7018. first = false;
  7019. else
  7020. os << "\n";
  7021. os << line;
  7022. }
  7023. return os;
  7024. }
  7025. auto operator + (Column const& other)->Columns;
  7026. auto toString() const -> std::string {
  7027. std::ostringstream oss;
  7028. oss << *this;
  7029. return oss.str();
  7030. }
  7031. };
  7032. class Spacer : public Column {
  7033. public:
  7034. explicit Spacer(size_t spaceWidth) : Column("") {
  7035. width(spaceWidth);
  7036. }
  7037. };
  7038. class Columns {
  7039. std::vector<Column> m_columns;
  7040. public:
  7041. class iterator {
  7042. friend Columns;
  7043. struct EndTag {};
  7044. std::vector<Column> const& m_columns;
  7045. std::vector<Column::iterator> m_iterators;
  7046. size_t m_activeIterators;
  7047. iterator(Columns const& columns, EndTag)
  7048. : m_columns(columns.m_columns),
  7049. m_activeIterators(0) {
  7050. m_iterators.reserve(m_columns.size());
  7051. for (auto const& col : m_columns)
  7052. m_iterators.push_back(col.end());
  7053. }
  7054. public:
  7055. using difference_type = std::ptrdiff_t;
  7056. using value_type = std::string;
  7057. using pointer = value_type * ;
  7058. using reference = value_type & ;
  7059. using iterator_category = std::forward_iterator_tag;
  7060. explicit iterator(Columns const& columns)
  7061. : m_columns(columns.m_columns),
  7062. m_activeIterators(m_columns.size()) {
  7063. m_iterators.reserve(m_columns.size());
  7064. for (auto const& col : m_columns)
  7065. m_iterators.push_back(col.begin());
  7066. }
  7067. auto operator ==(iterator const& other) const -> bool {
  7068. return m_iterators == other.m_iterators;
  7069. }
  7070. auto operator !=(iterator const& other) const -> bool {
  7071. return m_iterators != other.m_iterators;
  7072. }
  7073. auto operator *() const -> std::string {
  7074. std::string row, padding;
  7075. for (size_t i = 0; i < m_columns.size(); ++i) {
  7076. auto width = m_columns[i].width();
  7077. if (m_iterators[i] != m_columns[i].end()) {
  7078. std::string col = *m_iterators[i];
  7079. row += padding + col;
  7080. if (col.size() < width)
  7081. padding = std::string(width - col.size(), ' ');
  7082. else
  7083. padding = "";
  7084. } else {
  7085. padding += std::string(width, ' ');
  7086. }
  7087. }
  7088. return row;
  7089. }
  7090. auto operator ++() -> iterator& {
  7091. for (size_t i = 0; i < m_columns.size(); ++i) {
  7092. if (m_iterators[i] != m_columns[i].end())
  7093. ++m_iterators[i];
  7094. }
  7095. return *this;
  7096. }
  7097. auto operator ++(int) -> iterator {
  7098. iterator prev(*this);
  7099. operator++();
  7100. return prev;
  7101. }
  7102. };
  7103. using const_iterator = iterator;
  7104. auto begin() const -> iterator { return iterator(*this); }
  7105. auto end() const -> iterator { return { *this, iterator::EndTag() }; }
  7106. auto operator += (Column const& col) -> Columns& {
  7107. m_columns.push_back(col);
  7108. return *this;
  7109. }
  7110. auto operator + (Column const& col) -> Columns {
  7111. Columns combined = *this;
  7112. combined += col;
  7113. return combined;
  7114. }
  7115. inline friend std::ostream& operator << (std::ostream& os, Columns const& cols) {
  7116. bool first = true;
  7117. for (auto line : cols) {
  7118. if (first)
  7119. first = false;
  7120. else
  7121. os << "\n";
  7122. os << line;
  7123. }
  7124. return os;
  7125. }
  7126. auto toString() const -> std::string {
  7127. std::ostringstream oss;
  7128. oss << *this;
  7129. return oss.str();
  7130. }
  7131. };
  7132. inline auto Column::operator + (Column const& other) -> Columns {
  7133. Columns cols;
  7134. cols += *this;
  7135. cols += other;
  7136. return cols;
  7137. }
  7138. }
  7139. }
  7140. }
  7141. // ----------- end of #include from clara_textflow.hpp -----------
  7142. // ........... back in clara.hpp
  7143. #include <cctype>
  7144. #include <string>
  7145. #include <memory>
  7146. #include <set>
  7147. #include <algorithm>
  7148. #if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) )
  7149. #define CATCH_PLATFORM_WINDOWS
  7150. #endif
  7151. namespace Catch { namespace clara {
  7152. namespace detail {
  7153. // Traits for extracting arg and return type of lambdas (for single argument lambdas)
  7154. template<typename L>
  7155. struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {};
  7156. template<typename ClassT, typename ReturnT, typename... Args>
  7157. struct UnaryLambdaTraits<ReturnT( ClassT::* )( Args... ) const> {
  7158. static const bool isValid = false;
  7159. };
  7160. template<typename ClassT, typename ReturnT, typename ArgT>
  7161. struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
  7162. static const bool isValid = true;
  7163. using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;
  7164. using ReturnType = ReturnT;
  7165. };
  7166. class TokenStream;
  7167. // Transport for raw args (copied from main args, or supplied via init list for testing)
  7168. class Args {
  7169. friend TokenStream;
  7170. std::string m_exeName;
  7171. std::vector<std::string> m_args;
  7172. public:
  7173. Args( int argc, char const* const* argv )
  7174. : m_exeName(argv[0]),
  7175. m_args(argv + 1, argv + argc) {}
  7176. Args( std::initializer_list<std::string> args )
  7177. : m_exeName( *args.begin() ),
  7178. m_args( args.begin()+1, args.end() )
  7179. {}
  7180. auto exeName() const -> std::string {
  7181. return m_exeName;
  7182. }
  7183. };
  7184. // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string
  7185. // may encode an option + its argument if the : or = form is used
  7186. enum class TokenType {
  7187. Option, Argument
  7188. };
  7189. struct Token {
  7190. TokenType type;
  7191. std::string token;
  7192. };
  7193. inline auto isOptPrefix( char c ) -> bool {
  7194. return c == '-'
  7195. #ifdef CATCH_PLATFORM_WINDOWS
  7196. || c == '/'
  7197. #endif
  7198. ;
  7199. }
  7200. // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
  7201. class TokenStream {
  7202. using Iterator = std::vector<std::string>::const_iterator;
  7203. Iterator it;
  7204. Iterator itEnd;
  7205. std::vector<Token> m_tokenBuffer;
  7206. void loadBuffer() {
  7207. m_tokenBuffer.resize( 0 );
  7208. // Skip any empty strings
  7209. while( it != itEnd && it->empty() )
  7210. ++it;
  7211. if( it != itEnd ) {
  7212. auto const &next = *it;
  7213. if( isOptPrefix( next[0] ) ) {
  7214. auto delimiterPos = next.find_first_of( " :=" );
  7215. if( delimiterPos != std::string::npos ) {
  7216. m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
  7217. m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } );
  7218. } else {
  7219. if( next[1] != '-' && next.size() > 2 ) {
  7220. std::string opt = "- ";
  7221. for( size_t i = 1; i < next.size(); ++i ) {
  7222. opt[1] = next[i];
  7223. m_tokenBuffer.push_back( { TokenType::Option, opt } );
  7224. }
  7225. } else {
  7226. m_tokenBuffer.push_back( { TokenType::Option, next } );
  7227. }
  7228. }
  7229. } else {
  7230. m_tokenBuffer.push_back( { TokenType::Argument, next } );
  7231. }
  7232. }
  7233. }
  7234. public:
  7235. explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {}
  7236. TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) {
  7237. loadBuffer();
  7238. }
  7239. explicit operator bool() const {
  7240. return !m_tokenBuffer.empty() || it != itEnd;
  7241. }
  7242. auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); }
  7243. auto operator*() const -> Token {
  7244. assert( !m_tokenBuffer.empty() );
  7245. return m_tokenBuffer.front();
  7246. }
  7247. auto operator->() const -> Token const * {
  7248. assert( !m_tokenBuffer.empty() );
  7249. return &m_tokenBuffer.front();
  7250. }
  7251. auto operator++() -> TokenStream & {
  7252. if( m_tokenBuffer.size() >= 2 ) {
  7253. m_tokenBuffer.erase( m_tokenBuffer.begin() );
  7254. } else {
  7255. if( it != itEnd )
  7256. ++it;
  7257. loadBuffer();
  7258. }
  7259. return *this;
  7260. }
  7261. };
  7262. class ResultBase {
  7263. public:
  7264. enum Type {
  7265. Ok, LogicError, RuntimeError
  7266. };
  7267. protected:
  7268. ResultBase( Type type ) : m_type( type ) {}
  7269. virtual ~ResultBase() = default;
  7270. virtual void enforceOk() const = 0;
  7271. Type m_type;
  7272. };
  7273. template<typename T>
  7274. class ResultValueBase : public ResultBase {
  7275. public:
  7276. auto value() const -> T const & {
  7277. enforceOk();
  7278. return m_value;
  7279. }
  7280. protected:
  7281. ResultValueBase( Type type ) : ResultBase( type ) {}
  7282. ResultValueBase( ResultValueBase const &other ) : ResultBase( other ) {
  7283. if( m_type == ResultBase::Ok )
  7284. new( &m_value ) T( other.m_value );
  7285. }
  7286. ResultValueBase( Type, T const &value ) : ResultBase( Ok ) {
  7287. new( &m_value ) T( value );
  7288. }
  7289. auto operator=( ResultValueBase const &other ) -> ResultValueBase & {
  7290. if( m_type == ResultBase::Ok )
  7291. m_value.~T();
  7292. ResultBase::operator=(other);
  7293. if( m_type == ResultBase::Ok )
  7294. new( &m_value ) T( other.m_value );
  7295. return *this;
  7296. }
  7297. ~ResultValueBase() override {
  7298. if( m_type == Ok )
  7299. m_value.~T();
  7300. }
  7301. union {
  7302. T m_value;
  7303. };
  7304. };
  7305. template<>
  7306. class ResultValueBase<void> : public ResultBase {
  7307. protected:
  7308. using ResultBase::ResultBase;
  7309. };
  7310. template<typename T = void>
  7311. class BasicResult : public ResultValueBase<T> {
  7312. public:
  7313. template<typename U>
  7314. explicit BasicResult( BasicResult<U> const &other )
  7315. : ResultValueBase<T>( other.type() ),
  7316. m_errorMessage( other.errorMessage() )
  7317. {
  7318. assert( type() != ResultBase::Ok );
  7319. }
  7320. template<typename U>
  7321. static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; }
  7322. static auto ok() -> BasicResult { return { ResultBase::Ok }; }
  7323. static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; }
  7324. static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; }
  7325. explicit operator bool() const { return m_type == ResultBase::Ok; }
  7326. auto type() const -> ResultBase::Type { return m_type; }
  7327. auto errorMessage() const -> std::string { return m_errorMessage; }
  7328. protected:
  7329. void enforceOk() const override {
  7330. // Errors shouldn't reach this point, but if they do
  7331. // the actual error message will be in m_errorMessage
  7332. assert( m_type != ResultBase::LogicError );
  7333. assert( m_type != ResultBase::RuntimeError );
  7334. if( m_type != ResultBase::Ok )
  7335. std::abort();
  7336. }
  7337. std::string m_errorMessage; // Only populated if resultType is an error
  7338. BasicResult( ResultBase::Type type, std::string const &message )
  7339. : ResultValueBase<T>(type),
  7340. m_errorMessage(message)
  7341. {
  7342. assert( m_type != ResultBase::Ok );
  7343. }
  7344. using ResultValueBase<T>::ResultValueBase;
  7345. using ResultBase::m_type;
  7346. };
  7347. enum class ParseResultType {
  7348. Matched, NoMatch, ShortCircuitAll, ShortCircuitSame
  7349. };
  7350. class ParseState {
  7351. public:
  7352. ParseState( ParseResultType type, TokenStream const &remainingTokens )
  7353. : m_type(type),
  7354. m_remainingTokens( remainingTokens )
  7355. {}
  7356. auto type() const -> ParseResultType { return m_type; }
  7357. auto remainingTokens() const -> TokenStream { return m_remainingTokens; }
  7358. private:
  7359. ParseResultType m_type;
  7360. TokenStream m_remainingTokens;
  7361. };
  7362. using Result = BasicResult<void>;
  7363. using ParserResult = BasicResult<ParseResultType>;
  7364. using InternalParseResult = BasicResult<ParseState>;
  7365. struct HelpColumns {
  7366. std::string left;
  7367. std::string right;
  7368. };
  7369. template<typename T>
  7370. inline auto convertInto( std::string const &source, T& target ) -> ParserResult {
  7371. std::stringstream ss;
  7372. ss << source;
  7373. ss >> target;
  7374. if( ss.fail() )
  7375. return ParserResult::runtimeError( "Unable to convert '" + source + "' to destination type" );
  7376. else
  7377. return ParserResult::ok( ParseResultType::Matched );
  7378. }
  7379. inline auto convertInto( std::string const &source, std::string& target ) -> ParserResult {
  7380. target = source;
  7381. return ParserResult::ok( ParseResultType::Matched );
  7382. }
  7383. inline auto convertInto( std::string const &source, bool &target ) -> ParserResult {
  7384. std::string srcLC = source;
  7385. std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( unsigned char c ) { return static_cast<char>( std::tolower(c) ); } );
  7386. if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
  7387. target = true;
  7388. else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
  7389. target = false;
  7390. else
  7391. return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" );
  7392. return ParserResult::ok( ParseResultType::Matched );
  7393. }
  7394. #ifdef CLARA_CONFIG_OPTIONAL_TYPE
  7395. template<typename T>
  7396. inline auto convertInto( std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target ) -> ParserResult {
  7397. T temp;
  7398. auto result = convertInto( source, temp );
  7399. if( result )
  7400. target = std::move(temp);
  7401. return result;
  7402. }
  7403. #endif // CLARA_CONFIG_OPTIONAL_TYPE
  7404. struct NonCopyable {
  7405. NonCopyable() = default;
  7406. NonCopyable( NonCopyable const & ) = delete;
  7407. NonCopyable( NonCopyable && ) = delete;
  7408. NonCopyable &operator=( NonCopyable const & ) = delete;
  7409. NonCopyable &operator=( NonCopyable && ) = delete;
  7410. };
  7411. struct BoundRef : NonCopyable {
  7412. virtual ~BoundRef() = default;
  7413. virtual auto isContainer() const -> bool { return false; }
  7414. virtual auto isFlag() const -> bool { return false; }
  7415. };
  7416. struct BoundValueRefBase : BoundRef {
  7417. virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
  7418. };
  7419. struct BoundFlagRefBase : BoundRef {
  7420. virtual auto setFlag( bool flag ) -> ParserResult = 0;
  7421. virtual auto isFlag() const -> bool { return true; }
  7422. };
  7423. template<typename T>
  7424. struct BoundValueRef : BoundValueRefBase {
  7425. T &m_ref;
  7426. explicit BoundValueRef( T &ref ) : m_ref( ref ) {}
  7427. auto setValue( std::string const &arg ) -> ParserResult override {
  7428. return convertInto( arg, m_ref );
  7429. }
  7430. };
  7431. template<typename T>
  7432. struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
  7433. std::vector<T> &m_ref;
  7434. explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {}
  7435. auto isContainer() const -> bool override { return true; }
  7436. auto setValue( std::string const &arg ) -> ParserResult override {
  7437. T temp;
  7438. auto result = convertInto( arg, temp );
  7439. if( result )
  7440. m_ref.push_back( temp );
  7441. return result;
  7442. }
  7443. };
  7444. struct BoundFlagRef : BoundFlagRefBase {
  7445. bool &m_ref;
  7446. explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {}
  7447. auto setFlag( bool flag ) -> ParserResult override {
  7448. m_ref = flag;
  7449. return ParserResult::ok( ParseResultType::Matched );
  7450. }
  7451. };
  7452. template<typename ReturnType>
  7453. struct LambdaInvoker {
  7454. static_assert( std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult" );
  7455. template<typename L, typename ArgType>
  7456. static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
  7457. return lambda( arg );
  7458. }
  7459. };
  7460. template<>
  7461. struct LambdaInvoker<void> {
  7462. template<typename L, typename ArgType>
  7463. static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
  7464. lambda( arg );
  7465. return ParserResult::ok( ParseResultType::Matched );
  7466. }
  7467. };
  7468. template<typename ArgType, typename L>
  7469. inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
  7470. ArgType temp{};
  7471. auto result = convertInto( arg, temp );
  7472. return !result
  7473. ? result
  7474. : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
  7475. }
  7476. template<typename L>
  7477. struct BoundLambda : BoundValueRefBase {
  7478. L m_lambda;
  7479. static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
  7480. explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {}
  7481. auto setValue( std::string const &arg ) -> ParserResult override {
  7482. return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>( m_lambda, arg );
  7483. }
  7484. };
  7485. template<typename L>
  7486. struct BoundFlagLambda : BoundFlagRefBase {
  7487. L m_lambda;
  7488. static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
  7489. static_assert( std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, "flags must be boolean" );
  7490. explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {}
  7491. auto setFlag( bool flag ) -> ParserResult override {
  7492. return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( m_lambda, flag );
  7493. }
  7494. };
  7495. enum class Optionality { Optional, Required };
  7496. struct Parser;
  7497. class ParserBase {
  7498. public:
  7499. virtual ~ParserBase() = default;
  7500. virtual auto validate() const -> Result { return Result::ok(); }
  7501. virtual auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult = 0;
  7502. virtual auto cardinality() const -> size_t { return 1; }
  7503. auto parse( Args const &args ) const -> InternalParseResult {
  7504. return parse( args.exeName(), TokenStream( args ) );
  7505. }
  7506. };
  7507. template<typename DerivedT>
  7508. class ComposableParserImpl : public ParserBase {
  7509. public:
  7510. template<typename T>
  7511. auto operator|( T const &other ) const -> Parser;
  7512. template<typename T>
  7513. auto operator+( T const &other ) const -> Parser;
  7514. };
  7515. // Common code and state for Args and Opts
  7516. template<typename DerivedT>
  7517. class ParserRefImpl : public ComposableParserImpl<DerivedT> {
  7518. protected:
  7519. Optionality m_optionality = Optionality::Optional;
  7520. std::shared_ptr<BoundRef> m_ref;
  7521. std::string m_hint;
  7522. std::string m_description;
  7523. explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {}
  7524. public:
  7525. template<typename T>
  7526. ParserRefImpl( T &ref, std::string const &hint )
  7527. : m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
  7528. m_hint( hint )
  7529. {}
  7530. template<typename LambdaT>
  7531. ParserRefImpl( LambdaT const &ref, std::string const &hint )
  7532. : m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),
  7533. m_hint(hint)
  7534. {}
  7535. auto operator()( std::string const &description ) -> DerivedT & {
  7536. m_description = description;
  7537. return static_cast<DerivedT &>( *this );
  7538. }
  7539. auto optional() -> DerivedT & {
  7540. m_optionality = Optionality::Optional;
  7541. return static_cast<DerivedT &>( *this );
  7542. };
  7543. auto required() -> DerivedT & {
  7544. m_optionality = Optionality::Required;
  7545. return static_cast<DerivedT &>( *this );
  7546. };
  7547. auto isOptional() const -> bool {
  7548. return m_optionality == Optionality::Optional;
  7549. }
  7550. auto cardinality() const -> size_t override {
  7551. if( m_ref->isContainer() )
  7552. return 0;
  7553. else
  7554. return 1;
  7555. }
  7556. auto hint() const -> std::string { return m_hint; }
  7557. };
  7558. class ExeName : public ComposableParserImpl<ExeName> {
  7559. std::shared_ptr<std::string> m_name;
  7560. std::shared_ptr<BoundValueRefBase> m_ref;
  7561. template<typename LambdaT>
  7562. static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {
  7563. return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
  7564. }
  7565. public:
  7566. ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
  7567. explicit ExeName( std::string &ref ) : ExeName() {
  7568. m_ref = std::make_shared<BoundValueRef<std::string>>( ref );
  7569. }
  7570. template<typename LambdaT>
  7571. explicit ExeName( LambdaT const& lambda ) : ExeName() {
  7572. m_ref = std::make_shared<BoundLambda<LambdaT>>( lambda );
  7573. }
  7574. // The exe name is not parsed out of the normal tokens, but is handled specially
  7575. auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
  7576. return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
  7577. }
  7578. auto name() const -> std::string { return *m_name; }
  7579. auto set( std::string const& newName ) -> ParserResult {
  7580. auto lastSlash = newName.find_last_of( "\\/" );
  7581. auto filename = ( lastSlash == std::string::npos )
  7582. ? newName
  7583. : newName.substr( lastSlash+1 );
  7584. *m_name = filename;
  7585. if( m_ref )
  7586. return m_ref->setValue( filename );
  7587. else
  7588. return ParserResult::ok( ParseResultType::Matched );
  7589. }
  7590. };
  7591. class Arg : public ParserRefImpl<Arg> {
  7592. public:
  7593. using ParserRefImpl::ParserRefImpl;
  7594. auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override {
  7595. auto validationResult = validate();
  7596. if( !validationResult )
  7597. return InternalParseResult( validationResult );
  7598. auto remainingTokens = tokens;
  7599. auto const &token = *remainingTokens;
  7600. if( token.type != TokenType::Argument )
  7601. return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
  7602. assert( !m_ref->isFlag() );
  7603. auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
  7604. auto result = valueRef->setValue( remainingTokens->token );
  7605. if( !result )
  7606. return InternalParseResult( result );
  7607. else
  7608. return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
  7609. }
  7610. };
  7611. inline auto normaliseOpt( std::string const &optName ) -> std::string {
  7612. #ifdef CATCH_PLATFORM_WINDOWS
  7613. if( optName[0] == '/' )
  7614. return "-" + optName.substr( 1 );
  7615. else
  7616. #endif
  7617. return optName;
  7618. }
  7619. class Opt : public ParserRefImpl<Opt> {
  7620. protected:
  7621. std::vector<std::string> m_optNames;
  7622. public:
  7623. template<typename LambdaT>
  7624. explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared<BoundFlagLambda<LambdaT>>( ref ) ) {}
  7625. explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared<BoundFlagRef>( ref ) ) {}
  7626. template<typename LambdaT>
  7627. Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
  7628. template<typename T>
  7629. Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
  7630. auto operator[]( std::string const &optName ) -> Opt & {
  7631. m_optNames.push_back( optName );
  7632. return *this;
  7633. }
  7634. auto getHelpColumns() const -> std::vector<HelpColumns> {
  7635. std::ostringstream oss;
  7636. bool first = true;
  7637. for( auto const &opt : m_optNames ) {
  7638. if (first)
  7639. first = false;
  7640. else
  7641. oss << ", ";
  7642. oss << opt;
  7643. }
  7644. if( !m_hint.empty() )
  7645. oss << " <" << m_hint << ">";
  7646. return { { oss.str(), m_description } };
  7647. }
  7648. auto isMatch( std::string const &optToken ) const -> bool {
  7649. auto normalisedToken = normaliseOpt( optToken );
  7650. for( auto const &name : m_optNames ) {
  7651. if( normaliseOpt( name ) == normalisedToken )
  7652. return true;
  7653. }
  7654. return false;
  7655. }
  7656. using ParserBase::parse;
  7657. auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
  7658. auto validationResult = validate();
  7659. if( !validationResult )
  7660. return InternalParseResult( validationResult );
  7661. auto remainingTokens = tokens;
  7662. if( remainingTokens && remainingTokens->type == TokenType::Option ) {
  7663. auto const &token = *remainingTokens;
  7664. if( isMatch(token.token ) ) {
  7665. if( m_ref->isFlag() ) {
  7666. auto flagRef = static_cast<detail::BoundFlagRefBase*>( m_ref.get() );
  7667. auto result = flagRef->setFlag( true );
  7668. if( !result )
  7669. return InternalParseResult( result );
  7670. if( result.value() == ParseResultType::ShortCircuitAll )
  7671. return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
  7672. } else {
  7673. auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
  7674. ++remainingTokens;
  7675. if( !remainingTokens )
  7676. return InternalParseResult::runtimeError( "Expected argument following " + token.token );
  7677. auto const &argToken = *remainingTokens;
  7678. if( argToken.type != TokenType::Argument )
  7679. return InternalParseResult::runtimeError( "Expected argument following " + token.token );
  7680. auto result = valueRef->setValue( argToken.token );
  7681. if( !result )
  7682. return InternalParseResult( result );
  7683. if( result.value() == ParseResultType::ShortCircuitAll )
  7684. return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
  7685. }
  7686. return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
  7687. }
  7688. }
  7689. return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
  7690. }
  7691. auto validate() const -> Result override {
  7692. if( m_optNames.empty() )
  7693. return Result::logicError( "No options supplied to Opt" );
  7694. for( auto const &name : m_optNames ) {
  7695. if( name.empty() )
  7696. return Result::logicError( "Option name cannot be empty" );
  7697. #ifdef CATCH_PLATFORM_WINDOWS
  7698. if( name[0] != '-' && name[0] != '/' )
  7699. return Result::logicError( "Option name must begin with '-' or '/'" );
  7700. #else
  7701. if( name[0] != '-' )
  7702. return Result::logicError( "Option name must begin with '-'" );
  7703. #endif
  7704. }
  7705. return ParserRefImpl::validate();
  7706. }
  7707. };
  7708. struct Help : Opt {
  7709. Help( bool &showHelpFlag )
  7710. : Opt([&]( bool flag ) {
  7711. showHelpFlag = flag;
  7712. return ParserResult::ok( ParseResultType::ShortCircuitAll );
  7713. })
  7714. {
  7715. static_cast<Opt &>( *this )
  7716. ("display usage information")
  7717. ["-?"]["-h"]["--help"]
  7718. .optional();
  7719. }
  7720. };
  7721. struct Parser : ParserBase {
  7722. mutable ExeName m_exeName;
  7723. std::vector<Opt> m_options;
  7724. std::vector<Arg> m_args;
  7725. auto operator|=( ExeName const &exeName ) -> Parser & {
  7726. m_exeName = exeName;
  7727. return *this;
  7728. }
  7729. auto operator|=( Arg const &arg ) -> Parser & {
  7730. m_args.push_back(arg);
  7731. return *this;
  7732. }
  7733. auto operator|=( Opt const &opt ) -> Parser & {
  7734. m_options.push_back(opt);
  7735. return *this;
  7736. }
  7737. auto operator|=( Parser const &other ) -> Parser & {
  7738. m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
  7739. m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
  7740. return *this;
  7741. }
  7742. template<typename T>
  7743. auto operator|( T const &other ) const -> Parser {
  7744. return Parser( *this ) |= other;
  7745. }
  7746. // Forward deprecated interface with '+' instead of '|'
  7747. template<typename T>
  7748. auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }
  7749. template<typename T>
  7750. auto operator+( T const &other ) const -> Parser { return operator|( other ); }
  7751. auto getHelpColumns() const -> std::vector<HelpColumns> {
  7752. std::vector<HelpColumns> cols;
  7753. for (auto const &o : m_options) {
  7754. auto childCols = o.getHelpColumns();
  7755. cols.insert( cols.end(), childCols.begin(), childCols.end() );
  7756. }
  7757. return cols;
  7758. }
  7759. void writeToStream( std::ostream &os ) const {
  7760. if (!m_exeName.name().empty()) {
  7761. os << "usage:\n" << " " << m_exeName.name() << " ";
  7762. bool required = true, first = true;
  7763. for( auto const &arg : m_args ) {
  7764. if (first)
  7765. first = false;
  7766. else
  7767. os << " ";
  7768. if( arg.isOptional() && required ) {
  7769. os << "[";
  7770. required = false;
  7771. }
  7772. os << "<" << arg.hint() << ">";
  7773. if( arg.cardinality() == 0 )
  7774. os << " ... ";
  7775. }
  7776. if( !required )
  7777. os << "]";
  7778. if( !m_options.empty() )
  7779. os << " options";
  7780. os << "\n\nwhere options are:" << std::endl;
  7781. }
  7782. auto rows = getHelpColumns();
  7783. size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
  7784. size_t optWidth = 0;
  7785. for( auto const &cols : rows )
  7786. optWidth = (std::max)(optWidth, cols.left.size() + 2);
  7787. optWidth = (std::min)(optWidth, consoleWidth/2);
  7788. for( auto const &cols : rows ) {
  7789. auto row =
  7790. TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
  7791. TextFlow::Spacer(4) +
  7792. TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth );
  7793. os << row << std::endl;
  7794. }
  7795. }
  7796. friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream& {
  7797. parser.writeToStream( os );
  7798. return os;
  7799. }
  7800. auto validate() const -> Result override {
  7801. for( auto const &opt : m_options ) {
  7802. auto result = opt.validate();
  7803. if( !result )
  7804. return result;
  7805. }
  7806. for( auto const &arg : m_args ) {
  7807. auto result = arg.validate();
  7808. if( !result )
  7809. return result;
  7810. }
  7811. return Result::ok();
  7812. }
  7813. using ParserBase::parse;
  7814. auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override {
  7815. struct ParserInfo {
  7816. ParserBase const* parser = nullptr;
  7817. size_t count = 0;
  7818. };
  7819. const size_t totalParsers = m_options.size() + m_args.size();
  7820. assert( totalParsers < 512 );
  7821. // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do
  7822. ParserInfo parseInfos[512];
  7823. {
  7824. size_t i = 0;
  7825. for (auto const &opt : m_options) parseInfos[i++].parser = &opt;
  7826. for (auto const &arg : m_args) parseInfos[i++].parser = &arg;
  7827. }
  7828. m_exeName.set( exeName );
  7829. auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
  7830. while( result.value().remainingTokens() ) {
  7831. bool tokenParsed = false;
  7832. for( size_t i = 0; i < totalParsers; ++i ) {
  7833. auto& parseInfo = parseInfos[i];
  7834. if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) {
  7835. result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
  7836. if (!result)
  7837. return result;
  7838. if (result.value().type() != ParseResultType::NoMatch) {
  7839. tokenParsed = true;
  7840. ++parseInfo.count;
  7841. break;
  7842. }
  7843. }
  7844. }
  7845. if( result.value().type() == ParseResultType::ShortCircuitAll )
  7846. return result;
  7847. if( !tokenParsed )
  7848. return InternalParseResult::runtimeError( "Unrecognised token: " + result.value().remainingTokens()->token );
  7849. }
  7850. // !TBD Check missing required options
  7851. return result;
  7852. }
  7853. };
  7854. template<typename DerivedT>
  7855. template<typename T>
  7856. auto ComposableParserImpl<DerivedT>::operator|( T const &other ) const -> Parser {
  7857. return Parser() | static_cast<DerivedT const &>( *this ) | other;
  7858. }
  7859. } // namespace detail
  7860. // A Combined parser
  7861. using detail::Parser;
  7862. // A parser for options
  7863. using detail::Opt;
  7864. // A parser for arguments
  7865. using detail::Arg;
  7866. // Wrapper for argc, argv from main()
  7867. using detail::Args;
  7868. // Specifies the name of the executable
  7869. using detail::ExeName;
  7870. // Convenience wrapper for option parser that specifies the help option
  7871. using detail::Help;
  7872. // enum of result types from a parse
  7873. using detail::ParseResultType;
  7874. // Result type for parser operation
  7875. using detail::ParserResult;
  7876. }} // namespace Catch::clara
  7877. // end clara.hpp
  7878. #ifdef __clang__
  7879. #pragma clang diagnostic pop
  7880. #endif
  7881. // Restore Clara's value for console width, if present
  7882. #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
  7883. #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
  7884. #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
  7885. #endif
  7886. // end catch_clara.h
  7887. namespace Catch {
  7888. clara::Parser makeCommandLineParser( ConfigData& config );
  7889. } // end namespace Catch
  7890. // end catch_commandline.h
  7891. #include <fstream>
  7892. #include <ctime>
  7893. namespace Catch {
  7894. clara::Parser makeCommandLineParser( ConfigData& config ) {
  7895. using namespace clara;
  7896. auto const setWarning = [&]( std::string const& warning ) {
  7897. auto warningSet = [&]() {
  7898. if( warning == "NoAssertions" )
  7899. return WarnAbout::NoAssertions;
  7900. if ( warning == "NoTests" )
  7901. return WarnAbout::NoTests;
  7902. return WarnAbout::Nothing;
  7903. }();
  7904. if (warningSet == WarnAbout::Nothing)
  7905. return ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" );
  7906. config.warnings = static_cast<WarnAbout::What>( config.warnings | warningSet );
  7907. return ParserResult::ok( ParseResultType::Matched );
  7908. };
  7909. auto const loadTestNamesFromFile = [&]( std::string const& filename ) {
  7910. std::ifstream f( filename.c_str() );
  7911. if( !f.is_open() )
  7912. return ParserResult::runtimeError( "Unable to load input file: '" + filename + "'" );
  7913. std::string line;
  7914. while( std::getline( f, line ) ) {
  7915. line = trim(line);
  7916. if( !line.empty() && !startsWith( line, '#' ) ) {
  7917. if( !startsWith( line, '"' ) )
  7918. line = '"' + line + '"';
  7919. config.testsOrTags.push_back( line );
  7920. config.testsOrTags.emplace_back( "," );
  7921. }
  7922. }
  7923. //Remove comma in the end
  7924. if(!config.testsOrTags.empty())
  7925. config.testsOrTags.erase( config.testsOrTags.end()-1 );
  7926. return ParserResult::ok( ParseResultType::Matched );
  7927. };
  7928. auto const setTestOrder = [&]( std::string const& order ) {
  7929. if( startsWith( "declared", order ) )
  7930. config.runOrder = RunTests::InDeclarationOrder;
  7931. else if( startsWith( "lexical", order ) )
  7932. config.runOrder = RunTests::InLexicographicalOrder;
  7933. else if( startsWith( "random", order ) )
  7934. config.runOrder = RunTests::InRandomOrder;
  7935. else
  7936. return clara::ParserResult::runtimeError( "Unrecognised ordering: '" + order + "'" );
  7937. return ParserResult::ok( ParseResultType::Matched );
  7938. };
  7939. auto const setRngSeed = [&]( std::string const& seed ) {
  7940. if( seed != "time" )
  7941. return clara::detail::convertInto( seed, config.rngSeed );
  7942. config.rngSeed = static_cast<unsigned int>( std::time(nullptr) );
  7943. return ParserResult::ok( ParseResultType::Matched );
  7944. };
  7945. auto const setColourUsage = [&]( std::string const& useColour ) {
  7946. auto mode = toLower( useColour );
  7947. if( mode == "yes" )
  7948. config.useColour = UseColour::Yes;
  7949. else if( mode == "no" )
  7950. config.useColour = UseColour::No;
  7951. else if( mode == "auto" )
  7952. config.useColour = UseColour::Auto;
  7953. else
  7954. return ParserResult::runtimeError( "colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised" );
  7955. return ParserResult::ok( ParseResultType::Matched );
  7956. };
  7957. auto const setWaitForKeypress = [&]( std::string const& keypress ) {
  7958. auto keypressLc = toLower( keypress );
  7959. if (keypressLc == "never")
  7960. config.waitForKeypress = WaitForKeypress::Never;
  7961. else if( keypressLc == "start" )
  7962. config.waitForKeypress = WaitForKeypress::BeforeStart;
  7963. else if( keypressLc == "exit" )
  7964. config.waitForKeypress = WaitForKeypress::BeforeExit;
  7965. else if( keypressLc == "both" )
  7966. config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
  7967. else
  7968. return ParserResult::runtimeError( "keypress argument must be one of: never, start, exit or both. '" + keypress + "' not recognised" );
  7969. return ParserResult::ok( ParseResultType::Matched );
  7970. };
  7971. auto const setVerbosity = [&]( std::string const& verbosity ) {
  7972. auto lcVerbosity = toLower( verbosity );
  7973. if( lcVerbosity == "quiet" )
  7974. config.verbosity = Verbosity::Quiet;
  7975. else if( lcVerbosity == "normal" )
  7976. config.verbosity = Verbosity::Normal;
  7977. else if( lcVerbosity == "high" )
  7978. config.verbosity = Verbosity::High;
  7979. else
  7980. return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" );
  7981. return ParserResult::ok( ParseResultType::Matched );
  7982. };
  7983. auto const setReporter = [&]( std::string const& reporter ) {
  7984. IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
  7985. auto lcReporter = toLower( reporter );
  7986. auto result = factories.find( lcReporter );
  7987. if( factories.end() != result )
  7988. config.reporterName = lcReporter;
  7989. else
  7990. return ParserResult::runtimeError( "Unrecognized reporter, '" + reporter + "'. Check available with --list-reporters" );
  7991. return ParserResult::ok( ParseResultType::Matched );
  7992. };
  7993. auto cli
  7994. = ExeName( config.processName )
  7995. | Help( config.showHelp )
  7996. | Opt( config.listTests )
  7997. ["-l"]["--list-tests"]
  7998. ( "list all/matching test cases" )
  7999. | Opt( config.listTags )
  8000. ["-t"]["--list-tags"]
  8001. ( "list all/matching tags" )
  8002. | Opt( config.showSuccessfulTests )
  8003. ["-s"]["--success"]
  8004. ( "include successful tests in output" )
  8005. | Opt( config.shouldDebugBreak )
  8006. ["-b"]["--break"]
  8007. ( "break into debugger on failure" )
  8008. | Opt( config.noThrow )
  8009. ["-e"]["--nothrow"]
  8010. ( "skip exception tests" )
  8011. | Opt( config.showInvisibles )
  8012. ["-i"]["--invisibles"]
  8013. ( "show invisibles (tabs, newlines)" )
  8014. | Opt( config.outputFilename, "filename" )
  8015. ["-o"]["--out"]
  8016. ( "output filename" )
  8017. | Opt( setReporter, "name" )
  8018. ["-r"]["--reporter"]
  8019. ( "reporter to use (defaults to console)" )
  8020. | Opt( config.name, "name" )
  8021. ["-n"]["--name"]
  8022. ( "suite name" )
  8023. | Opt( [&]( bool ){ config.abortAfter = 1; } )
  8024. ["-a"]["--abort"]
  8025. ( "abort at first failure" )
  8026. | Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" )
  8027. ["-x"]["--abortx"]
  8028. ( "abort after x failures" )
  8029. | Opt( setWarning, "warning name" )
  8030. ["-w"]["--warn"]
  8031. ( "enable warnings" )
  8032. | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" )
  8033. ["-d"]["--durations"]
  8034. ( "show test durations" )
  8035. | Opt( config.minDuration, "seconds" )
  8036. ["-D"]["--min-duration"]
  8037. ( "show test durations for tests taking at least the given number of seconds" )
  8038. | Opt( loadTestNamesFromFile, "filename" )
  8039. ["-f"]["--input-file"]
  8040. ( "load test names to run from a file" )
  8041. | Opt( config.filenamesAsTags )
  8042. ["-#"]["--filenames-as-tags"]
  8043. ( "adds a tag for the filename" )
  8044. | Opt( config.sectionsToRun, "section name" )
  8045. ["-c"]["--section"]
  8046. ( "specify section to run" )
  8047. | Opt( setVerbosity, "quiet|normal|high" )
  8048. ["-v"]["--verbosity"]
  8049. ( "set output verbosity" )
  8050. | Opt( config.listTestNamesOnly )
  8051. ["--list-test-names-only"]
  8052. ( "list all/matching test cases names only" )
  8053. | Opt( config.listReporters )
  8054. ["--list-reporters"]
  8055. ( "list all reporters" )
  8056. | Opt( setTestOrder, "decl|lex|rand" )
  8057. ["--order"]
  8058. ( "test case order (defaults to decl)" )
  8059. | Opt( setRngSeed, "'time'|number" )
  8060. ["--rng-seed"]
  8061. ( "set a specific seed for random numbers" )
  8062. | Opt( setColourUsage, "yes|no" )
  8063. ["--use-colour"]
  8064. ( "should output be colourised" )
  8065. | Opt( config.libIdentify )
  8066. ["--libidentify"]
  8067. ( "report name and version according to libidentify standard" )
  8068. | Opt( setWaitForKeypress, "never|start|exit|both" )
  8069. ["--wait-for-keypress"]
  8070. ( "waits for a keypress before exiting" )
  8071. | Opt( config.benchmarkSamples, "samples" )
  8072. ["--benchmark-samples"]
  8073. ( "number of samples to collect (default: 100)" )
  8074. | Opt( config.benchmarkResamples, "resamples" )
  8075. ["--benchmark-resamples"]
  8076. ( "number of resamples for the bootstrap (default: 100000)" )
  8077. | Opt( config.benchmarkConfidenceInterval, "confidence interval" )
  8078. ["--benchmark-confidence-interval"]
  8079. ( "confidence interval for the bootstrap (between 0 and 1, default: 0.95)" )
  8080. | Opt( config.benchmarkNoAnalysis )
  8081. ["--benchmark-no-analysis"]
  8082. ( "perform only measurements; do not perform any analysis" )
  8083. | Opt( config.benchmarkWarmupTime, "benchmarkWarmupTime" )
  8084. ["--benchmark-warmup-time"]
  8085. ( "amount of time in milliseconds spent on warming up each test (default: 100)" )
  8086. | Arg( config.testsOrTags, "test name|pattern|tags" )
  8087. ( "which test or tests to use" );
  8088. return cli;
  8089. }
  8090. } // end namespace Catch
  8091. // end catch_commandline.cpp
  8092. // start catch_common.cpp
  8093. #include <cstring>
  8094. #include <ostream>
  8095. namespace Catch {
  8096. bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept {
  8097. return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
  8098. }
  8099. bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept {
  8100. // We can assume that the same file will usually have the same pointer.
  8101. // Thus, if the pointers are the same, there is no point in calling the strcmp
  8102. return line < other.line || ( line == other.line && file != other.file && (std::strcmp(file, other.file) < 0));
  8103. }
  8104. std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
  8105. #ifndef __GNUG__
  8106. os << info.file << '(' << info.line << ')';
  8107. #else
  8108. os << info.file << ':' << info.line;
  8109. #endif
  8110. return os;
  8111. }
  8112. std::string StreamEndStop::operator+() const {
  8113. return std::string();
  8114. }
  8115. NonCopyable::NonCopyable() = default;
  8116. NonCopyable::~NonCopyable() = default;
  8117. }
  8118. // end catch_common.cpp
  8119. // start catch_config.cpp
  8120. namespace Catch {
  8121. Config::Config( ConfigData const& data )
  8122. : m_data( data ),
  8123. m_stream( openStream() )
  8124. {
  8125. // We need to trim filter specs to avoid trouble with superfluous
  8126. // whitespace (esp. important for bdd macros, as those are manually
  8127. // aligned with whitespace).
  8128. for (auto& elem : m_data.testsOrTags) {
  8129. elem = trim(elem);
  8130. }
  8131. for (auto& elem : m_data.sectionsToRun) {
  8132. elem = trim(elem);
  8133. }
  8134. TestSpecParser parser(ITagAliasRegistry::get());
  8135. if (!m_data.testsOrTags.empty()) {
  8136. m_hasTestFilters = true;
  8137. for (auto const& testOrTags : m_data.testsOrTags) {
  8138. parser.parse(testOrTags);
  8139. }
  8140. }
  8141. m_testSpec = parser.testSpec();
  8142. }
  8143. std::string const& Config::getFilename() const {
  8144. return m_data.outputFilename ;
  8145. }
  8146. bool Config::listTests() const { return m_data.listTests; }
  8147. bool Config::listTestNamesOnly() const { return m_data.listTestNamesOnly; }
  8148. bool Config::listTags() const { return m_data.listTags; }
  8149. bool Config::listReporters() const { return m_data.listReporters; }
  8150. std::string Config::getProcessName() const { return m_data.processName; }
  8151. std::string const& Config::getReporterName() const { return m_data.reporterName; }
  8152. std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }
  8153. std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
  8154. TestSpec const& Config::testSpec() const { return m_testSpec; }
  8155. bool Config::hasTestFilters() const { return m_hasTestFilters; }
  8156. bool Config::showHelp() const { return m_data.showHelp; }
  8157. // IConfig interface
  8158. bool Config::allowThrows() const { return !m_data.noThrow; }
  8159. std::ostream& Config::stream() const { return m_stream->stream(); }
  8160. std::string Config::name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
  8161. bool Config::includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
  8162. bool Config::warnAboutMissingAssertions() const { return !!(m_data.warnings & WarnAbout::NoAssertions); }
  8163. bool Config::warnAboutNoTests() const { return !!(m_data.warnings & WarnAbout::NoTests); }
  8164. ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }
  8165. double Config::minDuration() const { return m_data.minDuration; }
  8166. RunTests::InWhatOrder Config::runOrder() const { return m_data.runOrder; }
  8167. unsigned int Config::rngSeed() const { return m_data.rngSeed; }
  8168. UseColour::YesOrNo Config::useColour() const { return m_data.useColour; }
  8169. bool Config::shouldDebugBreak() const { return m_data.shouldDebugBreak; }
  8170. int Config::abortAfter() const { return m_data.abortAfter; }
  8171. bool Config::showInvisibles() const { return m_data.showInvisibles; }
  8172. Verbosity Config::verbosity() const { return m_data.verbosity; }
  8173. bool Config::benchmarkNoAnalysis() const { return m_data.benchmarkNoAnalysis; }
  8174. int Config::benchmarkSamples() const { return m_data.benchmarkSamples; }
  8175. double Config::benchmarkConfidenceInterval() const { return m_data.benchmarkConfidenceInterval; }
  8176. unsigned int Config::benchmarkResamples() const { return m_data.benchmarkResamples; }
  8177. std::chrono::milliseconds Config::benchmarkWarmupTime() const { return std::chrono::milliseconds(m_data.benchmarkWarmupTime); }
  8178. IStream const* Config::openStream() {
  8179. return Catch::makeStream(m_data.outputFilename);
  8180. }
  8181. } // end namespace Catch
  8182. // end catch_config.cpp
  8183. // start catch_console_colour.cpp
  8184. #if defined(__clang__)
  8185. # pragma clang diagnostic push
  8186. # pragma clang diagnostic ignored "-Wexit-time-destructors"
  8187. #endif
  8188. // start catch_errno_guard.h
  8189. namespace Catch {
  8190. class ErrnoGuard {
  8191. public:
  8192. ErrnoGuard();
  8193. ~ErrnoGuard();
  8194. private:
  8195. int m_oldErrno;
  8196. };
  8197. }
  8198. // end catch_errno_guard.h
  8199. #include <sstream>
  8200. namespace Catch {
  8201. namespace {
  8202. struct IColourImpl {
  8203. virtual ~IColourImpl() = default;
  8204. virtual void use( Colour::Code _colourCode ) = 0;
  8205. };
  8206. struct NoColourImpl : IColourImpl {
  8207. void use( Colour::Code ) override {}
  8208. static IColourImpl* instance() {
  8209. static NoColourImpl s_instance;
  8210. return &s_instance;
  8211. }
  8212. };
  8213. } // anon namespace
  8214. } // namespace Catch
  8215. #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
  8216. # ifdef CATCH_PLATFORM_WINDOWS
  8217. # define CATCH_CONFIG_COLOUR_WINDOWS
  8218. # else
  8219. # define CATCH_CONFIG_COLOUR_ANSI
  8220. # endif
  8221. #endif
  8222. #if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
  8223. namespace Catch {
  8224. namespace {
  8225. class Win32ColourImpl : public IColourImpl {
  8226. public:
  8227. Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
  8228. {
  8229. CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
  8230. GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
  8231. originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
  8232. originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
  8233. }
  8234. void use( Colour::Code _colourCode ) override {
  8235. switch( _colourCode ) {
  8236. case Colour::None: return setTextAttribute( originalForegroundAttributes );
  8237. case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
  8238. case Colour::Red: return setTextAttribute( FOREGROUND_RED );
  8239. case Colour::Green: return setTextAttribute( FOREGROUND_GREEN );
  8240. case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE );
  8241. case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
  8242. case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
  8243. case Colour::Grey: return setTextAttribute( 0 );
  8244. case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY );
  8245. case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
  8246. case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
  8247. case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
  8248. case Colour::BrightYellow: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN );
  8249. case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
  8250. default:
  8251. CATCH_ERROR( "Unknown colour requested" );
  8252. }
  8253. }
  8254. private:
  8255. void setTextAttribute( WORD _textAttribute ) {
  8256. SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
  8257. }
  8258. HANDLE stdoutHandle;
  8259. WORD originalForegroundAttributes;
  8260. WORD originalBackgroundAttributes;
  8261. };
  8262. IColourImpl* platformColourInstance() {
  8263. static Win32ColourImpl s_instance;
  8264. IConfigPtr config = getCurrentContext().getConfig();
  8265. UseColour::YesOrNo colourMode = config
  8266. ? config->useColour()
  8267. : UseColour::Auto;
  8268. if( colourMode == UseColour::Auto )
  8269. colourMode = UseColour::Yes;
  8270. return colourMode == UseColour::Yes
  8271. ? &s_instance
  8272. : NoColourImpl::instance();
  8273. }
  8274. } // end anon namespace
  8275. } // end namespace Catch
  8276. #elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
  8277. #include <unistd.h>
  8278. namespace Catch {
  8279. namespace {
  8280. // use POSIX/ ANSI console terminal codes
  8281. // Thanks to Adam Strzelecki for original contribution
  8282. // (http://github.com/nanoant)
  8283. // https://github.com/philsquared/Catch/pull/131
  8284. class PosixColourImpl : public IColourImpl {
  8285. public:
  8286. void use( Colour::Code _colourCode ) override {
  8287. switch( _colourCode ) {
  8288. case Colour::None:
  8289. case Colour::White: return setColour( "[0m" );
  8290. case Colour::Red: return setColour( "[0;31m" );
  8291. case Colour::Green: return setColour( "[0;32m" );
  8292. case Colour::Blue: return setColour( "[0;34m" );
  8293. case Colour::Cyan: return setColour( "[0;36m" );
  8294. case Colour::Yellow: return setColour( "[0;33m" );
  8295. case Colour::Grey: return setColour( "[1;30m" );
  8296. case Colour::LightGrey: return setColour( "[0;37m" );
  8297. case Colour::BrightRed: return setColour( "[1;31m" );
  8298. case Colour::BrightGreen: return setColour( "[1;32m" );
  8299. case Colour::BrightWhite: return setColour( "[1;37m" );
  8300. case Colour::BrightYellow: return setColour( "[1;33m" );
  8301. case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
  8302. default: CATCH_INTERNAL_ERROR( "Unknown colour requested" );
  8303. }
  8304. }
  8305. static IColourImpl* instance() {
  8306. static PosixColourImpl s_instance;
  8307. return &s_instance;
  8308. }
  8309. private:
  8310. void setColour( const char* _escapeCode ) {
  8311. getCurrentContext().getConfig()->stream()
  8312. << '\033' << _escapeCode;
  8313. }
  8314. };
  8315. bool useColourOnPlatform() {
  8316. return
  8317. #if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)
  8318. !isDebuggerActive() &&
  8319. #endif
  8320. #if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
  8321. isatty(STDOUT_FILENO)
  8322. #else
  8323. false
  8324. #endif
  8325. ;
  8326. }
  8327. IColourImpl* platformColourInstance() {
  8328. ErrnoGuard guard;
  8329. IConfigPtr config = getCurrentContext().getConfig();
  8330. UseColour::YesOrNo colourMode = config
  8331. ? config->useColour()
  8332. : UseColour::Auto;
  8333. if( colourMode == UseColour::Auto )
  8334. colourMode = useColourOnPlatform()
  8335. ? UseColour::Yes
  8336. : UseColour::No;
  8337. return colourMode == UseColour::Yes
  8338. ? PosixColourImpl::instance()
  8339. : NoColourImpl::instance();
  8340. }
  8341. } // end anon namespace
  8342. } // end namespace Catch
  8343. #else // not Windows or ANSI ///////////////////////////////////////////////
  8344. namespace Catch {
  8345. static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
  8346. } // end namespace Catch
  8347. #endif // Windows/ ANSI/ None
  8348. namespace Catch {
  8349. Colour::Colour( Code _colourCode ) { use( _colourCode ); }
  8350. Colour::Colour( Colour&& other ) noexcept {
  8351. m_moved = other.m_moved;
  8352. other.m_moved = true;
  8353. }
  8354. Colour& Colour::operator=( Colour&& other ) noexcept {
  8355. m_moved = other.m_moved;
  8356. other.m_moved = true;
  8357. return *this;
  8358. }
  8359. Colour::~Colour(){ if( !m_moved ) use( None ); }
  8360. void Colour::use( Code _colourCode ) {
  8361. static IColourImpl* impl = platformColourInstance();
  8362. // Strictly speaking, this cannot possibly happen.
  8363. // However, under some conditions it does happen (see #1626),
  8364. // and this change is small enough that we can let practicality
  8365. // triumph over purity in this case.
  8366. if (impl != nullptr) {
  8367. impl->use( _colourCode );
  8368. }
  8369. }
  8370. std::ostream& operator << ( std::ostream& os, Colour const& ) {
  8371. return os;
  8372. }
  8373. } // end namespace Catch
  8374. #if defined(__clang__)
  8375. # pragma clang diagnostic pop
  8376. #endif
  8377. // end catch_console_colour.cpp
  8378. // start catch_context.cpp
  8379. namespace Catch {
  8380. class Context : public IMutableContext, NonCopyable {
  8381. public: // IContext
  8382. IResultCapture* getResultCapture() override {
  8383. return m_resultCapture;
  8384. }
  8385. IRunner* getRunner() override {
  8386. return m_runner;
  8387. }
  8388. IConfigPtr const& getConfig() const override {
  8389. return m_config;
  8390. }
  8391. ~Context() override;
  8392. public: // IMutableContext
  8393. void setResultCapture( IResultCapture* resultCapture ) override {
  8394. m_resultCapture = resultCapture;
  8395. }
  8396. void setRunner( IRunner* runner ) override {
  8397. m_runner = runner;
  8398. }
  8399. void setConfig( IConfigPtr const& config ) override {
  8400. m_config = config;
  8401. }
  8402. friend IMutableContext& getCurrentMutableContext();
  8403. private:
  8404. IConfigPtr m_config;
  8405. IRunner* m_runner = nullptr;
  8406. IResultCapture* m_resultCapture = nullptr;
  8407. };
  8408. IMutableContext *IMutableContext::currentContext = nullptr;
  8409. void IMutableContext::createContext()
  8410. {
  8411. currentContext = new Context();
  8412. }
  8413. void cleanUpContext() {
  8414. delete IMutableContext::currentContext;
  8415. IMutableContext::currentContext = nullptr;
  8416. }
  8417. IContext::~IContext() = default;
  8418. IMutableContext::~IMutableContext() = default;
  8419. Context::~Context() = default;
  8420. SimplePcg32& rng() {
  8421. static SimplePcg32 s_rng;
  8422. return s_rng;
  8423. }
  8424. }
  8425. // end catch_context.cpp
  8426. // start catch_debug_console.cpp
  8427. // start catch_debug_console.h
  8428. #include <string>
  8429. namespace Catch {
  8430. void writeToDebugConsole( std::string const& text );
  8431. }
  8432. // end catch_debug_console.h
  8433. #if defined(CATCH_CONFIG_ANDROID_LOGWRITE)
  8434. #include <android/log.h>
  8435. namespace Catch {
  8436. void writeToDebugConsole( std::string const& text ) {
  8437. __android_log_write( ANDROID_LOG_DEBUG, "Catch", text.c_str() );
  8438. }
  8439. }
  8440. #elif defined(CATCH_PLATFORM_WINDOWS)
  8441. namespace Catch {
  8442. void writeToDebugConsole( std::string const& text ) {
  8443. ::OutputDebugStringA( text.c_str() );
  8444. }
  8445. }
  8446. #else
  8447. namespace Catch {
  8448. void writeToDebugConsole( std::string const& text ) {
  8449. // !TBD: Need a version for Mac/ XCode and other IDEs
  8450. Catch::cout() << text;
  8451. }
  8452. }
  8453. #endif // Platform
  8454. // end catch_debug_console.cpp
  8455. // start catch_debugger.cpp
  8456. #if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)
  8457. # include <cassert>
  8458. # include <sys/types.h>
  8459. # include <unistd.h>
  8460. # include <cstddef>
  8461. # include <ostream>
  8462. #ifdef __apple_build_version__
  8463. // These headers will only compile with AppleClang (XCode)
  8464. // For other compilers (Clang, GCC, ... ) we need to exclude them
  8465. # include <sys/sysctl.h>
  8466. #endif
  8467. namespace Catch {
  8468. #ifdef __apple_build_version__
  8469. // The following function is taken directly from the following technical note:
  8470. // https://developer.apple.com/library/archive/qa/qa1361/_index.html
  8471. // Returns true if the current process is being debugged (either
  8472. // running under the debugger or has a debugger attached post facto).
  8473. bool isDebuggerActive(){
  8474. int mib[4];
  8475. struct kinfo_proc info;
  8476. std::size_t size;
  8477. // Initialize the flags so that, if sysctl fails for some bizarre
  8478. // reason, we get a predictable result.
  8479. info.kp_proc.p_flag = 0;
  8480. // Initialize mib, which tells sysctl the info we want, in this case
  8481. // we're looking for information about a specific process ID.
  8482. mib[0] = CTL_KERN;
  8483. mib[1] = KERN_PROC;
  8484. mib[2] = KERN_PROC_PID;
  8485. mib[3] = getpid();
  8486. // Call sysctl.
  8487. size = sizeof(info);
  8488. if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) {
  8489. Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
  8490. return false;
  8491. }
  8492. // We're being debugged if the P_TRACED flag is set.
  8493. return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
  8494. }
  8495. #else
  8496. bool isDebuggerActive() {
  8497. // We need to find another way to determine this for non-appleclang compilers on macOS
  8498. return false;
  8499. }
  8500. #endif
  8501. } // namespace Catch
  8502. #elif defined(CATCH_PLATFORM_LINUX)
  8503. #include <fstream>
  8504. #include <string>
  8505. namespace Catch{
  8506. // The standard POSIX way of detecting a debugger is to attempt to
  8507. // ptrace() the process, but this needs to be done from a child and not
  8508. // this process itself to still allow attaching to this process later
  8509. // if wanted, so is rather heavy. Under Linux we have the PID of the
  8510. // "debugger" (which doesn't need to be gdb, of course, it could also
  8511. // be strace, for example) in /proc/$PID/status, so just get it from
  8512. // there instead.
  8513. bool isDebuggerActive(){
  8514. // Libstdc++ has a bug, where std::ifstream sets errno to 0
  8515. // This way our users can properly assert over errno values
  8516. ErrnoGuard guard;
  8517. std::ifstream in("/proc/self/status");
  8518. for( std::string line; std::getline(in, line); ) {
  8519. static const int PREFIX_LEN = 11;
  8520. if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
  8521. // We're traced if the PID is not 0 and no other PID starts
  8522. // with 0 digit, so it's enough to check for just a single
  8523. // character.
  8524. return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
  8525. }
  8526. }
  8527. return false;
  8528. }
  8529. } // namespace Catch
  8530. #elif defined(_MSC_VER)
  8531. extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
  8532. namespace Catch {
  8533. bool isDebuggerActive() {
  8534. return IsDebuggerPresent() != 0;
  8535. }
  8536. }
  8537. #elif defined(__MINGW32__)
  8538. extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
  8539. namespace Catch {
  8540. bool isDebuggerActive() {
  8541. return IsDebuggerPresent() != 0;
  8542. }
  8543. }
  8544. #else
  8545. namespace Catch {
  8546. bool isDebuggerActive() { return false; }
  8547. }
  8548. #endif // Platform
  8549. // end catch_debugger.cpp
  8550. // start catch_decomposer.cpp
  8551. namespace Catch {
  8552. ITransientExpression::~ITransientExpression() = default;
  8553. void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {
  8554. if( lhs.size() + rhs.size() < 40 &&
  8555. lhs.find('\n') == std::string::npos &&
  8556. rhs.find('\n') == std::string::npos )
  8557. os << lhs << " " << op << " " << rhs;
  8558. else
  8559. os << lhs << "\n" << op << "\n" << rhs;
  8560. }
  8561. }
  8562. // end catch_decomposer.cpp
  8563. // start catch_enforce.cpp
  8564. #include <stdexcept>
  8565. namespace Catch {
  8566. #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)
  8567. [[noreturn]]
  8568. void throw_exception(std::exception const& e) {
  8569. Catch::cerr() << "Catch will terminate because it needed to throw an exception.\n"
  8570. << "The message was: " << e.what() << '\n';
  8571. std::terminate();
  8572. }
  8573. #endif
  8574. [[noreturn]]
  8575. void throw_logic_error(std::string const& msg) {
  8576. throw_exception(std::logic_error(msg));
  8577. }
  8578. [[noreturn]]
  8579. void throw_domain_error(std::string const& msg) {
  8580. throw_exception(std::domain_error(msg));
  8581. }
  8582. [[noreturn]]
  8583. void throw_runtime_error(std::string const& msg) {
  8584. throw_exception(std::runtime_error(msg));
  8585. }
  8586. } // namespace Catch;
  8587. // end catch_enforce.cpp
  8588. // start catch_enum_values_registry.cpp
  8589. // start catch_enum_values_registry.h
  8590. #include <vector>
  8591. #include <memory>
  8592. namespace Catch {
  8593. namespace Detail {
  8594. std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values );
  8595. class EnumValuesRegistry : public IMutableEnumValuesRegistry {
  8596. std::vector<std::unique_ptr<EnumInfo>> m_enumInfos;
  8597. EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values) override;
  8598. };
  8599. std::vector<StringRef> parseEnums( StringRef enums );
  8600. } // Detail
  8601. } // Catch
  8602. // end catch_enum_values_registry.h
  8603. #include <map>
  8604. #include <cassert>
  8605. namespace Catch {
  8606. IMutableEnumValuesRegistry::~IMutableEnumValuesRegistry() {}
  8607. namespace Detail {
  8608. namespace {
  8609. // Extracts the actual name part of an enum instance
  8610. // In other words, it returns the Blue part of Bikeshed::Colour::Blue
  8611. StringRef extractInstanceName(StringRef enumInstance) {
  8612. // Find last occurence of ":"
  8613. size_t name_start = enumInstance.size();
  8614. while (name_start > 0 && enumInstance[name_start - 1] != ':') {
  8615. --name_start;
  8616. }
  8617. return enumInstance.substr(name_start, enumInstance.size() - name_start);
  8618. }
  8619. }
  8620. std::vector<StringRef> parseEnums( StringRef enums ) {
  8621. auto enumValues = splitStringRef( enums, ',' );
  8622. std::vector<StringRef> parsed;
  8623. parsed.reserve( enumValues.size() );
  8624. for( auto const& enumValue : enumValues ) {
  8625. parsed.push_back(trim(extractInstanceName(enumValue)));
  8626. }
  8627. return parsed;
  8628. }
  8629. EnumInfo::~EnumInfo() {}
  8630. StringRef EnumInfo::lookup( int value ) const {
  8631. for( auto const& valueToName : m_values ) {
  8632. if( valueToName.first == value )
  8633. return valueToName.second;
  8634. }
  8635. return "{** unexpected enum value **}"_sr;
  8636. }
  8637. std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
  8638. std::unique_ptr<EnumInfo> enumInfo( new EnumInfo );
  8639. enumInfo->m_name = enumName;
  8640. enumInfo->m_values.reserve( values.size() );
  8641. const auto valueNames = Catch::Detail::parseEnums( allValueNames );
  8642. assert( valueNames.size() == values.size() );
  8643. std::size_t i = 0;
  8644. for( auto value : values )
  8645. enumInfo->m_values.emplace_back(value, valueNames[i++]);
  8646. return enumInfo;
  8647. }
  8648. EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
  8649. m_enumInfos.push_back(makeEnumInfo(enumName, allValueNames, values));
  8650. return *m_enumInfos.back();
  8651. }
  8652. } // Detail
  8653. } // Catch
  8654. // end catch_enum_values_registry.cpp
  8655. // start catch_errno_guard.cpp
  8656. #include <cerrno>
  8657. namespace Catch {
  8658. ErrnoGuard::ErrnoGuard():m_oldErrno(errno){}
  8659. ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }
  8660. }
  8661. // end catch_errno_guard.cpp
  8662. // start catch_exception_translator_registry.cpp
  8663. // start catch_exception_translator_registry.h
  8664. #include <vector>
  8665. #include <string>
  8666. #include <memory>
  8667. namespace Catch {
  8668. class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
  8669. public:
  8670. ~ExceptionTranslatorRegistry();
  8671. virtual void registerTranslator( const IExceptionTranslator* translator );
  8672. std::string translateActiveException() const override;
  8673. std::string tryTranslators() const;
  8674. private:
  8675. std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators;
  8676. };
  8677. }
  8678. // end catch_exception_translator_registry.h
  8679. #ifdef __OBJC__
  8680. #import "Foundation/Foundation.h"
  8681. #endif
  8682. namespace Catch {
  8683. ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {
  8684. }
  8685. void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) {
  8686. m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );
  8687. }
  8688. #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  8689. std::string ExceptionTranslatorRegistry::translateActiveException() const {
  8690. try {
  8691. #ifdef __OBJC__
  8692. // In Objective-C try objective-c exceptions first
  8693. @try {
  8694. return tryTranslators();
  8695. }
  8696. @catch (NSException *exception) {
  8697. return Catch::Detail::stringify( [exception description] );
  8698. }
  8699. #else
  8700. // Compiling a mixed mode project with MSVC means that CLR
  8701. // exceptions will be caught in (...) as well. However, these
  8702. // do not fill-in std::current_exception and thus lead to crash
  8703. // when attempting rethrow.
  8704. // /EHa switch also causes structured exceptions to be caught
  8705. // here, but they fill-in current_exception properly, so
  8706. // at worst the output should be a little weird, instead of
  8707. // causing a crash.
  8708. if (std::current_exception() == nullptr) {
  8709. return "Non C++ exception. Possibly a CLR exception.";
  8710. }
  8711. return tryTranslators();
  8712. #endif
  8713. }
  8714. catch( TestFailureException& ) {
  8715. std::rethrow_exception(std::current_exception());
  8716. }
  8717. catch( std::exception& ex ) {
  8718. return ex.what();
  8719. }
  8720. catch( std::string& msg ) {
  8721. return msg;
  8722. }
  8723. catch( const char* msg ) {
  8724. return msg;
  8725. }
  8726. catch(...) {
  8727. return "Unknown exception";
  8728. }
  8729. }
  8730. std::string ExceptionTranslatorRegistry::tryTranslators() const {
  8731. if (m_translators.empty()) {
  8732. std::rethrow_exception(std::current_exception());
  8733. } else {
  8734. return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end());
  8735. }
  8736. }
  8737. #else // ^^ Exceptions are enabled // Exceptions are disabled vv
  8738. std::string ExceptionTranslatorRegistry::translateActiveException() const {
  8739. CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
  8740. }
  8741. std::string ExceptionTranslatorRegistry::tryTranslators() const {
  8742. CATCH_INTERNAL_ERROR("Attempted to use exception translators under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
  8743. }
  8744. #endif
  8745. }
  8746. // end catch_exception_translator_registry.cpp
  8747. // start catch_fatal_condition.cpp
  8748. #if defined(__GNUC__)
  8749. # pragma GCC diagnostic push
  8750. # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
  8751. #endif
  8752. #if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )
  8753. namespace {
  8754. // Report the error condition
  8755. void reportFatal( char const * const message ) {
  8756. Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
  8757. }
  8758. }
  8759. #endif // signals/SEH handling
  8760. #if defined( CATCH_CONFIG_WINDOWS_SEH )
  8761. namespace Catch {
  8762. struct SignalDefs { DWORD id; const char* name; };
  8763. // There is no 1-1 mapping between signals and windows exceptions.
  8764. // Windows can easily distinguish between SO and SigSegV,
  8765. // but SigInt, SigTerm, etc are handled differently.
  8766. static SignalDefs signalDefs[] = {
  8767. { static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION), "SIGILL - Illegal instruction signal" },
  8768. { static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow" },
  8769. { static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION), "SIGSEGV - Segmentation violation signal" },
  8770. { static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" },
  8771. };
  8772. LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
  8773. for (auto const& def : signalDefs) {
  8774. if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
  8775. reportFatal(def.name);
  8776. }
  8777. }
  8778. // If its not an exception we care about, pass it along.
  8779. // This stops us from eating debugger breaks etc.
  8780. return EXCEPTION_CONTINUE_SEARCH;
  8781. }
  8782. FatalConditionHandler::FatalConditionHandler() {
  8783. isSet = true;
  8784. // 32k seems enough for Catch to handle stack overflow,
  8785. // but the value was found experimentally, so there is no strong guarantee
  8786. guaranteeSize = 32 * 1024;
  8787. exceptionHandlerHandle = nullptr;
  8788. // Register as first handler in current chain
  8789. exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
  8790. // Pass in guarantee size to be filled
  8791. SetThreadStackGuarantee(&guaranteeSize);
  8792. }
  8793. void FatalConditionHandler::reset() {
  8794. if (isSet) {
  8795. RemoveVectoredExceptionHandler(exceptionHandlerHandle);
  8796. SetThreadStackGuarantee(&guaranteeSize);
  8797. exceptionHandlerHandle = nullptr;
  8798. isSet = false;
  8799. }
  8800. }
  8801. FatalConditionHandler::~FatalConditionHandler() {
  8802. reset();
  8803. }
  8804. bool FatalConditionHandler::isSet = false;
  8805. ULONG FatalConditionHandler::guaranteeSize = 0;
  8806. PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;
  8807. } // namespace Catch
  8808. #elif defined( CATCH_CONFIG_POSIX_SIGNALS )
  8809. namespace Catch {
  8810. struct SignalDefs {
  8811. int id;
  8812. const char* name;
  8813. };
  8814. // 32kb for the alternate stack seems to be sufficient. However, this value
  8815. // is experimentally determined, so that's not guaranteed.
  8816. static constexpr std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
  8817. static SignalDefs signalDefs[] = {
  8818. { SIGINT, "SIGINT - Terminal interrupt signal" },
  8819. { SIGILL, "SIGILL - Illegal instruction signal" },
  8820. { SIGFPE, "SIGFPE - Floating point error signal" },
  8821. { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
  8822. { SIGTERM, "SIGTERM - Termination request signal" },
  8823. { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
  8824. };
  8825. void FatalConditionHandler::handleSignal( int sig ) {
  8826. char const * name = "<unknown signal>";
  8827. for (auto const& def : signalDefs) {
  8828. if (sig == def.id) {
  8829. name = def.name;
  8830. break;
  8831. }
  8832. }
  8833. reset();
  8834. reportFatal(name);
  8835. raise( sig );
  8836. }
  8837. FatalConditionHandler::FatalConditionHandler() {
  8838. isSet = true;
  8839. stack_t sigStack;
  8840. sigStack.ss_sp = altStackMem;
  8841. sigStack.ss_size = sigStackSize;
  8842. sigStack.ss_flags = 0;
  8843. sigaltstack(&sigStack, &oldSigStack);
  8844. struct sigaction sa = { };
  8845. sa.sa_handler = handleSignal;
  8846. sa.sa_flags = SA_ONSTACK;
  8847. for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {
  8848. sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
  8849. }
  8850. }
  8851. FatalConditionHandler::~FatalConditionHandler() {
  8852. reset();
  8853. }
  8854. void FatalConditionHandler::reset() {
  8855. if( isSet ) {
  8856. // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
  8857. for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
  8858. sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
  8859. }
  8860. // Return the old stack
  8861. sigaltstack(&oldSigStack, nullptr);
  8862. isSet = false;
  8863. }
  8864. }
  8865. bool FatalConditionHandler::isSet = false;
  8866. struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
  8867. stack_t FatalConditionHandler::oldSigStack = {};
  8868. char FatalConditionHandler::altStackMem[sigStackSize] = {};
  8869. } // namespace Catch
  8870. #else
  8871. namespace Catch {
  8872. void FatalConditionHandler::reset() {}
  8873. }
  8874. #endif // signals/SEH handling
  8875. #if defined(__GNUC__)
  8876. # pragma GCC diagnostic pop
  8877. #endif
  8878. // end catch_fatal_condition.cpp
  8879. // start catch_generators.cpp
  8880. #include <limits>
  8881. #include <set>
  8882. namespace Catch {
  8883. IGeneratorTracker::~IGeneratorTracker() {}
  8884. const char* GeneratorException::what() const noexcept {
  8885. return m_msg;
  8886. }
  8887. namespace Generators {
  8888. GeneratorUntypedBase::~GeneratorUntypedBase() {}
  8889. auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
  8890. return getResultCapture().acquireGeneratorTracker( generatorName, lineInfo );
  8891. }
  8892. } // namespace Generators
  8893. } // namespace Catch
  8894. // end catch_generators.cpp
  8895. // start catch_interfaces_capture.cpp
  8896. namespace Catch {
  8897. IResultCapture::~IResultCapture() = default;
  8898. }
  8899. // end catch_interfaces_capture.cpp
  8900. // start catch_interfaces_config.cpp
  8901. namespace Catch {
  8902. IConfig::~IConfig() = default;
  8903. }
  8904. // end catch_interfaces_config.cpp
  8905. // start catch_interfaces_exception.cpp
  8906. namespace Catch {
  8907. IExceptionTranslator::~IExceptionTranslator() = default;
  8908. IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default;
  8909. }
  8910. // end catch_interfaces_exception.cpp
  8911. // start catch_interfaces_registry_hub.cpp
  8912. namespace Catch {
  8913. IRegistryHub::~IRegistryHub() = default;
  8914. IMutableRegistryHub::~IMutableRegistryHub() = default;
  8915. }
  8916. // end catch_interfaces_registry_hub.cpp
  8917. // start catch_interfaces_reporter.cpp
  8918. // start catch_reporter_listening.h
  8919. namespace Catch {
  8920. class ListeningReporter : public IStreamingReporter {
  8921. using Reporters = std::vector<IStreamingReporterPtr>;
  8922. Reporters m_listeners;
  8923. IStreamingReporterPtr m_reporter = nullptr;
  8924. ReporterPreferences m_preferences;
  8925. public:
  8926. ListeningReporter();
  8927. void addListener( IStreamingReporterPtr&& listener );
  8928. void addReporter( IStreamingReporterPtr&& reporter );
  8929. public: // IStreamingReporter
  8930. ReporterPreferences getPreferences() const override;
  8931. void noMatchingTestCases( std::string const& spec ) override;
  8932. void reportInvalidArguments(std::string const&arg) override;
  8933. static std::set<Verbosity> getSupportedVerbosities();
  8934. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  8935. void benchmarkPreparing(std::string const& name) override;
  8936. void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;
  8937. void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) override;
  8938. void benchmarkFailed(std::string const&) override;
  8939. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  8940. void testRunStarting( TestRunInfo const& testRunInfo ) override;
  8941. void testGroupStarting( GroupInfo const& groupInfo ) override;
  8942. void testCaseStarting( TestCaseInfo const& testInfo ) override;
  8943. void sectionStarting( SectionInfo const& sectionInfo ) override;
  8944. void assertionStarting( AssertionInfo const& assertionInfo ) override;
  8945. // The return value indicates if the messages buffer should be cleared:
  8946. bool assertionEnded( AssertionStats const& assertionStats ) override;
  8947. void sectionEnded( SectionStats const& sectionStats ) override;
  8948. void testCaseEnded( TestCaseStats const& testCaseStats ) override;
  8949. void testGroupEnded( TestGroupStats const& testGroupStats ) override;
  8950. void testRunEnded( TestRunStats const& testRunStats ) override;
  8951. void skipTest( TestCaseInfo const& testInfo ) override;
  8952. bool isMulti() const override;
  8953. };
  8954. } // end namespace Catch
  8955. // end catch_reporter_listening.h
  8956. namespace Catch {
  8957. ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig )
  8958. : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
  8959. ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream )
  8960. : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
  8961. std::ostream& ReporterConfig::stream() const { return *m_stream; }
  8962. IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; }
  8963. TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {}
  8964. GroupInfo::GroupInfo( std::string const& _name,
  8965. std::size_t _groupIndex,
  8966. std::size_t _groupsCount )
  8967. : name( _name ),
  8968. groupIndex( _groupIndex ),
  8969. groupsCounts( _groupsCount )
  8970. {}
  8971. AssertionStats::AssertionStats( AssertionResult const& _assertionResult,
  8972. std::vector<MessageInfo> const& _infoMessages,
  8973. Totals const& _totals )
  8974. : assertionResult( _assertionResult ),
  8975. infoMessages( _infoMessages ),
  8976. totals( _totals )
  8977. {
  8978. assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;
  8979. if( assertionResult.hasMessage() ) {
  8980. // Copy message into messages list.
  8981. // !TBD This should have been done earlier, somewhere
  8982. MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
  8983. builder << assertionResult.getMessage();
  8984. builder.m_info.message = builder.m_stream.str();
  8985. infoMessages.push_back( builder.m_info );
  8986. }
  8987. }
  8988. AssertionStats::~AssertionStats() = default;
  8989. SectionStats::SectionStats( SectionInfo const& _sectionInfo,
  8990. Counts const& _assertions,
  8991. double _durationInSeconds,
  8992. bool _missingAssertions )
  8993. : sectionInfo( _sectionInfo ),
  8994. assertions( _assertions ),
  8995. durationInSeconds( _durationInSeconds ),
  8996. missingAssertions( _missingAssertions )
  8997. {}
  8998. SectionStats::~SectionStats() = default;
  8999. TestCaseStats::TestCaseStats( TestCaseInfo const& _testInfo,
  9000. Totals const& _totals,
  9001. std::string const& _stdOut,
  9002. std::string const& _stdErr,
  9003. bool _aborting )
  9004. : testInfo( _testInfo ),
  9005. totals( _totals ),
  9006. stdOut( _stdOut ),
  9007. stdErr( _stdErr ),
  9008. aborting( _aborting )
  9009. {}
  9010. TestCaseStats::~TestCaseStats() = default;
  9011. TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo,
  9012. Totals const& _totals,
  9013. bool _aborting )
  9014. : groupInfo( _groupInfo ),
  9015. totals( _totals ),
  9016. aborting( _aborting )
  9017. {}
  9018. TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo )
  9019. : groupInfo( _groupInfo ),
  9020. aborting( false )
  9021. {}
  9022. TestGroupStats::~TestGroupStats() = default;
  9023. TestRunStats::TestRunStats( TestRunInfo const& _runInfo,
  9024. Totals const& _totals,
  9025. bool _aborting )
  9026. : runInfo( _runInfo ),
  9027. totals( _totals ),
  9028. aborting( _aborting )
  9029. {}
  9030. TestRunStats::~TestRunStats() = default;
  9031. void IStreamingReporter::fatalErrorEncountered( StringRef ) {}
  9032. bool IStreamingReporter::isMulti() const { return false; }
  9033. IReporterFactory::~IReporterFactory() = default;
  9034. IReporterRegistry::~IReporterRegistry() = default;
  9035. } // end namespace Catch
  9036. // end catch_interfaces_reporter.cpp
  9037. // start catch_interfaces_runner.cpp
  9038. namespace Catch {
  9039. IRunner::~IRunner() = default;
  9040. }
  9041. // end catch_interfaces_runner.cpp
  9042. // start catch_interfaces_testcase.cpp
  9043. namespace Catch {
  9044. ITestInvoker::~ITestInvoker() = default;
  9045. ITestCaseRegistry::~ITestCaseRegistry() = default;
  9046. }
  9047. // end catch_interfaces_testcase.cpp
  9048. // start catch_leak_detector.cpp
  9049. #ifdef CATCH_CONFIG_WINDOWS_CRTDBG
  9050. #include <crtdbg.h>
  9051. namespace Catch {
  9052. LeakDetector::LeakDetector() {
  9053. int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
  9054. flag |= _CRTDBG_LEAK_CHECK_DF;
  9055. flag |= _CRTDBG_ALLOC_MEM_DF;
  9056. _CrtSetDbgFlag(flag);
  9057. _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
  9058. _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
  9059. // Change this to leaking allocation's number to break there
  9060. _CrtSetBreakAlloc(-1);
  9061. }
  9062. }
  9063. #else
  9064. Catch::LeakDetector::LeakDetector() {}
  9065. #endif
  9066. Catch::LeakDetector::~LeakDetector() {
  9067. Catch::cleanUp();
  9068. }
  9069. // end catch_leak_detector.cpp
  9070. // start catch_list.cpp
  9071. // start catch_list.h
  9072. #include <set>
  9073. namespace Catch {
  9074. std::size_t listTests( Config const& config );
  9075. std::size_t listTestsNamesOnly( Config const& config );
  9076. struct TagInfo {
  9077. void add( std::string const& spelling );
  9078. std::string all() const;
  9079. std::set<std::string> spellings;
  9080. std::size_t count = 0;
  9081. };
  9082. std::size_t listTags( Config const& config );
  9083. std::size_t listReporters();
  9084. Option<std::size_t> list( std::shared_ptr<Config> const& config );
  9085. } // end namespace Catch
  9086. // end catch_list.h
  9087. // start catch_text.h
  9088. namespace Catch {
  9089. using namespace clara::TextFlow;
  9090. }
  9091. // end catch_text.h
  9092. #include <limits>
  9093. #include <algorithm>
  9094. #include <iomanip>
  9095. namespace Catch {
  9096. std::size_t listTests( Config const& config ) {
  9097. TestSpec const& testSpec = config.testSpec();
  9098. if( config.hasTestFilters() )
  9099. Catch::cout() << "Matching test cases:\n";
  9100. else {
  9101. Catch::cout() << "All available test cases:\n";
  9102. }
  9103. auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
  9104. for( auto const& testCaseInfo : matchedTestCases ) {
  9105. Colour::Code colour = testCaseInfo.isHidden()
  9106. ? Colour::SecondaryText
  9107. : Colour::None;
  9108. Colour colourGuard( colour );
  9109. Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << "\n";
  9110. if( config.verbosity() >= Verbosity::High ) {
  9111. Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl;
  9112. std::string description = testCaseInfo.description;
  9113. if( description.empty() )
  9114. description = "(NO DESCRIPTION)";
  9115. Catch::cout() << Column( description ).indent(4) << std::endl;
  9116. }
  9117. if( !testCaseInfo.tags.empty() )
  9118. Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << "\n";
  9119. }
  9120. if( !config.hasTestFilters() )
  9121. Catch::cout() << pluralise( matchedTestCases.size(), "test case" ) << '\n' << std::endl;
  9122. else
  9123. Catch::cout() << pluralise( matchedTestCases.size(), "matching test case" ) << '\n' << std::endl;
  9124. return matchedTestCases.size();
  9125. }
  9126. std::size_t listTestsNamesOnly( Config const& config ) {
  9127. TestSpec const& testSpec = config.testSpec();
  9128. std::size_t matchedTests = 0;
  9129. std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
  9130. for( auto const& testCaseInfo : matchedTestCases ) {
  9131. matchedTests++;
  9132. if( startsWith( testCaseInfo.name, '#' ) )
  9133. Catch::cout() << '"' << testCaseInfo.name << '"';
  9134. else
  9135. Catch::cout() << testCaseInfo.name;
  9136. if ( config.verbosity() >= Verbosity::High )
  9137. Catch::cout() << "\t@" << testCaseInfo.lineInfo;
  9138. Catch::cout() << std::endl;
  9139. }
  9140. return matchedTests;
  9141. }
  9142. void TagInfo::add( std::string const& spelling ) {
  9143. ++count;
  9144. spellings.insert( spelling );
  9145. }
  9146. std::string TagInfo::all() const {
  9147. size_t size = 0;
  9148. for (auto const& spelling : spellings) {
  9149. // Add 2 for the brackes
  9150. size += spelling.size() + 2;
  9151. }
  9152. std::string out; out.reserve(size);
  9153. for (auto const& spelling : spellings) {
  9154. out += '[';
  9155. out += spelling;
  9156. out += ']';
  9157. }
  9158. return out;
  9159. }
  9160. std::size_t listTags( Config const& config ) {
  9161. TestSpec const& testSpec = config.testSpec();
  9162. if( config.hasTestFilters() )
  9163. Catch::cout() << "Tags for matching test cases:\n";
  9164. else {
  9165. Catch::cout() << "All available tags:\n";
  9166. }
  9167. std::map<std::string, TagInfo> tagCounts;
  9168. std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
  9169. for( auto const& testCase : matchedTestCases ) {
  9170. for( auto const& tagName : testCase.getTestCaseInfo().tags ) {
  9171. std::string lcaseTagName = toLower( tagName );
  9172. auto countIt = tagCounts.find( lcaseTagName );
  9173. if( countIt == tagCounts.end() )
  9174. countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
  9175. countIt->second.add( tagName );
  9176. }
  9177. }
  9178. for( auto const& tagCount : tagCounts ) {
  9179. ReusableStringStream rss;
  9180. rss << " " << std::setw(2) << tagCount.second.count << " ";
  9181. auto str = rss.str();
  9182. auto wrapper = Column( tagCount.second.all() )
  9183. .initialIndent( 0 )
  9184. .indent( str.size() )
  9185. .width( CATCH_CONFIG_CONSOLE_WIDTH-10 );
  9186. Catch::cout() << str << wrapper << '\n';
  9187. }
  9188. Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl;
  9189. return tagCounts.size();
  9190. }
  9191. std::size_t listReporters() {
  9192. Catch::cout() << "Available reporters:\n";
  9193. IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
  9194. std::size_t maxNameLen = 0;
  9195. for( auto const& factoryKvp : factories )
  9196. maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() );
  9197. for( auto const& factoryKvp : factories ) {
  9198. Catch::cout()
  9199. << Column( factoryKvp.first + ":" )
  9200. .indent(2)
  9201. .width( 5+maxNameLen )
  9202. + Column( factoryKvp.second->getDescription() )
  9203. .initialIndent(0)
  9204. .indent(2)
  9205. .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 )
  9206. << "\n";
  9207. }
  9208. Catch::cout() << std::endl;
  9209. return factories.size();
  9210. }
  9211. Option<std::size_t> list( std::shared_ptr<Config> const& config ) {
  9212. Option<std::size_t> listedCount;
  9213. getCurrentMutableContext().setConfig( config );
  9214. if( config->listTests() )
  9215. listedCount = listedCount.valueOr(0) + listTests( *config );
  9216. if( config->listTestNamesOnly() )
  9217. listedCount = listedCount.valueOr(0) + listTestsNamesOnly( *config );
  9218. if( config->listTags() )
  9219. listedCount = listedCount.valueOr(0) + listTags( *config );
  9220. if( config->listReporters() )
  9221. listedCount = listedCount.valueOr(0) + listReporters();
  9222. return listedCount;
  9223. }
  9224. } // end namespace Catch
  9225. // end catch_list.cpp
  9226. // start catch_matchers.cpp
  9227. namespace Catch {
  9228. namespace Matchers {
  9229. namespace Impl {
  9230. std::string MatcherUntypedBase::toString() const {
  9231. if( m_cachedToString.empty() )
  9232. m_cachedToString = describe();
  9233. return m_cachedToString;
  9234. }
  9235. MatcherUntypedBase::~MatcherUntypedBase() = default;
  9236. } // namespace Impl
  9237. } // namespace Matchers
  9238. using namespace Matchers;
  9239. using Matchers::Impl::MatcherBase;
  9240. } // namespace Catch
  9241. // end catch_matchers.cpp
  9242. // start catch_matchers_exception.cpp
  9243. namespace Catch {
  9244. namespace Matchers {
  9245. namespace Exception {
  9246. bool ExceptionMessageMatcher::match(std::exception const& ex) const {
  9247. return ex.what() == m_message;
  9248. }
  9249. std::string ExceptionMessageMatcher::describe() const {
  9250. return "exception message matches \"" + m_message + "\"";
  9251. }
  9252. }
  9253. Exception::ExceptionMessageMatcher Message(std::string const& message) {
  9254. return Exception::ExceptionMessageMatcher(message);
  9255. }
  9256. // namespace Exception
  9257. } // namespace Matchers
  9258. } // namespace Catch
  9259. // end catch_matchers_exception.cpp
  9260. // start catch_matchers_floating.cpp
  9261. // start catch_polyfills.hpp
  9262. namespace Catch {
  9263. bool isnan(float f);
  9264. bool isnan(double d);
  9265. }
  9266. // end catch_polyfills.hpp
  9267. // start catch_to_string.hpp
  9268. #include <string>
  9269. namespace Catch {
  9270. template <typename T>
  9271. std::string to_string(T const& t) {
  9272. #if defined(CATCH_CONFIG_CPP11_TO_STRING)
  9273. return std::to_string(t);
  9274. #else
  9275. ReusableStringStream rss;
  9276. rss << t;
  9277. return rss.str();
  9278. #endif
  9279. }
  9280. } // end namespace Catch
  9281. // end catch_to_string.hpp
  9282. #include <algorithm>
  9283. #include <cmath>
  9284. #include <cstdlib>
  9285. #include <cstdint>
  9286. #include <cstring>
  9287. #include <sstream>
  9288. #include <type_traits>
  9289. #include <iomanip>
  9290. #include <limits>
  9291. namespace Catch {
  9292. namespace {
  9293. int32_t convert(float f) {
  9294. static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
  9295. int32_t i;
  9296. std::memcpy(&i, &f, sizeof(f));
  9297. return i;
  9298. }
  9299. int64_t convert(double d) {
  9300. static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
  9301. int64_t i;
  9302. std::memcpy(&i, &d, sizeof(d));
  9303. return i;
  9304. }
  9305. template <typename FP>
  9306. bool almostEqualUlps(FP lhs, FP rhs, uint64_t maxUlpDiff) {
  9307. // Comparison with NaN should always be false.
  9308. // This way we can rule it out before getting into the ugly details
  9309. if (Catch::isnan(lhs) || Catch::isnan(rhs)) {
  9310. return false;
  9311. }
  9312. auto lc = convert(lhs);
  9313. auto rc = convert(rhs);
  9314. if ((lc < 0) != (rc < 0)) {
  9315. // Potentially we can have +0 and -0
  9316. return lhs == rhs;
  9317. }
  9318. auto ulpDiff = std::abs(lc - rc);
  9319. return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff;
  9320. }
  9321. #if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
  9322. float nextafter(float x, float y) {
  9323. return ::nextafterf(x, y);
  9324. }
  9325. double nextafter(double x, double y) {
  9326. return ::nextafter(x, y);
  9327. }
  9328. #endif // ^^^ CATCH_CONFIG_GLOBAL_NEXTAFTER ^^^
  9329. template <typename FP>
  9330. FP step(FP start, FP direction, uint64_t steps) {
  9331. for (uint64_t i = 0; i < steps; ++i) {
  9332. #if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
  9333. start = Catch::nextafter(start, direction);
  9334. #else
  9335. start = std::nextafter(start, direction);
  9336. #endif
  9337. }
  9338. return start;
  9339. }
  9340. // Performs equivalent check of std::fabs(lhs - rhs) <= margin
  9341. // But without the subtraction to allow for INFINITY in comparison
  9342. bool marginComparison(double lhs, double rhs, double margin) {
  9343. return (lhs + margin >= rhs) && (rhs + margin >= lhs);
  9344. }
  9345. template <typename FloatingPoint>
  9346. void write(std::ostream& out, FloatingPoint num) {
  9347. out << std::scientific
  9348. << std::setprecision(std::numeric_limits<FloatingPoint>::max_digits10 - 1)
  9349. << num;
  9350. }
  9351. } // end anonymous namespace
  9352. namespace Matchers {
  9353. namespace Floating {
  9354. enum class FloatingPointKind : uint8_t {
  9355. Float,
  9356. Double
  9357. };
  9358. WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
  9359. :m_target{ target }, m_margin{ margin } {
  9360. CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.'
  9361. << " Margin has to be non-negative.");
  9362. }
  9363. // Performs equivalent check of std::fabs(lhs - rhs) <= margin
  9364. // But without the subtraction to allow for INFINITY in comparison
  9365. bool WithinAbsMatcher::match(double const& matchee) const {
  9366. return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);
  9367. }
  9368. std::string WithinAbsMatcher::describe() const {
  9369. return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target);
  9370. }
  9371. WithinUlpsMatcher::WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType)
  9372. :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
  9373. CATCH_ENFORCE(m_type == FloatingPointKind::Double
  9374. || m_ulps < (std::numeric_limits<uint32_t>::max)(),
  9375. "Provided ULP is impossibly large for a float comparison.");
  9376. }
  9377. #if defined(__clang__)
  9378. #pragma clang diagnostic push
  9379. // Clang <3.5 reports on the default branch in the switch below
  9380. #pragma clang diagnostic ignored "-Wunreachable-code"
  9381. #endif
  9382. bool WithinUlpsMatcher::match(double const& matchee) const {
  9383. switch (m_type) {
  9384. case FloatingPointKind::Float:
  9385. return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps);
  9386. case FloatingPointKind::Double:
  9387. return almostEqualUlps<double>(matchee, m_target, m_ulps);
  9388. default:
  9389. CATCH_INTERNAL_ERROR( "Unknown FloatingPointKind value" );
  9390. }
  9391. }
  9392. #if defined(__clang__)
  9393. #pragma clang diagnostic pop
  9394. #endif
  9395. std::string WithinUlpsMatcher::describe() const {
  9396. std::stringstream ret;
  9397. ret << "is within " << m_ulps << " ULPs of ";
  9398. if (m_type == FloatingPointKind::Float) {
  9399. write(ret, static_cast<float>(m_target));
  9400. ret << 'f';
  9401. } else {
  9402. write(ret, m_target);
  9403. }
  9404. ret << " ([";
  9405. if (m_type == FloatingPointKind::Double) {
  9406. write(ret, step(m_target, static_cast<double>(-INFINITY), m_ulps));
  9407. ret << ", ";
  9408. write(ret, step(m_target, static_cast<double>( INFINITY), m_ulps));
  9409. } else {
  9410. // We have to cast INFINITY to float because of MinGW, see #1782
  9411. write(ret, step(static_cast<float>(m_target), static_cast<float>(-INFINITY), m_ulps));
  9412. ret << ", ";
  9413. write(ret, step(static_cast<float>(m_target), static_cast<float>( INFINITY), m_ulps));
  9414. }
  9415. ret << "])";
  9416. return ret.str();
  9417. }
  9418. WithinRelMatcher::WithinRelMatcher(double target, double epsilon):
  9419. m_target(target),
  9420. m_epsilon(epsilon){
  9421. CATCH_ENFORCE(m_epsilon >= 0., "Relative comparison with epsilon < 0 does not make sense.");
  9422. CATCH_ENFORCE(m_epsilon < 1., "Relative comparison with epsilon >= 1 does not make sense.");
  9423. }
  9424. bool WithinRelMatcher::match(double const& matchee) const {
  9425. const auto relMargin = m_epsilon * (std::max)(std::fabs(matchee), std::fabs(m_target));
  9426. return marginComparison(matchee, m_target,
  9427. std::isinf(relMargin)? 0 : relMargin);
  9428. }
  9429. std::string WithinRelMatcher::describe() const {
  9430. Catch::ReusableStringStream sstr;
  9431. sstr << "and " << m_target << " are within " << m_epsilon * 100. << "% of each other";
  9432. return sstr.str();
  9433. }
  9434. }// namespace Floating
  9435. Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff) {
  9436. return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
  9437. }
  9438. Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff) {
  9439. return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
  9440. }
  9441. Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
  9442. return Floating::WithinAbsMatcher(target, margin);
  9443. }
  9444. Floating::WithinRelMatcher WithinRel(double target, double eps) {
  9445. return Floating::WithinRelMatcher(target, eps);
  9446. }
  9447. Floating::WithinRelMatcher WithinRel(double target) {
  9448. return Floating::WithinRelMatcher(target, std::numeric_limits<double>::epsilon() * 100);
  9449. }
  9450. Floating::WithinRelMatcher WithinRel(float target, float eps) {
  9451. return Floating::WithinRelMatcher(target, eps);
  9452. }
  9453. Floating::WithinRelMatcher WithinRel(float target) {
  9454. return Floating::WithinRelMatcher(target, std::numeric_limits<float>::epsilon() * 100);
  9455. }
  9456. } // namespace Matchers
  9457. } // namespace Catch
  9458. // end catch_matchers_floating.cpp
  9459. // start catch_matchers_generic.cpp
  9460. std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) {
  9461. if (desc.empty()) {
  9462. return "matches undescribed predicate";
  9463. } else {
  9464. return "matches predicate: \"" + desc + '"';
  9465. }
  9466. }
  9467. // end catch_matchers_generic.cpp
  9468. // start catch_matchers_string.cpp
  9469. #include <regex>
  9470. namespace Catch {
  9471. namespace Matchers {
  9472. namespace StdString {
  9473. CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
  9474. : m_caseSensitivity( caseSensitivity ),
  9475. m_str( adjustString( str ) )
  9476. {}
  9477. std::string CasedString::adjustString( std::string const& str ) const {
  9478. return m_caseSensitivity == CaseSensitive::No
  9479. ? toLower( str )
  9480. : str;
  9481. }
  9482. std::string CasedString::caseSensitivitySuffix() const {
  9483. return m_caseSensitivity == CaseSensitive::No
  9484. ? " (case insensitive)"
  9485. : std::string();
  9486. }
  9487. StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )
  9488. : m_comparator( comparator ),
  9489. m_operation( operation ) {
  9490. }
  9491. std::string StringMatcherBase::describe() const {
  9492. std::string description;
  9493. description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +
  9494. m_comparator.caseSensitivitySuffix().size());
  9495. description += m_operation;
  9496. description += ": \"";
  9497. description += m_comparator.m_str;
  9498. description += "\"";
  9499. description += m_comparator.caseSensitivitySuffix();
  9500. return description;
  9501. }
  9502. EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {}
  9503. bool EqualsMatcher::match( std::string const& source ) const {
  9504. return m_comparator.adjustString( source ) == m_comparator.m_str;
  9505. }
  9506. ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {}
  9507. bool ContainsMatcher::match( std::string const& source ) const {
  9508. return contains( m_comparator.adjustString( source ), m_comparator.m_str );
  9509. }
  9510. StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {}
  9511. bool StartsWithMatcher::match( std::string const& source ) const {
  9512. return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );
  9513. }
  9514. EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {}
  9515. bool EndsWithMatcher::match( std::string const& source ) const {
  9516. return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );
  9517. }
  9518. RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity): m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {}
  9519. bool RegexMatcher::match(std::string const& matchee) const {
  9520. auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway
  9521. if (m_caseSensitivity == CaseSensitive::Choice::No) {
  9522. flags |= std::regex::icase;
  9523. }
  9524. auto reg = std::regex(m_regex, flags);
  9525. return std::regex_match(matchee, reg);
  9526. }
  9527. std::string RegexMatcher::describe() const {
  9528. return "matches " + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? " case sensitively" : " case insensitively");
  9529. }
  9530. } // namespace StdString
  9531. StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
  9532. return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );
  9533. }
  9534. StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
  9535. return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );
  9536. }
  9537. StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
  9538. return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );
  9539. }
  9540. StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
  9541. return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );
  9542. }
  9543. StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity) {
  9544. return StdString::RegexMatcher(regex, caseSensitivity);
  9545. }
  9546. } // namespace Matchers
  9547. } // namespace Catch
  9548. // end catch_matchers_string.cpp
  9549. // start catch_message.cpp
  9550. // start catch_uncaught_exceptions.h
  9551. namespace Catch {
  9552. bool uncaught_exceptions();
  9553. } // end namespace Catch
  9554. // end catch_uncaught_exceptions.h
  9555. #include <cassert>
  9556. #include <stack>
  9557. namespace Catch {
  9558. MessageInfo::MessageInfo( StringRef const& _macroName,
  9559. SourceLineInfo const& _lineInfo,
  9560. ResultWas::OfType _type )
  9561. : macroName( _macroName ),
  9562. lineInfo( _lineInfo ),
  9563. type( _type ),
  9564. sequence( ++globalCount )
  9565. {}
  9566. bool MessageInfo::operator==( MessageInfo const& other ) const {
  9567. return sequence == other.sequence;
  9568. }
  9569. bool MessageInfo::operator<( MessageInfo const& other ) const {
  9570. return sequence < other.sequence;
  9571. }
  9572. // This may need protecting if threading support is added
  9573. unsigned int MessageInfo::globalCount = 0;
  9574. ////////////////////////////////////////////////////////////////////////////
  9575. Catch::MessageBuilder::MessageBuilder( StringRef const& macroName,
  9576. SourceLineInfo const& lineInfo,
  9577. ResultWas::OfType type )
  9578. :m_info(macroName, lineInfo, type) {}
  9579. ////////////////////////////////////////////////////////////////////////////
  9580. ScopedMessage::ScopedMessage( MessageBuilder const& builder )
  9581. : m_info( builder.m_info ), m_moved()
  9582. {
  9583. m_info.message = builder.m_stream.str();
  9584. getResultCapture().pushScopedMessage( m_info );
  9585. }
  9586. ScopedMessage::ScopedMessage( ScopedMessage&& old )
  9587. : m_info( old.m_info ), m_moved()
  9588. {
  9589. old.m_moved = true;
  9590. }
  9591. ScopedMessage::~ScopedMessage() {
  9592. if ( !uncaught_exceptions() && !m_moved ){
  9593. getResultCapture().popScopedMessage(m_info);
  9594. }
  9595. }
  9596. Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {
  9597. auto trimmed = [&] (size_t start, size_t end) {
  9598. while (names[start] == ',' || isspace(static_cast<unsigned char>(names[start]))) {
  9599. ++start;
  9600. }
  9601. while (names[end] == ',' || isspace(static_cast<unsigned char>(names[end]))) {
  9602. --end;
  9603. }
  9604. return names.substr(start, end - start + 1);
  9605. };
  9606. auto skipq = [&] (size_t start, char quote) {
  9607. for (auto i = start + 1; i < names.size() ; ++i) {
  9608. if (names[i] == quote)
  9609. return i;
  9610. if (names[i] == '\\')
  9611. ++i;
  9612. }
  9613. CATCH_INTERNAL_ERROR("CAPTURE parsing encountered unmatched quote");
  9614. };
  9615. size_t start = 0;
  9616. std::stack<char> openings;
  9617. for (size_t pos = 0; pos < names.size(); ++pos) {
  9618. char c = names[pos];
  9619. switch (c) {
  9620. case '[':
  9621. case '{':
  9622. case '(':
  9623. // It is basically impossible to disambiguate between
  9624. // comparison and start of template args in this context
  9625. // case '<':
  9626. openings.push(c);
  9627. break;
  9628. case ']':
  9629. case '}':
  9630. case ')':
  9631. // case '>':
  9632. openings.pop();
  9633. break;
  9634. case '"':
  9635. case '\'':
  9636. pos = skipq(pos, c);
  9637. break;
  9638. case ',':
  9639. if (start != pos && openings.empty()) {
  9640. m_messages.emplace_back(macroName, lineInfo, resultType);
  9641. m_messages.back().message = static_cast<std::string>(trimmed(start, pos));
  9642. m_messages.back().message += " := ";
  9643. start = pos;
  9644. }
  9645. }
  9646. }
  9647. assert(openings.empty() && "Mismatched openings");
  9648. m_messages.emplace_back(macroName, lineInfo, resultType);
  9649. m_messages.back().message = static_cast<std::string>(trimmed(start, names.size() - 1));
  9650. m_messages.back().message += " := ";
  9651. }
  9652. Capturer::~Capturer() {
  9653. if ( !uncaught_exceptions() ){
  9654. assert( m_captured == m_messages.size() );
  9655. for( size_t i = 0; i < m_captured; ++i )
  9656. m_resultCapture.popScopedMessage( m_messages[i] );
  9657. }
  9658. }
  9659. void Capturer::captureValue( size_t index, std::string const& value ) {
  9660. assert( index < m_messages.size() );
  9661. m_messages[index].message += value;
  9662. m_resultCapture.pushScopedMessage( m_messages[index] );
  9663. m_captured++;
  9664. }
  9665. } // end namespace Catch
  9666. // end catch_message.cpp
  9667. // start catch_output_redirect.cpp
  9668. // start catch_output_redirect.h
  9669. #ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
  9670. #define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
  9671. #include <cstdio>
  9672. #include <iosfwd>
  9673. #include <string>
  9674. namespace Catch {
  9675. class RedirectedStream {
  9676. std::ostream& m_originalStream;
  9677. std::ostream& m_redirectionStream;
  9678. std::streambuf* m_prevBuf;
  9679. public:
  9680. RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream );
  9681. ~RedirectedStream();
  9682. };
  9683. class RedirectedStdOut {
  9684. ReusableStringStream m_rss;
  9685. RedirectedStream m_cout;
  9686. public:
  9687. RedirectedStdOut();
  9688. auto str() const -> std::string;
  9689. };
  9690. // StdErr has two constituent streams in C++, std::cerr and std::clog
  9691. // This means that we need to redirect 2 streams into 1 to keep proper
  9692. // order of writes
  9693. class RedirectedStdErr {
  9694. ReusableStringStream m_rss;
  9695. RedirectedStream m_cerr;
  9696. RedirectedStream m_clog;
  9697. public:
  9698. RedirectedStdErr();
  9699. auto str() const -> std::string;
  9700. };
  9701. class RedirectedStreams {
  9702. public:
  9703. RedirectedStreams(RedirectedStreams const&) = delete;
  9704. RedirectedStreams& operator=(RedirectedStreams const&) = delete;
  9705. RedirectedStreams(RedirectedStreams&&) = delete;
  9706. RedirectedStreams& operator=(RedirectedStreams&&) = delete;
  9707. RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr);
  9708. ~RedirectedStreams();
  9709. private:
  9710. std::string& m_redirectedCout;
  9711. std::string& m_redirectedCerr;
  9712. RedirectedStdOut m_redirectedStdOut;
  9713. RedirectedStdErr m_redirectedStdErr;
  9714. };
  9715. #if defined(CATCH_CONFIG_NEW_CAPTURE)
  9716. // Windows's implementation of std::tmpfile is terrible (it tries
  9717. // to create a file inside system folder, thus requiring elevated
  9718. // privileges for the binary), so we have to use tmpnam(_s) and
  9719. // create the file ourselves there.
  9720. class TempFile {
  9721. public:
  9722. TempFile(TempFile const&) = delete;
  9723. TempFile& operator=(TempFile const&) = delete;
  9724. TempFile(TempFile&&) = delete;
  9725. TempFile& operator=(TempFile&&) = delete;
  9726. TempFile();
  9727. ~TempFile();
  9728. std::FILE* getFile();
  9729. std::string getContents();
  9730. private:
  9731. std::FILE* m_file = nullptr;
  9732. #if defined(_MSC_VER)
  9733. char m_buffer[L_tmpnam] = { 0 };
  9734. #endif
  9735. };
  9736. class OutputRedirect {
  9737. public:
  9738. OutputRedirect(OutputRedirect const&) = delete;
  9739. OutputRedirect& operator=(OutputRedirect const&) = delete;
  9740. OutputRedirect(OutputRedirect&&) = delete;
  9741. OutputRedirect& operator=(OutputRedirect&&) = delete;
  9742. OutputRedirect(std::string& stdout_dest, std::string& stderr_dest);
  9743. ~OutputRedirect();
  9744. private:
  9745. int m_originalStdout = -1;
  9746. int m_originalStderr = -1;
  9747. TempFile m_stdoutFile;
  9748. TempFile m_stderrFile;
  9749. std::string& m_stdoutDest;
  9750. std::string& m_stderrDest;
  9751. };
  9752. #endif
  9753. } // end namespace Catch
  9754. #endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
  9755. // end catch_output_redirect.h
  9756. #include <cstdio>
  9757. #include <cstring>
  9758. #include <fstream>
  9759. #include <sstream>
  9760. #include <stdexcept>
  9761. #if defined(CATCH_CONFIG_NEW_CAPTURE)
  9762. #if defined(_MSC_VER)
  9763. #include <io.h> //_dup and _dup2
  9764. #define dup _dup
  9765. #define dup2 _dup2
  9766. #define fileno _fileno
  9767. #else
  9768. #include <unistd.h> // dup and dup2
  9769. #endif
  9770. #endif
  9771. namespace Catch {
  9772. RedirectedStream::RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream )
  9773. : m_originalStream( originalStream ),
  9774. m_redirectionStream( redirectionStream ),
  9775. m_prevBuf( m_originalStream.rdbuf() )
  9776. {
  9777. m_originalStream.rdbuf( m_redirectionStream.rdbuf() );
  9778. }
  9779. RedirectedStream::~RedirectedStream() {
  9780. m_originalStream.rdbuf( m_prevBuf );
  9781. }
  9782. RedirectedStdOut::RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {}
  9783. auto RedirectedStdOut::str() const -> std::string { return m_rss.str(); }
  9784. RedirectedStdErr::RedirectedStdErr()
  9785. : m_cerr( Catch::cerr(), m_rss.get() ),
  9786. m_clog( Catch::clog(), m_rss.get() )
  9787. {}
  9788. auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }
  9789. RedirectedStreams::RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr)
  9790. : m_redirectedCout(redirectedCout),
  9791. m_redirectedCerr(redirectedCerr)
  9792. {}
  9793. RedirectedStreams::~RedirectedStreams() {
  9794. m_redirectedCout += m_redirectedStdOut.str();
  9795. m_redirectedCerr += m_redirectedStdErr.str();
  9796. }
  9797. #if defined(CATCH_CONFIG_NEW_CAPTURE)
  9798. #if defined(_MSC_VER)
  9799. TempFile::TempFile() {
  9800. if (tmpnam_s(m_buffer)) {
  9801. CATCH_RUNTIME_ERROR("Could not get a temp filename");
  9802. }
  9803. if (fopen_s(&m_file, m_buffer, "w+")) {
  9804. char buffer[100];
  9805. if (strerror_s(buffer, errno)) {
  9806. CATCH_RUNTIME_ERROR("Could not translate errno to a string");
  9807. }
  9808. CATCH_RUNTIME_ERROR("Could not open the temp file: '" << m_buffer << "' because: " << buffer);
  9809. }
  9810. }
  9811. #else
  9812. TempFile::TempFile() {
  9813. m_file = std::tmpfile();
  9814. if (!m_file) {
  9815. CATCH_RUNTIME_ERROR("Could not create a temp file.");
  9816. }
  9817. }
  9818. #endif
  9819. TempFile::~TempFile() {
  9820. // TBD: What to do about errors here?
  9821. std::fclose(m_file);
  9822. // We manually create the file on Windows only, on Linux
  9823. // it will be autodeleted
  9824. #if defined(_MSC_VER)
  9825. std::remove(m_buffer);
  9826. #endif
  9827. }
  9828. FILE* TempFile::getFile() {
  9829. return m_file;
  9830. }
  9831. std::string TempFile::getContents() {
  9832. std::stringstream sstr;
  9833. char buffer[100] = {};
  9834. std::rewind(m_file);
  9835. while (std::fgets(buffer, sizeof(buffer), m_file)) {
  9836. sstr << buffer;
  9837. }
  9838. return sstr.str();
  9839. }
  9840. OutputRedirect::OutputRedirect(std::string& stdout_dest, std::string& stderr_dest) :
  9841. m_originalStdout(dup(1)),
  9842. m_originalStderr(dup(2)),
  9843. m_stdoutDest(stdout_dest),
  9844. m_stderrDest(stderr_dest) {
  9845. dup2(fileno(m_stdoutFile.getFile()), 1);
  9846. dup2(fileno(m_stderrFile.getFile()), 2);
  9847. }
  9848. OutputRedirect::~OutputRedirect() {
  9849. Catch::cout() << std::flush;
  9850. fflush(stdout);
  9851. // Since we support overriding these streams, we flush cerr
  9852. // even though std::cerr is unbuffered
  9853. Catch::cerr() << std::flush;
  9854. Catch::clog() << std::flush;
  9855. fflush(stderr);
  9856. dup2(m_originalStdout, 1);
  9857. dup2(m_originalStderr, 2);
  9858. m_stdoutDest += m_stdoutFile.getContents();
  9859. m_stderrDest += m_stderrFile.getContents();
  9860. }
  9861. #endif // CATCH_CONFIG_NEW_CAPTURE
  9862. } // namespace Catch
  9863. #if defined(CATCH_CONFIG_NEW_CAPTURE)
  9864. #if defined(_MSC_VER)
  9865. #undef dup
  9866. #undef dup2
  9867. #undef fileno
  9868. #endif
  9869. #endif
  9870. // end catch_output_redirect.cpp
  9871. // start catch_polyfills.cpp
  9872. #include <cmath>
  9873. namespace Catch {
  9874. #if !defined(CATCH_CONFIG_POLYFILL_ISNAN)
  9875. bool isnan(float f) {
  9876. return std::isnan(f);
  9877. }
  9878. bool isnan(double d) {
  9879. return std::isnan(d);
  9880. }
  9881. #else
  9882. // For now we only use this for embarcadero
  9883. bool isnan(float f) {
  9884. return std::_isnan(f);
  9885. }
  9886. bool isnan(double d) {
  9887. return std::_isnan(d);
  9888. }
  9889. #endif
  9890. } // end namespace Catch
  9891. // end catch_polyfills.cpp
  9892. // start catch_random_number_generator.cpp
  9893. namespace Catch {
  9894. namespace {
  9895. #if defined(_MSC_VER)
  9896. #pragma warning(push)
  9897. #pragma warning(disable:4146) // we negate uint32 during the rotate
  9898. #endif
  9899. // Safe rotr implementation thanks to John Regehr
  9900. uint32_t rotate_right(uint32_t val, uint32_t count) {
  9901. const uint32_t mask = 31;
  9902. count &= mask;
  9903. return (val >> count) | (val << (-count & mask));
  9904. }
  9905. #if defined(_MSC_VER)
  9906. #pragma warning(pop)
  9907. #endif
  9908. }
  9909. SimplePcg32::SimplePcg32(result_type seed_) {
  9910. seed(seed_);
  9911. }
  9912. void SimplePcg32::seed(result_type seed_) {
  9913. m_state = 0;
  9914. (*this)();
  9915. m_state += seed_;
  9916. (*this)();
  9917. }
  9918. void SimplePcg32::discard(uint64_t skip) {
  9919. // We could implement this to run in O(log n) steps, but this
  9920. // should suffice for our use case.
  9921. for (uint64_t s = 0; s < skip; ++s) {
  9922. static_cast<void>((*this)());
  9923. }
  9924. }
  9925. SimplePcg32::result_type SimplePcg32::operator()() {
  9926. // prepare the output value
  9927. const uint32_t xorshifted = static_cast<uint32_t>(((m_state >> 18u) ^ m_state) >> 27u);
  9928. const auto output = rotate_right(xorshifted, m_state >> 59u);
  9929. // advance state
  9930. m_state = m_state * 6364136223846793005ULL + s_inc;
  9931. return output;
  9932. }
  9933. bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
  9934. return lhs.m_state == rhs.m_state;
  9935. }
  9936. bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
  9937. return lhs.m_state != rhs.m_state;
  9938. }
  9939. }
  9940. // end catch_random_number_generator.cpp
  9941. // start catch_registry_hub.cpp
  9942. // start catch_test_case_registry_impl.h
  9943. #include <vector>
  9944. #include <set>
  9945. #include <algorithm>
  9946. #include <ios>
  9947. namespace Catch {
  9948. class TestCase;
  9949. struct IConfig;
  9950. std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases );
  9951. bool isThrowSafe( TestCase const& testCase, IConfig const& config );
  9952. bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
  9953. void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions );
  9954. std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
  9955. std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
  9956. class TestRegistry : public ITestCaseRegistry {
  9957. public:
  9958. virtual ~TestRegistry() = default;
  9959. virtual void registerTest( TestCase const& testCase );
  9960. std::vector<TestCase> const& getAllTests() const override;
  9961. std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const override;
  9962. private:
  9963. std::vector<TestCase> m_functions;
  9964. mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;
  9965. mutable std::vector<TestCase> m_sortedFunctions;
  9966. std::size_t m_unnamedCount = 0;
  9967. std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
  9968. };
  9969. ///////////////////////////////////////////////////////////////////////////
  9970. class TestInvokerAsFunction : public ITestInvoker {
  9971. void(*m_testAsFunction)();
  9972. public:
  9973. TestInvokerAsFunction( void(*testAsFunction)() ) noexcept;
  9974. void invoke() const override;
  9975. };
  9976. std::string extractClassName( StringRef const& classOrQualifiedMethodName );
  9977. ///////////////////////////////////////////////////////////////////////////
  9978. } // end namespace Catch
  9979. // end catch_test_case_registry_impl.h
  9980. // start catch_reporter_registry.h
  9981. #include <map>
  9982. namespace Catch {
  9983. class ReporterRegistry : public IReporterRegistry {
  9984. public:
  9985. ~ReporterRegistry() override;
  9986. IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const override;
  9987. void registerReporter( std::string const& name, IReporterFactoryPtr const& factory );
  9988. void registerListener( IReporterFactoryPtr const& factory );
  9989. FactoryMap const& getFactories() const override;
  9990. Listeners const& getListeners() const override;
  9991. private:
  9992. FactoryMap m_factories;
  9993. Listeners m_listeners;
  9994. };
  9995. }
  9996. // end catch_reporter_registry.h
  9997. // start catch_tag_alias_registry.h
  9998. // start catch_tag_alias.h
  9999. #include <string>
  10000. namespace Catch {
  10001. struct TagAlias {
  10002. TagAlias(std::string const& _tag, SourceLineInfo _lineInfo);
  10003. std::string tag;
  10004. SourceLineInfo lineInfo;
  10005. };
  10006. } // end namespace Catch
  10007. // end catch_tag_alias.h
  10008. #include <map>
  10009. namespace Catch {
  10010. class TagAliasRegistry : public ITagAliasRegistry {
  10011. public:
  10012. ~TagAliasRegistry() override;
  10013. TagAlias const* find( std::string const& alias ) const override;
  10014. std::string expandAliases( std::string const& unexpandedTestSpec ) const override;
  10015. void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
  10016. private:
  10017. std::map<std::string, TagAlias> m_registry;
  10018. };
  10019. } // end namespace Catch
  10020. // end catch_tag_alias_registry.h
  10021. // start catch_startup_exception_registry.h
  10022. #include <vector>
  10023. #include <exception>
  10024. namespace Catch {
  10025. class StartupExceptionRegistry {
  10026. #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  10027. public:
  10028. void add(std::exception_ptr const& exception) noexcept;
  10029. std::vector<std::exception_ptr> const& getExceptions() const noexcept;
  10030. private:
  10031. std::vector<std::exception_ptr> m_exceptions;
  10032. #endif
  10033. };
  10034. } // end namespace Catch
  10035. // end catch_startup_exception_registry.h
  10036. // start catch_singletons.hpp
  10037. namespace Catch {
  10038. struct ISingleton {
  10039. virtual ~ISingleton();
  10040. };
  10041. void addSingleton( ISingleton* singleton );
  10042. void cleanupSingletons();
  10043. template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>
  10044. class Singleton : SingletonImplT, public ISingleton {
  10045. static auto getInternal() -> Singleton* {
  10046. static Singleton* s_instance = nullptr;
  10047. if( !s_instance ) {
  10048. s_instance = new Singleton;
  10049. addSingleton( s_instance );
  10050. }
  10051. return s_instance;
  10052. }
  10053. public:
  10054. static auto get() -> InterfaceT const& {
  10055. return *getInternal();
  10056. }
  10057. static auto getMutable() -> MutableInterfaceT& {
  10058. return *getInternal();
  10059. }
  10060. };
  10061. } // namespace Catch
  10062. // end catch_singletons.hpp
  10063. namespace Catch {
  10064. namespace {
  10065. class RegistryHub : public IRegistryHub, public IMutableRegistryHub,
  10066. private NonCopyable {
  10067. public: // IRegistryHub
  10068. RegistryHub() = default;
  10069. IReporterRegistry const& getReporterRegistry() const override {
  10070. return m_reporterRegistry;
  10071. }
  10072. ITestCaseRegistry const& getTestCaseRegistry() const override {
  10073. return m_testCaseRegistry;
  10074. }
  10075. IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override {
  10076. return m_exceptionTranslatorRegistry;
  10077. }
  10078. ITagAliasRegistry const& getTagAliasRegistry() const override {
  10079. return m_tagAliasRegistry;
  10080. }
  10081. StartupExceptionRegistry const& getStartupExceptionRegistry() const override {
  10082. return m_exceptionRegistry;
  10083. }
  10084. public: // IMutableRegistryHub
  10085. void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) override {
  10086. m_reporterRegistry.registerReporter( name, factory );
  10087. }
  10088. void registerListener( IReporterFactoryPtr const& factory ) override {
  10089. m_reporterRegistry.registerListener( factory );
  10090. }
  10091. void registerTest( TestCase const& testInfo ) override {
  10092. m_testCaseRegistry.registerTest( testInfo );
  10093. }
  10094. void registerTranslator( const IExceptionTranslator* translator ) override {
  10095. m_exceptionTranslatorRegistry.registerTranslator( translator );
  10096. }
  10097. void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override {
  10098. m_tagAliasRegistry.add( alias, tag, lineInfo );
  10099. }
  10100. void registerStartupException() noexcept override {
  10101. #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  10102. m_exceptionRegistry.add(std::current_exception());
  10103. #else
  10104. CATCH_INTERNAL_ERROR("Attempted to register active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
  10105. #endif
  10106. }
  10107. IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override {
  10108. return m_enumValuesRegistry;
  10109. }
  10110. private:
  10111. TestRegistry m_testCaseRegistry;
  10112. ReporterRegistry m_reporterRegistry;
  10113. ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
  10114. TagAliasRegistry m_tagAliasRegistry;
  10115. StartupExceptionRegistry m_exceptionRegistry;
  10116. Detail::EnumValuesRegistry m_enumValuesRegistry;
  10117. };
  10118. }
  10119. using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>;
  10120. IRegistryHub const& getRegistryHub() {
  10121. return RegistryHubSingleton::get();
  10122. }
  10123. IMutableRegistryHub& getMutableRegistryHub() {
  10124. return RegistryHubSingleton::getMutable();
  10125. }
  10126. void cleanUp() {
  10127. cleanupSingletons();
  10128. cleanUpContext();
  10129. }
  10130. std::string translateActiveException() {
  10131. return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
  10132. }
  10133. } // end namespace Catch
  10134. // end catch_registry_hub.cpp
  10135. // start catch_reporter_registry.cpp
  10136. namespace Catch {
  10137. ReporterRegistry::~ReporterRegistry() = default;
  10138. IStreamingReporterPtr ReporterRegistry::create( std::string const& name, IConfigPtr const& config ) const {
  10139. auto it = m_factories.find( name );
  10140. if( it == m_factories.end() )
  10141. return nullptr;
  10142. return it->second->create( ReporterConfig( config ) );
  10143. }
  10144. void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) {
  10145. m_factories.emplace(name, factory);
  10146. }
  10147. void ReporterRegistry::registerListener( IReporterFactoryPtr const& factory ) {
  10148. m_listeners.push_back( factory );
  10149. }
  10150. IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const {
  10151. return m_factories;
  10152. }
  10153. IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const {
  10154. return m_listeners;
  10155. }
  10156. }
  10157. // end catch_reporter_registry.cpp
  10158. // start catch_result_type.cpp
  10159. namespace Catch {
  10160. bool isOk( ResultWas::OfType resultType ) {
  10161. return ( resultType & ResultWas::FailureBit ) == 0;
  10162. }
  10163. bool isJustInfo( int flags ) {
  10164. return flags == ResultWas::Info;
  10165. }
  10166. ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
  10167. return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
  10168. }
  10169. bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
  10170. bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
  10171. } // end namespace Catch
  10172. // end catch_result_type.cpp
  10173. // start catch_run_context.cpp
  10174. #include <cassert>
  10175. #include <algorithm>
  10176. #include <sstream>
  10177. namespace Catch {
  10178. namespace Generators {
  10179. struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {
  10180. GeneratorBasePtr m_generator;
  10181. GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
  10182. : TrackerBase( nameAndLocation, ctx, parent )
  10183. {}
  10184. ~GeneratorTracker();
  10185. static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {
  10186. std::shared_ptr<GeneratorTracker> tracker;
  10187. ITracker& currentTracker = ctx.currentTracker();
  10188. // Under specific circumstances, the generator we want
  10189. // to acquire is also the current tracker. If this is
  10190. // the case, we have to avoid looking through current
  10191. // tracker's children, and instead return the current
  10192. // tracker.
  10193. // A case where this check is important is e.g.
  10194. // for (int i = 0; i < 5; ++i) {
  10195. // int n = GENERATE(1, 2);
  10196. // }
  10197. //
  10198. // without it, the code above creates 5 nested generators.
  10199. if (currentTracker.nameAndLocation() == nameAndLocation) {
  10200. auto thisTracker = currentTracker.parent().findChild(nameAndLocation);
  10201. assert(thisTracker);
  10202. assert(thisTracker->isGeneratorTracker());
  10203. tracker = std::static_pointer_cast<GeneratorTracker>(thisTracker);
  10204. } else if ( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
  10205. assert( childTracker );
  10206. assert( childTracker->isGeneratorTracker() );
  10207. tracker = std::static_pointer_cast<GeneratorTracker>( childTracker );
  10208. } else {
  10209. tracker = std::make_shared<GeneratorTracker>( nameAndLocation, ctx, &currentTracker );
  10210. currentTracker.addChild( tracker );
  10211. }
  10212. if( !tracker->isComplete() ) {
  10213. tracker->open();
  10214. }
  10215. return *tracker;
  10216. }
  10217. // TrackerBase interface
  10218. bool isGeneratorTracker() const override { return true; }
  10219. auto hasGenerator() const -> bool override {
  10220. return !!m_generator;
  10221. }
  10222. void close() override {
  10223. TrackerBase::close();
  10224. // If a generator has a child (it is followed by a section)
  10225. // and none of its children have started, then we must wait
  10226. // until later to start consuming its values.
  10227. // This catches cases where `GENERATE` is placed between two
  10228. // `SECTION`s.
  10229. // **The check for m_children.empty cannot be removed**.
  10230. // doing so would break `GENERATE` _not_ followed by `SECTION`s.
  10231. const bool should_wait_for_child = [&]() {
  10232. // No children -> nobody to wait for
  10233. if ( m_children.empty() ) {
  10234. return false;
  10235. }
  10236. // If at least one child started executing, don't wait
  10237. if ( std::find_if(
  10238. m_children.begin(),
  10239. m_children.end(),
  10240. []( TestCaseTracking::ITrackerPtr tracker ) {
  10241. return tracker->hasStarted();
  10242. } ) != m_children.end() ) {
  10243. return false;
  10244. }
  10245. // No children have started. We need to check if they _can_
  10246. // start, and thus we should wait for them, or they cannot
  10247. // start (due to filters), and we shouldn't wait for them
  10248. auto* parent = m_parent;
  10249. // This is safe: there is always at least one section
  10250. // tracker in a test case tracking tree
  10251. while ( !parent->isSectionTracker() ) {
  10252. parent = &( parent->parent() );
  10253. }
  10254. assert( parent &&
  10255. "Missing root (test case) level section" );
  10256. auto const& parentSection =
  10257. static_cast<SectionTracker&>( *parent );
  10258. auto const& filters = parentSection.getFilters();
  10259. // No filters -> no restrictions on running sections
  10260. if ( filters.empty() ) {
  10261. return true;
  10262. }
  10263. for ( auto const& child : m_children ) {
  10264. if ( child->isSectionTracker() &&
  10265. std::find( filters.begin(),
  10266. filters.end(),
  10267. static_cast<SectionTracker&>( *child )
  10268. .trimmedName() ) !=
  10269. filters.end() ) {
  10270. return true;
  10271. }
  10272. }
  10273. return false;
  10274. }();
  10275. // This check is a bit tricky, because m_generator->next()
  10276. // has a side-effect, where it consumes generator's current
  10277. // value, but we do not want to invoke the side-effect if
  10278. // this generator is still waiting for any child to start.
  10279. if ( should_wait_for_child ||
  10280. ( m_runState == CompletedSuccessfully &&
  10281. m_generator->next() ) ) {
  10282. m_children.clear();
  10283. m_runState = Executing;
  10284. }
  10285. }
  10286. // IGeneratorTracker interface
  10287. auto getGenerator() const -> GeneratorBasePtr const& override {
  10288. return m_generator;
  10289. }
  10290. void setGenerator( GeneratorBasePtr&& generator ) override {
  10291. m_generator = std::move( generator );
  10292. }
  10293. };
  10294. GeneratorTracker::~GeneratorTracker() {}
  10295. }
  10296. RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
  10297. : m_runInfo(_config->name()),
  10298. m_context(getCurrentMutableContext()),
  10299. m_config(_config),
  10300. m_reporter(std::move(reporter)),
  10301. m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
  10302. m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )
  10303. {
  10304. m_context.setRunner(this);
  10305. m_context.setConfig(m_config);
  10306. m_context.setResultCapture(this);
  10307. m_reporter->testRunStarting(m_runInfo);
  10308. }
  10309. RunContext::~RunContext() {
  10310. m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
  10311. }
  10312. void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) {
  10313. m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));
  10314. }
  10315. void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) {
  10316. m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));
  10317. }
  10318. Totals RunContext::runTest(TestCase const& testCase) {
  10319. Totals prevTotals = m_totals;
  10320. std::string redirectedCout;
  10321. std::string redirectedCerr;
  10322. auto const& testInfo = testCase.getTestCaseInfo();
  10323. m_reporter->testCaseStarting(testInfo);
  10324. m_activeTestCase = &testCase;
  10325. ITracker& rootTracker = m_trackerContext.startRun();
  10326. assert(rootTracker.isSectionTracker());
  10327. static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun());
  10328. do {
  10329. m_trackerContext.startCycle();
  10330. m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));
  10331. runCurrentTest(redirectedCout, redirectedCerr);
  10332. } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());
  10333. Totals deltaTotals = m_totals.delta(prevTotals);
  10334. if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) {
  10335. deltaTotals.assertions.failed++;
  10336. deltaTotals.testCases.passed--;
  10337. deltaTotals.testCases.failed++;
  10338. }
  10339. m_totals.testCases += deltaTotals.testCases;
  10340. m_reporter->testCaseEnded(TestCaseStats(testInfo,
  10341. deltaTotals,
  10342. redirectedCout,
  10343. redirectedCerr,
  10344. aborting()));
  10345. m_activeTestCase = nullptr;
  10346. m_testCaseTracker = nullptr;
  10347. return deltaTotals;
  10348. }
  10349. IConfigPtr RunContext::config() const {
  10350. return m_config;
  10351. }
  10352. IStreamingReporter& RunContext::reporter() const {
  10353. return *m_reporter;
  10354. }
  10355. void RunContext::assertionEnded(AssertionResult const & result) {
  10356. if (result.getResultType() == ResultWas::Ok) {
  10357. m_totals.assertions.passed++;
  10358. m_lastAssertionPassed = true;
  10359. } else if (!result.isOk()) {
  10360. m_lastAssertionPassed = false;
  10361. if( m_activeTestCase->getTestCaseInfo().okToFail() )
  10362. m_totals.assertions.failedButOk++;
  10363. else
  10364. m_totals.assertions.failed++;
  10365. }
  10366. else {
  10367. m_lastAssertionPassed = true;
  10368. }
  10369. // We have no use for the return value (whether messages should be cleared), because messages were made scoped
  10370. // and should be let to clear themselves out.
  10371. static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
  10372. if (result.getResultType() != ResultWas::Warning)
  10373. m_messageScopes.clear();
  10374. // Reset working state
  10375. resetAssertionInfo();
  10376. m_lastResult = result;
  10377. }
  10378. void RunContext::resetAssertionInfo() {
  10379. m_lastAssertionInfo.macroName = StringRef();
  10380. m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
  10381. }
  10382. bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) {
  10383. ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));
  10384. if (!sectionTracker.isOpen())
  10385. return false;
  10386. m_activeSections.push_back(&sectionTracker);
  10387. m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
  10388. m_reporter->sectionStarting(sectionInfo);
  10389. assertions = m_totals.assertions;
  10390. return true;
  10391. }
  10392. auto RunContext::acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
  10393. using namespace Generators;
  10394. GeneratorTracker& tracker = GeneratorTracker::acquire(m_trackerContext,
  10395. TestCaseTracking::NameAndLocation( static_cast<std::string>(generatorName), lineInfo ) );
  10396. m_lastAssertionInfo.lineInfo = lineInfo;
  10397. return tracker;
  10398. }
  10399. bool RunContext::testForMissingAssertions(Counts& assertions) {
  10400. if (assertions.total() != 0)
  10401. return false;
  10402. if (!m_config->warnAboutMissingAssertions())
  10403. return false;
  10404. if (m_trackerContext.currentTracker().hasChildren())
  10405. return false;
  10406. m_totals.assertions.failed++;
  10407. assertions.failed++;
  10408. return true;
  10409. }
  10410. void RunContext::sectionEnded(SectionEndInfo const & endInfo) {
  10411. Counts assertions = m_totals.assertions - endInfo.prevAssertions;
  10412. bool missingAssertions = testForMissingAssertions(assertions);
  10413. if (!m_activeSections.empty()) {
  10414. m_activeSections.back()->close();
  10415. m_activeSections.pop_back();
  10416. }
  10417. m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
  10418. m_messages.clear();
  10419. m_messageScopes.clear();
  10420. }
  10421. void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {
  10422. if (m_unfinishedSections.empty())
  10423. m_activeSections.back()->fail();
  10424. else
  10425. m_activeSections.back()->close();
  10426. m_activeSections.pop_back();
  10427. m_unfinishedSections.push_back(endInfo);
  10428. }
  10429. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  10430. void RunContext::benchmarkPreparing(std::string const& name) {
  10431. m_reporter->benchmarkPreparing(name);
  10432. }
  10433. void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {
  10434. m_reporter->benchmarkStarting( info );
  10435. }
  10436. void RunContext::benchmarkEnded( BenchmarkStats<> const& stats ) {
  10437. m_reporter->benchmarkEnded( stats );
  10438. }
  10439. void RunContext::benchmarkFailed(std::string const & error) {
  10440. m_reporter->benchmarkFailed(error);
  10441. }
  10442. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  10443. void RunContext::pushScopedMessage(MessageInfo const & message) {
  10444. m_messages.push_back(message);
  10445. }
  10446. void RunContext::popScopedMessage(MessageInfo const & message) {
  10447. m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
  10448. }
  10449. void RunContext::emplaceUnscopedMessage( MessageBuilder const& builder ) {
  10450. m_messageScopes.emplace_back( builder );
  10451. }
  10452. std::string RunContext::getCurrentTestName() const {
  10453. return m_activeTestCase
  10454. ? m_activeTestCase->getTestCaseInfo().name
  10455. : std::string();
  10456. }
  10457. const AssertionResult * RunContext::getLastResult() const {
  10458. return &(*m_lastResult);
  10459. }
  10460. void RunContext::exceptionEarlyReported() {
  10461. m_shouldReportUnexpected = false;
  10462. }
  10463. void RunContext::handleFatalErrorCondition( StringRef message ) {
  10464. // First notify reporter that bad things happened
  10465. m_reporter->fatalErrorEncountered(message);
  10466. // Don't rebuild the result -- the stringification itself can cause more fatal errors
  10467. // Instead, fake a result data.
  10468. AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );
  10469. tempResult.message = static_cast<std::string>(message);
  10470. AssertionResult result(m_lastAssertionInfo, tempResult);
  10471. assertionEnded(result);
  10472. handleUnfinishedSections();
  10473. // Recreate section for test case (as we will lose the one that was in scope)
  10474. auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
  10475. SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
  10476. Counts assertions;
  10477. assertions.failed = 1;
  10478. SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);
  10479. m_reporter->sectionEnded(testCaseSectionStats);
  10480. auto const& testInfo = m_activeTestCase->getTestCaseInfo();
  10481. Totals deltaTotals;
  10482. deltaTotals.testCases.failed = 1;
  10483. deltaTotals.assertions.failed = 1;
  10484. m_reporter->testCaseEnded(TestCaseStats(testInfo,
  10485. deltaTotals,
  10486. std::string(),
  10487. std::string(),
  10488. false));
  10489. m_totals.testCases.failed++;
  10490. testGroupEnded(std::string(), m_totals, 1, 1);
  10491. m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
  10492. }
  10493. bool RunContext::lastAssertionPassed() {
  10494. return m_lastAssertionPassed;
  10495. }
  10496. void RunContext::assertionPassed() {
  10497. m_lastAssertionPassed = true;
  10498. ++m_totals.assertions.passed;
  10499. resetAssertionInfo();
  10500. m_messageScopes.clear();
  10501. }
  10502. bool RunContext::aborting() const {
  10503. return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter());
  10504. }
  10505. void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
  10506. auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
  10507. SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
  10508. m_reporter->sectionStarting(testCaseSection);
  10509. Counts prevAssertions = m_totals.assertions;
  10510. double duration = 0;
  10511. m_shouldReportUnexpected = true;
  10512. m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal };
  10513. seedRng(*m_config);
  10514. Timer timer;
  10515. CATCH_TRY {
  10516. if (m_reporter->getPreferences().shouldRedirectStdOut) {
  10517. #if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
  10518. RedirectedStreams redirectedStreams(redirectedCout, redirectedCerr);
  10519. timer.start();
  10520. invokeActiveTestCase();
  10521. #else
  10522. OutputRedirect r(redirectedCout, redirectedCerr);
  10523. timer.start();
  10524. invokeActiveTestCase();
  10525. #endif
  10526. } else {
  10527. timer.start();
  10528. invokeActiveTestCase();
  10529. }
  10530. duration = timer.getElapsedSeconds();
  10531. } CATCH_CATCH_ANON (TestFailureException&) {
  10532. // This just means the test was aborted due to failure
  10533. } CATCH_CATCH_ALL {
  10534. // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
  10535. // are reported without translation at the point of origin.
  10536. if( m_shouldReportUnexpected ) {
  10537. AssertionReaction dummyReaction;
  10538. handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction );
  10539. }
  10540. }
  10541. Counts assertions = m_totals.assertions - prevAssertions;
  10542. bool missingAssertions = testForMissingAssertions(assertions);
  10543. m_testCaseTracker->close();
  10544. handleUnfinishedSections();
  10545. m_messages.clear();
  10546. m_messageScopes.clear();
  10547. SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
  10548. m_reporter->sectionEnded(testCaseSectionStats);
  10549. }
  10550. void RunContext::invokeActiveTestCase() {
  10551. FatalConditionHandler fatalConditionHandler; // Handle signals
  10552. m_activeTestCase->invoke();
  10553. fatalConditionHandler.reset();
  10554. }
  10555. void RunContext::handleUnfinishedSections() {
  10556. // If sections ended prematurely due to an exception we stored their
  10557. // infos here so we can tear them down outside the unwind process.
  10558. for (auto it = m_unfinishedSections.rbegin(),
  10559. itEnd = m_unfinishedSections.rend();
  10560. it != itEnd;
  10561. ++it)
  10562. sectionEnded(*it);
  10563. m_unfinishedSections.clear();
  10564. }
  10565. void RunContext::handleExpr(
  10566. AssertionInfo const& info,
  10567. ITransientExpression const& expr,
  10568. AssertionReaction& reaction
  10569. ) {
  10570. m_reporter->assertionStarting( info );
  10571. bool negated = isFalseTest( info.resultDisposition );
  10572. bool result = expr.getResult() != negated;
  10573. if( result ) {
  10574. if (!m_includeSuccessfulResults) {
  10575. assertionPassed();
  10576. }
  10577. else {
  10578. reportExpr(info, ResultWas::Ok, &expr, negated);
  10579. }
  10580. }
  10581. else {
  10582. reportExpr(info, ResultWas::ExpressionFailed, &expr, negated );
  10583. populateReaction( reaction );
  10584. }
  10585. }
  10586. void RunContext::reportExpr(
  10587. AssertionInfo const &info,
  10588. ResultWas::OfType resultType,
  10589. ITransientExpression const *expr,
  10590. bool negated ) {
  10591. m_lastAssertionInfo = info;
  10592. AssertionResultData data( resultType, LazyExpression( negated ) );
  10593. AssertionResult assertionResult{ info, data };
  10594. assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;
  10595. assertionEnded( assertionResult );
  10596. }
  10597. void RunContext::handleMessage(
  10598. AssertionInfo const& info,
  10599. ResultWas::OfType resultType,
  10600. StringRef const& message,
  10601. AssertionReaction& reaction
  10602. ) {
  10603. m_reporter->assertionStarting( info );
  10604. m_lastAssertionInfo = info;
  10605. AssertionResultData data( resultType, LazyExpression( false ) );
  10606. data.message = static_cast<std::string>(message);
  10607. AssertionResult assertionResult{ m_lastAssertionInfo, data };
  10608. assertionEnded( assertionResult );
  10609. if( !assertionResult.isOk() )
  10610. populateReaction( reaction );
  10611. }
  10612. void RunContext::handleUnexpectedExceptionNotThrown(
  10613. AssertionInfo const& info,
  10614. AssertionReaction& reaction
  10615. ) {
  10616. handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction);
  10617. }
  10618. void RunContext::handleUnexpectedInflightException(
  10619. AssertionInfo const& info,
  10620. std::string const& message,
  10621. AssertionReaction& reaction
  10622. ) {
  10623. m_lastAssertionInfo = info;
  10624. AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
  10625. data.message = message;
  10626. AssertionResult assertionResult{ info, data };
  10627. assertionEnded( assertionResult );
  10628. populateReaction( reaction );
  10629. }
  10630. void RunContext::populateReaction( AssertionReaction& reaction ) {
  10631. reaction.shouldDebugBreak = m_config->shouldDebugBreak();
  10632. reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal);
  10633. }
  10634. void RunContext::handleIncomplete(
  10635. AssertionInfo const& info
  10636. ) {
  10637. m_lastAssertionInfo = info;
  10638. AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
  10639. data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
  10640. AssertionResult assertionResult{ info, data };
  10641. assertionEnded( assertionResult );
  10642. }
  10643. void RunContext::handleNonExpr(
  10644. AssertionInfo const &info,
  10645. ResultWas::OfType resultType,
  10646. AssertionReaction &reaction
  10647. ) {
  10648. m_lastAssertionInfo = info;
  10649. AssertionResultData data( resultType, LazyExpression( false ) );
  10650. AssertionResult assertionResult{ info, data };
  10651. assertionEnded( assertionResult );
  10652. if( !assertionResult.isOk() )
  10653. populateReaction( reaction );
  10654. }
  10655. IResultCapture& getResultCapture() {
  10656. if (auto* capture = getCurrentContext().getResultCapture())
  10657. return *capture;
  10658. else
  10659. CATCH_INTERNAL_ERROR("No result capture instance");
  10660. }
  10661. void seedRng(IConfig const& config) {
  10662. if (config.rngSeed() != 0) {
  10663. std::srand(config.rngSeed());
  10664. rng().seed(config.rngSeed());
  10665. }
  10666. }
  10667. unsigned int rngSeed() {
  10668. return getCurrentContext().getConfig()->rngSeed();
  10669. }
  10670. }
  10671. // end catch_run_context.cpp
  10672. // start catch_section.cpp
  10673. namespace Catch {
  10674. Section::Section( SectionInfo const& info )
  10675. : m_info( info ),
  10676. m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
  10677. {
  10678. m_timer.start();
  10679. }
  10680. Section::~Section() {
  10681. if( m_sectionIncluded ) {
  10682. SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };
  10683. if( uncaught_exceptions() )
  10684. getResultCapture().sectionEndedEarly( endInfo );
  10685. else
  10686. getResultCapture().sectionEnded( endInfo );
  10687. }
  10688. }
  10689. // This indicates whether the section should be executed or not
  10690. Section::operator bool() const {
  10691. return m_sectionIncluded;
  10692. }
  10693. } // end namespace Catch
  10694. // end catch_section.cpp
  10695. // start catch_section_info.cpp
  10696. namespace Catch {
  10697. SectionInfo::SectionInfo
  10698. ( SourceLineInfo const& _lineInfo,
  10699. std::string const& _name )
  10700. : name( _name ),
  10701. lineInfo( _lineInfo )
  10702. {}
  10703. } // end namespace Catch
  10704. // end catch_section_info.cpp
  10705. // start catch_session.cpp
  10706. // start catch_session.h
  10707. #include <memory>
  10708. namespace Catch {
  10709. class Session : NonCopyable {
  10710. public:
  10711. Session();
  10712. ~Session() override;
  10713. void showHelp() const;
  10714. void libIdentify();
  10715. int applyCommandLine( int argc, char const * const * argv );
  10716. #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
  10717. int applyCommandLine( int argc, wchar_t const * const * argv );
  10718. #endif
  10719. void useConfigData( ConfigData const& configData );
  10720. template<typename CharT>
  10721. int run(int argc, CharT const * const argv[]) {
  10722. if (m_startupExceptions)
  10723. return 1;
  10724. int returnCode = applyCommandLine(argc, argv);
  10725. if (returnCode == 0)
  10726. returnCode = run();
  10727. return returnCode;
  10728. }
  10729. int run();
  10730. clara::Parser const& cli() const;
  10731. void cli( clara::Parser const& newParser );
  10732. ConfigData& configData();
  10733. Config& config();
  10734. private:
  10735. int runInternal();
  10736. clara::Parser m_cli;
  10737. ConfigData m_configData;
  10738. std::shared_ptr<Config> m_config;
  10739. bool m_startupExceptions = false;
  10740. };
  10741. } // end namespace Catch
  10742. // end catch_session.h
  10743. // start catch_version.h
  10744. #include <iosfwd>
  10745. namespace Catch {
  10746. // Versioning information
  10747. struct Version {
  10748. Version( Version const& ) = delete;
  10749. Version& operator=( Version const& ) = delete;
  10750. Version( unsigned int _majorVersion,
  10751. unsigned int _minorVersion,
  10752. unsigned int _patchNumber,
  10753. char const * const _branchName,
  10754. unsigned int _buildNumber );
  10755. unsigned int const majorVersion;
  10756. unsigned int const minorVersion;
  10757. unsigned int const patchNumber;
  10758. // buildNumber is only used if branchName is not null
  10759. char const * const branchName;
  10760. unsigned int const buildNumber;
  10761. friend std::ostream& operator << ( std::ostream& os, Version const& version );
  10762. };
  10763. Version const& libraryVersion();
  10764. }
  10765. // end catch_version.h
  10766. #include <cstdlib>
  10767. #include <iomanip>
  10768. #include <set>
  10769. #include <iterator>
  10770. namespace Catch {
  10771. namespace {
  10772. const int MaxExitCode = 255;
  10773. IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) {
  10774. auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config);
  10775. CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'");
  10776. return reporter;
  10777. }
  10778. IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) {
  10779. if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) {
  10780. return createReporter(config->getReporterName(), config);
  10781. }
  10782. // On older platforms, returning std::unique_ptr<ListeningReporter>
  10783. // when the return type is std::unique_ptr<IStreamingReporter>
  10784. // doesn't compile without a std::move call. However, this causes
  10785. // a warning on newer platforms. Thus, we have to work around
  10786. // it a bit and downcast the pointer manually.
  10787. auto ret = std::unique_ptr<IStreamingReporter>(new ListeningReporter);
  10788. auto& multi = static_cast<ListeningReporter&>(*ret);
  10789. auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();
  10790. for (auto const& listener : listeners) {
  10791. multi.addListener(listener->create(Catch::ReporterConfig(config)));
  10792. }
  10793. multi.addReporter(createReporter(config->getReporterName(), config));
  10794. return ret;
  10795. }
  10796. class TestGroup {
  10797. public:
  10798. explicit TestGroup(std::shared_ptr<Config> const& config)
  10799. : m_config{config}
  10800. , m_context{config, makeReporter(config)}
  10801. {
  10802. auto const& allTestCases = getAllTestCasesSorted(*m_config);
  10803. m_matches = m_config->testSpec().matchesByFilter(allTestCases, *m_config);
  10804. auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
  10805. if (m_matches.empty() && invalidArgs.empty()) {
  10806. for (auto const& test : allTestCases)
  10807. if (!test.isHidden())
  10808. m_tests.emplace(&test);
  10809. } else {
  10810. for (auto const& match : m_matches)
  10811. m_tests.insert(match.tests.begin(), match.tests.end());
  10812. }
  10813. }
  10814. Totals execute() {
  10815. auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
  10816. Totals totals;
  10817. m_context.testGroupStarting(m_config->name(), 1, 1);
  10818. for (auto const& testCase : m_tests) {
  10819. if (!m_context.aborting())
  10820. totals += m_context.runTest(*testCase);
  10821. else
  10822. m_context.reporter().skipTest(*testCase);
  10823. }
  10824. for (auto const& match : m_matches) {
  10825. if (match.tests.empty()) {
  10826. m_context.reporter().noMatchingTestCases(match.name);
  10827. totals.error = -1;
  10828. }
  10829. }
  10830. if (!invalidArgs.empty()) {
  10831. for (auto const& invalidArg: invalidArgs)
  10832. m_context.reporter().reportInvalidArguments(invalidArg);
  10833. }
  10834. m_context.testGroupEnded(m_config->name(), totals, 1, 1);
  10835. return totals;
  10836. }
  10837. private:
  10838. using Tests = std::set<TestCase const*>;
  10839. std::shared_ptr<Config> m_config;
  10840. RunContext m_context;
  10841. Tests m_tests;
  10842. TestSpec::Matches m_matches;
  10843. };
  10844. void applyFilenamesAsTags(Catch::IConfig const& config) {
  10845. auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));
  10846. for (auto& testCase : tests) {
  10847. auto tags = testCase.tags;
  10848. std::string filename = testCase.lineInfo.file;
  10849. auto lastSlash = filename.find_last_of("\\/");
  10850. if (lastSlash != std::string::npos) {
  10851. filename.erase(0, lastSlash);
  10852. filename[0] = '#';
  10853. }
  10854. auto lastDot = filename.find_last_of('.');
  10855. if (lastDot != std::string::npos) {
  10856. filename.erase(lastDot);
  10857. }
  10858. tags.push_back(std::move(filename));
  10859. setTags(testCase, tags);
  10860. }
  10861. }
  10862. } // anon namespace
  10863. Session::Session() {
  10864. static bool alreadyInstantiated = false;
  10865. if( alreadyInstantiated ) {
  10866. CATCH_TRY { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
  10867. CATCH_CATCH_ALL { getMutableRegistryHub().registerStartupException(); }
  10868. }
  10869. // There cannot be exceptions at startup in no-exception mode.
  10870. #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  10871. const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
  10872. if ( !exceptions.empty() ) {
  10873. config();
  10874. getCurrentMutableContext().setConfig(m_config);
  10875. m_startupExceptions = true;
  10876. Colour colourGuard( Colour::Red );
  10877. Catch::cerr() << "Errors occurred during startup!" << '\n';
  10878. // iterate over all exceptions and notify user
  10879. for ( const auto& ex_ptr : exceptions ) {
  10880. try {
  10881. std::rethrow_exception(ex_ptr);
  10882. } catch ( std::exception const& ex ) {
  10883. Catch::cerr() << Column( ex.what() ).indent(2) << '\n';
  10884. }
  10885. }
  10886. }
  10887. #endif
  10888. alreadyInstantiated = true;
  10889. m_cli = makeCommandLineParser( m_configData );
  10890. }
  10891. Session::~Session() {
  10892. Catch::cleanUp();
  10893. }
  10894. void Session::showHelp() const {
  10895. Catch::cout()
  10896. << "\nCatch v" << libraryVersion() << "\n"
  10897. << m_cli << std::endl
  10898. << "For more detailed usage please see the project docs\n" << std::endl;
  10899. }
  10900. void Session::libIdentify() {
  10901. Catch::cout()
  10902. << std::left << std::setw(16) << "description: " << "A Catch2 test executable\n"
  10903. << std::left << std::setw(16) << "category: " << "testframework\n"
  10904. << std::left << std::setw(16) << "framework: " << "Catch Test\n"
  10905. << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
  10906. }
  10907. int Session::applyCommandLine( int argc, char const * const * argv ) {
  10908. if( m_startupExceptions )
  10909. return 1;
  10910. auto result = m_cli.parse( clara::Args( argc, argv ) );
  10911. if( !result ) {
  10912. config();
  10913. getCurrentMutableContext().setConfig(m_config);
  10914. Catch::cerr()
  10915. << Colour( Colour::Red )
  10916. << "\nError(s) in input:\n"
  10917. << Column( result.errorMessage() ).indent( 2 )
  10918. << "\n\n";
  10919. Catch::cerr() << "Run with -? for usage\n" << std::endl;
  10920. return MaxExitCode;
  10921. }
  10922. if( m_configData.showHelp )
  10923. showHelp();
  10924. if( m_configData.libIdentify )
  10925. libIdentify();
  10926. m_config.reset();
  10927. return 0;
  10928. }
  10929. #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
  10930. int Session::applyCommandLine( int argc, wchar_t const * const * argv ) {
  10931. char **utf8Argv = new char *[ argc ];
  10932. for ( int i = 0; i < argc; ++i ) {
  10933. int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, nullptr, 0, nullptr, nullptr );
  10934. utf8Argv[ i ] = new char[ bufSize ];
  10935. WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, nullptr, nullptr );
  10936. }
  10937. int returnCode = applyCommandLine( argc, utf8Argv );
  10938. for ( int i = 0; i < argc; ++i )
  10939. delete [] utf8Argv[ i ];
  10940. delete [] utf8Argv;
  10941. return returnCode;
  10942. }
  10943. #endif
  10944. void Session::useConfigData( ConfigData const& configData ) {
  10945. m_configData = configData;
  10946. m_config.reset();
  10947. }
  10948. int Session::run() {
  10949. if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {
  10950. Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
  10951. static_cast<void>(std::getchar());
  10952. }
  10953. int exitCode = runInternal();
  10954. if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {
  10955. Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
  10956. static_cast<void>(std::getchar());
  10957. }
  10958. return exitCode;
  10959. }
  10960. clara::Parser const& Session::cli() const {
  10961. return m_cli;
  10962. }
  10963. void Session::cli( clara::Parser const& newParser ) {
  10964. m_cli = newParser;
  10965. }
  10966. ConfigData& Session::configData() {
  10967. return m_configData;
  10968. }
  10969. Config& Session::config() {
  10970. if( !m_config )
  10971. m_config = std::make_shared<Config>( m_configData );
  10972. return *m_config;
  10973. }
  10974. int Session::runInternal() {
  10975. if( m_startupExceptions )
  10976. return 1;
  10977. if (m_configData.showHelp || m_configData.libIdentify) {
  10978. return 0;
  10979. }
  10980. CATCH_TRY {
  10981. config(); // Force config to be constructed
  10982. seedRng( *m_config );
  10983. if( m_configData.filenamesAsTags )
  10984. applyFilenamesAsTags( *m_config );
  10985. // Handle list request
  10986. if( Option<std::size_t> listed = list( m_config ) )
  10987. return static_cast<int>( *listed );
  10988. TestGroup tests { m_config };
  10989. auto const totals = tests.execute();
  10990. if( m_config->warnAboutNoTests() && totals.error == -1 )
  10991. return 2;
  10992. // Note that on unices only the lower 8 bits are usually used, clamping
  10993. // the return value to 255 prevents false negative when some multiple
  10994. // of 256 tests has failed
  10995. return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed)));
  10996. }
  10997. #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  10998. catch( std::exception& ex ) {
  10999. Catch::cerr() << ex.what() << std::endl;
  11000. return MaxExitCode;
  11001. }
  11002. #endif
  11003. }
  11004. } // end namespace Catch
  11005. // end catch_session.cpp
  11006. // start catch_singletons.cpp
  11007. #include <vector>
  11008. namespace Catch {
  11009. namespace {
  11010. static auto getSingletons() -> std::vector<ISingleton*>*& {
  11011. static std::vector<ISingleton*>* g_singletons = nullptr;
  11012. if( !g_singletons )
  11013. g_singletons = new std::vector<ISingleton*>();
  11014. return g_singletons;
  11015. }
  11016. }
  11017. ISingleton::~ISingleton() {}
  11018. void addSingleton(ISingleton* singleton ) {
  11019. getSingletons()->push_back( singleton );
  11020. }
  11021. void cleanupSingletons() {
  11022. auto& singletons = getSingletons();
  11023. for( auto singleton : *singletons )
  11024. delete singleton;
  11025. delete singletons;
  11026. singletons = nullptr;
  11027. }
  11028. } // namespace Catch
  11029. // end catch_singletons.cpp
  11030. // start catch_startup_exception_registry.cpp
  11031. #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  11032. namespace Catch {
  11033. void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
  11034. CATCH_TRY {
  11035. m_exceptions.push_back(exception);
  11036. } CATCH_CATCH_ALL {
  11037. // If we run out of memory during start-up there's really not a lot more we can do about it
  11038. std::terminate();
  11039. }
  11040. }
  11041. std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept {
  11042. return m_exceptions;
  11043. }
  11044. } // end namespace Catch
  11045. #endif
  11046. // end catch_startup_exception_registry.cpp
  11047. // start catch_stream.cpp
  11048. #include <cstdio>
  11049. #include <iostream>
  11050. #include <fstream>
  11051. #include <sstream>
  11052. #include <vector>
  11053. #include <memory>
  11054. namespace Catch {
  11055. Catch::IStream::~IStream() = default;
  11056. namespace Detail { namespace {
  11057. template<typename WriterF, std::size_t bufferSize=256>
  11058. class StreamBufImpl : public std::streambuf {
  11059. char data[bufferSize];
  11060. WriterF m_writer;
  11061. public:
  11062. StreamBufImpl() {
  11063. setp( data, data + sizeof(data) );
  11064. }
  11065. ~StreamBufImpl() noexcept {
  11066. StreamBufImpl::sync();
  11067. }
  11068. private:
  11069. int overflow( int c ) override {
  11070. sync();
  11071. if( c != EOF ) {
  11072. if( pbase() == epptr() )
  11073. m_writer( std::string( 1, static_cast<char>( c ) ) );
  11074. else
  11075. sputc( static_cast<char>( c ) );
  11076. }
  11077. return 0;
  11078. }
  11079. int sync() override {
  11080. if( pbase() != pptr() ) {
  11081. m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
  11082. setp( pbase(), epptr() );
  11083. }
  11084. return 0;
  11085. }
  11086. };
  11087. ///////////////////////////////////////////////////////////////////////////
  11088. struct OutputDebugWriter {
  11089. void operator()( std::string const&str ) {
  11090. writeToDebugConsole( str );
  11091. }
  11092. };
  11093. ///////////////////////////////////////////////////////////////////////////
  11094. class FileStream : public IStream {
  11095. mutable std::ofstream m_ofs;
  11096. public:
  11097. FileStream( StringRef filename ) {
  11098. m_ofs.open( filename.c_str() );
  11099. CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << "'" );
  11100. }
  11101. ~FileStream() override = default;
  11102. public: // IStream
  11103. std::ostream& stream() const override {
  11104. return m_ofs;
  11105. }
  11106. };
  11107. ///////////////////////////////////////////////////////////////////////////
  11108. class CoutStream : public IStream {
  11109. mutable std::ostream m_os;
  11110. public:
  11111. // Store the streambuf from cout up-front because
  11112. // cout may get redirected when running tests
  11113. CoutStream() : m_os( Catch::cout().rdbuf() ) {}
  11114. ~CoutStream() override = default;
  11115. public: // IStream
  11116. std::ostream& stream() const override { return m_os; }
  11117. };
  11118. ///////////////////////////////////////////////////////////////////////////
  11119. class DebugOutStream : public IStream {
  11120. std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf;
  11121. mutable std::ostream m_os;
  11122. public:
  11123. DebugOutStream()
  11124. : m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
  11125. m_os( m_streamBuf.get() )
  11126. {}
  11127. ~DebugOutStream() override = default;
  11128. public: // IStream
  11129. std::ostream& stream() const override { return m_os; }
  11130. };
  11131. }} // namespace anon::detail
  11132. ///////////////////////////////////////////////////////////////////////////
  11133. auto makeStream( StringRef const &filename ) -> IStream const* {
  11134. if( filename.empty() )
  11135. return new Detail::CoutStream();
  11136. else if( filename[0] == '%' ) {
  11137. if( filename == "%debug" )
  11138. return new Detail::DebugOutStream();
  11139. else
  11140. CATCH_ERROR( "Unrecognised stream: '" << filename << "'" );
  11141. }
  11142. else
  11143. return new Detail::FileStream( filename );
  11144. }
  11145. // This class encapsulates the idea of a pool of ostringstreams that can be reused.
  11146. struct StringStreams {
  11147. std::vector<std::unique_ptr<std::ostringstream>> m_streams;
  11148. std::vector<std::size_t> m_unused;
  11149. std::ostringstream m_referenceStream; // Used for copy state/ flags from
  11150. auto add() -> std::size_t {
  11151. if( m_unused.empty() ) {
  11152. m_streams.push_back( std::unique_ptr<std::ostringstream>( new std::ostringstream ) );
  11153. return m_streams.size()-1;
  11154. }
  11155. else {
  11156. auto index = m_unused.back();
  11157. m_unused.pop_back();
  11158. return index;
  11159. }
  11160. }
  11161. void release( std::size_t index ) {
  11162. m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state
  11163. m_unused.push_back(index);
  11164. }
  11165. };
  11166. ReusableStringStream::ReusableStringStream()
  11167. : m_index( Singleton<StringStreams>::getMutable().add() ),
  11168. m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].get() )
  11169. {}
  11170. ReusableStringStream::~ReusableStringStream() {
  11171. static_cast<std::ostringstream*>( m_oss )->str("");
  11172. m_oss->clear();
  11173. Singleton<StringStreams>::getMutable().release( m_index );
  11174. }
  11175. auto ReusableStringStream::str() const -> std::string {
  11176. return static_cast<std::ostringstream*>( m_oss )->str();
  11177. }
  11178. ///////////////////////////////////////////////////////////////////////////
  11179. #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
  11180. std::ostream& cout() { return std::cout; }
  11181. std::ostream& cerr() { return std::cerr; }
  11182. std::ostream& clog() { return std::clog; }
  11183. #endif
  11184. }
  11185. // end catch_stream.cpp
  11186. // start catch_string_manip.cpp
  11187. #include <algorithm>
  11188. #include <ostream>
  11189. #include <cstring>
  11190. #include <cctype>
  11191. #include <vector>
  11192. namespace Catch {
  11193. namespace {
  11194. char toLowerCh(char c) {
  11195. return static_cast<char>( std::tolower( static_cast<unsigned char>(c) ) );
  11196. }
  11197. }
  11198. bool startsWith( std::string const& s, std::string const& prefix ) {
  11199. return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
  11200. }
  11201. bool startsWith( std::string const& s, char prefix ) {
  11202. return !s.empty() && s[0] == prefix;
  11203. }
  11204. bool endsWith( std::string const& s, std::string const& suffix ) {
  11205. return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
  11206. }
  11207. bool endsWith( std::string const& s, char suffix ) {
  11208. return !s.empty() && s[s.size()-1] == suffix;
  11209. }
  11210. bool contains( std::string const& s, std::string const& infix ) {
  11211. return s.find( infix ) != std::string::npos;
  11212. }
  11213. void toLowerInPlace( std::string& s ) {
  11214. std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
  11215. }
  11216. std::string toLower( std::string const& s ) {
  11217. std::string lc = s;
  11218. toLowerInPlace( lc );
  11219. return lc;
  11220. }
  11221. std::string trim( std::string const& str ) {
  11222. static char const* whitespaceChars = "\n\r\t ";
  11223. std::string::size_type start = str.find_first_not_of( whitespaceChars );
  11224. std::string::size_type end = str.find_last_not_of( whitespaceChars );
  11225. return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
  11226. }
  11227. StringRef trim(StringRef ref) {
  11228. const auto is_ws = [](char c) {
  11229. return c == ' ' || c == '\t' || c == '\n' || c == '\r';
  11230. };
  11231. size_t real_begin = 0;
  11232. while (real_begin < ref.size() && is_ws(ref[real_begin])) { ++real_begin; }
  11233. size_t real_end = ref.size();
  11234. while (real_end > real_begin && is_ws(ref[real_end - 1])) { --real_end; }
  11235. return ref.substr(real_begin, real_end - real_begin);
  11236. }
  11237. bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
  11238. bool replaced = false;
  11239. std::size_t i = str.find( replaceThis );
  11240. while( i != std::string::npos ) {
  11241. replaced = true;
  11242. str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
  11243. if( i < str.size()-withThis.size() )
  11244. i = str.find( replaceThis, i+withThis.size() );
  11245. else
  11246. i = std::string::npos;
  11247. }
  11248. return replaced;
  11249. }
  11250. std::vector<StringRef> splitStringRef( StringRef str, char delimiter ) {
  11251. std::vector<StringRef> subStrings;
  11252. std::size_t start = 0;
  11253. for(std::size_t pos = 0; pos < str.size(); ++pos ) {
  11254. if( str[pos] == delimiter ) {
  11255. if( pos - start > 1 )
  11256. subStrings.push_back( str.substr( start, pos-start ) );
  11257. start = pos+1;
  11258. }
  11259. }
  11260. if( start < str.size() )
  11261. subStrings.push_back( str.substr( start, str.size()-start ) );
  11262. return subStrings;
  11263. }
  11264. pluralise::pluralise( std::size_t count, std::string const& label )
  11265. : m_count( count ),
  11266. m_label( label )
  11267. {}
  11268. std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
  11269. os << pluraliser.m_count << ' ' << pluraliser.m_label;
  11270. if( pluraliser.m_count != 1 )
  11271. os << 's';
  11272. return os;
  11273. }
  11274. }
  11275. // end catch_string_manip.cpp
  11276. // start catch_stringref.cpp
  11277. #include <algorithm>
  11278. #include <ostream>
  11279. #include <cstring>
  11280. #include <cstdint>
  11281. namespace Catch {
  11282. StringRef::StringRef( char const* rawChars ) noexcept
  11283. : StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) )
  11284. {}
  11285. auto StringRef::c_str() const -> char const* {
  11286. CATCH_ENFORCE(isNullTerminated(), "Called StringRef::c_str() on a non-null-terminated instance");
  11287. return m_start;
  11288. }
  11289. auto StringRef::data() const noexcept -> char const* {
  11290. return m_start;
  11291. }
  11292. auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {
  11293. if (start < m_size) {
  11294. return StringRef(m_start + start, (std::min)(m_size - start, size));
  11295. } else {
  11296. return StringRef();
  11297. }
  11298. }
  11299. auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool {
  11300. return m_size == other.m_size
  11301. && (std::memcmp( m_start, other.m_start, m_size ) == 0);
  11302. }
  11303. auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {
  11304. return os.write(str.data(), str.size());
  11305. }
  11306. auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& {
  11307. lhs.append(rhs.data(), rhs.size());
  11308. return lhs;
  11309. }
  11310. } // namespace Catch
  11311. // end catch_stringref.cpp
  11312. // start catch_tag_alias.cpp
  11313. namespace Catch {
  11314. TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {}
  11315. }
  11316. // end catch_tag_alias.cpp
  11317. // start catch_tag_alias_autoregistrar.cpp
  11318. namespace Catch {
  11319. RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {
  11320. CATCH_TRY {
  11321. getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
  11322. } CATCH_CATCH_ALL {
  11323. // Do not throw when constructing global objects, instead register the exception to be processed later
  11324. getMutableRegistryHub().registerStartupException();
  11325. }
  11326. }
  11327. }
  11328. // end catch_tag_alias_autoregistrar.cpp
  11329. // start catch_tag_alias_registry.cpp
  11330. #include <sstream>
  11331. namespace Catch {
  11332. TagAliasRegistry::~TagAliasRegistry() {}
  11333. TagAlias const* TagAliasRegistry::find( std::string const& alias ) const {
  11334. auto it = m_registry.find( alias );
  11335. if( it != m_registry.end() )
  11336. return &(it->second);
  11337. else
  11338. return nullptr;
  11339. }
  11340. std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
  11341. std::string expandedTestSpec = unexpandedTestSpec;
  11342. for( auto const& registryKvp : m_registry ) {
  11343. std::size_t pos = expandedTestSpec.find( registryKvp.first );
  11344. if( pos != std::string::npos ) {
  11345. expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
  11346. registryKvp.second.tag +
  11347. expandedTestSpec.substr( pos + registryKvp.first.size() );
  11348. }
  11349. }
  11350. return expandedTestSpec;
  11351. }
  11352. void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) {
  11353. CATCH_ENFORCE( startsWith(alias, "[@") && endsWith(alias, ']'),
  11354. "error: tag alias, '" << alias << "' is not of the form [@alias name].\n" << lineInfo );
  11355. CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,
  11356. "error: tag alias, '" << alias << "' already registered.\n"
  11357. << "\tFirst seen at: " << find(alias)->lineInfo << "\n"
  11358. << "\tRedefined at: " << lineInfo );
  11359. }
  11360. ITagAliasRegistry::~ITagAliasRegistry() {}
  11361. ITagAliasRegistry const& ITagAliasRegistry::get() {
  11362. return getRegistryHub().getTagAliasRegistry();
  11363. }
  11364. } // end namespace Catch
  11365. // end catch_tag_alias_registry.cpp
  11366. // start catch_test_case_info.cpp
  11367. #include <cctype>
  11368. #include <exception>
  11369. #include <algorithm>
  11370. #include <sstream>
  11371. namespace Catch {
  11372. namespace {
  11373. TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
  11374. if( startsWith( tag, '.' ) ||
  11375. tag == "!hide" )
  11376. return TestCaseInfo::IsHidden;
  11377. else if( tag == "!throws" )
  11378. return TestCaseInfo::Throws;
  11379. else if( tag == "!shouldfail" )
  11380. return TestCaseInfo::ShouldFail;
  11381. else if( tag == "!mayfail" )
  11382. return TestCaseInfo::MayFail;
  11383. else if( tag == "!nonportable" )
  11384. return TestCaseInfo::NonPortable;
  11385. else if( tag == "!benchmark" )
  11386. return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden );
  11387. else
  11388. return TestCaseInfo::None;
  11389. }
  11390. bool isReservedTag( std::string const& tag ) {
  11391. return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) );
  11392. }
  11393. void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
  11394. CATCH_ENFORCE( !isReservedTag(tag),
  11395. "Tag name: [" << tag << "] is not allowed.\n"
  11396. << "Tag names starting with non alphanumeric characters are reserved\n"
  11397. << _lineInfo );
  11398. }
  11399. }
  11400. TestCase makeTestCase( ITestInvoker* _testCase,
  11401. std::string const& _className,
  11402. NameAndTags const& nameAndTags,
  11403. SourceLineInfo const& _lineInfo )
  11404. {
  11405. bool isHidden = false;
  11406. // Parse out tags
  11407. std::vector<std::string> tags;
  11408. std::string desc, tag;
  11409. bool inTag = false;
  11410. for (char c : nameAndTags.tags) {
  11411. if( !inTag ) {
  11412. if( c == '[' )
  11413. inTag = true;
  11414. else
  11415. desc += c;
  11416. }
  11417. else {
  11418. if( c == ']' ) {
  11419. TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
  11420. if( ( prop & TestCaseInfo::IsHidden ) != 0 )
  11421. isHidden = true;
  11422. else if( prop == TestCaseInfo::None )
  11423. enforceNotReservedTag( tag, _lineInfo );
  11424. // Merged hide tags like `[.approvals]` should be added as
  11425. // `[.][approvals]`. The `[.]` is added at later point, so
  11426. // we only strip the prefix
  11427. if (startsWith(tag, '.') && tag.size() > 1) {
  11428. tag.erase(0, 1);
  11429. }
  11430. tags.push_back( tag );
  11431. tag.clear();
  11432. inTag = false;
  11433. }
  11434. else
  11435. tag += c;
  11436. }
  11437. }
  11438. if( isHidden ) {
  11439. // Add all "hidden" tags to make them behave identically
  11440. tags.insert( tags.end(), { ".", "!hide" } );
  11441. }
  11442. TestCaseInfo info( static_cast<std::string>(nameAndTags.name), _className, desc, tags, _lineInfo );
  11443. return TestCase( _testCase, std::move(info) );
  11444. }
  11445. void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ) {
  11446. std::sort(begin(tags), end(tags));
  11447. tags.erase(std::unique(begin(tags), end(tags)), end(tags));
  11448. testCaseInfo.lcaseTags.clear();
  11449. for( auto const& tag : tags ) {
  11450. std::string lcaseTag = toLower( tag );
  11451. testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
  11452. testCaseInfo.lcaseTags.push_back( lcaseTag );
  11453. }
  11454. testCaseInfo.tags = std::move(tags);
  11455. }
  11456. TestCaseInfo::TestCaseInfo( std::string const& _name,
  11457. std::string const& _className,
  11458. std::string const& _description,
  11459. std::vector<std::string> const& _tags,
  11460. SourceLineInfo const& _lineInfo )
  11461. : name( _name ),
  11462. className( _className ),
  11463. description( _description ),
  11464. lineInfo( _lineInfo ),
  11465. properties( None )
  11466. {
  11467. setTags( *this, _tags );
  11468. }
  11469. bool TestCaseInfo::isHidden() const {
  11470. return ( properties & IsHidden ) != 0;
  11471. }
  11472. bool TestCaseInfo::throws() const {
  11473. return ( properties & Throws ) != 0;
  11474. }
  11475. bool TestCaseInfo::okToFail() const {
  11476. return ( properties & (ShouldFail | MayFail ) ) != 0;
  11477. }
  11478. bool TestCaseInfo::expectedToFail() const {
  11479. return ( properties & (ShouldFail ) ) != 0;
  11480. }
  11481. std::string TestCaseInfo::tagsAsString() const {
  11482. std::string ret;
  11483. // '[' and ']' per tag
  11484. std::size_t full_size = 2 * tags.size();
  11485. for (const auto& tag : tags) {
  11486. full_size += tag.size();
  11487. }
  11488. ret.reserve(full_size);
  11489. for (const auto& tag : tags) {
  11490. ret.push_back('[');
  11491. ret.append(tag);
  11492. ret.push_back(']');
  11493. }
  11494. return ret;
  11495. }
  11496. TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( std::move(info) ), test( testCase ) {}
  11497. TestCase TestCase::withName( std::string const& _newName ) const {
  11498. TestCase other( *this );
  11499. other.name = _newName;
  11500. return other;
  11501. }
  11502. void TestCase::invoke() const {
  11503. test->invoke();
  11504. }
  11505. bool TestCase::operator == ( TestCase const& other ) const {
  11506. return test.get() == other.test.get() &&
  11507. name == other.name &&
  11508. className == other.className;
  11509. }
  11510. bool TestCase::operator < ( TestCase const& other ) const {
  11511. return name < other.name;
  11512. }
  11513. TestCaseInfo const& TestCase::getTestCaseInfo() const
  11514. {
  11515. return *this;
  11516. }
  11517. } // end namespace Catch
  11518. // end catch_test_case_info.cpp
  11519. // start catch_test_case_registry_impl.cpp
  11520. #include <algorithm>
  11521. #include <sstream>
  11522. namespace Catch {
  11523. namespace {
  11524. struct TestHasher {
  11525. explicit TestHasher(Catch::SimplePcg32& rng_instance) {
  11526. basis = rng_instance();
  11527. basis <<= 32;
  11528. basis |= rng_instance();
  11529. }
  11530. uint64_t basis;
  11531. uint64_t operator()(TestCase const& t) const {
  11532. // Modified FNV-1a hash
  11533. static constexpr uint64_t prime = 1099511628211;
  11534. uint64_t hash = basis;
  11535. for (const char c : t.name) {
  11536. hash ^= c;
  11537. hash *= prime;
  11538. }
  11539. return hash;
  11540. }
  11541. };
  11542. } // end unnamed namespace
  11543. std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
  11544. switch( config.runOrder() ) {
  11545. case RunTests::InDeclarationOrder:
  11546. // already in declaration order
  11547. break;
  11548. case RunTests::InLexicographicalOrder: {
  11549. std::vector<TestCase> sorted = unsortedTestCases;
  11550. std::sort( sorted.begin(), sorted.end() );
  11551. return sorted;
  11552. }
  11553. case RunTests::InRandomOrder: {
  11554. seedRng( config );
  11555. TestHasher h( rng() );
  11556. using hashedTest = std::pair<uint64_t, TestCase const*>;
  11557. std::vector<hashedTest> indexed_tests;
  11558. indexed_tests.reserve( unsortedTestCases.size() );
  11559. for (auto const& testCase : unsortedTestCases) {
  11560. indexed_tests.emplace_back(h(testCase), &testCase);
  11561. }
  11562. std::sort(indexed_tests.begin(), indexed_tests.end(),
  11563. [](hashedTest const& lhs, hashedTest const& rhs) {
  11564. if (lhs.first == rhs.first) {
  11565. return lhs.second->name < rhs.second->name;
  11566. }
  11567. return lhs.first < rhs.first;
  11568. });
  11569. std::vector<TestCase> sorted;
  11570. sorted.reserve( indexed_tests.size() );
  11571. for (auto const& hashed : indexed_tests) {
  11572. sorted.emplace_back(*hashed.second);
  11573. }
  11574. return sorted;
  11575. }
  11576. }
  11577. return unsortedTestCases;
  11578. }
  11579. bool isThrowSafe( TestCase const& testCase, IConfig const& config ) {
  11580. return !testCase.throws() || config.allowThrows();
  11581. }
  11582. bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
  11583. return testSpec.matches( testCase ) && isThrowSafe( testCase, config );
  11584. }
  11585. void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
  11586. std::set<TestCase> seenFunctions;
  11587. for( auto const& function : functions ) {
  11588. auto prev = seenFunctions.insert( function );
  11589. CATCH_ENFORCE( prev.second,
  11590. "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n"
  11591. << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
  11592. << "\tRedefined at " << function.getTestCaseInfo().lineInfo );
  11593. }
  11594. }
  11595. std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
  11596. std::vector<TestCase> filtered;
  11597. filtered.reserve( testCases.size() );
  11598. for (auto const& testCase : testCases) {
  11599. if ((!testSpec.hasFilters() && !testCase.isHidden()) ||
  11600. (testSpec.hasFilters() && matchTest(testCase, testSpec, config))) {
  11601. filtered.push_back(testCase);
  11602. }
  11603. }
  11604. return filtered;
  11605. }
  11606. std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
  11607. return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
  11608. }
  11609. void TestRegistry::registerTest( TestCase const& testCase ) {
  11610. std::string name = testCase.getTestCaseInfo().name;
  11611. if( name.empty() ) {
  11612. ReusableStringStream rss;
  11613. rss << "Anonymous test case " << ++m_unnamedCount;
  11614. return registerTest( testCase.withName( rss.str() ) );
  11615. }
  11616. m_functions.push_back( testCase );
  11617. }
  11618. std::vector<TestCase> const& TestRegistry::getAllTests() const {
  11619. return m_functions;
  11620. }
  11621. std::vector<TestCase> const& TestRegistry::getAllTestsSorted( IConfig const& config ) const {
  11622. if( m_sortedFunctions.empty() )
  11623. enforceNoDuplicateTestCases( m_functions );
  11624. if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
  11625. m_sortedFunctions = sortTests( config, m_functions );
  11626. m_currentSortOrder = config.runOrder();
  11627. }
  11628. return m_sortedFunctions;
  11629. }
  11630. ///////////////////////////////////////////////////////////////////////////
  11631. TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {}
  11632. void TestInvokerAsFunction::invoke() const {
  11633. m_testAsFunction();
  11634. }
  11635. std::string extractClassName( StringRef const& classOrQualifiedMethodName ) {
  11636. std::string className(classOrQualifiedMethodName);
  11637. if( startsWith( className, '&' ) )
  11638. {
  11639. std::size_t lastColons = className.rfind( "::" );
  11640. std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
  11641. if( penultimateColons == std::string::npos )
  11642. penultimateColons = 1;
  11643. className = className.substr( penultimateColons, lastColons-penultimateColons );
  11644. }
  11645. return className;
  11646. }
  11647. } // end namespace Catch
  11648. // end catch_test_case_registry_impl.cpp
  11649. // start catch_test_case_tracker.cpp
  11650. #include <algorithm>
  11651. #include <cassert>
  11652. #include <stdexcept>
  11653. #include <memory>
  11654. #include <sstream>
  11655. #if defined(__clang__)
  11656. # pragma clang diagnostic push
  11657. # pragma clang diagnostic ignored "-Wexit-time-destructors"
  11658. #endif
  11659. namespace Catch {
  11660. namespace TestCaseTracking {
  11661. NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location )
  11662. : name( _name ),
  11663. location( _location )
  11664. {}
  11665. ITracker::~ITracker() = default;
  11666. ITracker& TrackerContext::startRun() {
  11667. m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr );
  11668. m_currentTracker = nullptr;
  11669. m_runState = Executing;
  11670. return *m_rootTracker;
  11671. }
  11672. void TrackerContext::endRun() {
  11673. m_rootTracker.reset();
  11674. m_currentTracker = nullptr;
  11675. m_runState = NotStarted;
  11676. }
  11677. void TrackerContext::startCycle() {
  11678. m_currentTracker = m_rootTracker.get();
  11679. m_runState = Executing;
  11680. }
  11681. void TrackerContext::completeCycle() {
  11682. m_runState = CompletedCycle;
  11683. }
  11684. bool TrackerContext::completedCycle() const {
  11685. return m_runState == CompletedCycle;
  11686. }
  11687. ITracker& TrackerContext::currentTracker() {
  11688. return *m_currentTracker;
  11689. }
  11690. void TrackerContext::setCurrentTracker( ITracker* tracker ) {
  11691. m_currentTracker = tracker;
  11692. }
  11693. TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ):
  11694. ITracker(nameAndLocation),
  11695. m_ctx( ctx ),
  11696. m_parent( parent )
  11697. {}
  11698. bool TrackerBase::isComplete() const {
  11699. return m_runState == CompletedSuccessfully || m_runState == Failed;
  11700. }
  11701. bool TrackerBase::isSuccessfullyCompleted() const {
  11702. return m_runState == CompletedSuccessfully;
  11703. }
  11704. bool TrackerBase::isOpen() const {
  11705. return m_runState != NotStarted && !isComplete();
  11706. }
  11707. bool TrackerBase::hasChildren() const {
  11708. return !m_children.empty();
  11709. }
  11710. void TrackerBase::addChild( ITrackerPtr const& child ) {
  11711. m_children.push_back( child );
  11712. }
  11713. ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) {
  11714. auto it = std::find_if( m_children.begin(), m_children.end(),
  11715. [&nameAndLocation]( ITrackerPtr const& tracker ){
  11716. return
  11717. tracker->nameAndLocation().location == nameAndLocation.location &&
  11718. tracker->nameAndLocation().name == nameAndLocation.name;
  11719. } );
  11720. return( it != m_children.end() )
  11721. ? *it
  11722. : nullptr;
  11723. }
  11724. ITracker& TrackerBase::parent() {
  11725. assert( m_parent ); // Should always be non-null except for root
  11726. return *m_parent;
  11727. }
  11728. void TrackerBase::openChild() {
  11729. if( m_runState != ExecutingChildren ) {
  11730. m_runState = ExecutingChildren;
  11731. if( m_parent )
  11732. m_parent->openChild();
  11733. }
  11734. }
  11735. bool TrackerBase::isSectionTracker() const { return false; }
  11736. bool TrackerBase::isGeneratorTracker() const { return false; }
  11737. void TrackerBase::open() {
  11738. m_runState = Executing;
  11739. moveToThis();
  11740. if( m_parent )
  11741. m_parent->openChild();
  11742. }
  11743. void TrackerBase::close() {
  11744. // Close any still open children (e.g. generators)
  11745. while( &m_ctx.currentTracker() != this )
  11746. m_ctx.currentTracker().close();
  11747. switch( m_runState ) {
  11748. case NeedsAnotherRun:
  11749. break;
  11750. case Executing:
  11751. m_runState = CompletedSuccessfully;
  11752. break;
  11753. case ExecutingChildren:
  11754. if( std::all_of(m_children.begin(), m_children.end(), [](ITrackerPtr const& t){ return t->isComplete(); }) )
  11755. m_runState = CompletedSuccessfully;
  11756. break;
  11757. case NotStarted:
  11758. case CompletedSuccessfully:
  11759. case Failed:
  11760. CATCH_INTERNAL_ERROR( "Illogical state: " << m_runState );
  11761. default:
  11762. CATCH_INTERNAL_ERROR( "Unknown state: " << m_runState );
  11763. }
  11764. moveToParent();
  11765. m_ctx.completeCycle();
  11766. }
  11767. void TrackerBase::fail() {
  11768. m_runState = Failed;
  11769. if( m_parent )
  11770. m_parent->markAsNeedingAnotherRun();
  11771. moveToParent();
  11772. m_ctx.completeCycle();
  11773. }
  11774. void TrackerBase::markAsNeedingAnotherRun() {
  11775. m_runState = NeedsAnotherRun;
  11776. }
  11777. void TrackerBase::moveToParent() {
  11778. assert( m_parent );
  11779. m_ctx.setCurrentTracker( m_parent );
  11780. }
  11781. void TrackerBase::moveToThis() {
  11782. m_ctx.setCurrentTracker( this );
  11783. }
  11784. SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
  11785. : TrackerBase( nameAndLocation, ctx, parent ),
  11786. m_trimmed_name(trim(nameAndLocation.name))
  11787. {
  11788. if( parent ) {
  11789. while( !parent->isSectionTracker() )
  11790. parent = &parent->parent();
  11791. SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );
  11792. addNextFilters( parentSection.m_filters );
  11793. }
  11794. }
  11795. bool SectionTracker::isComplete() const {
  11796. bool complete = true;
  11797. if (m_filters.empty()
  11798. || m_filters[0] == ""
  11799. || std::find(m_filters.begin(), m_filters.end(), m_trimmed_name) != m_filters.end()) {
  11800. complete = TrackerBase::isComplete();
  11801. }
  11802. return complete;
  11803. }
  11804. bool SectionTracker::isSectionTracker() const { return true; }
  11805. SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {
  11806. std::shared_ptr<SectionTracker> section;
  11807. ITracker& currentTracker = ctx.currentTracker();
  11808. if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
  11809. assert( childTracker );
  11810. assert( childTracker->isSectionTracker() );
  11811. section = std::static_pointer_cast<SectionTracker>( childTracker );
  11812. }
  11813. else {
  11814. section = std::make_shared<SectionTracker>( nameAndLocation, ctx, &currentTracker );
  11815. currentTracker.addChild( section );
  11816. }
  11817. if( !ctx.completedCycle() )
  11818. section->tryOpen();
  11819. return *section;
  11820. }
  11821. void SectionTracker::tryOpen() {
  11822. if( !isComplete() )
  11823. open();
  11824. }
  11825. void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) {
  11826. if( !filters.empty() ) {
  11827. m_filters.reserve( m_filters.size() + filters.size() + 2 );
  11828. m_filters.emplace_back(""); // Root - should never be consulted
  11829. m_filters.emplace_back(""); // Test Case - not a section filter
  11830. m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
  11831. }
  11832. }
  11833. void SectionTracker::addNextFilters( std::vector<std::string> const& filters ) {
  11834. if( filters.size() > 1 )
  11835. m_filters.insert( m_filters.end(), filters.begin()+1, filters.end() );
  11836. }
  11837. std::vector<std::string> const& SectionTracker::getFilters() const {
  11838. return m_filters;
  11839. }
  11840. std::string const& SectionTracker::trimmedName() const {
  11841. return m_trimmed_name;
  11842. }
  11843. } // namespace TestCaseTracking
  11844. using TestCaseTracking::ITracker;
  11845. using TestCaseTracking::TrackerContext;
  11846. using TestCaseTracking::SectionTracker;
  11847. } // namespace Catch
  11848. #if defined(__clang__)
  11849. # pragma clang diagnostic pop
  11850. #endif
  11851. // end catch_test_case_tracker.cpp
  11852. // start catch_test_registry.cpp
  11853. namespace Catch {
  11854. auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker* {
  11855. return new(std::nothrow) TestInvokerAsFunction( testAsFunction );
  11856. }
  11857. NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {}
  11858. AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept {
  11859. CATCH_TRY {
  11860. getMutableRegistryHub()
  11861. .registerTest(
  11862. makeTestCase(
  11863. invoker,
  11864. extractClassName( classOrMethod ),
  11865. nameAndTags,
  11866. lineInfo));
  11867. } CATCH_CATCH_ALL {
  11868. // Do not throw when constructing global objects, instead register the exception to be processed later
  11869. getMutableRegistryHub().registerStartupException();
  11870. }
  11871. }
  11872. AutoReg::~AutoReg() = default;
  11873. }
  11874. // end catch_test_registry.cpp
  11875. // start catch_test_spec.cpp
  11876. #include <algorithm>
  11877. #include <string>
  11878. #include <vector>
  11879. #include <memory>
  11880. namespace Catch {
  11881. TestSpec::Pattern::Pattern( std::string const& name )
  11882. : m_name( name )
  11883. {}
  11884. TestSpec::Pattern::~Pattern() = default;
  11885. std::string const& TestSpec::Pattern::name() const {
  11886. return m_name;
  11887. }
  11888. TestSpec::NamePattern::NamePattern( std::string const& name, std::string const& filterString )
  11889. : Pattern( filterString )
  11890. , m_wildcardPattern( toLower( name ), CaseSensitive::No )
  11891. {}
  11892. bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const {
  11893. return m_wildcardPattern.matches( testCase.name );
  11894. }
  11895. TestSpec::TagPattern::TagPattern( std::string const& tag, std::string const& filterString )
  11896. : Pattern( filterString )
  11897. , m_tag( toLower( tag ) )
  11898. {}
  11899. bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const {
  11900. return std::find(begin(testCase.lcaseTags),
  11901. end(testCase.lcaseTags),
  11902. m_tag) != end(testCase.lcaseTags);
  11903. }
  11904. TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern )
  11905. : Pattern( underlyingPattern->name() )
  11906. , m_underlyingPattern( underlyingPattern )
  11907. {}
  11908. bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const {
  11909. return !m_underlyingPattern->matches( testCase );
  11910. }
  11911. bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const {
  11912. return std::all_of( m_patterns.begin(), m_patterns.end(), [&]( PatternPtr const& p ){ return p->matches( testCase ); } );
  11913. }
  11914. std::string TestSpec::Filter::name() const {
  11915. std::string name;
  11916. for( auto const& p : m_patterns )
  11917. name += p->name();
  11918. return name;
  11919. }
  11920. bool TestSpec::hasFilters() const {
  11921. return !m_filters.empty();
  11922. }
  11923. bool TestSpec::matches( TestCaseInfo const& testCase ) const {
  11924. return std::any_of( m_filters.begin(), m_filters.end(), [&]( Filter const& f ){ return f.matches( testCase ); } );
  11925. }
  11926. TestSpec::Matches TestSpec::matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const
  11927. {
  11928. Matches matches( m_filters.size() );
  11929. std::transform( m_filters.begin(), m_filters.end(), matches.begin(), [&]( Filter const& filter ){
  11930. std::vector<TestCase const*> currentMatches;
  11931. for( auto const& test : testCases )
  11932. if( isThrowSafe( test, config ) && filter.matches( test ) )
  11933. currentMatches.emplace_back( &test );
  11934. return FilterMatch{ filter.name(), currentMatches };
  11935. } );
  11936. return matches;
  11937. }
  11938. const TestSpec::vectorStrings& TestSpec::getInvalidArgs() const{
  11939. return (m_invalidArgs);
  11940. }
  11941. }
  11942. // end catch_test_spec.cpp
  11943. // start catch_test_spec_parser.cpp
  11944. namespace Catch {
  11945. TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
  11946. TestSpecParser& TestSpecParser::parse( std::string const& arg ) {
  11947. m_mode = None;
  11948. m_exclusion = false;
  11949. m_arg = m_tagAliases->expandAliases( arg );
  11950. m_escapeChars.clear();
  11951. m_substring.reserve(m_arg.size());
  11952. m_patternName.reserve(m_arg.size());
  11953. m_realPatternPos = 0;
  11954. for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
  11955. //if visitChar fails
  11956. if( !visitChar( m_arg[m_pos] ) ){
  11957. m_testSpec.m_invalidArgs.push_back(arg);
  11958. break;
  11959. }
  11960. endMode();
  11961. return *this;
  11962. }
  11963. TestSpec TestSpecParser::testSpec() {
  11964. addFilter();
  11965. return m_testSpec;
  11966. }
  11967. bool TestSpecParser::visitChar( char c ) {
  11968. if( (m_mode != EscapedName) && (c == '\\') ) {
  11969. escape();
  11970. addCharToPattern(c);
  11971. return true;
  11972. }else if((m_mode != EscapedName) && (c == ',') ) {
  11973. return separate();
  11974. }
  11975. switch( m_mode ) {
  11976. case None:
  11977. if( processNoneChar( c ) )
  11978. return true;
  11979. break;
  11980. case Name:
  11981. processNameChar( c );
  11982. break;
  11983. case EscapedName:
  11984. endMode();
  11985. addCharToPattern(c);
  11986. return true;
  11987. default:
  11988. case Tag:
  11989. case QuotedName:
  11990. if( processOtherChar( c ) )
  11991. return true;
  11992. break;
  11993. }
  11994. m_substring += c;
  11995. if( !isControlChar( c ) ) {
  11996. m_patternName += c;
  11997. m_realPatternPos++;
  11998. }
  11999. return true;
  12000. }
  12001. // Two of the processing methods return true to signal the caller to return
  12002. // without adding the given character to the current pattern strings
  12003. bool TestSpecParser::processNoneChar( char c ) {
  12004. switch( c ) {
  12005. case ' ':
  12006. return true;
  12007. case '~':
  12008. m_exclusion = true;
  12009. return false;
  12010. case '[':
  12011. startNewMode( Tag );
  12012. return false;
  12013. case '"':
  12014. startNewMode( QuotedName );
  12015. return false;
  12016. default:
  12017. startNewMode( Name );
  12018. return false;
  12019. }
  12020. }
  12021. void TestSpecParser::processNameChar( char c ) {
  12022. if( c == '[' ) {
  12023. if( m_substring == "exclude:" )
  12024. m_exclusion = true;
  12025. else
  12026. endMode();
  12027. startNewMode( Tag );
  12028. }
  12029. }
  12030. bool TestSpecParser::processOtherChar( char c ) {
  12031. if( !isControlChar( c ) )
  12032. return false;
  12033. m_substring += c;
  12034. endMode();
  12035. return true;
  12036. }
  12037. void TestSpecParser::startNewMode( Mode mode ) {
  12038. m_mode = mode;
  12039. }
  12040. void TestSpecParser::endMode() {
  12041. switch( m_mode ) {
  12042. case Name:
  12043. case QuotedName:
  12044. return addNamePattern();
  12045. case Tag:
  12046. return addTagPattern();
  12047. case EscapedName:
  12048. revertBackToLastMode();
  12049. return;
  12050. case None:
  12051. default:
  12052. return startNewMode( None );
  12053. }
  12054. }
  12055. void TestSpecParser::escape() {
  12056. saveLastMode();
  12057. m_mode = EscapedName;
  12058. m_escapeChars.push_back(m_realPatternPos);
  12059. }
  12060. bool TestSpecParser::isControlChar( char c ) const {
  12061. switch( m_mode ) {
  12062. default:
  12063. return false;
  12064. case None:
  12065. return c == '~';
  12066. case Name:
  12067. return c == '[';
  12068. case EscapedName:
  12069. return true;
  12070. case QuotedName:
  12071. return c == '"';
  12072. case Tag:
  12073. return c == '[' || c == ']';
  12074. }
  12075. }
  12076. void TestSpecParser::addFilter() {
  12077. if( !m_currentFilter.m_patterns.empty() ) {
  12078. m_testSpec.m_filters.push_back( m_currentFilter );
  12079. m_currentFilter = TestSpec::Filter();
  12080. }
  12081. }
  12082. void TestSpecParser::saveLastMode() {
  12083. lastMode = m_mode;
  12084. }
  12085. void TestSpecParser::revertBackToLastMode() {
  12086. m_mode = lastMode;
  12087. }
  12088. bool TestSpecParser::separate() {
  12089. if( (m_mode==QuotedName) || (m_mode==Tag) ){
  12090. //invalid argument, signal failure to previous scope.
  12091. m_mode = None;
  12092. m_pos = m_arg.size();
  12093. m_substring.clear();
  12094. m_patternName.clear();
  12095. m_realPatternPos = 0;
  12096. return false;
  12097. }
  12098. endMode();
  12099. addFilter();
  12100. return true; //success
  12101. }
  12102. std::string TestSpecParser::preprocessPattern() {
  12103. std::string token = m_patternName;
  12104. for (std::size_t i = 0; i < m_escapeChars.size(); ++i)
  12105. token = token.substr(0, m_escapeChars[i] - i) + token.substr(m_escapeChars[i] - i + 1);
  12106. m_escapeChars.clear();
  12107. if (startsWith(token, "exclude:")) {
  12108. m_exclusion = true;
  12109. token = token.substr(8);
  12110. }
  12111. m_patternName.clear();
  12112. m_realPatternPos = 0;
  12113. return token;
  12114. }
  12115. void TestSpecParser::addNamePattern() {
  12116. auto token = preprocessPattern();
  12117. if (!token.empty()) {
  12118. TestSpec::PatternPtr pattern = std::make_shared<TestSpec::NamePattern>(token, m_substring);
  12119. if (m_exclusion)
  12120. pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
  12121. m_currentFilter.m_patterns.push_back(pattern);
  12122. }
  12123. m_substring.clear();
  12124. m_exclusion = false;
  12125. m_mode = None;
  12126. }
  12127. void TestSpecParser::addTagPattern() {
  12128. auto token = preprocessPattern();
  12129. if (!token.empty()) {
  12130. // If the tag pattern is the "hide and tag" shorthand (e.g. [.foo])
  12131. // we have to create a separate hide tag and shorten the real one
  12132. if (token.size() > 1 && token[0] == '.') {
  12133. token.erase(token.begin());
  12134. TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(".", m_substring);
  12135. if (m_exclusion) {
  12136. pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
  12137. }
  12138. m_currentFilter.m_patterns.push_back(pattern);
  12139. }
  12140. TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(token, m_substring);
  12141. if (m_exclusion) {
  12142. pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
  12143. }
  12144. m_currentFilter.m_patterns.push_back(pattern);
  12145. }
  12146. m_substring.clear();
  12147. m_exclusion = false;
  12148. m_mode = None;
  12149. }
  12150. TestSpec parseTestSpec( std::string const& arg ) {
  12151. return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
  12152. }
  12153. } // namespace Catch
  12154. // end catch_test_spec_parser.cpp
  12155. // start catch_timer.cpp
  12156. #include <chrono>
  12157. static const uint64_t nanosecondsInSecond = 1000000000;
  12158. namespace Catch {
  12159. auto getCurrentNanosecondsSinceEpoch() -> uint64_t {
  12160. return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
  12161. }
  12162. namespace {
  12163. auto estimateClockResolution() -> uint64_t {
  12164. uint64_t sum = 0;
  12165. static const uint64_t iterations = 1000000;
  12166. auto startTime = getCurrentNanosecondsSinceEpoch();
  12167. for( std::size_t i = 0; i < iterations; ++i ) {
  12168. uint64_t ticks;
  12169. uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
  12170. do {
  12171. ticks = getCurrentNanosecondsSinceEpoch();
  12172. } while( ticks == baseTicks );
  12173. auto delta = ticks - baseTicks;
  12174. sum += delta;
  12175. // If we have been calibrating for over 3 seconds -- the clock
  12176. // is terrible and we should move on.
  12177. // TBD: How to signal that the measured resolution is probably wrong?
  12178. if (ticks > startTime + 3 * nanosecondsInSecond) {
  12179. return sum / ( i + 1u );
  12180. }
  12181. }
  12182. // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
  12183. // - and potentially do more iterations if there's a high variance.
  12184. return sum/iterations;
  12185. }
  12186. }
  12187. auto getEstimatedClockResolution() -> uint64_t {
  12188. static auto s_resolution = estimateClockResolution();
  12189. return s_resolution;
  12190. }
  12191. void Timer::start() {
  12192. m_nanoseconds = getCurrentNanosecondsSinceEpoch();
  12193. }
  12194. auto Timer::getElapsedNanoseconds() const -> uint64_t {
  12195. return getCurrentNanosecondsSinceEpoch() - m_nanoseconds;
  12196. }
  12197. auto Timer::getElapsedMicroseconds() const -> uint64_t {
  12198. return getElapsedNanoseconds()/1000;
  12199. }
  12200. auto Timer::getElapsedMilliseconds() const -> unsigned int {
  12201. return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
  12202. }
  12203. auto Timer::getElapsedSeconds() const -> double {
  12204. return getElapsedMicroseconds()/1000000.0;
  12205. }
  12206. } // namespace Catch
  12207. // end catch_timer.cpp
  12208. // start catch_tostring.cpp
  12209. #if defined(__clang__)
  12210. # pragma clang diagnostic push
  12211. # pragma clang diagnostic ignored "-Wexit-time-destructors"
  12212. # pragma clang diagnostic ignored "-Wglobal-constructors"
  12213. #endif
  12214. // Enable specific decls locally
  12215. #if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
  12216. #define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
  12217. #endif
  12218. #include <cmath>
  12219. #include <iomanip>
  12220. namespace Catch {
  12221. namespace Detail {
  12222. const std::string unprintableString = "{?}";
  12223. namespace {
  12224. const int hexThreshold = 255;
  12225. struct Endianness {
  12226. enum Arch { Big, Little };
  12227. static Arch which() {
  12228. int one = 1;
  12229. // If the lowest byte we read is non-zero, we can assume
  12230. // that little endian format is used.
  12231. auto value = *reinterpret_cast<char*>(&one);
  12232. return value ? Little : Big;
  12233. }
  12234. };
  12235. }
  12236. std::string rawMemoryToString( const void *object, std::size_t size ) {
  12237. // Reverse order for little endian architectures
  12238. int i = 0, end = static_cast<int>( size ), inc = 1;
  12239. if( Endianness::which() == Endianness::Little ) {
  12240. i = end-1;
  12241. end = inc = -1;
  12242. }
  12243. unsigned char const *bytes = static_cast<unsigned char const *>(object);
  12244. ReusableStringStream rss;
  12245. rss << "0x" << std::setfill('0') << std::hex;
  12246. for( ; i != end; i += inc )
  12247. rss << std::setw(2) << static_cast<unsigned>(bytes[i]);
  12248. return rss.str();
  12249. }
  12250. }
  12251. template<typename T>
  12252. std::string fpToString( T value, int precision ) {
  12253. if (Catch::isnan(value)) {
  12254. return "nan";
  12255. }
  12256. ReusableStringStream rss;
  12257. rss << std::setprecision( precision )
  12258. << std::fixed
  12259. << value;
  12260. std::string d = rss.str();
  12261. std::size_t i = d.find_last_not_of( '0' );
  12262. if( i != std::string::npos && i != d.size()-1 ) {
  12263. if( d[i] == '.' )
  12264. i++;
  12265. d = d.substr( 0, i+1 );
  12266. }
  12267. return d;
  12268. }
  12269. //// ======================================================= ////
  12270. //
  12271. // Out-of-line defs for full specialization of StringMaker
  12272. //
  12273. //// ======================================================= ////
  12274. std::string StringMaker<std::string>::convert(const std::string& str) {
  12275. if (!getCurrentContext().getConfig()->showInvisibles()) {
  12276. return '"' + str + '"';
  12277. }
  12278. std::string s("\"");
  12279. for (char c : str) {
  12280. switch (c) {
  12281. case '\n':
  12282. s.append("\\n");
  12283. break;
  12284. case '\t':
  12285. s.append("\\t");
  12286. break;
  12287. default:
  12288. s.push_back(c);
  12289. break;
  12290. }
  12291. }
  12292. s.append("\"");
  12293. return s;
  12294. }
  12295. #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
  12296. std::string StringMaker<std::string_view>::convert(std::string_view str) {
  12297. return ::Catch::Detail::stringify(std::string{ str });
  12298. }
  12299. #endif
  12300. std::string StringMaker<char const*>::convert(char const* str) {
  12301. if (str) {
  12302. return ::Catch::Detail::stringify(std::string{ str });
  12303. } else {
  12304. return{ "{null string}" };
  12305. }
  12306. }
  12307. std::string StringMaker<char*>::convert(char* str) {
  12308. if (str) {
  12309. return ::Catch::Detail::stringify(std::string{ str });
  12310. } else {
  12311. return{ "{null string}" };
  12312. }
  12313. }
  12314. #ifdef CATCH_CONFIG_WCHAR
  12315. std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
  12316. std::string s;
  12317. s.reserve(wstr.size());
  12318. for (auto c : wstr) {
  12319. s += (c <= 0xff) ? static_cast<char>(c) : '?';
  12320. }
  12321. return ::Catch::Detail::stringify(s);
  12322. }
  12323. # ifdef CATCH_CONFIG_CPP17_STRING_VIEW
  12324. std::string StringMaker<std::wstring_view>::convert(std::wstring_view str) {
  12325. return StringMaker<std::wstring>::convert(std::wstring(str));
  12326. }
  12327. # endif
  12328. std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {
  12329. if (str) {
  12330. return ::Catch::Detail::stringify(std::wstring{ str });
  12331. } else {
  12332. return{ "{null string}" };
  12333. }
  12334. }
  12335. std::string StringMaker<wchar_t *>::convert(wchar_t * str) {
  12336. if (str) {
  12337. return ::Catch::Detail::stringify(std::wstring{ str });
  12338. } else {
  12339. return{ "{null string}" };
  12340. }
  12341. }
  12342. #endif
  12343. #if defined(CATCH_CONFIG_CPP17_BYTE)
  12344. #include <cstddef>
  12345. std::string StringMaker<std::byte>::convert(std::byte value) {
  12346. return ::Catch::Detail::stringify(std::to_integer<unsigned long long>(value));
  12347. }
  12348. #endif // defined(CATCH_CONFIG_CPP17_BYTE)
  12349. std::string StringMaker<int>::convert(int value) {
  12350. return ::Catch::Detail::stringify(static_cast<long long>(value));
  12351. }
  12352. std::string StringMaker<long>::convert(long value) {
  12353. return ::Catch::Detail::stringify(static_cast<long long>(value));
  12354. }
  12355. std::string StringMaker<long long>::convert(long long value) {
  12356. ReusableStringStream rss;
  12357. rss << value;
  12358. if (value > Detail::hexThreshold) {
  12359. rss << " (0x" << std::hex << value << ')';
  12360. }
  12361. return rss.str();
  12362. }
  12363. std::string StringMaker<unsigned int>::convert(unsigned int value) {
  12364. return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
  12365. }
  12366. std::string StringMaker<unsigned long>::convert(unsigned long value) {
  12367. return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
  12368. }
  12369. std::string StringMaker<unsigned long long>::convert(unsigned long long value) {
  12370. ReusableStringStream rss;
  12371. rss << value;
  12372. if (value > Detail::hexThreshold) {
  12373. rss << " (0x" << std::hex << value << ')';
  12374. }
  12375. return rss.str();
  12376. }
  12377. std::string StringMaker<bool>::convert(bool b) {
  12378. return b ? "true" : "false";
  12379. }
  12380. std::string StringMaker<signed char>::convert(signed char value) {
  12381. if (value == '\r') {
  12382. return "'\\r'";
  12383. } else if (value == '\f') {
  12384. return "'\\f'";
  12385. } else if (value == '\n') {
  12386. return "'\\n'";
  12387. } else if (value == '\t') {
  12388. return "'\\t'";
  12389. } else if ('\0' <= value && value < ' ') {
  12390. return ::Catch::Detail::stringify(static_cast<unsigned int>(value));
  12391. } else {
  12392. char chstr[] = "' '";
  12393. chstr[1] = value;
  12394. return chstr;
  12395. }
  12396. }
  12397. std::string StringMaker<char>::convert(char c) {
  12398. return ::Catch::Detail::stringify(static_cast<signed char>(c));
  12399. }
  12400. std::string StringMaker<unsigned char>::convert(unsigned char c) {
  12401. return ::Catch::Detail::stringify(static_cast<char>(c));
  12402. }
  12403. std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) {
  12404. return "nullptr";
  12405. }
  12406. int StringMaker<float>::precision = 5;
  12407. std::string StringMaker<float>::convert(float value) {
  12408. return fpToString(value, precision) + 'f';
  12409. }
  12410. int StringMaker<double>::precision = 10;
  12411. std::string StringMaker<double>::convert(double value) {
  12412. return fpToString(value, precision);
  12413. }
  12414. std::string ratio_string<std::atto>::symbol() { return "a"; }
  12415. std::string ratio_string<std::femto>::symbol() { return "f"; }
  12416. std::string ratio_string<std::pico>::symbol() { return "p"; }
  12417. std::string ratio_string<std::nano>::symbol() { return "n"; }
  12418. std::string ratio_string<std::micro>::symbol() { return "u"; }
  12419. std::string ratio_string<std::milli>::symbol() { return "m"; }
  12420. } // end namespace Catch
  12421. #if defined(__clang__)
  12422. # pragma clang diagnostic pop
  12423. #endif
  12424. // end catch_tostring.cpp
  12425. // start catch_totals.cpp
  12426. namespace Catch {
  12427. Counts Counts::operator - ( Counts const& other ) const {
  12428. Counts diff;
  12429. diff.passed = passed - other.passed;
  12430. diff.failed = failed - other.failed;
  12431. diff.failedButOk = failedButOk - other.failedButOk;
  12432. return diff;
  12433. }
  12434. Counts& Counts::operator += ( Counts const& other ) {
  12435. passed += other.passed;
  12436. failed += other.failed;
  12437. failedButOk += other.failedButOk;
  12438. return *this;
  12439. }
  12440. std::size_t Counts::total() const {
  12441. return passed + failed + failedButOk;
  12442. }
  12443. bool Counts::allPassed() const {
  12444. return failed == 0 && failedButOk == 0;
  12445. }
  12446. bool Counts::allOk() const {
  12447. return failed == 0;
  12448. }
  12449. Totals Totals::operator - ( Totals const& other ) const {
  12450. Totals diff;
  12451. diff.assertions = assertions - other.assertions;
  12452. diff.testCases = testCases - other.testCases;
  12453. return diff;
  12454. }
  12455. Totals& Totals::operator += ( Totals const& other ) {
  12456. assertions += other.assertions;
  12457. testCases += other.testCases;
  12458. return *this;
  12459. }
  12460. Totals Totals::delta( Totals const& prevTotals ) const {
  12461. Totals diff = *this - prevTotals;
  12462. if( diff.assertions.failed > 0 )
  12463. ++diff.testCases.failed;
  12464. else if( diff.assertions.failedButOk > 0 )
  12465. ++diff.testCases.failedButOk;
  12466. else
  12467. ++diff.testCases.passed;
  12468. return diff;
  12469. }
  12470. }
  12471. // end catch_totals.cpp
  12472. // start catch_uncaught_exceptions.cpp
  12473. // start catch_config_uncaught_exceptions.hpp
  12474. // Copyright Catch2 Authors
  12475. // Distributed under the Boost Software License, Version 1.0.
  12476. // (See accompanying file LICENSE_1_0.txt or copy at
  12477. // https://www.boost.org/LICENSE_1_0.txt)
  12478. // SPDX-License-Identifier: BSL-1.0
  12479. #ifndef CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP
  12480. #define CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP
  12481. #if defined(_MSC_VER)
  12482. # if _MSC_VER >= 1900 // Visual Studio 2015 or newer
  12483. # define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
  12484. # endif
  12485. #endif
  12486. #include <exception>
  12487. #if defined(__cpp_lib_uncaught_exceptions) \
  12488. && !defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
  12489. # define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
  12490. #endif // __cpp_lib_uncaught_exceptions
  12491. #if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) \
  12492. && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) \
  12493. && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
  12494. # define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
  12495. #endif
  12496. #endif // CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP
  12497. // end catch_config_uncaught_exceptions.hpp
  12498. #include <exception>
  12499. namespace Catch {
  12500. bool uncaught_exceptions() {
  12501. #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
  12502. return false;
  12503. #elif defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
  12504. return std::uncaught_exceptions() > 0;
  12505. #else
  12506. return std::uncaught_exception();
  12507. #endif
  12508. }
  12509. } // end namespace Catch
  12510. // end catch_uncaught_exceptions.cpp
  12511. // start catch_version.cpp
  12512. #include <ostream>
  12513. namespace Catch {
  12514. Version::Version
  12515. ( unsigned int _majorVersion,
  12516. unsigned int _minorVersion,
  12517. unsigned int _patchNumber,
  12518. char const * const _branchName,
  12519. unsigned int _buildNumber )
  12520. : majorVersion( _majorVersion ),
  12521. minorVersion( _minorVersion ),
  12522. patchNumber( _patchNumber ),
  12523. branchName( _branchName ),
  12524. buildNumber( _buildNumber )
  12525. {}
  12526. std::ostream& operator << ( std::ostream& os, Version const& version ) {
  12527. os << version.majorVersion << '.'
  12528. << version.minorVersion << '.'
  12529. << version.patchNumber;
  12530. // branchName is never null -> 0th char is \0 if it is empty
  12531. if (version.branchName[0]) {
  12532. os << '-' << version.branchName
  12533. << '.' << version.buildNumber;
  12534. }
  12535. return os;
  12536. }
  12537. Version const& libraryVersion() {
  12538. static Version version( 2, 13, 3, "", 0 );
  12539. return version;
  12540. }
  12541. }
  12542. // end catch_version.cpp
  12543. // start catch_wildcard_pattern.cpp
  12544. namespace Catch {
  12545. WildcardPattern::WildcardPattern( std::string const& pattern,
  12546. CaseSensitive::Choice caseSensitivity )
  12547. : m_caseSensitivity( caseSensitivity ),
  12548. m_pattern( normaliseString( pattern ) )
  12549. {
  12550. if( startsWith( m_pattern, '*' ) ) {
  12551. m_pattern = m_pattern.substr( 1 );
  12552. m_wildcard = WildcardAtStart;
  12553. }
  12554. if( endsWith( m_pattern, '*' ) ) {
  12555. m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
  12556. m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
  12557. }
  12558. }
  12559. bool WildcardPattern::matches( std::string const& str ) const {
  12560. switch( m_wildcard ) {
  12561. case NoWildcard:
  12562. return m_pattern == normaliseString( str );
  12563. case WildcardAtStart:
  12564. return endsWith( normaliseString( str ), m_pattern );
  12565. case WildcardAtEnd:
  12566. return startsWith( normaliseString( str ), m_pattern );
  12567. case WildcardAtBothEnds:
  12568. return contains( normaliseString( str ), m_pattern );
  12569. default:
  12570. CATCH_INTERNAL_ERROR( "Unknown enum" );
  12571. }
  12572. }
  12573. std::string WildcardPattern::normaliseString( std::string const& str ) const {
  12574. return trim( m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str );
  12575. }
  12576. }
  12577. // end catch_wildcard_pattern.cpp
  12578. // start catch_xmlwriter.cpp
  12579. #include <iomanip>
  12580. #include <type_traits>
  12581. namespace Catch {
  12582. namespace {
  12583. size_t trailingBytes(unsigned char c) {
  12584. if ((c & 0xE0) == 0xC0) {
  12585. return 2;
  12586. }
  12587. if ((c & 0xF0) == 0xE0) {
  12588. return 3;
  12589. }
  12590. if ((c & 0xF8) == 0xF0) {
  12591. return 4;
  12592. }
  12593. CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
  12594. }
  12595. uint32_t headerValue(unsigned char c) {
  12596. if ((c & 0xE0) == 0xC0) {
  12597. return c & 0x1F;
  12598. }
  12599. if ((c & 0xF0) == 0xE0) {
  12600. return c & 0x0F;
  12601. }
  12602. if ((c & 0xF8) == 0xF0) {
  12603. return c & 0x07;
  12604. }
  12605. CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
  12606. }
  12607. void hexEscapeChar(std::ostream& os, unsigned char c) {
  12608. std::ios_base::fmtflags f(os.flags());
  12609. os << "\\x"
  12610. << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
  12611. << static_cast<int>(c);
  12612. os.flags(f);
  12613. }
  12614. bool shouldNewline(XmlFormatting fmt) {
  12615. return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Newline));
  12616. }
  12617. bool shouldIndent(XmlFormatting fmt) {
  12618. return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Indent));
  12619. }
  12620. } // anonymous namespace
  12621. XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs) {
  12622. return static_cast<XmlFormatting>(
  12623. static_cast<std::underlying_type<XmlFormatting>::type>(lhs) |
  12624. static_cast<std::underlying_type<XmlFormatting>::type>(rhs)
  12625. );
  12626. }
  12627. XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs) {
  12628. return static_cast<XmlFormatting>(
  12629. static_cast<std::underlying_type<XmlFormatting>::type>(lhs) &
  12630. static_cast<std::underlying_type<XmlFormatting>::type>(rhs)
  12631. );
  12632. }
  12633. XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )
  12634. : m_str( str ),
  12635. m_forWhat( forWhat )
  12636. {}
  12637. void XmlEncode::encodeTo( std::ostream& os ) const {
  12638. // Apostrophe escaping not necessary if we always use " to write attributes
  12639. // (see: http://www.w3.org/TR/xml/#syntax)
  12640. for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
  12641. unsigned char c = m_str[idx];
  12642. switch (c) {
  12643. case '<': os << "&lt;"; break;
  12644. case '&': os << "&amp;"; break;
  12645. case '>':
  12646. // See: http://www.w3.org/TR/xml/#syntax
  12647. if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
  12648. os << "&gt;";
  12649. else
  12650. os << c;
  12651. break;
  12652. case '\"':
  12653. if (m_forWhat == ForAttributes)
  12654. os << "&quot;";
  12655. else
  12656. os << c;
  12657. break;
  12658. default:
  12659. // Check for control characters and invalid utf-8
  12660. // Escape control characters in standard ascii
  12661. // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
  12662. if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
  12663. hexEscapeChar(os, c);
  12664. break;
  12665. }
  12666. // Plain ASCII: Write it to stream
  12667. if (c < 0x7F) {
  12668. os << c;
  12669. break;
  12670. }
  12671. // UTF-8 territory
  12672. // Check if the encoding is valid and if it is not, hex escape bytes.
  12673. // Important: We do not check the exact decoded values for validity, only the encoding format
  12674. // First check that this bytes is a valid lead byte:
  12675. // This means that it is not encoded as 1111 1XXX
  12676. // Or as 10XX XXXX
  12677. if (c < 0xC0 ||
  12678. c >= 0xF8) {
  12679. hexEscapeChar(os, c);
  12680. break;
  12681. }
  12682. auto encBytes = trailingBytes(c);
  12683. // Are there enough bytes left to avoid accessing out-of-bounds memory?
  12684. if (idx + encBytes - 1 >= m_str.size()) {
  12685. hexEscapeChar(os, c);
  12686. break;
  12687. }
  12688. // The header is valid, check data
  12689. // The next encBytes bytes must together be a valid utf-8
  12690. // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)
  12691. bool valid = true;
  12692. uint32_t value = headerValue(c);
  12693. for (std::size_t n = 1; n < encBytes; ++n) {
  12694. unsigned char nc = m_str[idx + n];
  12695. valid &= ((nc & 0xC0) == 0x80);
  12696. value = (value << 6) | (nc & 0x3F);
  12697. }
  12698. if (
  12699. // Wrong bit pattern of following bytes
  12700. (!valid) ||
  12701. // Overlong encodings
  12702. (value < 0x80) ||
  12703. (0x80 <= value && value < 0x800 && encBytes > 2) ||
  12704. (0x800 < value && value < 0x10000 && encBytes > 3) ||
  12705. // Encoded value out of range
  12706. (value >= 0x110000)
  12707. ) {
  12708. hexEscapeChar(os, c);
  12709. break;
  12710. }
  12711. // If we got here, this is in fact a valid(ish) utf-8 sequence
  12712. for (std::size_t n = 0; n < encBytes; ++n) {
  12713. os << m_str[idx + n];
  12714. }
  12715. idx += encBytes - 1;
  12716. break;
  12717. }
  12718. }
  12719. }
  12720. std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
  12721. xmlEncode.encodeTo( os );
  12722. return os;
  12723. }
  12724. XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer, XmlFormatting fmt )
  12725. : m_writer( writer ),
  12726. m_fmt(fmt)
  12727. {}
  12728. XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept
  12729. : m_writer( other.m_writer ),
  12730. m_fmt(other.m_fmt)
  12731. {
  12732. other.m_writer = nullptr;
  12733. other.m_fmt = XmlFormatting::None;
  12734. }
  12735. XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept {
  12736. if ( m_writer ) {
  12737. m_writer->endElement();
  12738. }
  12739. m_writer = other.m_writer;
  12740. other.m_writer = nullptr;
  12741. m_fmt = other.m_fmt;
  12742. other.m_fmt = XmlFormatting::None;
  12743. return *this;
  12744. }
  12745. XmlWriter::ScopedElement::~ScopedElement() {
  12746. if (m_writer) {
  12747. m_writer->endElement(m_fmt);
  12748. }
  12749. }
  12750. XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, XmlFormatting fmt ) {
  12751. m_writer->writeText( text, fmt );
  12752. return *this;
  12753. }
  12754. XmlWriter::XmlWriter( std::ostream& os ) : m_os( os )
  12755. {
  12756. writeDeclaration();
  12757. }
  12758. XmlWriter::~XmlWriter() {
  12759. while (!m_tags.empty()) {
  12760. endElement();
  12761. }
  12762. newlineIfNecessary();
  12763. }
  12764. XmlWriter& XmlWriter::startElement( std::string const& name, XmlFormatting fmt ) {
  12765. ensureTagClosed();
  12766. newlineIfNecessary();
  12767. if (shouldIndent(fmt)) {
  12768. m_os << m_indent;
  12769. m_indent += " ";
  12770. }
  12771. m_os << '<' << name;
  12772. m_tags.push_back( name );
  12773. m_tagIsOpen = true;
  12774. applyFormatting(fmt);
  12775. return *this;
  12776. }
  12777. XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name, XmlFormatting fmt ) {
  12778. ScopedElement scoped( this, fmt );
  12779. startElement( name, fmt );
  12780. return scoped;
  12781. }
  12782. XmlWriter& XmlWriter::endElement(XmlFormatting fmt) {
  12783. m_indent = m_indent.substr(0, m_indent.size() - 2);
  12784. if( m_tagIsOpen ) {
  12785. m_os << "/>";
  12786. m_tagIsOpen = false;
  12787. } else {
  12788. newlineIfNecessary();
  12789. if (shouldIndent(fmt)) {
  12790. m_os << m_indent;
  12791. }
  12792. m_os << "</" << m_tags.back() << ">";
  12793. }
  12794. m_os << std::flush;
  12795. applyFormatting(fmt);
  12796. m_tags.pop_back();
  12797. return *this;
  12798. }
  12799. XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) {
  12800. if( !name.empty() && !attribute.empty() )
  12801. m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
  12802. return *this;
  12803. }
  12804. XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) {
  12805. m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
  12806. return *this;
  12807. }
  12808. XmlWriter& XmlWriter::writeText( std::string const& text, XmlFormatting fmt) {
  12809. if( !text.empty() ){
  12810. bool tagWasOpen = m_tagIsOpen;
  12811. ensureTagClosed();
  12812. if (tagWasOpen && shouldIndent(fmt)) {
  12813. m_os << m_indent;
  12814. }
  12815. m_os << XmlEncode( text );
  12816. applyFormatting(fmt);
  12817. }
  12818. return *this;
  12819. }
  12820. XmlWriter& XmlWriter::writeComment( std::string const& text, XmlFormatting fmt) {
  12821. ensureTagClosed();
  12822. if (shouldIndent(fmt)) {
  12823. m_os << m_indent;
  12824. }
  12825. m_os << "<!--" << text << "-->";
  12826. applyFormatting(fmt);
  12827. return *this;
  12828. }
  12829. void XmlWriter::writeStylesheetRef( std::string const& url ) {
  12830. m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
  12831. }
  12832. XmlWriter& XmlWriter::writeBlankLine() {
  12833. ensureTagClosed();
  12834. m_os << '\n';
  12835. return *this;
  12836. }
  12837. void XmlWriter::ensureTagClosed() {
  12838. if( m_tagIsOpen ) {
  12839. m_os << '>' << std::flush;
  12840. newlineIfNecessary();
  12841. m_tagIsOpen = false;
  12842. }
  12843. }
  12844. void XmlWriter::applyFormatting(XmlFormatting fmt) {
  12845. m_needsNewline = shouldNewline(fmt);
  12846. }
  12847. void XmlWriter::writeDeclaration() {
  12848. m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
  12849. }
  12850. void XmlWriter::newlineIfNecessary() {
  12851. if( m_needsNewline ) {
  12852. m_os << std::endl;
  12853. m_needsNewline = false;
  12854. }
  12855. }
  12856. }
  12857. // end catch_xmlwriter.cpp
  12858. // start catch_reporter_bases.cpp
  12859. #include <cstring>
  12860. #include <cfloat>
  12861. #include <cstdio>
  12862. #include <cassert>
  12863. #include <memory>
  12864. namespace Catch {
  12865. void prepareExpandedExpression(AssertionResult& result) {
  12866. result.getExpandedExpression();
  12867. }
  12868. // Because formatting using c++ streams is stateful, drop down to C is required
  12869. // Alternatively we could use stringstream, but its performance is... not good.
  12870. std::string getFormattedDuration( double duration ) {
  12871. // Max exponent + 1 is required to represent the whole part
  12872. // + 1 for decimal point
  12873. // + 3 for the 3 decimal places
  12874. // + 1 for null terminator
  12875. const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
  12876. char buffer[maxDoubleSize];
  12877. // Save previous errno, to prevent sprintf from overwriting it
  12878. ErrnoGuard guard;
  12879. #ifdef _MSC_VER
  12880. sprintf_s(buffer, "%.3f", duration);
  12881. #else
  12882. std::sprintf(buffer, "%.3f", duration);
  12883. #endif
  12884. return std::string(buffer);
  12885. }
  12886. bool shouldShowDuration( IConfig const& config, double duration ) {
  12887. if ( config.showDurations() == ShowDurations::Always ) {
  12888. return true;
  12889. }
  12890. if ( config.showDurations() == ShowDurations::Never ) {
  12891. return false;
  12892. }
  12893. const double min = config.minDuration();
  12894. return min >= 0 && duration >= min;
  12895. }
  12896. std::string serializeFilters( std::vector<std::string> const& container ) {
  12897. ReusableStringStream oss;
  12898. bool first = true;
  12899. for (auto&& filter : container)
  12900. {
  12901. if (!first)
  12902. oss << ' ';
  12903. else
  12904. first = false;
  12905. oss << filter;
  12906. }
  12907. return oss.str();
  12908. }
  12909. TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)
  12910. :StreamingReporterBase(_config) {}
  12911. std::set<Verbosity> TestEventListenerBase::getSupportedVerbosities() {
  12912. return { Verbosity::Quiet, Verbosity::Normal, Verbosity::High };
  12913. }
  12914. void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}
  12915. bool TestEventListenerBase::assertionEnded(AssertionStats const &) {
  12916. return false;
  12917. }
  12918. } // end namespace Catch
  12919. // end catch_reporter_bases.cpp
  12920. // start catch_reporter_compact.cpp
  12921. namespace {
  12922. #ifdef CATCH_PLATFORM_MAC
  12923. const char* failedString() { return "FAILED"; }
  12924. const char* passedString() { return "PASSED"; }
  12925. #else
  12926. const char* failedString() { return "failed"; }
  12927. const char* passedString() { return "passed"; }
  12928. #endif
  12929. // Colour::LightGrey
  12930. Catch::Colour::Code dimColour() { return Catch::Colour::FileName; }
  12931. std::string bothOrAll( std::size_t count ) {
  12932. return count == 1 ? std::string() :
  12933. count == 2 ? "both " : "all " ;
  12934. }
  12935. } // anon namespace
  12936. namespace Catch {
  12937. namespace {
  12938. // Colour, message variants:
  12939. // - white: No tests ran.
  12940. // - red: Failed [both/all] N test cases, failed [both/all] M assertions.
  12941. // - white: Passed [both/all] N test cases (no assertions).
  12942. // - red: Failed N tests cases, failed M assertions.
  12943. // - green: Passed [both/all] N tests cases with M assertions.
  12944. void printTotals(std::ostream& out, const Totals& totals) {
  12945. if (totals.testCases.total() == 0) {
  12946. out << "No tests ran.";
  12947. } else if (totals.testCases.failed == totals.testCases.total()) {
  12948. Colour colour(Colour::ResultError);
  12949. const std::string qualify_assertions_failed =
  12950. totals.assertions.failed == totals.assertions.total() ?
  12951. bothOrAll(totals.assertions.failed) : std::string();
  12952. out <<
  12953. "Failed " << bothOrAll(totals.testCases.failed)
  12954. << pluralise(totals.testCases.failed, "test case") << ", "
  12955. "failed " << qualify_assertions_failed <<
  12956. pluralise(totals.assertions.failed, "assertion") << '.';
  12957. } else if (totals.assertions.total() == 0) {
  12958. out <<
  12959. "Passed " << bothOrAll(totals.testCases.total())
  12960. << pluralise(totals.testCases.total(), "test case")
  12961. << " (no assertions).";
  12962. } else if (totals.assertions.failed) {
  12963. Colour colour(Colour::ResultError);
  12964. out <<
  12965. "Failed " << pluralise(totals.testCases.failed, "test case") << ", "
  12966. "failed " << pluralise(totals.assertions.failed, "assertion") << '.';
  12967. } else {
  12968. Colour colour(Colour::ResultSuccess);
  12969. out <<
  12970. "Passed " << bothOrAll(totals.testCases.passed)
  12971. << pluralise(totals.testCases.passed, "test case") <<
  12972. " with " << pluralise(totals.assertions.passed, "assertion") << '.';
  12973. }
  12974. }
  12975. // Implementation of CompactReporter formatting
  12976. class AssertionPrinter {
  12977. public:
  12978. AssertionPrinter& operator= (AssertionPrinter const&) = delete;
  12979. AssertionPrinter(AssertionPrinter const&) = delete;
  12980. AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
  12981. : stream(_stream)
  12982. , result(_stats.assertionResult)
  12983. , messages(_stats.infoMessages)
  12984. , itMessage(_stats.infoMessages.begin())
  12985. , printInfoMessages(_printInfoMessages) {}
  12986. void print() {
  12987. printSourceInfo();
  12988. itMessage = messages.begin();
  12989. switch (result.getResultType()) {
  12990. case ResultWas::Ok:
  12991. printResultType(Colour::ResultSuccess, passedString());
  12992. printOriginalExpression();
  12993. printReconstructedExpression();
  12994. if (!result.hasExpression())
  12995. printRemainingMessages(Colour::None);
  12996. else
  12997. printRemainingMessages();
  12998. break;
  12999. case ResultWas::ExpressionFailed:
  13000. if (result.isOk())
  13001. printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok"));
  13002. else
  13003. printResultType(Colour::Error, failedString());
  13004. printOriginalExpression();
  13005. printReconstructedExpression();
  13006. printRemainingMessages();
  13007. break;
  13008. case ResultWas::ThrewException:
  13009. printResultType(Colour::Error, failedString());
  13010. printIssue("unexpected exception with message:");
  13011. printMessage();
  13012. printExpressionWas();
  13013. printRemainingMessages();
  13014. break;
  13015. case ResultWas::FatalErrorCondition:
  13016. printResultType(Colour::Error, failedString());
  13017. printIssue("fatal error condition with message:");
  13018. printMessage();
  13019. printExpressionWas();
  13020. printRemainingMessages();
  13021. break;
  13022. case ResultWas::DidntThrowException:
  13023. printResultType(Colour::Error, failedString());
  13024. printIssue("expected exception, got none");
  13025. printExpressionWas();
  13026. printRemainingMessages();
  13027. break;
  13028. case ResultWas::Info:
  13029. printResultType(Colour::None, "info");
  13030. printMessage();
  13031. printRemainingMessages();
  13032. break;
  13033. case ResultWas::Warning:
  13034. printResultType(Colour::None, "warning");
  13035. printMessage();
  13036. printRemainingMessages();
  13037. break;
  13038. case ResultWas::ExplicitFailure:
  13039. printResultType(Colour::Error, failedString());
  13040. printIssue("explicitly");
  13041. printRemainingMessages(Colour::None);
  13042. break;
  13043. // These cases are here to prevent compiler warnings
  13044. case ResultWas::Unknown:
  13045. case ResultWas::FailureBit:
  13046. case ResultWas::Exception:
  13047. printResultType(Colour::Error, "** internal error **");
  13048. break;
  13049. }
  13050. }
  13051. private:
  13052. void printSourceInfo() const {
  13053. Colour colourGuard(Colour::FileName);
  13054. stream << result.getSourceInfo() << ':';
  13055. }
  13056. void printResultType(Colour::Code colour, std::string const& passOrFail) const {
  13057. if (!passOrFail.empty()) {
  13058. {
  13059. Colour colourGuard(colour);
  13060. stream << ' ' << passOrFail;
  13061. }
  13062. stream << ':';
  13063. }
  13064. }
  13065. void printIssue(std::string const& issue) const {
  13066. stream << ' ' << issue;
  13067. }
  13068. void printExpressionWas() {
  13069. if (result.hasExpression()) {
  13070. stream << ';';
  13071. {
  13072. Colour colour(dimColour());
  13073. stream << " expression was:";
  13074. }
  13075. printOriginalExpression();
  13076. }
  13077. }
  13078. void printOriginalExpression() const {
  13079. if (result.hasExpression()) {
  13080. stream << ' ' << result.getExpression();
  13081. }
  13082. }
  13083. void printReconstructedExpression() const {
  13084. if (result.hasExpandedExpression()) {
  13085. {
  13086. Colour colour(dimColour());
  13087. stream << " for: ";
  13088. }
  13089. stream << result.getExpandedExpression();
  13090. }
  13091. }
  13092. void printMessage() {
  13093. if (itMessage != messages.end()) {
  13094. stream << " '" << itMessage->message << '\'';
  13095. ++itMessage;
  13096. }
  13097. }
  13098. void printRemainingMessages(Colour::Code colour = dimColour()) {
  13099. if (itMessage == messages.end())
  13100. return;
  13101. const auto itEnd = messages.cend();
  13102. const auto N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
  13103. {
  13104. Colour colourGuard(colour);
  13105. stream << " with " << pluralise(N, "message") << ':';
  13106. }
  13107. while (itMessage != itEnd) {
  13108. // If this assertion is a warning ignore any INFO messages
  13109. if (printInfoMessages || itMessage->type != ResultWas::Info) {
  13110. printMessage();
  13111. if (itMessage != itEnd) {
  13112. Colour colourGuard(dimColour());
  13113. stream << " and";
  13114. }
  13115. continue;
  13116. }
  13117. ++itMessage;
  13118. }
  13119. }
  13120. private:
  13121. std::ostream& stream;
  13122. AssertionResult const& result;
  13123. std::vector<MessageInfo> messages;
  13124. std::vector<MessageInfo>::const_iterator itMessage;
  13125. bool printInfoMessages;
  13126. };
  13127. } // anon namespace
  13128. std::string CompactReporter::getDescription() {
  13129. return "Reports test results on a single line, suitable for IDEs";
  13130. }
  13131. void CompactReporter::noMatchingTestCases( std::string const& spec ) {
  13132. stream << "No test cases matched '" << spec << '\'' << std::endl;
  13133. }
  13134. void CompactReporter::assertionStarting( AssertionInfo const& ) {}
  13135. bool CompactReporter::assertionEnded( AssertionStats const& _assertionStats ) {
  13136. AssertionResult const& result = _assertionStats.assertionResult;
  13137. bool printInfoMessages = true;
  13138. // Drop out if result was successful and we're not printing those
  13139. if( !m_config->includeSuccessfulResults() && result.isOk() ) {
  13140. if( result.getResultType() != ResultWas::Warning )
  13141. return false;
  13142. printInfoMessages = false;
  13143. }
  13144. AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
  13145. printer.print();
  13146. stream << std::endl;
  13147. return true;
  13148. }
  13149. void CompactReporter::sectionEnded(SectionStats const& _sectionStats) {
  13150. double dur = _sectionStats.durationInSeconds;
  13151. if ( shouldShowDuration( *m_config, dur ) ) {
  13152. stream << getFormattedDuration( dur ) << " s: " << _sectionStats.sectionInfo.name << std::endl;
  13153. }
  13154. }
  13155. void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) {
  13156. printTotals( stream, _testRunStats.totals );
  13157. stream << '\n' << std::endl;
  13158. StreamingReporterBase::testRunEnded( _testRunStats );
  13159. }
  13160. CompactReporter::~CompactReporter() {}
  13161. CATCH_REGISTER_REPORTER( "compact", CompactReporter )
  13162. } // end namespace Catch
  13163. // end catch_reporter_compact.cpp
  13164. // start catch_reporter_console.cpp
  13165. #include <cfloat>
  13166. #include <cstdio>
  13167. #if defined(_MSC_VER)
  13168. #pragma warning(push)
  13169. #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
  13170. // Note that 4062 (not all labels are handled and default is missing) is enabled
  13171. #endif
  13172. #if defined(__clang__)
  13173. # pragma clang diagnostic push
  13174. // For simplicity, benchmarking-only helpers are always enabled
  13175. # pragma clang diagnostic ignored "-Wunused-function"
  13176. #endif
  13177. namespace Catch {
  13178. namespace {
  13179. // Formatter impl for ConsoleReporter
  13180. class ConsoleAssertionPrinter {
  13181. public:
  13182. ConsoleAssertionPrinter& operator= (ConsoleAssertionPrinter const&) = delete;
  13183. ConsoleAssertionPrinter(ConsoleAssertionPrinter const&) = delete;
  13184. ConsoleAssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
  13185. : stream(_stream),
  13186. stats(_stats),
  13187. result(_stats.assertionResult),
  13188. colour(Colour::None),
  13189. message(result.getMessage()),
  13190. messages(_stats.infoMessages),
  13191. printInfoMessages(_printInfoMessages) {
  13192. switch (result.getResultType()) {
  13193. case ResultWas::Ok:
  13194. colour = Colour::Success;
  13195. passOrFail = "PASSED";
  13196. //if( result.hasMessage() )
  13197. if (_stats.infoMessages.size() == 1)
  13198. messageLabel = "with message";
  13199. if (_stats.infoMessages.size() > 1)
  13200. messageLabel = "with messages";
  13201. break;
  13202. case ResultWas::ExpressionFailed:
  13203. if (result.isOk()) {
  13204. colour = Colour::Success;
  13205. passOrFail = "FAILED - but was ok";
  13206. } else {
  13207. colour = Colour::Error;
  13208. passOrFail = "FAILED";
  13209. }
  13210. if (_stats.infoMessages.size() == 1)
  13211. messageLabel = "with message";
  13212. if (_stats.infoMessages.size() > 1)
  13213. messageLabel = "with messages";
  13214. break;
  13215. case ResultWas::ThrewException:
  13216. colour = Colour::Error;
  13217. passOrFail = "FAILED";
  13218. messageLabel = "due to unexpected exception with ";
  13219. if (_stats.infoMessages.size() == 1)
  13220. messageLabel += "message";
  13221. if (_stats.infoMessages.size() > 1)
  13222. messageLabel += "messages";
  13223. break;
  13224. case ResultWas::FatalErrorCondition:
  13225. colour = Colour::Error;
  13226. passOrFail = "FAILED";
  13227. messageLabel = "due to a fatal error condition";
  13228. break;
  13229. case ResultWas::DidntThrowException:
  13230. colour = Colour::Error;
  13231. passOrFail = "FAILED";
  13232. messageLabel = "because no exception was thrown where one was expected";
  13233. break;
  13234. case ResultWas::Info:
  13235. messageLabel = "info";
  13236. break;
  13237. case ResultWas::Warning:
  13238. messageLabel = "warning";
  13239. break;
  13240. case ResultWas::ExplicitFailure:
  13241. passOrFail = "FAILED";
  13242. colour = Colour::Error;
  13243. if (_stats.infoMessages.size() == 1)
  13244. messageLabel = "explicitly with message";
  13245. if (_stats.infoMessages.size() > 1)
  13246. messageLabel = "explicitly with messages";
  13247. break;
  13248. // These cases are here to prevent compiler warnings
  13249. case ResultWas::Unknown:
  13250. case ResultWas::FailureBit:
  13251. case ResultWas::Exception:
  13252. passOrFail = "** internal error **";
  13253. colour = Colour::Error;
  13254. break;
  13255. }
  13256. }
  13257. void print() const {
  13258. printSourceInfo();
  13259. if (stats.totals.assertions.total() > 0) {
  13260. printResultType();
  13261. printOriginalExpression();
  13262. printReconstructedExpression();
  13263. } else {
  13264. stream << '\n';
  13265. }
  13266. printMessage();
  13267. }
  13268. private:
  13269. void printResultType() const {
  13270. if (!passOrFail.empty()) {
  13271. Colour colourGuard(colour);
  13272. stream << passOrFail << ":\n";
  13273. }
  13274. }
  13275. void printOriginalExpression() const {
  13276. if (result.hasExpression()) {
  13277. Colour colourGuard(Colour::OriginalExpression);
  13278. stream << " ";
  13279. stream << result.getExpressionInMacro();
  13280. stream << '\n';
  13281. }
  13282. }
  13283. void printReconstructedExpression() const {
  13284. if (result.hasExpandedExpression()) {
  13285. stream << "with expansion:\n";
  13286. Colour colourGuard(Colour::ReconstructedExpression);
  13287. stream << Column(result.getExpandedExpression()).indent(2) << '\n';
  13288. }
  13289. }
  13290. void printMessage() const {
  13291. if (!messageLabel.empty())
  13292. stream << messageLabel << ':' << '\n';
  13293. for (auto const& msg : messages) {
  13294. // If this assertion is a warning ignore any INFO messages
  13295. if (printInfoMessages || msg.type != ResultWas::Info)
  13296. stream << Column(msg.message).indent(2) << '\n';
  13297. }
  13298. }
  13299. void printSourceInfo() const {
  13300. Colour colourGuard(Colour::FileName);
  13301. stream << result.getSourceInfo() << ": ";
  13302. }
  13303. std::ostream& stream;
  13304. AssertionStats const& stats;
  13305. AssertionResult const& result;
  13306. Colour::Code colour;
  13307. std::string passOrFail;
  13308. std::string messageLabel;
  13309. std::string message;
  13310. std::vector<MessageInfo> messages;
  13311. bool printInfoMessages;
  13312. };
  13313. std::size_t makeRatio(std::size_t number, std::size_t total) {
  13314. std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0;
  13315. return (ratio == 0 && number > 0) ? 1 : ratio;
  13316. }
  13317. std::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k) {
  13318. if (i > j && i > k)
  13319. return i;
  13320. else if (j > k)
  13321. return j;
  13322. else
  13323. return k;
  13324. }
  13325. struct ColumnInfo {
  13326. enum Justification { Left, Right };
  13327. std::string name;
  13328. int width;
  13329. Justification justification;
  13330. };
  13331. struct ColumnBreak {};
  13332. struct RowBreak {};
  13333. class Duration {
  13334. enum class Unit {
  13335. Auto,
  13336. Nanoseconds,
  13337. Microseconds,
  13338. Milliseconds,
  13339. Seconds,
  13340. Minutes
  13341. };
  13342. static const uint64_t s_nanosecondsInAMicrosecond = 1000;
  13343. static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond;
  13344. static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;
  13345. static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;
  13346. double m_inNanoseconds;
  13347. Unit m_units;
  13348. public:
  13349. explicit Duration(double inNanoseconds, Unit units = Unit::Auto)
  13350. : m_inNanoseconds(inNanoseconds),
  13351. m_units(units) {
  13352. if (m_units == Unit::Auto) {
  13353. if (m_inNanoseconds < s_nanosecondsInAMicrosecond)
  13354. m_units = Unit::Nanoseconds;
  13355. else if (m_inNanoseconds < s_nanosecondsInAMillisecond)
  13356. m_units = Unit::Microseconds;
  13357. else if (m_inNanoseconds < s_nanosecondsInASecond)
  13358. m_units = Unit::Milliseconds;
  13359. else if (m_inNanoseconds < s_nanosecondsInAMinute)
  13360. m_units = Unit::Seconds;
  13361. else
  13362. m_units = Unit::Minutes;
  13363. }
  13364. }
  13365. auto value() const -> double {
  13366. switch (m_units) {
  13367. case Unit::Microseconds:
  13368. return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond);
  13369. case Unit::Milliseconds:
  13370. return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond);
  13371. case Unit::Seconds:
  13372. return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond);
  13373. case Unit::Minutes:
  13374. return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute);
  13375. default:
  13376. return m_inNanoseconds;
  13377. }
  13378. }
  13379. auto unitsAsString() const -> std::string {
  13380. switch (m_units) {
  13381. case Unit::Nanoseconds:
  13382. return "ns";
  13383. case Unit::Microseconds:
  13384. return "us";
  13385. case Unit::Milliseconds:
  13386. return "ms";
  13387. case Unit::Seconds:
  13388. return "s";
  13389. case Unit::Minutes:
  13390. return "m";
  13391. default:
  13392. return "** internal error **";
  13393. }
  13394. }
  13395. friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& {
  13396. return os << duration.value() << ' ' << duration.unitsAsString();
  13397. }
  13398. };
  13399. } // end anon namespace
  13400. class TablePrinter {
  13401. std::ostream& m_os;
  13402. std::vector<ColumnInfo> m_columnInfos;
  13403. std::ostringstream m_oss;
  13404. int m_currentColumn = -1;
  13405. bool m_isOpen = false;
  13406. public:
  13407. TablePrinter( std::ostream& os, std::vector<ColumnInfo> columnInfos )
  13408. : m_os( os ),
  13409. m_columnInfos( std::move( columnInfos ) ) {}
  13410. auto columnInfos() const -> std::vector<ColumnInfo> const& {
  13411. return m_columnInfos;
  13412. }
  13413. void open() {
  13414. if (!m_isOpen) {
  13415. m_isOpen = true;
  13416. *this << RowBreak();
  13417. Columns headerCols;
  13418. Spacer spacer(2);
  13419. for (auto const& info : m_columnInfos) {
  13420. headerCols += Column(info.name).width(static_cast<std::size_t>(info.width - 2));
  13421. headerCols += spacer;
  13422. }
  13423. m_os << headerCols << '\n';
  13424. m_os << Catch::getLineOfChars<'-'>() << '\n';
  13425. }
  13426. }
  13427. void close() {
  13428. if (m_isOpen) {
  13429. *this << RowBreak();
  13430. m_os << std::endl;
  13431. m_isOpen = false;
  13432. }
  13433. }
  13434. template<typename T>
  13435. friend TablePrinter& operator << (TablePrinter& tp, T const& value) {
  13436. tp.m_oss << value;
  13437. return tp;
  13438. }
  13439. friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) {
  13440. auto colStr = tp.m_oss.str();
  13441. const auto strSize = colStr.size();
  13442. tp.m_oss.str("");
  13443. tp.open();
  13444. if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) {
  13445. tp.m_currentColumn = -1;
  13446. tp.m_os << '\n';
  13447. }
  13448. tp.m_currentColumn++;
  13449. auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
  13450. auto padding = (strSize + 1 < static_cast<std::size_t>(colInfo.width))
  13451. ? std::string(colInfo.width - (strSize + 1), ' ')
  13452. : std::string();
  13453. if (colInfo.justification == ColumnInfo::Left)
  13454. tp.m_os << colStr << padding << ' ';
  13455. else
  13456. tp.m_os << padding << colStr << ' ';
  13457. return tp;
  13458. }
  13459. friend TablePrinter& operator << (TablePrinter& tp, RowBreak) {
  13460. if (tp.m_currentColumn > 0) {
  13461. tp.m_os << '\n';
  13462. tp.m_currentColumn = -1;
  13463. }
  13464. return tp;
  13465. }
  13466. };
  13467. ConsoleReporter::ConsoleReporter(ReporterConfig const& config)
  13468. : StreamingReporterBase(config),
  13469. m_tablePrinter(new TablePrinter(config.stream(),
  13470. [&config]() -> std::vector<ColumnInfo> {
  13471. if (config.fullConfig()->benchmarkNoAnalysis())
  13472. {
  13473. return{
  13474. { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left },
  13475. { " samples", 14, ColumnInfo::Right },
  13476. { " iterations", 14, ColumnInfo::Right },
  13477. { " mean", 14, ColumnInfo::Right }
  13478. };
  13479. }
  13480. else
  13481. {
  13482. return{
  13483. { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left },
  13484. { "samples mean std dev", 14, ColumnInfo::Right },
  13485. { "iterations low mean low std dev", 14, ColumnInfo::Right },
  13486. { "estimated high mean high std dev", 14, ColumnInfo::Right }
  13487. };
  13488. }
  13489. }())) {}
  13490. ConsoleReporter::~ConsoleReporter() = default;
  13491. std::string ConsoleReporter::getDescription() {
  13492. return "Reports test results as plain lines of text";
  13493. }
  13494. void ConsoleReporter::noMatchingTestCases(std::string const& spec) {
  13495. stream << "No test cases matched '" << spec << '\'' << std::endl;
  13496. }
  13497. void ConsoleReporter::reportInvalidArguments(std::string const&arg){
  13498. stream << "Invalid Filter: " << arg << std::endl;
  13499. }
  13500. void ConsoleReporter::assertionStarting(AssertionInfo const&) {}
  13501. bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {
  13502. AssertionResult const& result = _assertionStats.assertionResult;
  13503. bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
  13504. // Drop out if result was successful but we're not printing them.
  13505. if (!includeResults && result.getResultType() != ResultWas::Warning)
  13506. return false;
  13507. lazyPrint();
  13508. ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults);
  13509. printer.print();
  13510. stream << std::endl;
  13511. return true;
  13512. }
  13513. void ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) {
  13514. m_tablePrinter->close();
  13515. m_headerPrinted = false;
  13516. StreamingReporterBase::sectionStarting(_sectionInfo);
  13517. }
  13518. void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) {
  13519. m_tablePrinter->close();
  13520. if (_sectionStats.missingAssertions) {
  13521. lazyPrint();
  13522. Colour colour(Colour::ResultError);
  13523. if (m_sectionStack.size() > 1)
  13524. stream << "\nNo assertions in section";
  13525. else
  13526. stream << "\nNo assertions in test case";
  13527. stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
  13528. }
  13529. double dur = _sectionStats.durationInSeconds;
  13530. if (shouldShowDuration(*m_config, dur)) {
  13531. stream << getFormattedDuration(dur) << " s: " << _sectionStats.sectionInfo.name << std::endl;
  13532. }
  13533. if (m_headerPrinted) {
  13534. m_headerPrinted = false;
  13535. }
  13536. StreamingReporterBase::sectionEnded(_sectionStats);
  13537. }
  13538. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  13539. void ConsoleReporter::benchmarkPreparing(std::string const& name) {
  13540. lazyPrintWithoutClosingBenchmarkTable();
  13541. auto nameCol = Column(name).width(static_cast<std::size_t>(m_tablePrinter->columnInfos()[0].width - 2));
  13542. bool firstLine = true;
  13543. for (auto line : nameCol) {
  13544. if (!firstLine)
  13545. (*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();
  13546. else
  13547. firstLine = false;
  13548. (*m_tablePrinter) << line << ColumnBreak();
  13549. }
  13550. }
  13551. void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {
  13552. (*m_tablePrinter) << info.samples << ColumnBreak()
  13553. << info.iterations << ColumnBreak();
  13554. if (!m_config->benchmarkNoAnalysis())
  13555. (*m_tablePrinter) << Duration(info.estimatedDuration) << ColumnBreak();
  13556. }
  13557. void ConsoleReporter::benchmarkEnded(BenchmarkStats<> const& stats) {
  13558. if (m_config->benchmarkNoAnalysis())
  13559. {
  13560. (*m_tablePrinter) << Duration(stats.mean.point.count()) << ColumnBreak();
  13561. }
  13562. else
  13563. {
  13564. (*m_tablePrinter) << ColumnBreak()
  13565. << Duration(stats.mean.point.count()) << ColumnBreak()
  13566. << Duration(stats.mean.lower_bound.count()) << ColumnBreak()
  13567. << Duration(stats.mean.upper_bound.count()) << ColumnBreak() << ColumnBreak()
  13568. << Duration(stats.standardDeviation.point.count()) << ColumnBreak()
  13569. << Duration(stats.standardDeviation.lower_bound.count()) << ColumnBreak()
  13570. << Duration(stats.standardDeviation.upper_bound.count()) << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak();
  13571. }
  13572. }
  13573. void ConsoleReporter::benchmarkFailed(std::string const& error) {
  13574. Colour colour(Colour::Red);
  13575. (*m_tablePrinter)
  13576. << "Benchmark failed (" << error << ')'
  13577. << ColumnBreak() << RowBreak();
  13578. }
  13579. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  13580. void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {
  13581. m_tablePrinter->close();
  13582. StreamingReporterBase::testCaseEnded(_testCaseStats);
  13583. m_headerPrinted = false;
  13584. }
  13585. void ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats) {
  13586. if (currentGroupInfo.used) {
  13587. printSummaryDivider();
  13588. stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
  13589. printTotals(_testGroupStats.totals);
  13590. stream << '\n' << std::endl;
  13591. }
  13592. StreamingReporterBase::testGroupEnded(_testGroupStats);
  13593. }
  13594. void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
  13595. printTotalsDivider(_testRunStats.totals);
  13596. printTotals(_testRunStats.totals);
  13597. stream << std::endl;
  13598. StreamingReporterBase::testRunEnded(_testRunStats);
  13599. }
  13600. void ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) {
  13601. StreamingReporterBase::testRunStarting(_testInfo);
  13602. printTestFilters();
  13603. }
  13604. void ConsoleReporter::lazyPrint() {
  13605. m_tablePrinter->close();
  13606. lazyPrintWithoutClosingBenchmarkTable();
  13607. }
  13608. void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() {
  13609. if (!currentTestRunInfo.used)
  13610. lazyPrintRunInfo();
  13611. if (!currentGroupInfo.used)
  13612. lazyPrintGroupInfo();
  13613. if (!m_headerPrinted) {
  13614. printTestCaseAndSectionHeader();
  13615. m_headerPrinted = true;
  13616. }
  13617. }
  13618. void ConsoleReporter::lazyPrintRunInfo() {
  13619. stream << '\n' << getLineOfChars<'~'>() << '\n';
  13620. Colour colour(Colour::SecondaryText);
  13621. stream << currentTestRunInfo->name
  13622. << " is a Catch v" << libraryVersion() << " host application.\n"
  13623. << "Run with -? for options\n\n";
  13624. if (m_config->rngSeed() != 0)
  13625. stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
  13626. currentTestRunInfo.used = true;
  13627. }
  13628. void ConsoleReporter::lazyPrintGroupInfo() {
  13629. if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) {
  13630. printClosedHeader("Group: " + currentGroupInfo->name);
  13631. currentGroupInfo.used = true;
  13632. }
  13633. }
  13634. void ConsoleReporter::printTestCaseAndSectionHeader() {
  13635. assert(!m_sectionStack.empty());
  13636. printOpenHeader(currentTestCaseInfo->name);
  13637. if (m_sectionStack.size() > 1) {
  13638. Colour colourGuard(Colour::Headers);
  13639. auto
  13640. it = m_sectionStack.begin() + 1, // Skip first section (test case)
  13641. itEnd = m_sectionStack.end();
  13642. for (; it != itEnd; ++it)
  13643. printHeaderString(it->name, 2);
  13644. }
  13645. SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
  13646. stream << getLineOfChars<'-'>() << '\n';
  13647. Colour colourGuard(Colour::FileName);
  13648. stream << lineInfo << '\n';
  13649. stream << getLineOfChars<'.'>() << '\n' << std::endl;
  13650. }
  13651. void ConsoleReporter::printClosedHeader(std::string const& _name) {
  13652. printOpenHeader(_name);
  13653. stream << getLineOfChars<'.'>() << '\n';
  13654. }
  13655. void ConsoleReporter::printOpenHeader(std::string const& _name) {
  13656. stream << getLineOfChars<'-'>() << '\n';
  13657. {
  13658. Colour colourGuard(Colour::Headers);
  13659. printHeaderString(_name);
  13660. }
  13661. }
  13662. // if string has a : in first line will set indent to follow it on
  13663. // subsequent lines
  13664. void ConsoleReporter::printHeaderString(std::string const& _string, std::size_t indent) {
  13665. std::size_t i = _string.find(": ");
  13666. if (i != std::string::npos)
  13667. i += 2;
  13668. else
  13669. i = 0;
  13670. stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n';
  13671. }
  13672. struct SummaryColumn {
  13673. SummaryColumn( std::string _label, Colour::Code _colour )
  13674. : label( std::move( _label ) ),
  13675. colour( _colour ) {}
  13676. SummaryColumn addRow( std::size_t count ) {
  13677. ReusableStringStream rss;
  13678. rss << count;
  13679. std::string row = rss.str();
  13680. for (auto& oldRow : rows) {
  13681. while (oldRow.size() < row.size())
  13682. oldRow = ' ' + oldRow;
  13683. while (oldRow.size() > row.size())
  13684. row = ' ' + row;
  13685. }
  13686. rows.push_back(row);
  13687. return *this;
  13688. }
  13689. std::string label;
  13690. Colour::Code colour;
  13691. std::vector<std::string> rows;
  13692. };
  13693. void ConsoleReporter::printTotals( Totals const& totals ) {
  13694. if (totals.testCases.total() == 0) {
  13695. stream << Colour(Colour::Warning) << "No tests ran\n";
  13696. } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) {
  13697. stream << Colour(Colour::ResultSuccess) << "All tests passed";
  13698. stream << " ("
  13699. << pluralise(totals.assertions.passed, "assertion") << " in "
  13700. << pluralise(totals.testCases.passed, "test case") << ')'
  13701. << '\n';
  13702. } else {
  13703. std::vector<SummaryColumn> columns;
  13704. columns.push_back(SummaryColumn("", Colour::None)
  13705. .addRow(totals.testCases.total())
  13706. .addRow(totals.assertions.total()));
  13707. columns.push_back(SummaryColumn("passed", Colour::Success)
  13708. .addRow(totals.testCases.passed)
  13709. .addRow(totals.assertions.passed));
  13710. columns.push_back(SummaryColumn("failed", Colour::ResultError)
  13711. .addRow(totals.testCases.failed)
  13712. .addRow(totals.assertions.failed));
  13713. columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure)
  13714. .addRow(totals.testCases.failedButOk)
  13715. .addRow(totals.assertions.failedButOk));
  13716. printSummaryRow("test cases", columns, 0);
  13717. printSummaryRow("assertions", columns, 1);
  13718. }
  13719. }
  13720. void ConsoleReporter::printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row) {
  13721. for (auto col : cols) {
  13722. std::string value = col.rows[row];
  13723. if (col.label.empty()) {
  13724. stream << label << ": ";
  13725. if (value != "0")
  13726. stream << value;
  13727. else
  13728. stream << Colour(Colour::Warning) << "- none -";
  13729. } else if (value != "0") {
  13730. stream << Colour(Colour::LightGrey) << " | ";
  13731. stream << Colour(col.colour)
  13732. << value << ' ' << col.label;
  13733. }
  13734. }
  13735. stream << '\n';
  13736. }
  13737. void ConsoleReporter::printTotalsDivider(Totals const& totals) {
  13738. if (totals.testCases.total() > 0) {
  13739. std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());
  13740. std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());
  13741. std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());
  13742. while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
  13743. findMax(failedRatio, failedButOkRatio, passedRatio)++;
  13744. while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)
  13745. findMax(failedRatio, failedButOkRatio, passedRatio)--;
  13746. stream << Colour(Colour::Error) << std::string(failedRatio, '=');
  13747. stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '=');
  13748. if (totals.testCases.allPassed())
  13749. stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '=');
  13750. else
  13751. stream << Colour(Colour::Success) << std::string(passedRatio, '=');
  13752. } else {
  13753. stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '=');
  13754. }
  13755. stream << '\n';
  13756. }
  13757. void ConsoleReporter::printSummaryDivider() {
  13758. stream << getLineOfChars<'-'>() << '\n';
  13759. }
  13760. void ConsoleReporter::printTestFilters() {
  13761. if (m_config->testSpec().hasFilters()) {
  13762. Colour guard(Colour::BrightYellow);
  13763. stream << "Filters: " << serializeFilters(m_config->getTestsOrTags()) << '\n';
  13764. }
  13765. }
  13766. CATCH_REGISTER_REPORTER("console", ConsoleReporter)
  13767. } // end namespace Catch
  13768. #if defined(_MSC_VER)
  13769. #pragma warning(pop)
  13770. #endif
  13771. #if defined(__clang__)
  13772. # pragma clang diagnostic pop
  13773. #endif
  13774. // end catch_reporter_console.cpp
  13775. // start catch_reporter_junit.cpp
  13776. #include <cassert>
  13777. #include <sstream>
  13778. #include <ctime>
  13779. #include <algorithm>
  13780. namespace Catch {
  13781. namespace {
  13782. std::string getCurrentTimestamp() {
  13783. // Beware, this is not reentrant because of backward compatibility issues
  13784. // Also, UTC only, again because of backward compatibility (%z is C++11)
  13785. time_t rawtime;
  13786. std::time(&rawtime);
  13787. auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
  13788. #ifdef _MSC_VER
  13789. std::tm timeInfo = {};
  13790. gmtime_s(&timeInfo, &rawtime);
  13791. #else
  13792. std::tm* timeInfo;
  13793. timeInfo = std::gmtime(&rawtime);
  13794. #endif
  13795. char timeStamp[timeStampSize];
  13796. const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
  13797. #ifdef _MSC_VER
  13798. std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
  13799. #else
  13800. std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
  13801. #endif
  13802. return std::string(timeStamp);
  13803. }
  13804. std::string fileNameTag(const std::vector<std::string> &tags) {
  13805. auto it = std::find_if(begin(tags),
  13806. end(tags),
  13807. [] (std::string const& tag) {return tag.front() == '#'; });
  13808. if (it != tags.end())
  13809. return it->substr(1);
  13810. return std::string();
  13811. }
  13812. } // anonymous namespace
  13813. JunitReporter::JunitReporter( ReporterConfig const& _config )
  13814. : CumulativeReporterBase( _config ),
  13815. xml( _config.stream() )
  13816. {
  13817. m_reporterPrefs.shouldRedirectStdOut = true;
  13818. m_reporterPrefs.shouldReportAllAssertions = true;
  13819. }
  13820. JunitReporter::~JunitReporter() {}
  13821. std::string JunitReporter::getDescription() {
  13822. return "Reports test results in an XML format that looks like Ant's junitreport target";
  13823. }
  13824. void JunitReporter::noMatchingTestCases( std::string const& /*spec*/ ) {}
  13825. void JunitReporter::testRunStarting( TestRunInfo const& runInfo ) {
  13826. CumulativeReporterBase::testRunStarting( runInfo );
  13827. xml.startElement( "testsuites" );
  13828. }
  13829. void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) {
  13830. suiteTimer.start();
  13831. stdOutForSuite.clear();
  13832. stdErrForSuite.clear();
  13833. unexpectedExceptions = 0;
  13834. CumulativeReporterBase::testGroupStarting( groupInfo );
  13835. }
  13836. void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) {
  13837. m_okToFail = testCaseInfo.okToFail();
  13838. }
  13839. bool JunitReporter::assertionEnded( AssertionStats const& assertionStats ) {
  13840. if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
  13841. unexpectedExceptions++;
  13842. return CumulativeReporterBase::assertionEnded( assertionStats );
  13843. }
  13844. void JunitReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
  13845. stdOutForSuite += testCaseStats.stdOut;
  13846. stdErrForSuite += testCaseStats.stdErr;
  13847. CumulativeReporterBase::testCaseEnded( testCaseStats );
  13848. }
  13849. void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
  13850. double suiteTime = suiteTimer.getElapsedSeconds();
  13851. CumulativeReporterBase::testGroupEnded( testGroupStats );
  13852. writeGroup( *m_testGroups.back(), suiteTime );
  13853. }
  13854. void JunitReporter::testRunEndedCumulative() {
  13855. xml.endElement();
  13856. }
  13857. void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
  13858. XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
  13859. TestGroupStats const& stats = groupNode.value;
  13860. xml.writeAttribute( "name", stats.groupInfo.name );
  13861. xml.writeAttribute( "errors", unexpectedExceptions );
  13862. xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
  13863. xml.writeAttribute( "tests", stats.totals.assertions.total() );
  13864. xml.writeAttribute( "hostname", "tbd" ); // !TBD
  13865. if( m_config->showDurations() == ShowDurations::Never )
  13866. xml.writeAttribute( "time", "" );
  13867. else
  13868. xml.writeAttribute( "time", suiteTime );
  13869. xml.writeAttribute( "timestamp", getCurrentTimestamp() );
  13870. // Write properties if there are any
  13871. if (m_config->hasTestFilters() || m_config->rngSeed() != 0) {
  13872. auto properties = xml.scopedElement("properties");
  13873. if (m_config->hasTestFilters()) {
  13874. xml.scopedElement("property")
  13875. .writeAttribute("name", "filters")
  13876. .writeAttribute("value", serializeFilters(m_config->getTestsOrTags()));
  13877. }
  13878. if (m_config->rngSeed() != 0) {
  13879. xml.scopedElement("property")
  13880. .writeAttribute("name", "random-seed")
  13881. .writeAttribute("value", m_config->rngSeed());
  13882. }
  13883. }
  13884. // Write test cases
  13885. for( auto const& child : groupNode.children )
  13886. writeTestCase( *child );
  13887. xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), XmlFormatting::Newline );
  13888. xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), XmlFormatting::Newline );
  13889. }
  13890. void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) {
  13891. TestCaseStats const& stats = testCaseNode.value;
  13892. // All test cases have exactly one section - which represents the
  13893. // test case itself. That section may have 0-n nested sections
  13894. assert( testCaseNode.children.size() == 1 );
  13895. SectionNode const& rootSection = *testCaseNode.children.front();
  13896. std::string className = stats.testInfo.className;
  13897. if( className.empty() ) {
  13898. className = fileNameTag(stats.testInfo.tags);
  13899. if ( className.empty() )
  13900. className = "global";
  13901. }
  13902. if ( !m_config->name().empty() )
  13903. className = m_config->name() + "." + className;
  13904. writeSection( className, "", rootSection );
  13905. }
  13906. void JunitReporter::writeSection( std::string const& className,
  13907. std::string const& rootName,
  13908. SectionNode const& sectionNode ) {
  13909. std::string name = trim( sectionNode.stats.sectionInfo.name );
  13910. if( !rootName.empty() )
  13911. name = rootName + '/' + name;
  13912. if( !sectionNode.assertions.empty() ||
  13913. !sectionNode.stdOut.empty() ||
  13914. !sectionNode.stdErr.empty() ) {
  13915. XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
  13916. if( className.empty() ) {
  13917. xml.writeAttribute( "classname", name );
  13918. xml.writeAttribute( "name", "root" );
  13919. }
  13920. else {
  13921. xml.writeAttribute( "classname", className );
  13922. xml.writeAttribute( "name", name );
  13923. }
  13924. xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) );
  13925. // This is not ideal, but it should be enough to mimic gtest's
  13926. // junit output.
  13927. // Ideally the JUnit reporter would also handle `skipTest`
  13928. // events and write those out appropriately.
  13929. xml.writeAttribute( "status", "run" );
  13930. writeAssertions( sectionNode );
  13931. if( !sectionNode.stdOut.empty() )
  13932. xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), XmlFormatting::Newline );
  13933. if( !sectionNode.stdErr.empty() )
  13934. xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), XmlFormatting::Newline );
  13935. }
  13936. for( auto const& childNode : sectionNode.childSections )
  13937. if( className.empty() )
  13938. writeSection( name, "", *childNode );
  13939. else
  13940. writeSection( className, name, *childNode );
  13941. }
  13942. void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {
  13943. for( auto const& assertion : sectionNode.assertions )
  13944. writeAssertion( assertion );
  13945. }
  13946. void JunitReporter::writeAssertion( AssertionStats const& stats ) {
  13947. AssertionResult const& result = stats.assertionResult;
  13948. if( !result.isOk() ) {
  13949. std::string elementName;
  13950. switch( result.getResultType() ) {
  13951. case ResultWas::ThrewException:
  13952. case ResultWas::FatalErrorCondition:
  13953. elementName = "error";
  13954. break;
  13955. case ResultWas::ExplicitFailure:
  13956. case ResultWas::ExpressionFailed:
  13957. case ResultWas::DidntThrowException:
  13958. elementName = "failure";
  13959. break;
  13960. // We should never see these here:
  13961. case ResultWas::Info:
  13962. case ResultWas::Warning:
  13963. case ResultWas::Ok:
  13964. case ResultWas::Unknown:
  13965. case ResultWas::FailureBit:
  13966. case ResultWas::Exception:
  13967. elementName = "internalError";
  13968. break;
  13969. }
  13970. XmlWriter::ScopedElement e = xml.scopedElement( elementName );
  13971. xml.writeAttribute( "message", result.getExpression() );
  13972. xml.writeAttribute( "type", result.getTestMacroName() );
  13973. ReusableStringStream rss;
  13974. if (stats.totals.assertions.total() > 0) {
  13975. rss << "FAILED" << ":\n";
  13976. if (result.hasExpression()) {
  13977. rss << " ";
  13978. rss << result.getExpressionInMacro();
  13979. rss << '\n';
  13980. }
  13981. if (result.hasExpandedExpression()) {
  13982. rss << "with expansion:\n";
  13983. rss << Column(result.getExpandedExpression()).indent(2) << '\n';
  13984. }
  13985. } else {
  13986. rss << '\n';
  13987. }
  13988. if( !result.getMessage().empty() )
  13989. rss << result.getMessage() << '\n';
  13990. for( auto const& msg : stats.infoMessages )
  13991. if( msg.type == ResultWas::Info )
  13992. rss << msg.message << '\n';
  13993. rss << "at " << result.getSourceInfo();
  13994. xml.writeText( rss.str(), XmlFormatting::Newline );
  13995. }
  13996. }
  13997. CATCH_REGISTER_REPORTER( "junit", JunitReporter )
  13998. } // end namespace Catch
  13999. // end catch_reporter_junit.cpp
  14000. // start catch_reporter_listening.cpp
  14001. #include <cassert>
  14002. namespace Catch {
  14003. ListeningReporter::ListeningReporter() {
  14004. // We will assume that listeners will always want all assertions
  14005. m_preferences.shouldReportAllAssertions = true;
  14006. }
  14007. void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) {
  14008. m_listeners.push_back( std::move( listener ) );
  14009. }
  14010. void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {
  14011. assert(!m_reporter && "Listening reporter can wrap only 1 real reporter");
  14012. m_reporter = std::move( reporter );
  14013. m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;
  14014. }
  14015. ReporterPreferences ListeningReporter::getPreferences() const {
  14016. return m_preferences;
  14017. }
  14018. std::set<Verbosity> ListeningReporter::getSupportedVerbosities() {
  14019. return std::set<Verbosity>{ };
  14020. }
  14021. void ListeningReporter::noMatchingTestCases( std::string const& spec ) {
  14022. for ( auto const& listener : m_listeners ) {
  14023. listener->noMatchingTestCases( spec );
  14024. }
  14025. m_reporter->noMatchingTestCases( spec );
  14026. }
  14027. void ListeningReporter::reportInvalidArguments(std::string const&arg){
  14028. for ( auto const& listener : m_listeners ) {
  14029. listener->reportInvalidArguments( arg );
  14030. }
  14031. m_reporter->reportInvalidArguments( arg );
  14032. }
  14033. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  14034. void ListeningReporter::benchmarkPreparing( std::string const& name ) {
  14035. for (auto const& listener : m_listeners) {
  14036. listener->benchmarkPreparing(name);
  14037. }
  14038. m_reporter->benchmarkPreparing(name);
  14039. }
  14040. void ListeningReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {
  14041. for ( auto const& listener : m_listeners ) {
  14042. listener->benchmarkStarting( benchmarkInfo );
  14043. }
  14044. m_reporter->benchmarkStarting( benchmarkInfo );
  14045. }
  14046. void ListeningReporter::benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) {
  14047. for ( auto const& listener : m_listeners ) {
  14048. listener->benchmarkEnded( benchmarkStats );
  14049. }
  14050. m_reporter->benchmarkEnded( benchmarkStats );
  14051. }
  14052. void ListeningReporter::benchmarkFailed( std::string const& error ) {
  14053. for (auto const& listener : m_listeners) {
  14054. listener->benchmarkFailed(error);
  14055. }
  14056. m_reporter->benchmarkFailed(error);
  14057. }
  14058. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  14059. void ListeningReporter::testRunStarting( TestRunInfo const& testRunInfo ) {
  14060. for ( auto const& listener : m_listeners ) {
  14061. listener->testRunStarting( testRunInfo );
  14062. }
  14063. m_reporter->testRunStarting( testRunInfo );
  14064. }
  14065. void ListeningReporter::testGroupStarting( GroupInfo const& groupInfo ) {
  14066. for ( auto const& listener : m_listeners ) {
  14067. listener->testGroupStarting( groupInfo );
  14068. }
  14069. m_reporter->testGroupStarting( groupInfo );
  14070. }
  14071. void ListeningReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
  14072. for ( auto const& listener : m_listeners ) {
  14073. listener->testCaseStarting( testInfo );
  14074. }
  14075. m_reporter->testCaseStarting( testInfo );
  14076. }
  14077. void ListeningReporter::sectionStarting( SectionInfo const& sectionInfo ) {
  14078. for ( auto const& listener : m_listeners ) {
  14079. listener->sectionStarting( sectionInfo );
  14080. }
  14081. m_reporter->sectionStarting( sectionInfo );
  14082. }
  14083. void ListeningReporter::assertionStarting( AssertionInfo const& assertionInfo ) {
  14084. for ( auto const& listener : m_listeners ) {
  14085. listener->assertionStarting( assertionInfo );
  14086. }
  14087. m_reporter->assertionStarting( assertionInfo );
  14088. }
  14089. // The return value indicates if the messages buffer should be cleared:
  14090. bool ListeningReporter::assertionEnded( AssertionStats const& assertionStats ) {
  14091. for( auto const& listener : m_listeners ) {
  14092. static_cast<void>( listener->assertionEnded( assertionStats ) );
  14093. }
  14094. return m_reporter->assertionEnded( assertionStats );
  14095. }
  14096. void ListeningReporter::sectionEnded( SectionStats const& sectionStats ) {
  14097. for ( auto const& listener : m_listeners ) {
  14098. listener->sectionEnded( sectionStats );
  14099. }
  14100. m_reporter->sectionEnded( sectionStats );
  14101. }
  14102. void ListeningReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
  14103. for ( auto const& listener : m_listeners ) {
  14104. listener->testCaseEnded( testCaseStats );
  14105. }
  14106. m_reporter->testCaseEnded( testCaseStats );
  14107. }
  14108. void ListeningReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
  14109. for ( auto const& listener : m_listeners ) {
  14110. listener->testGroupEnded( testGroupStats );
  14111. }
  14112. m_reporter->testGroupEnded( testGroupStats );
  14113. }
  14114. void ListeningReporter::testRunEnded( TestRunStats const& testRunStats ) {
  14115. for ( auto const& listener : m_listeners ) {
  14116. listener->testRunEnded( testRunStats );
  14117. }
  14118. m_reporter->testRunEnded( testRunStats );
  14119. }
  14120. void ListeningReporter::skipTest( TestCaseInfo const& testInfo ) {
  14121. for ( auto const& listener : m_listeners ) {
  14122. listener->skipTest( testInfo );
  14123. }
  14124. m_reporter->skipTest( testInfo );
  14125. }
  14126. bool ListeningReporter::isMulti() const {
  14127. return true;
  14128. }
  14129. } // end namespace Catch
  14130. // end catch_reporter_listening.cpp
  14131. // start catch_reporter_xml.cpp
  14132. #if defined(_MSC_VER)
  14133. #pragma warning(push)
  14134. #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
  14135. // Note that 4062 (not all labels are handled
  14136. // and default is missing) is enabled
  14137. #endif
  14138. namespace Catch {
  14139. XmlReporter::XmlReporter( ReporterConfig const& _config )
  14140. : StreamingReporterBase( _config ),
  14141. m_xml(_config.stream())
  14142. {
  14143. m_reporterPrefs.shouldRedirectStdOut = true;
  14144. m_reporterPrefs.shouldReportAllAssertions = true;
  14145. }
  14146. XmlReporter::~XmlReporter() = default;
  14147. std::string XmlReporter::getDescription() {
  14148. return "Reports test results as an XML document";
  14149. }
  14150. std::string XmlReporter::getStylesheetRef() const {
  14151. return std::string();
  14152. }
  14153. void XmlReporter::writeSourceInfo( SourceLineInfo const& sourceInfo ) {
  14154. m_xml
  14155. .writeAttribute( "filename", sourceInfo.file )
  14156. .writeAttribute( "line", sourceInfo.line );
  14157. }
  14158. void XmlReporter::noMatchingTestCases( std::string const& s ) {
  14159. StreamingReporterBase::noMatchingTestCases( s );
  14160. }
  14161. void XmlReporter::testRunStarting( TestRunInfo const& testInfo ) {
  14162. StreamingReporterBase::testRunStarting( testInfo );
  14163. std::string stylesheetRef = getStylesheetRef();
  14164. if( !stylesheetRef.empty() )
  14165. m_xml.writeStylesheetRef( stylesheetRef );
  14166. m_xml.startElement( "Catch" );
  14167. if( !m_config->name().empty() )
  14168. m_xml.writeAttribute( "name", m_config->name() );
  14169. if (m_config->testSpec().hasFilters())
  14170. m_xml.writeAttribute( "filters", serializeFilters( m_config->getTestsOrTags() ) );
  14171. if( m_config->rngSeed() != 0 )
  14172. m_xml.scopedElement( "Randomness" )
  14173. .writeAttribute( "seed", m_config->rngSeed() );
  14174. }
  14175. void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) {
  14176. StreamingReporterBase::testGroupStarting( groupInfo );
  14177. m_xml.startElement( "Group" )
  14178. .writeAttribute( "name", groupInfo.name );
  14179. }
  14180. void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
  14181. StreamingReporterBase::testCaseStarting(testInfo);
  14182. m_xml.startElement( "TestCase" )
  14183. .writeAttribute( "name", trim( testInfo.name ) )
  14184. .writeAttribute( "description", testInfo.description )
  14185. .writeAttribute( "tags", testInfo.tagsAsString() );
  14186. writeSourceInfo( testInfo.lineInfo );
  14187. if ( m_config->showDurations() == ShowDurations::Always )
  14188. m_testCaseTimer.start();
  14189. m_xml.ensureTagClosed();
  14190. }
  14191. void XmlReporter::sectionStarting( SectionInfo const& sectionInfo ) {
  14192. StreamingReporterBase::sectionStarting( sectionInfo );
  14193. if( m_sectionDepth++ > 0 ) {
  14194. m_xml.startElement( "Section" )
  14195. .writeAttribute( "name", trim( sectionInfo.name ) );
  14196. writeSourceInfo( sectionInfo.lineInfo );
  14197. m_xml.ensureTagClosed();
  14198. }
  14199. }
  14200. void XmlReporter::assertionStarting( AssertionInfo const& ) { }
  14201. bool XmlReporter::assertionEnded( AssertionStats const& assertionStats ) {
  14202. AssertionResult const& result = assertionStats.assertionResult;
  14203. bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
  14204. if( includeResults || result.getResultType() == ResultWas::Warning ) {
  14205. // Print any info messages in <Info> tags.
  14206. for( auto const& msg : assertionStats.infoMessages ) {
  14207. if( msg.type == ResultWas::Info && includeResults ) {
  14208. m_xml.scopedElement( "Info" )
  14209. .writeText( msg.message );
  14210. } else if ( msg.type == ResultWas::Warning ) {
  14211. m_xml.scopedElement( "Warning" )
  14212. .writeText( msg.message );
  14213. }
  14214. }
  14215. }
  14216. // Drop out if result was successful but we're not printing them.
  14217. if( !includeResults && result.getResultType() != ResultWas::Warning )
  14218. return true;
  14219. // Print the expression if there is one.
  14220. if( result.hasExpression() ) {
  14221. m_xml.startElement( "Expression" )
  14222. .writeAttribute( "success", result.succeeded() )
  14223. .writeAttribute( "type", result.getTestMacroName() );
  14224. writeSourceInfo( result.getSourceInfo() );
  14225. m_xml.scopedElement( "Original" )
  14226. .writeText( result.getExpression() );
  14227. m_xml.scopedElement( "Expanded" )
  14228. .writeText( result.getExpandedExpression() );
  14229. }
  14230. // And... Print a result applicable to each result type.
  14231. switch( result.getResultType() ) {
  14232. case ResultWas::ThrewException:
  14233. m_xml.startElement( "Exception" );
  14234. writeSourceInfo( result.getSourceInfo() );
  14235. m_xml.writeText( result.getMessage() );
  14236. m_xml.endElement();
  14237. break;
  14238. case ResultWas::FatalErrorCondition:
  14239. m_xml.startElement( "FatalErrorCondition" );
  14240. writeSourceInfo( result.getSourceInfo() );
  14241. m_xml.writeText( result.getMessage() );
  14242. m_xml.endElement();
  14243. break;
  14244. case ResultWas::Info:
  14245. m_xml.scopedElement( "Info" )
  14246. .writeText( result.getMessage() );
  14247. break;
  14248. case ResultWas::Warning:
  14249. // Warning will already have been written
  14250. break;
  14251. case ResultWas::ExplicitFailure:
  14252. m_xml.startElement( "Failure" );
  14253. writeSourceInfo( result.getSourceInfo() );
  14254. m_xml.writeText( result.getMessage() );
  14255. m_xml.endElement();
  14256. break;
  14257. default:
  14258. break;
  14259. }
  14260. if( result.hasExpression() )
  14261. m_xml.endElement();
  14262. return true;
  14263. }
  14264. void XmlReporter::sectionEnded( SectionStats const& sectionStats ) {
  14265. StreamingReporterBase::sectionEnded( sectionStats );
  14266. if( --m_sectionDepth > 0 ) {
  14267. XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
  14268. e.writeAttribute( "successes", sectionStats.assertions.passed );
  14269. e.writeAttribute( "failures", sectionStats.assertions.failed );
  14270. e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
  14271. if ( m_config->showDurations() == ShowDurations::Always )
  14272. e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
  14273. m_xml.endElement();
  14274. }
  14275. }
  14276. void XmlReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
  14277. StreamingReporterBase::testCaseEnded( testCaseStats );
  14278. XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
  14279. e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
  14280. if ( m_config->showDurations() == ShowDurations::Always )
  14281. e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
  14282. if( !testCaseStats.stdOut.empty() )
  14283. m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), XmlFormatting::Newline );
  14284. if( !testCaseStats.stdErr.empty() )
  14285. m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), XmlFormatting::Newline );
  14286. m_xml.endElement();
  14287. }
  14288. void XmlReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
  14289. StreamingReporterBase::testGroupEnded( testGroupStats );
  14290. // TODO: Check testGroupStats.aborting and act accordingly.
  14291. m_xml.scopedElement( "OverallResults" )
  14292. .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
  14293. .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
  14294. .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
  14295. m_xml.scopedElement( "OverallResultsCases")
  14296. .writeAttribute( "successes", testGroupStats.totals.testCases.passed )
  14297. .writeAttribute( "failures", testGroupStats.totals.testCases.failed )
  14298. .writeAttribute( "expectedFailures", testGroupStats.totals.testCases.failedButOk );
  14299. m_xml.endElement();
  14300. }
  14301. void XmlReporter::testRunEnded( TestRunStats const& testRunStats ) {
  14302. StreamingReporterBase::testRunEnded( testRunStats );
  14303. m_xml.scopedElement( "OverallResults" )
  14304. .writeAttribute( "successes", testRunStats.totals.assertions.passed )
  14305. .writeAttribute( "failures", testRunStats.totals.assertions.failed )
  14306. .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
  14307. m_xml.scopedElement( "OverallResultsCases")
  14308. .writeAttribute( "successes", testRunStats.totals.testCases.passed )
  14309. .writeAttribute( "failures", testRunStats.totals.testCases.failed )
  14310. .writeAttribute( "expectedFailures", testRunStats.totals.testCases.failedButOk );
  14311. m_xml.endElement();
  14312. }
  14313. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  14314. void XmlReporter::benchmarkPreparing(std::string const& name) {
  14315. m_xml.startElement("BenchmarkResults")
  14316. .writeAttribute("name", name);
  14317. }
  14318. void XmlReporter::benchmarkStarting(BenchmarkInfo const &info) {
  14319. m_xml.writeAttribute("samples", info.samples)
  14320. .writeAttribute("resamples", info.resamples)
  14321. .writeAttribute("iterations", info.iterations)
  14322. .writeAttribute("clockResolution", info.clockResolution)
  14323. .writeAttribute("estimatedDuration", info.estimatedDuration)
  14324. .writeComment("All values in nano seconds");
  14325. }
  14326. void XmlReporter::benchmarkEnded(BenchmarkStats<> const& benchmarkStats) {
  14327. m_xml.startElement("mean")
  14328. .writeAttribute("value", benchmarkStats.mean.point.count())
  14329. .writeAttribute("lowerBound", benchmarkStats.mean.lower_bound.count())
  14330. .writeAttribute("upperBound", benchmarkStats.mean.upper_bound.count())
  14331. .writeAttribute("ci", benchmarkStats.mean.confidence_interval);
  14332. m_xml.endElement();
  14333. m_xml.startElement("standardDeviation")
  14334. .writeAttribute("value", benchmarkStats.standardDeviation.point.count())
  14335. .writeAttribute("lowerBound", benchmarkStats.standardDeviation.lower_bound.count())
  14336. .writeAttribute("upperBound", benchmarkStats.standardDeviation.upper_bound.count())
  14337. .writeAttribute("ci", benchmarkStats.standardDeviation.confidence_interval);
  14338. m_xml.endElement();
  14339. m_xml.startElement("outliers")
  14340. .writeAttribute("variance", benchmarkStats.outlierVariance)
  14341. .writeAttribute("lowMild", benchmarkStats.outliers.low_mild)
  14342. .writeAttribute("lowSevere", benchmarkStats.outliers.low_severe)
  14343. .writeAttribute("highMild", benchmarkStats.outliers.high_mild)
  14344. .writeAttribute("highSevere", benchmarkStats.outliers.high_severe);
  14345. m_xml.endElement();
  14346. m_xml.endElement();
  14347. }
  14348. void XmlReporter::benchmarkFailed(std::string const &error) {
  14349. m_xml.scopedElement("failed").
  14350. writeAttribute("message", error);
  14351. m_xml.endElement();
  14352. }
  14353. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  14354. CATCH_REGISTER_REPORTER( "xml", XmlReporter )
  14355. } // end namespace Catch
  14356. #if defined(_MSC_VER)
  14357. #pragma warning(pop)
  14358. #endif
  14359. // end catch_reporter_xml.cpp
  14360. namespace Catch {
  14361. LeakDetector leakDetector;
  14362. }
  14363. #ifdef __clang__
  14364. #pragma clang diagnostic pop
  14365. #endif
  14366. // end catch_impl.hpp
  14367. #endif
  14368. #ifdef CATCH_CONFIG_MAIN
  14369. // start catch_default_main.hpp
  14370. #ifndef __OBJC__
  14371. #if defined(CATCH_CONFIG_WCHAR) && defined(CATCH_PLATFORM_WINDOWS) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
  14372. // Standard C/C++ Win32 Unicode wmain entry point
  14373. extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
  14374. #else
  14375. // Standard C/C++ main entry point
  14376. int main (int argc, char * argv[]) {
  14377. #endif
  14378. return Catch::Session().run( argc, argv );
  14379. }
  14380. #else // __OBJC__
  14381. // Objective-C entry point
  14382. int main (int argc, char * const argv[]) {
  14383. #if !CATCH_ARC_ENABLED
  14384. NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
  14385. #endif
  14386. Catch::registerTestMethods();
  14387. int result = Catch::Session().run( argc, (char**)argv );
  14388. #if !CATCH_ARC_ENABLED
  14389. [pool drain];
  14390. #endif
  14391. return result;
  14392. }
  14393. #endif // __OBJC__
  14394. // end catch_default_main.hpp
  14395. #endif
  14396. #if !defined(CATCH_CONFIG_IMPL_ONLY)
  14397. #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
  14398. # undef CLARA_CONFIG_MAIN
  14399. #endif
  14400. #if !defined(CATCH_CONFIG_DISABLE)
  14401. //////
  14402. // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
  14403. #ifdef CATCH_CONFIG_PREFIX_ALL
  14404. #define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  14405. #define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  14406. #define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  14407. #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
  14408. #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
  14409. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  14410. #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
  14411. #endif// CATCH_CONFIG_DISABLE_MATCHERS
  14412. #define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  14413. #define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14414. #define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  14415. #define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14416. #define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14417. #define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
  14418. #define CATCH_CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14419. #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
  14420. #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  14421. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  14422. #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  14423. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  14424. #define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14425. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  14426. #define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
  14427. #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
  14428. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  14429. #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
  14430. #define CATCH_UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "CATCH_UNSCOPED_INFO", msg )
  14431. #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
  14432. #define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE",__VA_ARGS__ )
  14433. #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
  14434. #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14435. #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
  14436. #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
  14437. #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
  14438. #define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
  14439. #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
  14440. #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14441. #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14442. #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
  14443. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  14444. #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
  14445. #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
  14446. #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14447. #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
  14448. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
  14449. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
  14450. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14451. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
  14452. #else
  14453. #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
  14454. #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
  14455. #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
  14456. #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
  14457. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
  14458. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
  14459. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
  14460. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
  14461. #endif
  14462. #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
  14463. #define CATCH_STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__ , #__VA_ARGS__ ); CATCH_SUCCEED( #__VA_ARGS__ )
  14464. #define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ )
  14465. #else
  14466. #define CATCH_STATIC_REQUIRE( ... ) CATCH_REQUIRE( __VA_ARGS__ )
  14467. #define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ )
  14468. #endif
  14469. // "BDD-style" convenience wrappers
  14470. #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
  14471. #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
  14472. #define CATCH_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
  14473. #define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
  14474. #define CATCH_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
  14475. #define CATCH_AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
  14476. #define CATCH_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
  14477. #define CATCH_AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )
  14478. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  14479. #define CATCH_BENCHMARK(...) \
  14480. INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
  14481. #define CATCH_BENCHMARK_ADVANCED(name) \
  14482. INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
  14483. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  14484. // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
  14485. #else
  14486. #define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  14487. #define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  14488. #define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  14489. #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
  14490. #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
  14491. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  14492. #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
  14493. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  14494. #define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
  14495. #define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14496. #define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
  14497. #define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14498. #define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14499. #define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
  14500. #define CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14501. #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
  14502. #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  14503. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  14504. #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
  14505. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  14506. #define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14507. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  14508. #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
  14509. #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
  14510. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  14511. #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
  14512. #define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "UNSCOPED_INFO", msg )
  14513. #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
  14514. #define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ )
  14515. #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
  14516. #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14517. #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
  14518. #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
  14519. #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
  14520. #define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
  14521. #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
  14522. #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14523. #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
  14524. #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
  14525. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  14526. #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
  14527. #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )
  14528. #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14529. #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
  14530. #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
  14531. #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )
  14532. #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14533. #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )
  14534. #define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__)
  14535. #define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14536. #else
  14537. #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
  14538. #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )
  14539. #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
  14540. #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
  14541. #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
  14542. #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )
  14543. #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
  14544. #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )
  14545. #define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE( __VA_ARGS__ ) )
  14546. #define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
  14547. #endif
  14548. #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
  14549. #define STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__, #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ )
  14550. #define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" )
  14551. #else
  14552. #define STATIC_REQUIRE( ... ) REQUIRE( __VA_ARGS__ )
  14553. #define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ )
  14554. #endif
  14555. #endif
  14556. #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
  14557. // "BDD-style" convenience wrappers
  14558. #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
  14559. #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
  14560. #define GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
  14561. #define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
  14562. #define WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
  14563. #define AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
  14564. #define THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
  14565. #define AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )
  14566. #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
  14567. #define BENCHMARK(...) \
  14568. INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))
  14569. #define BENCHMARK_ADVANCED(name) \
  14570. INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name)
  14571. #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
  14572. using Catch::Detail::Approx;
  14573. #else // CATCH_CONFIG_DISABLE
  14574. //////
  14575. // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
  14576. #ifdef CATCH_CONFIG_PREFIX_ALL
  14577. #define CATCH_REQUIRE( ... ) (void)(0)
  14578. #define CATCH_REQUIRE_FALSE( ... ) (void)(0)
  14579. #define CATCH_REQUIRE_THROWS( ... ) (void)(0)
  14580. #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
  14581. #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
  14582. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  14583. #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  14584. #endif// CATCH_CONFIG_DISABLE_MATCHERS
  14585. #define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)
  14586. #define CATCH_CHECK( ... ) (void)(0)
  14587. #define CATCH_CHECK_FALSE( ... ) (void)(0)
  14588. #define CATCH_CHECKED_IF( ... ) if (__VA_ARGS__)
  14589. #define CATCH_CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
  14590. #define CATCH_CHECK_NOFAIL( ... ) (void)(0)
  14591. #define CATCH_CHECK_THROWS( ... ) (void)(0)
  14592. #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
  14593. #define CATCH_CHECK_THROWS_WITH( expr, matcher ) (void)(0)
  14594. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  14595. #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  14596. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  14597. #define CATCH_CHECK_NOTHROW( ... ) (void)(0)
  14598. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  14599. #define CATCH_CHECK_THAT( arg, matcher ) (void)(0)
  14600. #define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
  14601. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  14602. #define CATCH_INFO( msg ) (void)(0)
  14603. #define CATCH_UNSCOPED_INFO( msg ) (void)(0)
  14604. #define CATCH_WARN( msg ) (void)(0)
  14605. #define CATCH_CAPTURE( msg ) (void)(0)
  14606. #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  14607. #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  14608. #define CATCH_METHOD_AS_TEST_CASE( method, ... )
  14609. #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
  14610. #define CATCH_SECTION( ... )
  14611. #define CATCH_DYNAMIC_SECTION( ... )
  14612. #define CATCH_FAIL( ... ) (void)(0)
  14613. #define CATCH_FAIL_CHECK( ... ) (void)(0)
  14614. #define CATCH_SUCCEED( ... ) (void)(0)
  14615. #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  14616. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  14617. #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
  14618. #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
  14619. #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
  14620. #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
  14621. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
  14622. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
  14623. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14624. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14625. #else
  14626. #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
  14627. #define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
  14628. #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
  14629. #define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
  14630. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
  14631. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
  14632. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14633. #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14634. #endif
  14635. // "BDD-style" convenience wrappers
  14636. #define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  14637. #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 )
  14638. #define CATCH_GIVEN( desc )
  14639. #define CATCH_AND_GIVEN( desc )
  14640. #define CATCH_WHEN( desc )
  14641. #define CATCH_AND_WHEN( desc )
  14642. #define CATCH_THEN( desc )
  14643. #define CATCH_AND_THEN( desc )
  14644. #define CATCH_STATIC_REQUIRE( ... ) (void)(0)
  14645. #define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0)
  14646. // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
  14647. #else
  14648. #define REQUIRE( ... ) (void)(0)
  14649. #define REQUIRE_FALSE( ... ) (void)(0)
  14650. #define REQUIRE_THROWS( ... ) (void)(0)
  14651. #define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
  14652. #define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
  14653. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  14654. #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  14655. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  14656. #define REQUIRE_NOTHROW( ... ) (void)(0)
  14657. #define CHECK( ... ) (void)(0)
  14658. #define CHECK_FALSE( ... ) (void)(0)
  14659. #define CHECKED_IF( ... ) if (__VA_ARGS__)
  14660. #define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
  14661. #define CHECK_NOFAIL( ... ) (void)(0)
  14662. #define CHECK_THROWS( ... ) (void)(0)
  14663. #define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
  14664. #define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
  14665. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  14666. #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
  14667. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  14668. #define CHECK_NOTHROW( ... ) (void)(0)
  14669. #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
  14670. #define CHECK_THAT( arg, matcher ) (void)(0)
  14671. #define REQUIRE_THAT( arg, matcher ) (void)(0)
  14672. #endif // CATCH_CONFIG_DISABLE_MATCHERS
  14673. #define INFO( msg ) (void)(0)
  14674. #define UNSCOPED_INFO( msg ) (void)(0)
  14675. #define WARN( msg ) (void)(0)
  14676. #define CAPTURE( msg ) (void)(0)
  14677. #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  14678. #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  14679. #define METHOD_AS_TEST_CASE( method, ... )
  14680. #define REGISTER_TEST_CASE( Function, ... ) (void)(0)
  14681. #define SECTION( ... )
  14682. #define DYNAMIC_SECTION( ... )
  14683. #define FAIL( ... ) (void)(0)
  14684. #define FAIL_CHECK( ... ) (void)(0)
  14685. #define SUCCEED( ... ) (void)(0)
  14686. #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
  14687. #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
  14688. #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)
  14689. #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)
  14690. #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)
  14691. #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )
  14692. #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
  14693. #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
  14694. #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14695. #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14696. #else
  14697. #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )
  14698. #define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )
  14699. #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )
  14700. #define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )
  14701. #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
  14702. #define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
  14703. #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14704. #define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
  14705. #endif
  14706. #define STATIC_REQUIRE( ... ) (void)(0)
  14707. #define STATIC_REQUIRE_FALSE( ... ) (void)(0)
  14708. #endif
  14709. #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
  14710. // "BDD-style" convenience wrappers
  14711. #define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) )
  14712. #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
  14713. #define GIVEN( desc )
  14714. #define AND_GIVEN( desc )
  14715. #define WHEN( desc )
  14716. #define AND_WHEN( desc )
  14717. #define THEN( desc )
  14718. #define AND_THEN( desc )
  14719. using Catch::Detail::Approx;
  14720. #endif
  14721. #endif // ! CATCH_CONFIG_IMPL_ONLY
  14722. // start catch_reenable_warnings.h
  14723. #ifdef __clang__
  14724. # ifdef __ICC // icpc defines the __clang__ macro
  14725. # pragma warning(pop)
  14726. # else
  14727. # pragma clang diagnostic pop
  14728. # endif
  14729. #elif defined __GNUC__
  14730. # pragma GCC diagnostic pop
  14731. #endif
  14732. // end catch_reenable_warnings.h
  14733. // end catch.hpp
  14734. #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED