catch.hpp
Go to the documentation of this file.
1 /*
2  * Catch v2.7.0
3  * Generated: 2019-03-07 21:34:30.252164
4  * ----------------------------------------------------------
5  * This file has been merged from multiple headers. Please don't edit it directly
6  * Copyright (c) 2019 Two Blue Cubes Ltd. All rights reserved.
7  *
8  * Distributed under the Boost Software License, Version 1.0. (See accompanying
9  * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10  */
11 #ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
12 #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
13 // start catch.hpp
14 
15 
16 #define CATCH_VERSION_MAJOR 2
17 #define CATCH_VERSION_MINOR 7
18 #define CATCH_VERSION_PATCH 0
19 
20 #ifdef __clang__
21 # pragma clang system_header
22 #elif defined __GNUC__
23 # pragma GCC system_header
24 #endif
25 
26 // start catch_suppress_warnings.h
27 
28 #ifdef __clang__
29 # ifdef __ICC // icpc defines the __clang__ macro
30 # pragma warning(push)
31 # pragma warning(disable: 161 1682)
32 # else // __ICC
33 # pragma clang diagnostic push
34 # pragma clang diagnostic ignored "-Wpadded"
35 # pragma clang diagnostic ignored "-Wswitch-enum"
36 # pragma clang diagnostic ignored "-Wcovered-switch-default"
37 # endif
38 #elif defined __GNUC__
39  // Because REQUIREs trigger GCC's -Wparentheses, and because still
40  // supported version of g++ have only buggy support for _Pragmas,
41  // Wparentheses have to be suppressed globally.
42 # pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details
43 
44 # pragma GCC diagnostic push
45 # pragma GCC diagnostic ignored "-Wunused-variable"
46 # pragma GCC diagnostic ignored "-Wpadded"
47 #endif
48 // end catch_suppress_warnings.h
49 #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
50 # define CATCH_IMPL
51 # define CATCH_CONFIG_ALL_PARTS
52 #endif
53 
54 // In the impl file, we want to have access to all parts of the headers
55 // Can also be used to sanely support PCHs
56 #if defined(CATCH_CONFIG_ALL_PARTS)
57 # define CATCH_CONFIG_EXTERNAL_INTERFACES
58 # if defined(CATCH_CONFIG_DISABLE_MATCHERS)
59 # undef CATCH_CONFIG_DISABLE_MATCHERS
60 # endif
61 # if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
62 # define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
63 # endif
64 #endif
65 
66 #if !defined(CATCH_CONFIG_IMPL_ONLY)
67 // start catch_platform.h
68 
69 #ifdef __APPLE__
70 # include <TargetConditionals.h>
71 # if TARGET_OS_OSX == 1
72 # define CATCH_PLATFORM_MAC
73 # elif TARGET_OS_IPHONE == 1
74 # define CATCH_PLATFORM_IPHONE
75 # endif
76 
77 #elif defined(linux) || defined(__linux) || defined(__linux__)
78 # define CATCH_PLATFORM_LINUX
79 
80 #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
81 # define CATCH_PLATFORM_WINDOWS
82 #endif
83 
84 // end catch_platform.h
85 
86 #ifdef CATCH_IMPL
87 # ifndef CLARA_CONFIG_MAIN
88 # define CLARA_CONFIG_MAIN_NOT_DEFINED
89 # define CLARA_CONFIG_MAIN
90 # endif
91 #endif
92 
93 // start catch_user_interfaces.h
94 
95 namespace Catch {
96  unsigned int rngSeed();
97 }
98 
99 // end catch_user_interfaces.h
100 // start catch_tag_alias_autoregistrar.h
101 
102 // start catch_common.h
103 
104 // start catch_compiler_capabilities.h
105 
106 // Detect a number of compiler features - by compiler
107 // The following features are defined:
108 //
109 // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
110 // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
111 // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
112 // CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
113 // ****************
114 // Note to maintainers: if new toggles are added please document them
115 // in configuration.md, too
116 // ****************
117 
118 // In general each macro has a _NO_<feature name> form
119 // (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
120 // Many features, at point of detection, define an _INTERNAL_ macro, so they
121 // can be combined, en-mass, with the _NO_ forms later.
122 
123 #ifdef __cplusplus
124 
125 # if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
126 # define CATCH_CPP14_OR_GREATER
127 # endif
128 
129 # if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
130 # define CATCH_CPP17_OR_GREATER
131 # endif
132 
133 #endif
134 
135 #if defined(CATCH_CPP17_OR_GREATER)
136 # define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
137 #endif
138 
139 #ifdef __clang__
140 
141 # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
142  _Pragma( "clang diagnostic push" ) \
143  _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
144  _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
145 # define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
146  _Pragma( "clang diagnostic pop" )
147 
148 # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
149  _Pragma( "clang diagnostic push" ) \
150  _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
151 # define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
152  _Pragma( "clang diagnostic pop" )
153 
154 # define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
155  _Pragma( "clang diagnostic push" ) \
156  _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
157 # define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS \
158  _Pragma( "clang diagnostic pop" )
159 
160 #endif // __clang__
161 
163 // Assume that non-Windows platforms support posix signals by default
164 #if !defined(CATCH_PLATFORM_WINDOWS)
165  #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
166 #endif
167 
169 // We know some environments not to support full POSIX signals
170 #if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
171  #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
172 #endif
173 
174 #ifdef __OS400__
175 # define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
176 # define CATCH_CONFIG_COLOUR_NONE
177 #endif
178 
180 // Android somehow still does not support std::to_string
181 #if defined(__ANDROID__)
182 # define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
183 #endif
184 
186 // Not all Windows environments support SEH properly
187 #if defined(__MINGW32__)
188 # define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
189 #endif
190 
192 // PS4
193 #if defined(__ORBIS__)
194 # define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
195 #endif
196 
198 // Cygwin
199 #ifdef __CYGWIN__
200 
201 // Required for some versions of Cygwin to declare gettimeofday
202 // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
203 # define _BSD_SOURCE
204 // some versions of cygwin (most) do not support std::to_string. Use the libstd check.
205 // https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
206 # if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
207  && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
208 
209 # define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
210 
211 # endif
212 #endif // __CYGWIN__
213 
215 // Visual C++
216 #ifdef _MSC_VER
217 
218 # if _MSC_VER >= 1900 // Visual Studio 2015 or newer
219 # define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
220 # endif
221 
222 // Universal Windows platform does not support SEH
223 // Or console colours (or console at all...)
224 # if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
225 # define CATCH_CONFIG_COLOUR_NONE
226 # else
227 # define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
228 # endif
229 
230 // MSVC traditional preprocessor needs some workaround for __VA_ARGS__
231 // _MSVC_TRADITIONAL == 0 means new conformant preprocessor
232 // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
233 # if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
234 # define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
235 # endif
236 
237 #endif // _MSC_VER
238 
240 // Check if we are compiled with -fno-exceptions or equivalent
241 #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
242 # define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
243 #endif
244 
246 // DJGPP
247 #ifdef __DJGPP__
248 # define CATCH_INTERNAL_CONFIG_NO_WCHAR
249 #endif // __DJGPP__
250 
252 // Embarcadero C++Build
253 #if defined(__BORLANDC__)
254  #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN
255 #endif
256 
258 
259 // Use of __COUNTER__ is suppressed during code analysis in
260 // CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
261 // handled by it.
262 // Otherwise all supported compilers support COUNTER macro,
263 // but user still might want to turn it off
264 #if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
265  #define CATCH_INTERNAL_CONFIG_COUNTER
266 #endif
267 
269 // Check if string_view is available and usable
270 // The check is split apart to work around v140 (VS2015) preprocessor issue...
271 #if defined(__has_include)
272 #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
273 # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
274 #endif
275 #endif
276 
278 // Check if optional is available and usable
279 #if defined(__has_include)
280 # if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
281 # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
282 # endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
283 #endif // __has_include
284 
286 // Check if variant is available and usable
287 #if defined(__has_include)
288 # if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
289 # if defined(__clang__) && (__clang_major__ < 8)
290  // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
291  // fix should be in clang 8, workaround in libstdc++ 8.2
292 # include <ciso646>
293 # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
294 # define CATCH_CONFIG_NO_CPP17_VARIANT
295 # else
296 # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
297 # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
298 # else
299 # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
300 # endif // defined(__clang__) && (__clang_major__ < 8)
301 # endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
302 #endif // __has_include
303 
304 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
305 # define CATCH_CONFIG_COUNTER
306 #endif
307 #if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH)
308 # define CATCH_CONFIG_WINDOWS_SEH
309 #endif
310 // This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
311 #if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
312 # define CATCH_CONFIG_POSIX_SIGNALS
313 #endif
314 // This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.
315 #if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
316 # define CATCH_CONFIG_WCHAR
317 #endif
318 
319 #if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
320 # define CATCH_CONFIG_CPP11_TO_STRING
321 #endif
322 
323 #if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL)
324 # define CATCH_CONFIG_CPP17_OPTIONAL
325 #endif
326 
327 #if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
328 # define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
329 #endif
330 
331 #if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
332 # define CATCH_CONFIG_CPP17_STRING_VIEW
333 #endif
334 
335 #if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
336 # define CATCH_CONFIG_CPP17_VARIANT
337 #endif
338 
339 #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
340 # define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
341 #endif
342 
343 #if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE)
344 # define CATCH_CONFIG_NEW_CAPTURE
345 #endif
346 
347 #if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
348 # define CATCH_CONFIG_DISABLE_EXCEPTIONS
349 #endif
350 
351 #if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN)
352 # define CATCH_CONFIG_POLYFILL_ISNAN
353 #endif
354 
355 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
356 # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
357 # define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
358 #endif
359 #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
360 # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
361 # define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
362 #endif
363 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
364 # define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
365 # define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
366 #endif
367 
368 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
369 #define CATCH_TRY if ((true))
370 #define CATCH_CATCH_ALL if ((false))
371 #define CATCH_CATCH_ANON(type) if ((false))
372 #else
373 #define CATCH_TRY try
374 #define CATCH_CATCH_ALL catch (...)
375 #define CATCH_CATCH_ANON(type) catch (type)
376 #endif
377 
378 #if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)
379 #define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
380 #endif
381 
382 // end catch_compiler_capabilities.h
383 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
384 #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
385 #ifdef CATCH_CONFIG_COUNTER
386 # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
387 #else
388 # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
389 #endif
390 
391 #include <iosfwd>
392 #include <string>
393 #include <cstdint>
394 
395 // We need a dummy global operator<< so we can bring it into Catch namespace later
397 std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
398 
399 namespace Catch {
400 
401  struct CaseSensitive { enum Choice {
403  No
404  }; };
405 
406  class NonCopyable {
407  NonCopyable( NonCopyable const& ) = delete;
408  NonCopyable( NonCopyable && ) = delete;
409  NonCopyable& operator = ( NonCopyable const& ) = delete;
410  NonCopyable& operator = ( NonCopyable && ) = delete;
411 
412  protected:
413  NonCopyable();
414  virtual ~NonCopyable();
415  };
416 
417  struct SourceLineInfo {
418 
419  SourceLineInfo() = delete;
420  SourceLineInfo( char const* _file, std::size_t _line ) noexcept
421  : file( _file ),
422  line( _line )
423  {}
424 
425  SourceLineInfo( SourceLineInfo const& other ) = default;
426  SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
427  SourceLineInfo( SourceLineInfo&& ) noexcept = default;
428  SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default;
429 
430  bool empty() const noexcept;
431  bool operator == ( SourceLineInfo const& other ) const noexcept;
432  bool operator < ( SourceLineInfo const& other ) const noexcept;
433 
434  char const* file;
435  std::size_t line;
436  };
437 
438  std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
439 
440  // Bring in operator<< from global namespace into Catch namespace
441  // This is necessary because the overload of operator<< above makes
442  // lookup stop at namespace Catch
443  using ::operator<<;
444 
445  // Use this in variadic streaming macros to allow
446  // >> +StreamEndStop
447  // as well as
448  // >> stuff +StreamEndStop
449  struct StreamEndStop {
450  std::string operator+() const;
451  };
452  template<typename T>
453  T const& operator + ( T const& value, StreamEndStop ) {
454  return value;
455  }
456 }
457 
458 #define CATCH_INTERNAL_LINEINFO \
459  ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
460 
461 // end catch_common.h
462 namespace Catch {
463 
465  RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
466  };
467 
468 } // end namespace Catch
469 
470 #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
471  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
472  namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
473  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
474 
475 // end catch_tag_alias_autoregistrar.h
476 // start catch_test_registry.h
477 
478 // start catch_interfaces_testcase.h
479 
480 #include <vector>
481 
482 namespace Catch {
483 
484  class TestSpec;
485 
486  struct ITestInvoker {
487  virtual void invoke () const = 0;
488  virtual ~ITestInvoker();
489  };
490 
491  class TestCase;
492  struct IConfig;
493 
495  virtual ~ITestCaseRegistry();
496  virtual std::vector<TestCase> const& getAllTests() const = 0;
497  virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
498  };
499 
500  bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
501  std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
502  std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
503 
504 }
505 
506 // end catch_interfaces_testcase.h
507 // start catch_stringref.h
508 
509 #include <cstddef>
510 #include <string>
511 #include <iosfwd>
512 
513 namespace Catch {
514 
522  class StringRef {
523  public:
524  using size_type = std::size_t;
525 
526  private:
527  friend struct StringRefTestAccess;
528 
529  char const* m_start;
531 
532  char* m_data = nullptr;
533 
534  void takeOwnership();
535 
536  static constexpr char const* const s_empty = "";
537 
538  public: // construction/ assignment
539  StringRef() noexcept
540  : StringRef( s_empty, 0 )
541  {}
542 
543  StringRef( StringRef const& other ) noexcept
544  : m_start( other.m_start ),
545  m_size( other.m_size )
546  {}
547 
548  StringRef( StringRef&& other ) noexcept
549  : m_start( other.m_start ),
550  m_size( other.m_size ),
551  m_data( other.m_data )
552  {
553  other.m_data = nullptr;
554  }
555 
556  StringRef( char const* rawChars ) noexcept;
557 
558  StringRef( char const* rawChars, size_type size ) noexcept
559  : m_start( rawChars ),
560  m_size( size )
561  {}
562 
563  StringRef( std::string const& stdString ) noexcept
564  : m_start( stdString.c_str() ),
565  m_size( stdString.size() )
566  {}
567 
568  ~StringRef() noexcept {
569  delete[] m_data;
570  }
571 
572  auto operator = ( StringRef const &other ) noexcept -> StringRef& {
573  delete[] m_data;
574  m_data = nullptr;
575  m_start = other.m_start;
576  m_size = other.m_size;
577  return *this;
578  }
579 
580  operator std::string() const;
581 
582  void swap( StringRef& other ) noexcept;
583 
584  public: // operators
585  auto operator == ( StringRef const& other ) const noexcept -> bool;
586  auto operator != ( StringRef const& other ) const noexcept -> bool;
587 
588  auto operator[] ( size_type index ) const noexcept -> char;
589 
590  public: // named queries
591  auto empty() const noexcept -> bool {
592  return m_size == 0;
593  }
594  auto size() const noexcept -> size_type {
595  return m_size;
596  }
597 
598  auto numberOfCharacters() const noexcept -> size_type;
599  auto c_str() const -> char const*;
600 
601  public: // substrings and searches
602  auto substr( size_type start, size_type size ) const noexcept -> StringRef;
603 
604  // Returns the current start pointer.
605  // Note that the pointer can change when if the StringRef is a substring
606  auto currentData() const noexcept -> char const*;
607 
608  private: // ownership queries - may not be consistent between calls
609  auto isOwned() const noexcept -> bool;
610  auto isSubstring() const noexcept -> bool;
611  };
612 
613  auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string;
614  auto operator + ( StringRef const& lhs, char const* rhs ) -> std::string;
615  auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string;
616 
617  auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
618  auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
619 
620  inline auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
621  return StringRef( rawChars, size );
622  }
623 
624 } // namespace Catch
625 
626 inline auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
627  return Catch::StringRef( rawChars, size );
628 }
629 
630 // end catch_stringref.h
631 // start catch_type_traits.hpp
632 
633 
634 #include <type_traits>
635 
636 namespace Catch{
637 
638 #ifdef CATCH_CPP17_OR_GREATER
639  template <typename...>
640  inline constexpr auto is_unique = std::true_type{};
641 
642  template <typename T, typename... Rest>
643  inline constexpr auto is_unique<T, Rest...> = std::bool_constant<
644  (!std::is_same_v<T, Rest> && ...) && is_unique<Rest...>
645  >{};
646 #else
647 
648 template <typename...>
649 struct is_unique : std::true_type{};
650 
651 template <typename T0, typename T1, typename... Rest>
652 struct is_unique<T0, T1, Rest...> : std::integral_constant
653 <bool,
654  !std::is_same<T0, T1>::value
655  && is_unique<T0, Rest...>::value
656  && is_unique<T1, Rest...>::value
657 >{};
658 
659 #endif
660 }
661 
662 // end catch_type_traits.hpp
663 // start catch_preprocessor.hpp
664 
665 
666 #define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__
667 #define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))
668 #define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))
669 #define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__)))
670 #define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__)))
671 #define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__)))
672 
673 #ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
674 #define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__
675 // MSVC needs more evaluations
676 #define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__)))
677 #define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__))
678 #else
679 #define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__)
680 #endif
681 
682 #define CATCH_REC_END(...)
683 #define CATCH_REC_OUT
684 
685 #define CATCH_EMPTY()
686 #define CATCH_DEFER(id) id CATCH_EMPTY()
687 
688 #define CATCH_REC_GET_END2() 0, CATCH_REC_END
689 #define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2
690 #define CATCH_REC_GET_END(...) CATCH_REC_GET_END1
691 #define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT
692 #define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0)
693 #define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next)
694 
695 #define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
696 #define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ )
697 #define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
698 
699 #define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )
700 #define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ )
701 #define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )
702 
703 // Applies the function macro `f` to each of the remaining parameters, inserts commas between the results,
704 // and passes userdata as the first parameter to each invocation,
705 // e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c)
706 #define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
707 
708 #define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
709 
710 #define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
711 #define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__
712 #define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
713 #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
714 #define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__)
715 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
716 #define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__
717 #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param))
718 #else
719 // MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
720 #define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__)
721 #define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__
722 #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1)
723 #endif
724 
725 #define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)
726 
727 #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name, __VA_ARGS__)
728 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
729 #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name,...) Name " - " #__VA_ARGS__
730 #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME(Name,...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
731 #else
732 // MSVC is adding extra space and needs more calls to properly remove ()
733 #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name,...) Name " -" #__VA_ARGS__
734 #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME1(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, __VA_ARGS__)
735 #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME1(Name, INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
736 #endif
737 
738 #define INTERNAL_CATCH_MAKE_TYPE_LIST(types) Catch::TypeList<INTERNAL_CATCH_REMOVE_PARENS(types)>
739 
740 #define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(types)\
741  CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,INTERNAL_CATCH_REMOVE_PARENS(types))
742 
743 // end catch_preprocessor.hpp
744 // start catch_meta.hpp
745 
746 
747 #include <type_traits>
748 
749 namespace Catch {
750 template< typename... >
751 struct TypeList {};
752 
753 template< typename... >
754 struct append;
755 
756 template< template<typename...> class L1
757  , typename...E1
758  , template<typename...> class L2
759  , typename...E2
760 >
761 struct append< L1<E1...>, L2<E2...> > {
762  using type = L1<E1..., E2...>;
763 };
764 
765 template< template<typename...> class L1
766  , typename...E1
767  , template<typename...> class L2
768  , typename...E2
769  , typename...Rest
770 >
771 struct append< L1<E1...>, L2<E2...>, Rest...> {
772  using type = typename append< L1<E1..., E2...>, Rest... >::type;
773 };
774 
775 template< template<typename...> class
776  , typename...
777 >
778 struct rewrap;
779 
780 template< template<typename...> class Container
781  , template<typename...> class List
782  , typename...elems
783 >
784 struct rewrap<Container, List<elems...>> {
785  using type = TypeList< Container< elems... > >;
786 };
787 
788 template< template<typename...> class Container
789  , template<typename...> class List
790  , class...Elems
791  , typename...Elements>
792  struct rewrap<Container, List<Elems...>, Elements...> {
793  using type = typename append<TypeList<Container<Elems...>>, typename rewrap<Container, Elements...>::type>::type;
794 };
795 
796 template< template<typename...> class...Containers >
797 struct combine {
798  template< typename...Types >
799  struct with_types {
800  template< template <typename...> class Final >
801  struct into {
802  using type = typename append<Final<>, typename rewrap<Containers, Types...>::type...>::type;
803  };
804  };
805 };
806 
807 template<typename T>
808 struct always_false : std::false_type {};
809 
810 } // namespace Catch
811 
812 // end catch_meta.hpp
813 namespace Catch {
814 
815 template<typename C>
817  void (C::*m_testAsMethod)();
818 public:
819  TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}
820 
821  void invoke() const override {
822  C obj;
823  (obj.*m_testAsMethod)();
824  }
825 };
826 
827 auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;
828 
829 template<typename C>
830 auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {
831  return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod );
832 }
833 
834 struct NameAndTags {
835  NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;
838 };
839 
841  AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;
842  ~AutoReg();
843 };
844 
845 } // end namespace Catch
846 
847 #if defined(CATCH_CONFIG_DISABLE)
848  #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
849  static void TestName()
850  #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
851  namespace{ \
852  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
853  void test(); \
854  }; \
855  } \
856  void TestName::test()
857  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION( TestName, ... ) \
858  template<typename TestType> \
859  static void TestName()
860  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
861  namespace{ \
862  template<typename TestType> \
863  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
864  void test(); \
865  }; \
866  } \
867  template<typename TestType> \
868  void TestName::test()
869 #endif
870 
872  #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
873  static void TestName(); \
874  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
875  namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
876  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
877  static void TestName()
878  #define INTERNAL_CATCH_TESTCASE( ... ) \
879  INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
880 
882  #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
883  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
884  namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
885  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
886 
888  #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
889  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
890  namespace{ \
891  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
892  void test(); \
893  }; \
894  Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
895  } \
896  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
897  void TestName::test()
898  #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
899  INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
900 
902  #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
903  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
904  Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
905  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
906 
908  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, ... )\
909  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
910  template<typename TestType> \
911  static void TestFunc();\
912  namespace {\
913  template<typename...Types> \
914  struct TestName{\
915  template<typename...Ts> \
916  TestName(Ts...names){\
917  CATCH_INTERNAL_CHECK_UNIQUE_TYPES(CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)) \
918  using expander = int[];\
919  (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ names, Tags } ), 0)... };/* NOLINT */ \
920  }\
921  };\
922  INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestName, Name, __VA_ARGS__) \
923  }\
924  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
925  template<typename TestType> \
926  static void TestFunc()
927 
928 #if defined(CATCH_CPP17_OR_GREATER)
929 #define CATCH_INTERNAL_CHECK_UNIQUE_TYPES(...) static_assert(Catch::is_unique<__VA_ARGS__>,"Duplicate type detected in declaration of template test case");
930 #else
931 #define CATCH_INTERNAL_CHECK_UNIQUE_TYPES(...) static_assert(Catch::is_unique<__VA_ARGS__>::value,"Duplicate type detected in declaration of template test case");
932 #endif
933 
934 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
935  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
936  INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, __VA_ARGS__ )
937 #else
938  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
939  INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, __VA_ARGS__ ) )
940 #endif
941 
942  #define INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestName, Name, ...)\
943  static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
944  TestName<CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)>(CATCH_REC_LIST_UD(INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME,Name, __VA_ARGS__));\
945  return 0;\
946  }();
947 
948  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, TmplTypes, TypesList) \
949  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
950  template<typename TestType> static void TestFuncName(); \
951  namespace { \
952  template<typename... Types> \
953  struct TestName { \
954  TestName() { \
955  CATCH_INTERNAL_CHECK_UNIQUE_TYPES(Types...) \
956  int index = 0; \
957  using expander = int[]; \
958  constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
959  constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
960  constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
961  (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */\
962  } \
963  }; \
964  static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
965  using TestInit = Catch::combine<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)> \
966  ::with_types<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(TypesList)>::into<TestName>::type; \
967  TestInit(); \
968  return 0; \
969  }(); \
970  } \
971  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
972  template<typename TestType> \
973  static void TestFuncName()
974 
975 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
976  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
977  INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ),Name,Tags,__VA_ARGS__)
978 #else
979  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
980  INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, __VA_ARGS__ ) )
981 #endif
982 
983  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, ... ) \
984  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
985  namespace{ \
986  template<typename TestType> \
987  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
988  void test();\
989  };\
990  template<typename...Types> \
991  struct TestNameClass{\
992  template<typename...Ts> \
993  TestNameClass(Ts...names){\
994  CATCH_INTERNAL_CHECK_UNIQUE_TYPES(CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)) \
995  using expander = int[];\
996  (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ names, Tags } ), 0)... };/* NOLINT */ \
997  }\
998  };\
999  INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestNameClass, Name, __VA_ARGS__)\
1000  }\
1001  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS\
1002  template<typename TestType> \
1003  void TestName<TestType>::test()
1004 
1005 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1006  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
1007  INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, __VA_ARGS__ )
1008 #else
1009  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
1010  INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, __VA_ARGS__ ) )
1011 #endif
1012 
1013  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, TmplTypes, TypesList)\
1014  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
1015  template<typename TestType> \
1016  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
1017  void test();\
1018  };\
1019  namespace {\
1020  template<typename...Types>\
1021  struct TestNameClass{\
1022  TestNameClass(){\
1023  CATCH_INTERNAL_CHECK_UNIQUE_TYPES(Types...)\
1024  int index = 0;\
1025  using expander = int[];\
1026  constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
1027  constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
1028  constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
1029  (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */ \
1030  }\
1031  };\
1032  static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
1033  using TestInit = Catch::combine<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>\
1034  ::with_types<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(TypesList)>::into<TestNameClass>::type;\
1035  TestInit();\
1036  return 0;\
1037  }(); \
1038  }\
1039  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
1040  template<typename TestType> \
1041  void TestName<TestType>::test()
1042 
1043 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
1044  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
1045  INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, __VA_ARGS__ )
1046 #else
1047  #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
1048  INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, __VA_ARGS__ ) )
1049 #endif
1050 
1051 // end catch_test_registry.h
1052 // start catch_capture.hpp
1053 
1054 // start catch_assertionhandler.h
1055 
1056 // start catch_assertioninfo.h
1057 
1058 // start catch_result_type.h
1059 
1060 namespace Catch {
1061 
1062  // ResultWas::OfType enum
1063  struct ResultWas { enum OfType {
1064  Unknown = -1,
1065  Ok = 0,
1066  Info = 1,
1067  Warning = 2,
1068 
1069  FailureBit = 0x10,
1070 
1071  ExpressionFailed = FailureBit | 1,
1072  ExplicitFailure = FailureBit | 2,
1073 
1074  Exception = 0x100 | FailureBit,
1075 
1076  ThrewException = Exception | 1,
1077  DidntThrowException = Exception | 2,
1078 
1079  FatalErrorCondition = 0x200 | FailureBit
1080 
1081  }; };
1082 
1083  bool isOk( ResultWas::OfType resultType );
1084  bool isJustInfo( int flags );
1085 
1086  // ResultDisposition::Flags enum
1087  struct ResultDisposition { enum Flags {
1088  Normal = 0x01,
1089 
1090  ContinueOnFailure = 0x02, // Failures fail test, but execution continues
1091  FalseTest = 0x04, // Prefix expression with !
1092  SuppressFail = 0x08 // Failures are reported but do not fail the test
1093  }; };
1094 
1096 
1097  bool shouldContinueOnFailure( int flags );
1098  inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
1099  bool shouldSuppressFailure( int flags );
1100 
1101 } // end namespace Catch
1102 
1103 // end catch_result_type.h
1104 namespace Catch {
1105 
1107  {
1112 
1113  // We want to delete this constructor but a compiler bug in 4.8 means
1114  // the struct is then treated as non-aggregate
1115  //AssertionInfo() = delete;
1116  };
1117 
1118 } // end namespace Catch
1119 
1120 // end catch_assertioninfo.h
1121 // start catch_decomposer.h
1122 
1123 // start catch_tostring.h
1124 
1125 #include <vector>
1126 #include <cstddef>
1127 #include <type_traits>
1128 #include <string>
1129 // start catch_stream.h
1130 
1131 #include <iosfwd>
1132 #include <cstddef>
1133 #include <ostream>
1134 
1135 namespace Catch {
1136 
1137  std::ostream& cout();
1138  std::ostream& cerr();
1139  std::ostream& clog();
1140 
1141  class StringRef;
1142 
1143  struct IStream {
1144  virtual ~IStream();
1145  virtual std::ostream& stream() const = 0;
1146  };
1147 
1148  auto makeStream( StringRef const &filename ) -> IStream const*;
1149 
1151  std::size_t m_index;
1152  std::ostream* m_oss;
1153  public:
1156 
1157  auto str() const -> std::string;
1158 
1159  template<typename T>
1160  auto operator << ( T const& value ) -> ReusableStringStream& {
1161  *m_oss << value;
1162  return *this;
1163  }
1164  auto get() -> std::ostream& { return *m_oss; }
1165  };
1166 }
1167 
1168 // end catch_stream.h
1169 
1170 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1171 #include <string_view>
1172 #endif
1173 
1174 #ifdef __OBJC__
1175 // start catch_objc_arc.hpp
1176 
1177 #import <Foundation/Foundation.h>
1178 
1179 #ifdef __has_feature
1180 #define CATCH_ARC_ENABLED __has_feature(objc_arc)
1181 #else
1182 #define CATCH_ARC_ENABLED 0
1183 #endif
1184 
1185 void arcSafeRelease( NSObject* obj );
1186 id performOptionalSelector( id obj, SEL sel );
1187 
1188 #if !CATCH_ARC_ENABLED
1189 inline void arcSafeRelease( NSObject* obj ) {
1190  [obj release];
1191 }
1192 inline id performOptionalSelector( id obj, SEL sel ) {
1193  if( [obj respondsToSelector: sel] )
1194  return [obj performSelector: sel];
1195  return nil;
1196 }
1197 #define CATCH_UNSAFE_UNRETAINED
1198 #define CATCH_ARC_STRONG
1199 #else
1200 inline void arcSafeRelease( NSObject* ){}
1201 inline id performOptionalSelector( id obj, SEL sel ) {
1202 #ifdef __clang__
1203 #pragma clang diagnostic push
1204 #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
1205 #endif
1206  if( [obj respondsToSelector: sel] )
1207  return [obj performSelector: sel];
1208 #ifdef __clang__
1209 #pragma clang diagnostic pop
1210 #endif
1211  return nil;
1212 }
1213 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
1214 #define CATCH_ARC_STRONG __strong
1215 #endif
1216 
1217 // end catch_objc_arc.hpp
1218 #endif
1219 
1220 #ifdef _MSC_VER
1221 #pragma warning(push)
1222 #pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
1223 #endif
1224 
1225 namespace Catch {
1226  namespace Detail {
1227 
1228  extern const std::string unprintableString;
1229 
1230  std::string rawMemoryToString( const void *object, std::size_t size );
1231 
1232  template<typename T>
1233  std::string rawMemoryToString( const T& object ) {
1234  return rawMemoryToString( &object, sizeof(object) );
1235  }
1236 
1237  template<typename T>
1239  template<typename SS, typename TT>
1240  static auto test(int)
1241  -> decltype(std::declval<SS&>() << std::declval<TT>(), std::true_type());
1242 
1243  template<typename, typename>
1244  static auto test(...)->std::false_type;
1245 
1246  public:
1247  static const bool value = decltype(test<std::ostream, const T&>(0))::value;
1248  };
1249 
1250  template<typename E>
1251  std::string convertUnknownEnumToString( E e );
1252 
1253  template<typename T>
1254  typename std::enable_if<
1256  std::string>::type convertUnstreamable( T const& ) {
1258  }
1259  template<typename T>
1260  typename std::enable_if<
1262  std::string>::type convertUnstreamable(T const& ex) {
1263  return ex.what();
1264  }
1265 
1266  template<typename T>
1267  typename std::enable_if<
1269  , std::string>::type convertUnstreamable( T const& value ) {
1270  return convertUnknownEnumToString( value );
1271  }
1272 
1273 #if defined(_MANAGED)
1274  template<typename T>
1276  std::string clrReferenceToString( T^ ref ) {
1277  if (ref == nullptr)
1278  return std::string("null");
1279  auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
1280  cli::pin_ptr<System::Byte> p = &bytes[0];
1281  return std::string(reinterpret_cast<char const *>(p), bytes->Length);
1282  }
1283 #endif
1284 
1285  } // namespace Detail
1286 
1287  // If we decide for C++14, change these to enable_if_ts
1288  template <typename T, typename = void>
1289  struct StringMaker {
1290  template <typename Fake = T>
1291  static
1293  convert(const Fake& value) {
1295  // NB: call using the function-like syntax to avoid ambiguity with
1296  // user-defined templated operator<< under clang.
1297  rss.operator<<(value);
1298  return rss.str();
1299  }
1300 
1301  template <typename Fake = T>
1302  static
1304  convert( const Fake& value ) {
1305 #if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
1306  return Detail::convertUnstreamable(value);
1307 #else
1308  return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
1309 #endif
1310  }
1311  };
1312 
1313  namespace Detail {
1314 
1315  // This function dispatches all stringification requests inside of Catch.
1316  // Should be preferably called fully qualified, like ::Catch::Detail::stringify
1317  template <typename T>
1318  std::string stringify(const T& e) {
1319  return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);
1320  }
1321 
1322  template<typename E>
1323  std::string convertUnknownEnumToString( E e ) {
1324  return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));
1325  }
1326 
1327 #if defined(_MANAGED)
1328  template <typename T>
1329  std::string stringify( T^ e ) {
1330  return ::Catch::StringMaker<T^>::convert(e);
1331  }
1332 #endif
1333 
1334  } // namespace Detail
1335 
1336  // Some predefined specializations
1337 
1338  template<>
1339  struct StringMaker<std::string> {
1340  static std::string convert(const std::string& str);
1341  };
1342 
1343 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1344  template<>
1345  struct StringMaker<std::string_view> {
1346  static std::string convert(std::string_view str);
1347  };
1348 #endif
1349 
1350  template<>
1351  struct StringMaker<char const *> {
1352  static std::string convert(char const * str);
1353  };
1354  template<>
1355  struct StringMaker<char *> {
1356  static std::string convert(char * str);
1357  };
1358 
1359 #ifdef CATCH_CONFIG_WCHAR
1360  template<>
1361  struct StringMaker<std::wstring> {
1362  static std::string convert(const std::wstring& wstr);
1363  };
1364 
1365 # ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1366  template<>
1367  struct StringMaker<std::wstring_view> {
1368  static std::string convert(std::wstring_view str);
1369  };
1370 # endif
1371 
1372  template<>
1373  struct StringMaker<wchar_t const *> {
1374  static std::string convert(wchar_t const * str);
1375  };
1376  template<>
1377  struct StringMaker<wchar_t *> {
1378  static std::string convert(wchar_t * str);
1379  };
1380 #endif
1381 
1382  // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
1383  // while keeping string semantics?
1384  template<int SZ>
1385  struct StringMaker<char[SZ]> {
1386  static std::string convert(char const* str) {
1387  return ::Catch::Detail::stringify(std::string{ str });
1388  }
1389  };
1390  template<int SZ>
1391  struct StringMaker<signed char[SZ]> {
1392  static std::string convert(signed char const* str) {
1393  return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
1394  }
1395  };
1396  template<int SZ>
1397  struct StringMaker<unsigned char[SZ]> {
1398  static std::string convert(unsigned char const* str) {
1399  return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
1400  }
1401  };
1402 
1403  template<>
1404  struct StringMaker<int> {
1405  static std::string convert(int value);
1406  };
1407  template<>
1408  struct StringMaker<long> {
1409  static std::string convert(long value);
1410  };
1411  template<>
1412  struct StringMaker<long long> {
1413  static std::string convert(long long value);
1414  };
1415  template<>
1416  struct StringMaker<unsigned int> {
1417  static std::string convert(unsigned int value);
1418  };
1419  template<>
1420  struct StringMaker<unsigned long> {
1421  static std::string convert(unsigned long value);
1422  };
1423  template<>
1424  struct StringMaker<unsigned long long> {
1425  static std::string convert(unsigned long long value);
1426  };
1427 
1428  template<>
1429  struct StringMaker<bool> {
1430  static std::string convert(bool b);
1431  };
1432 
1433  template<>
1434  struct StringMaker<char> {
1435  static std::string convert(char c);
1436  };
1437  template<>
1438  struct StringMaker<signed char> {
1439  static std::string convert(signed char c);
1440  };
1441  template<>
1442  struct StringMaker<unsigned char> {
1443  static std::string convert(unsigned char c);
1444  };
1445 
1446  template<>
1447  struct StringMaker<std::nullptr_t> {
1448  static std::string convert(std::nullptr_t);
1449  };
1450 
1451  template<>
1452  struct StringMaker<float> {
1453  static std::string convert(float value);
1454  };
1455  template<>
1456  struct StringMaker<double> {
1457  static std::string convert(double value);
1458  };
1459 
1460  template <typename T>
1461  struct StringMaker<T*> {
1462  template <typename U>
1463  static std::string convert(U* p) {
1464  if (p) {
1466  } else {
1467  return "nullptr";
1468  }
1469  }
1470  };
1471 
1472  template <typename R, typename C>
1473  struct StringMaker<R C::*> {
1474  static std::string convert(R C::* p) {
1475  if (p) {
1477  } else {
1478  return "nullptr";
1479  }
1480  }
1481  };
1482 
1483 #if defined(_MANAGED)
1484  template <typename T>
1485  struct StringMaker<T^> {
1486  static std::string convert( T^ ref ) {
1487  return ::Catch::Detail::clrReferenceToString(ref);
1488  }
1489  };
1490 #endif
1491 
1492  namespace Detail {
1493  template<typename InputIterator>
1494  std::string rangeToString(InputIterator first, InputIterator last) {
1496  rss << "{ ";
1497  if (first != last) {
1498  rss << ::Catch::Detail::stringify(*first);
1499  for (++first; first != last; ++first)
1500  rss << ", " << ::Catch::Detail::stringify(*first);
1501  }
1502  rss << " }";
1503  return rss.str();
1504  }
1505  }
1506 
1507 #ifdef __OBJC__
1508  template<>
1509  struct StringMaker<NSString*> {
1510  static std::string convert(NSString * nsstring) {
1511  if (!nsstring)
1512  return "nil";
1513  return std::string("@") + [nsstring UTF8String];
1514  }
1515  };
1516  template<>
1517  struct StringMaker<NSObject*> {
1518  static std::string convert(NSObject* nsObject) {
1519  return ::Catch::Detail::stringify([nsObject description]);
1520  }
1521 
1522  };
1523  namespace Detail {
1524  inline std::string stringify( NSString* nsstring ) {
1525  return StringMaker<NSString*>::convert( nsstring );
1526  }
1527 
1528  } // namespace Detail
1529 #endif // __OBJC__
1530 
1531 } // namespace Catch
1532 
1534 // Separate std-lib types stringification, so it can be selectively enabled
1535 // This means that we do not bring in
1536 
1537 #if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
1538 # define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
1539 # define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
1540 # define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
1541 # define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
1542 # define CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
1543 #endif
1544 
1545 // Separate std::pair specialization
1546 #if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
1547 #include <utility>
1548 namespace Catch {
1549  template<typename T1, typename T2>
1550  struct StringMaker<std::pair<T1, T2> > {
1551  static std::string convert(const std::pair<T1, T2>& pair) {
1553  rss << "{ "
1554  << ::Catch::Detail::stringify(pair.first)
1555  << ", "
1556  << ::Catch::Detail::stringify(pair.second)
1557  << " }";
1558  return rss.str();
1559  }
1560  };
1561 }
1562 #endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
1563 
1564 #if defined(CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_OPTIONAL)
1565 #include <optional>
1566 namespace Catch {
1567  template<typename T>
1568  struct StringMaker<std::optional<T> > {
1569  static std::string convert(const std::optional<T>& optional) {
1571  if (optional.has_value()) {
1572  rss << ::Catch::Detail::stringify(*optional);
1573  } else {
1574  rss << "{ }";
1575  }
1576  return rss.str();
1577  }
1578  };
1579 }
1580 #endif // CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER
1581 
1582 // Separate std::tuple specialization
1583 #if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
1584 #include <tuple>
1585 namespace Catch {
1586  namespace Detail {
1587  template<
1588  typename Tuple,
1589  std::size_t N = 0,
1591  >
1592  struct TupleElementPrinter {
1593  static void print(const Tuple& tuple, std::ostream& os) {
1594  os << (N ? ", " : " ")
1595  << ::Catch::Detail::stringify(std::get<N>(tuple));
1596  TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
1597  }
1598  };
1599 
1600  template<
1601  typename Tuple,
1602  std::size_t N
1603  >
1604  struct TupleElementPrinter<Tuple, N, false> {
1605  static void print(const Tuple&, std::ostream&) {}
1606  };
1607 
1608  }
1609 
1610  template<typename ...Types>
1611  struct StringMaker<std::tuple<Types...>> {
1612  static std::string convert(const std::tuple<Types...>& tuple) {
1614  rss << '{';
1615  Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
1616  rss << " }";
1617  return rss.str();
1618  }
1619  };
1620 }
1621 #endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
1622 
1623 #if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
1624 #include <variant>
1625 namespace Catch {
1626  template<>
1627  struct StringMaker<std::monostate> {
1628  static std::string convert(const std::monostate&) {
1629  return "{ }";
1630  }
1631  };
1632 
1633  template<typename... Elements>
1634  struct StringMaker<std::variant<Elements...>> {
1635  static std::string convert(const std::variant<Elements...>& variant) {
1636  if (variant.valueless_by_exception()) {
1637  return "{valueless variant}";
1638  } else {
1639  return std::visit(
1640  [](const auto& value) {
1642  },
1643  variant
1644  );
1645  }
1646  }
1647  };
1648 }
1649 #endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
1650 
1651 namespace Catch {
1652  struct not_this_one {}; // Tag type for detecting which begin/ end are being selected
1653 
1654  // Import begin/ end from std here so they are considered alongside the fallback (...) overloads in this namespace
1655  using std::begin;
1656  using std::end;
1657 
1658  not_this_one begin( ... );
1659  not_this_one end( ... );
1660 
1661  template <typename T>
1662  struct is_range {
1663  static const bool value =
1664  !std::is_same<decltype(begin(std::declval<T>())), not_this_one>::value &&
1665  !std::is_same<decltype(end(std::declval<T>())), not_this_one>::value;
1666  };
1667 
1668 #if defined(_MANAGED) // Managed types are never ranges
1669  template <typename T>
1670  struct is_range<T^> {
1671  static const bool value = false;
1672  };
1673 #endif
1674 
1675  template<typename Range>
1676  std::string rangeToString( Range const& range ) {
1677  return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
1678  }
1679 
1680  // Handle vector<bool> specially
1681  template<typename Allocator>
1682  std::string rangeToString( std::vector<bool, Allocator> const& v ) {
1684  rss << "{ ";
1685  bool first = true;
1686  for( bool b : v ) {
1687  if( first )
1688  first = false;
1689  else
1690  rss << ", ";
1691  rss << ::Catch::Detail::stringify( b );
1692  }
1693  rss << " }";
1694  return rss.str();
1695  }
1696 
1697  template<typename R>
1698  struct StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {
1699  static std::string convert( R const& range ) {
1700  return rangeToString( range );
1701  }
1702  };
1703 
1704  template <typename T, int SZ>
1705  struct StringMaker<T[SZ]> {
1706  static std::string convert(T const(&arr)[SZ]) {
1707  return rangeToString(arr);
1708  }
1709  };
1710 
1711 } // namespace Catch
1712 
1713 // Separate std::chrono::duration specialization
1714 #if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
1715 #include <ctime>
1716 #include <ratio>
1717 #include <chrono>
1718 
1719 namespace Catch {
1720 
1721 template <class Ratio>
1722 struct ratio_string {
1723  static std::string symbol();
1724 };
1725 
1726 template <class Ratio>
1727 std::string ratio_string<Ratio>::symbol() {
1729  rss << '[' << Ratio::num << '/'
1730  << Ratio::den << ']';
1731  return rss.str();
1732 }
1733 template <>
1734 struct ratio_string<std::atto> {
1735  static std::string symbol();
1736 };
1737 template <>
1738 struct ratio_string<std::femto> {
1739  static std::string symbol();
1740 };
1741 template <>
1742 struct ratio_string<std::pico> {
1743  static std::string symbol();
1744 };
1745 template <>
1746 struct ratio_string<std::nano> {
1747  static std::string symbol();
1748 };
1749 template <>
1750 struct ratio_string<std::micro> {
1751  static std::string symbol();
1752 };
1753 template <>
1754 struct ratio_string<std::milli> {
1755  static std::string symbol();
1756 };
1757 
1759  // std::chrono::duration specializations
1760  template<typename Value, typename Ratio>
1761  struct StringMaker<std::chrono::duration<Value, Ratio>> {
1762  static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
1764  rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
1765  return rss.str();
1766  }
1767  };
1768  template<typename Value>
1769  struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
1770  static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
1772  rss << duration.count() << " s";
1773  return rss.str();
1774  }
1775  };
1776  template<typename Value>
1777  struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
1778  static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
1780  rss << duration.count() << " m";
1781  return rss.str();
1782  }
1783  };
1784  template<typename Value>
1785  struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
1786  static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
1788  rss << duration.count() << " h";
1789  return rss.str();
1790  }
1791  };
1792 
1794  // std::chrono::time_point specialization
1795  // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
1796  template<typename Clock, typename Duration>
1797  struct StringMaker<std::chrono::time_point<Clock, Duration>> {
1798  static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {
1799  return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
1800  }
1801  };
1802  // std::chrono::time_point<system_clock> specialization
1803  template<typename Duration>
1804  struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
1805  static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
1806  auto converted = std::chrono::system_clock::to_time_t(time_point);
1807 
1808 #ifdef _MSC_VER
1809  std::tm timeInfo = {};
1810  gmtime_s(&timeInfo, &converted);
1811 #else
1812  std::tm* timeInfo = std::gmtime(&converted);
1813 #endif
1814 
1815  auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
1816  char timeStamp[timeStampSize];
1817  const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
1818 
1819 #ifdef _MSC_VER
1820  std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
1821 #else
1822  std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
1823 #endif
1824  return std::string(timeStamp);
1825  }
1826  };
1827 }
1828 #endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
1829 
1830 #ifdef _MSC_VER
1831 #pragma warning(pop)
1832 #endif
1833 
1834 // end catch_tostring.h
1835 #include <iosfwd>
1836 
1837 #ifdef _MSC_VER
1838 #pragma warning(push)
1839 #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
1840 #pragma warning(disable:4018) // more "signed/unsigned mismatch"
1841 #pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
1842 #pragma warning(disable:4180) // qualifier applied to function type has no meaning
1843 #pragma warning(disable:4800) // Forcing result to true or false
1844 #endif
1845 
1846 namespace Catch {
1847 
1849  auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
1850  auto getResult() const -> bool { return m_result; }
1851  virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
1852 
1853  ITransientExpression( bool isBinaryExpression, bool result )
1854  : m_isBinaryExpression( isBinaryExpression ),
1855  m_result( result )
1856  {}
1857 
1858  // We don't actually need a virtual destructor, but many static analysers
1859  // complain if it's not here :-(
1860  virtual ~ITransientExpression();
1861 
1863  bool m_result;
1864 
1865  };
1866 
1867  void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
1868 
1869  template<typename LhsT, typename RhsT>
1871  LhsT m_lhs;
1873  RhsT m_rhs;
1874 
1875  void streamReconstructedExpression( std::ostream &os ) const override {
1877  ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
1878  }
1879 
1880  public:
1881  BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
1882  : ITransientExpression{ true, comparisonResult },
1883  m_lhs( lhs ),
1884  m_op( op ),
1885  m_rhs( rhs )
1886  {}
1887 
1888  template<typename T>
1889  auto operator && ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
1890  static_assert(always_false<T>::value,
1891  "chained comparisons are not supported inside assertions, "
1892  "wrap the expression inside parentheses, or decompose it");
1893  }
1894 
1895  template<typename T>
1896  auto operator || ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
1897  static_assert(always_false<T>::value,
1898  "chained comparisons are not supported inside assertions, "
1899  "wrap the expression inside parentheses, or decompose it");
1900  }
1901 
1902  template<typename T>
1903  auto operator == ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
1904  static_assert(always_false<T>::value,
1905  "chained comparisons are not supported inside assertions, "
1906  "wrap the expression inside parentheses, or decompose it");
1907  }
1908 
1909  template<typename T>
1910  auto operator != ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
1911  static_assert(always_false<T>::value,
1912  "chained comparisons are not supported inside assertions, "
1913  "wrap the expression inside parentheses, or decompose it");
1914  }
1915 
1916  template<typename T>
1917  auto operator > ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
1918  static_assert(always_false<T>::value,
1919  "chained comparisons are not supported inside assertions, "
1920  "wrap the expression inside parentheses, or decompose it");
1921  }
1922 
1923  template<typename T>
1924  auto operator < ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
1925  static_assert(always_false<T>::value,
1926  "chained comparisons are not supported inside assertions, "
1927  "wrap the expression inside parentheses, or decompose it");
1928  }
1929 
1930  template<typename T>
1931  auto operator >= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
1932  static_assert(always_false<T>::value,
1933  "chained comparisons are not supported inside assertions, "
1934  "wrap the expression inside parentheses, or decompose it");
1935  }
1936 
1937  template<typename T>
1938  auto operator <= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
1939  static_assert(always_false<T>::value,
1940  "chained comparisons are not supported inside assertions, "
1941  "wrap the expression inside parentheses, or decompose it");
1942  }
1943  };
1944 
1945  template<typename LhsT>
1947  LhsT m_lhs;
1948 
1949  void streamReconstructedExpression( std::ostream &os ) const override {
1950  os << Catch::Detail::stringify( m_lhs );
1951  }
1952 
1953  public:
1954  explicit UnaryExpr( LhsT lhs )
1955  : ITransientExpression{ false, static_cast<bool>(lhs) },
1956  m_lhs( lhs )
1957  {}
1958  };
1959 
1960  // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
1961  template<typename LhsT, typename RhsT>
1962  auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }
1963  template<typename T>
1964  auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
1965  template<typename T>
1966  auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
1967  template<typename T>
1968  auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
1969  template<typename T>
1970  auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
1971 
1972  template<typename LhsT, typename RhsT>
1973  auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }
1974  template<typename T>
1975  auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
1976  template<typename T>
1977  auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
1978  template<typename T>
1979  auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
1980  template<typename T>
1981  auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
1982 
1983  template<typename LhsT>
1984  class ExprLhs {
1985  LhsT m_lhs;
1986  public:
1987  explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
1988 
1989  template<typename RhsT>
1990  auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
1991  return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs };
1992  }
1993  auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
1994  return { m_lhs == rhs, m_lhs, "==", rhs };
1995  }
1996 
1997  template<typename RhsT>
1998  auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
1999  return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs };
2000  }
2001  auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
2002  return { m_lhs != rhs, m_lhs, "!=", rhs };
2003  }
2004 
2005  template<typename RhsT>
2006  auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2007  return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs };
2008  }
2009  template<typename RhsT>
2010  auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2011  return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs };
2012  }
2013  template<typename RhsT>
2014  auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2015  return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs };
2016  }
2017  template<typename RhsT>
2018  auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
2019  return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs };
2020  }
2021 
2022  template<typename RhsT>
2023  auto operator && ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
2024  static_assert(always_false<RhsT>::value,
2025  "operator&& is not supported inside assertions, "
2026  "wrap the expression inside parentheses, or decompose it");
2027  }
2028 
2029  template<typename RhsT>
2030  auto operator || ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
2031  static_assert(always_false<RhsT>::value,
2032  "operator|| is not supported inside assertions, "
2033  "wrap the expression inside parentheses, or decompose it");
2034  }
2035 
2036  auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
2037  return UnaryExpr<LhsT>{ m_lhs };
2038  }
2039  };
2040 
2041  void handleExpression( ITransientExpression const& expr );
2042 
2043  template<typename T>
2044  void handleExpression( ExprLhs<T> const& expr ) {
2045  handleExpression( expr.makeUnaryExpr() );
2046  }
2047 
2048  struct Decomposer {
2049  template<typename T>
2050  auto operator <= ( T const& lhs ) -> ExprLhs<T const&> {
2051  return ExprLhs<T const&>{ lhs };
2052  }
2053 
2054  auto operator <=( bool value ) -> ExprLhs<bool> {
2055  return ExprLhs<bool>{ value };
2056  }
2057  };
2058 
2059 } // end namespace Catch
2060 
2061 #ifdef _MSC_VER
2062 #pragma warning(pop)
2063 #endif
2064 
2065 // end catch_decomposer.h
2066 // start catch_interfaces_capture.h
2067 
2068 #include <string>
2069 
2070 namespace Catch {
2071 
2072  class AssertionResult;
2073  struct AssertionInfo;
2074  struct SectionInfo;
2075  struct SectionEndInfo;
2076  struct MessageInfo;
2077  struct MessageBuilder;
2078  struct Counts;
2079  struct BenchmarkInfo;
2080  struct BenchmarkStats;
2081  struct AssertionReaction;
2082  struct SourceLineInfo;
2083 
2084  struct ITransientExpression;
2085  struct IGeneratorTracker;
2086 
2088 
2089  virtual ~IResultCapture();
2090 
2091  virtual bool sectionStarted( SectionInfo const& sectionInfo,
2092  Counts& assertions ) = 0;
2093  virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
2094  virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
2095 
2096  virtual auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
2097 
2098  virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
2099  virtual void benchmarkEnded( BenchmarkStats const& stats ) = 0;
2100 
2101  virtual void pushScopedMessage( MessageInfo const& message ) = 0;
2102  virtual void popScopedMessage( MessageInfo const& message ) = 0;
2103 
2104  virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0;
2105 
2106  virtual void handleFatalErrorCondition( StringRef message ) = 0;
2107 
2108  virtual void handleExpr
2109  ( AssertionInfo const& info,
2110  ITransientExpression const& expr,
2111  AssertionReaction& reaction ) = 0;
2112  virtual void handleMessage
2113  ( AssertionInfo const& info,
2114  ResultWas::OfType resultType,
2115  StringRef const& message,
2116  AssertionReaction& reaction ) = 0;
2117  virtual void handleUnexpectedExceptionNotThrown
2118  ( AssertionInfo const& info,
2119  AssertionReaction& reaction ) = 0;
2120  virtual void handleUnexpectedInflightException
2121  ( AssertionInfo const& info,
2122  std::string const& message,
2123  AssertionReaction& reaction ) = 0;
2124  virtual void handleIncomplete
2125  ( AssertionInfo const& info ) = 0;
2126  virtual void handleNonExpr
2127  ( AssertionInfo const &info,
2128  ResultWas::OfType resultType,
2129  AssertionReaction &reaction ) = 0;
2130 
2131  virtual bool lastAssertionPassed() = 0;
2132  virtual void assertionPassed() = 0;
2133 
2134  // Deprecated, do not use:
2135  virtual std::string getCurrentTestName() const = 0;
2136  virtual const AssertionResult* getLastResult() const = 0;
2137  virtual void exceptionEarlyReported() = 0;
2138  };
2139 
2141 }
2142 
2143 // end catch_interfaces_capture.h
2144 namespace Catch {
2145 
2147  struct AssertionResultData;
2148  struct IResultCapture;
2149  class RunContext;
2150 
2152  friend class AssertionHandler;
2153  friend struct AssertionStats;
2154  friend class RunContext;
2155 
2156  ITransientExpression const* m_transientExpression = nullptr;
2158  public:
2159  LazyExpression( bool isNegated );
2160  LazyExpression( LazyExpression const& other );
2161  LazyExpression& operator = ( LazyExpression const& ) = delete;
2162 
2163  explicit operator bool() const;
2164 
2165  friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&;
2166  };
2167 
2169  bool shouldDebugBreak = false;
2170  bool shouldThrow = false;
2171  };
2172 
2176  bool m_completed = false;
2178 
2179  public:
2181  ( StringRef const& macroName,
2182  SourceLineInfo const& lineInfo,
2183  StringRef capturedExpression,
2184  ResultDisposition::Flags resultDisposition );
2186  if ( !m_completed ) {
2187  m_resultCapture.handleIncomplete( m_assertionInfo );
2188  }
2189  }
2190 
2191  template<typename T>
2192  void handleExpr( ExprLhs<T> const& expr ) {
2193  handleExpr( expr.makeUnaryExpr() );
2194  }
2195  void handleExpr( ITransientExpression const& expr );
2196 
2197  void handleMessage(ResultWas::OfType resultType, StringRef const& message);
2198 
2199  void handleExceptionThrownAsExpected();
2200  void handleUnexpectedExceptionNotThrown();
2201  void handleExceptionNotThrownAsExpected();
2202  void handleThrowingCallSkipped();
2203  void handleUnexpectedInflightException();
2204 
2205  void complete();
2206  void setCompleted();
2207 
2208  // query
2209  auto allowThrows() const -> bool;
2210  };
2211 
2212  void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString );
2213 
2214 } // namespace Catch
2215 
2216 // end catch_assertionhandler.h
2217 // start catch_message.h
2218 
2219 #include <string>
2220 #include <vector>
2221 
2222 namespace Catch {
2223 
2224  struct MessageInfo {
2225  MessageInfo( StringRef const& _macroName,
2226  SourceLineInfo const& _lineInfo,
2227  ResultWas::OfType _type );
2228 
2230  std::string message;
2233  unsigned int sequence;
2234 
2235  bool operator == ( MessageInfo const& other ) const;
2236  bool operator < ( MessageInfo const& other ) const;
2237  private:
2238  static unsigned int globalCount;
2239  };
2240 
2241  struct MessageStream {
2242 
2243  template<typename T>
2245  m_stream << value;
2246  return *this;
2247  }
2248 
2250  };
2251 
2253  MessageBuilder( StringRef const& macroName,
2254  SourceLineInfo const& lineInfo,
2255  ResultWas::OfType type );
2256 
2257  template<typename T>
2259  m_stream << value;
2260  return *this;
2261  }
2262 
2264  };
2265 
2267  public:
2268  explicit ScopedMessage( MessageBuilder const& builder );
2269  ScopedMessage( ScopedMessage& duplicate ) = delete;
2270  ScopedMessage( ScopedMessage&& old );
2271  ~ScopedMessage();
2272 
2274  bool m_moved;
2275  };
2276 
2277  class Capturer {
2278  std::vector<MessageInfo> m_messages;
2279  IResultCapture& m_resultCapture = getResultCapture();
2280  size_t m_captured = 0;
2281  public:
2282  Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
2283  ~Capturer();
2284 
2285  void captureValue( size_t index, std::string const& value );
2286 
2287  template<typename T>
2288  void captureValues( size_t index, T const& value ) {
2289  captureValue( index, Catch::Detail::stringify( value ) );
2290  }
2291 
2292  template<typename T, typename... Ts>
2293  void captureValues( size_t index, T const& value, Ts const&... values ) {
2294  captureValue( index, Catch::Detail::stringify(value) );
2295  captureValues( index+1, values... );
2296  }
2297  };
2298 
2299 } // end namespace Catch
2300 
2301 // end catch_message.h
2302 #if !defined(CATCH_CONFIG_DISABLE)
2303 
2304 #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
2305  #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
2306 #else
2307  #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
2308 #endif
2309 
2310 #if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
2311 
2313 // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
2314 // macros.
2315 #define INTERNAL_CATCH_TRY
2316 #define INTERNAL_CATCH_CATCH( capturer )
2317 
2318 #else // CATCH_CONFIG_FAST_COMPILE
2319 
2320 #define INTERNAL_CATCH_TRY try
2321 #define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); }
2322 
2323 #endif
2324 
2325 #define INTERNAL_CATCH_REACT( handler ) handler.complete();
2326 
2328 #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
2329  do { \
2330  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
2331  INTERNAL_CATCH_TRY { \
2332  CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
2333  catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
2334  CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
2335  } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
2336  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2337  } while( (void)0, (false) && static_cast<bool>( !!(__VA_ARGS__) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look
2338  // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
2339 
2341 #define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
2342  INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
2343  if( Catch::getResultCapture().lastAssertionPassed() )
2344 
2346 #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
2347  INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
2348  if( !Catch::getResultCapture().lastAssertionPassed() )
2349 
2351 #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
2352  do { \
2353  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
2354  try { \
2355  static_cast<void>(__VA_ARGS__); \
2356  catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
2357  } \
2358  catch( ... ) { \
2359  catchAssertionHandler.handleUnexpectedInflightException(); \
2360  } \
2361  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2362  } while( false )
2363 
2365 #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
2366  do { \
2367  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
2368  if( catchAssertionHandler.allowThrows() ) \
2369  try { \
2370  static_cast<void>(__VA_ARGS__); \
2371  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
2372  } \
2373  catch( ... ) { \
2374  catchAssertionHandler.handleExceptionThrownAsExpected(); \
2375  } \
2376  else \
2377  catchAssertionHandler.handleThrowingCallSkipped(); \
2378  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2379  } while( false )
2380 
2382 #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
2383  do { \
2384  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
2385  if( catchAssertionHandler.allowThrows() ) \
2386  try { \
2387  static_cast<void>(expr); \
2388  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
2389  } \
2390  catch( exceptionType const& ) { \
2391  catchAssertionHandler.handleExceptionThrownAsExpected(); \
2392  } \
2393  catch( ... ) { \
2394  catchAssertionHandler.handleUnexpectedInflightException(); \
2395  } \
2396  else \
2397  catchAssertionHandler.handleThrowingCallSkipped(); \
2398  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2399  } while( false )
2400 
2402 #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
2403  do { \
2404  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
2405  catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
2406  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2407  } while( false )
2408 
2410 #define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
2411  auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \
2412  varName.captureValues( 0, __VA_ARGS__ )
2413 
2415 #define INTERNAL_CATCH_INFO( macroName, log ) \
2416  Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
2417 
2419 #define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \
2420  Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )
2421 
2423 // Although this is matcher-based, it can be used with just a string
2424 #define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
2425  do { \
2426  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
2427  if( catchAssertionHandler.allowThrows() ) \
2428  try { \
2429  static_cast<void>(__VA_ARGS__); \
2430  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
2431  } \
2432  catch( ... ) { \
2433  Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \
2434  } \
2435  else \
2436  catchAssertionHandler.handleThrowingCallSkipped(); \
2437  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2438  } while( false )
2439 
2440 #endif // CATCH_CONFIG_DISABLE
2441 
2442 // end catch_capture.hpp
2443 // start catch_section.h
2444 
2445 // start catch_section_info.h
2446 
2447 // start catch_totals.h
2448 
2449 #include <cstddef>
2450 
2451 namespace Catch {
2452 
2453  struct Counts {
2454  Counts operator - ( Counts const& other ) const;
2455  Counts& operator += ( Counts const& other );
2456 
2457  std::size_t total() const;
2458  bool allPassed() const;
2459  bool allOk() const;
2460 
2461  std::size_t passed = 0;
2462  std::size_t failed = 0;
2463  std::size_t failedButOk = 0;
2464  };
2465 
2466  struct Totals {
2467 
2468  Totals operator - ( Totals const& other ) const;
2469  Totals& operator += ( Totals const& other );
2470 
2471  Totals delta( Totals const& prevTotals ) const;
2472 
2473  int error = 0;
2476  };
2477 }
2478 
2479 // end catch_totals.h
2480 #include <string>
2481 
2482 namespace Catch {
2483 
2484  struct SectionInfo {
2485  SectionInfo
2486  ( SourceLineInfo const& _lineInfo,
2487  std::string const& _name );
2488 
2489  // Deprecated
2490  SectionInfo
2491  ( SourceLineInfo const& _lineInfo,
2492  std::string const& _name,
2493  std::string const& ) : SectionInfo( _lineInfo, _name ) {}
2494 
2495  std::string name;
2496  std::string description; // !Deprecated: this will always be empty
2498  };
2499 
2504  };
2505 
2506 } // end namespace Catch
2507 
2508 // end catch_section_info.h
2509 // start catch_timer.h
2510 
2511 #include <cstdint>
2512 
2513 namespace Catch {
2514 
2515  auto getCurrentNanosecondsSinceEpoch() -> uint64_t;
2516  auto getEstimatedClockResolution() -> uint64_t;
2517 
2518  class Timer {
2519  uint64_t m_nanoseconds = 0;
2520  public:
2521  void start();
2522  auto getElapsedNanoseconds() const -> uint64_t;
2523  auto getElapsedMicroseconds() const -> uint64_t;
2524  auto getElapsedMilliseconds() const -> unsigned int;
2525  auto getElapsedSeconds() const -> double;
2526  };
2527 
2528 } // namespace Catch
2529 
2530 // end catch_timer.h
2531 #include <string>
2532 
2533 namespace Catch {
2534 
2536  public:
2537  Section( SectionInfo const& info );
2538  ~Section();
2539 
2540  // This indicates whether the section should be executed or not
2541  explicit operator bool() const;
2542 
2543  private:
2545 
2546  std::string m_name;
2550  };
2551 
2552 } // end namespace Catch
2553 
2554 #define INTERNAL_CATCH_SECTION( ... ) \
2555  CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
2556  if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
2557  CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
2558 
2559 #define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
2560  CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
2561  if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \
2562  CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
2563 
2564 // end catch_section.h
2565 // start catch_benchmark.h
2566 
2567 #include <cstdint>
2568 #include <string>
2569 
2570 namespace Catch {
2571 
2573 
2574  std::string m_name;
2575  std::size_t m_count = 0;
2576  std::size_t m_iterationsToRun = 1;
2577  uint64_t m_resolution;
2579 
2580  static auto getResolution() -> uint64_t;
2581  public:
2582  // Keep most of this inline as it's on the code path that is being timed
2584  : m_name( name ),
2585  m_resolution( getResolution() )
2586  {
2587  reportStart();
2588  m_timer.start();
2589  }
2590 
2591  explicit operator bool() {
2592  if( m_count < m_iterationsToRun )
2593  return true;
2594  return needsMoreIterations();
2595  }
2596 
2597  void increment() {
2598  ++m_count;
2599  }
2600 
2601  void reportStart();
2602  auto needsMoreIterations() -> bool;
2603  };
2604 
2605 } // end namespace Catch
2606 
2607 #define BENCHMARK( name ) \
2608  for( Catch::BenchmarkLooper looper( name ); looper; looper.increment() )
2609 
2610 // end catch_benchmark.h
2611 // start catch_interfaces_exception.h
2612 
2613 // start catch_interfaces_registry_hub.h
2614 
2615 #include <string>
2616 #include <memory>
2617 
2618 namespace Catch {
2619 
2620  class TestCase;
2621  struct ITestCaseRegistry;
2622  struct IExceptionTranslatorRegistry;
2623  struct IExceptionTranslator;
2624  struct IReporterRegistry;
2625  struct IReporterFactory;
2626  struct ITagAliasRegistry;
2627  class StartupExceptionRegistry;
2628 
2629  using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
2630 
2631  struct IRegistryHub {
2632  virtual ~IRegistryHub();
2633 
2634  virtual IReporterRegistry const& getReporterRegistry() const = 0;
2635  virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
2636  virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
2637 
2638  virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0;
2639 
2640  virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
2641  };
2642 
2644  virtual ~IMutableRegistryHub();
2645  virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0;
2646  virtual void registerListener( IReporterFactoryPtr const& factory ) = 0;
2647  virtual void registerTest( TestCase const& testInfo ) = 0;
2648  virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
2649  virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
2650  virtual void registerStartupException() noexcept = 0;
2651  };
2652 
2653  IRegistryHub const& getRegistryHub();
2655  void cleanUp();
2656  std::string translateActiveException();
2657 
2658 }
2659 
2660 // end catch_interfaces_registry_hub.h
2661 #if defined(CATCH_CONFIG_DISABLE)
2662  #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \
2663  static std::string translatorName( signature )
2664 #endif
2665 
2666 #include <exception>
2667 #include <string>
2668 #include <vector>
2669 
2670 namespace Catch {
2671  using exceptionTranslateFunction = std::string(*)();
2672 
2673  struct IExceptionTranslator;
2674  using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;
2675 
2677  virtual ~IExceptionTranslator();
2678  virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
2679  };
2680 
2682  virtual ~IExceptionTranslatorRegistry();
2683 
2684  virtual std::string translateActiveException() const = 0;
2685  };
2686 
2688  template<typename T>
2690  public:
2691 
2692  ExceptionTranslator( std::string(*translateFunction)( T& ) )
2693  : m_translateFunction( translateFunction )
2694  {}
2695 
2696  std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override {
2697  try {
2698  if( it == itEnd )
2699  std::rethrow_exception(std::current_exception());
2700  else
2701  return (*it)->translate( it+1, itEnd );
2702  }
2703  catch( T& ex ) {
2704  return m_translateFunction( ex );
2705  }
2706  }
2707 
2708  protected:
2709  std::string(*m_translateFunction)( T& );
2710  };
2711 
2712  public:
2713  template<typename T>
2714  ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
2716  ( new ExceptionTranslator<T>( translateFunction ) );
2717  }
2718  };
2719 }
2720 
2722 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
2723  static std::string translatorName( signature ); \
2724  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
2725  namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \
2726  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
2727  static std::string translatorName( signature )
2728 
2729 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
2730 
2731 // end catch_interfaces_exception.h
2732 // start catch_approx.h
2733 
2734 #include <type_traits>
2735 
2736 namespace Catch {
2737 namespace Detail {
2738 
2739  class Approx {
2740  private:
2741  bool equalityComparisonImpl(double other) const;
2742  // Validates the new margin (margin >= 0)
2743  // out-of-line to avoid including stdexcept in the header
2744  void setMargin(double margin);
2745  // Validates the new epsilon (0 < epsilon < 1)
2746  // out-of-line to avoid including stdexcept in the header
2747  void setEpsilon(double epsilon);
2748 
2749  public:
2750  explicit Approx ( double value );
2751 
2752  static Approx custom();
2753 
2754  Approx operator-() const;
2755 
2757  Approx operator()( T const& value ) {
2758  Approx approx( static_cast<double>(value) );
2759  approx.m_epsilon = m_epsilon;
2760  approx.m_margin = m_margin;
2761  approx.m_scale = m_scale;
2762  return approx;
2763  }
2764 
2766  explicit Approx( T const& value ): Approx(static_cast<double>(value))
2767  {}
2768 
2770  friend bool operator == ( const T& lhs, Approx const& rhs ) {
2771  auto lhs_v = static_cast<double>(lhs);
2772  return rhs.equalityComparisonImpl(lhs_v);
2773  }
2774 
2776  friend bool operator == ( Approx const& lhs, const T& rhs ) {
2777  return operator==( rhs, lhs );
2778  }
2779 
2781  friend bool operator != ( T const& lhs, Approx const& rhs ) {
2782  return !operator==( lhs, rhs );
2783  }
2784 
2786  friend bool operator != ( Approx const& lhs, T const& rhs ) {
2787  return !operator==( rhs, lhs );
2788  }
2789 
2791  friend bool operator <= ( T const& lhs, Approx const& rhs ) {
2792  return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;
2793  }
2794 
2796  friend bool operator <= ( Approx const& lhs, T const& rhs ) {
2797  return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
2798  }
2799 
2801  friend bool operator >= ( T const& lhs, Approx const& rhs ) {
2802  return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;
2803  }
2804 
2806  friend bool operator >= ( Approx const& lhs, T const& rhs ) {
2807  return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
2808  }
2809 
2811  Approx& epsilon( T const& newEpsilon ) {
2812  double epsilonAsDouble = static_cast<double>(newEpsilon);
2813  setEpsilon(epsilonAsDouble);
2814  return *this;
2815  }
2816 
2818  Approx& margin( T const& newMargin ) {
2819  double marginAsDouble = static_cast<double>(newMargin);
2820  setMargin(marginAsDouble);
2821  return *this;
2822  }
2823 
2825  Approx& scale( T const& newScale ) {
2826  m_scale = static_cast<double>(newScale);
2827  return *this;
2828  }
2829 
2830  std::string toString() const;
2831 
2832  private:
2833  double m_epsilon;
2834  double m_margin;
2835  double m_scale;
2836  double m_value;
2837  };
2838 } // end namespace Detail
2839 
2840 namespace literals {
2841  Detail::Approx operator "" _a(long double val);
2842  Detail::Approx operator "" _a(unsigned long long val);
2843 } // end namespace literals
2844 
2845 template<>
2847  static std::string convert(Catch::Detail::Approx const& value);
2848 };
2849 
2850 } // end namespace Catch
2851 
2852 // end catch_approx.h
2853 // start catch_string_manip.h
2854 
2855 #include <string>
2856 #include <iosfwd>
2857 
2858 namespace Catch {
2859 
2860  bool startsWith( std::string const& s, std::string const& prefix );
2861  bool startsWith( std::string const& s, char prefix );
2862  bool endsWith( std::string const& s, std::string const& suffix );
2863  bool endsWith( std::string const& s, char suffix );
2864  bool contains( std::string const& s, std::string const& infix );
2865  void toLowerInPlace( std::string& s );
2866  std::string toLower( std::string const& s );
2867  std::string trim( std::string const& str );
2868  bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
2869 
2870  struct pluralise {
2871  pluralise( std::size_t count, std::string const& label );
2872 
2873  friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
2874 
2875  std::size_t m_count;
2876  std::string m_label;
2877  };
2878 }
2879 
2880 // end catch_string_manip.h
2881 #ifndef CATCH_CONFIG_DISABLE_MATCHERS
2882 // start catch_capture_matchers.h
2883 
2884 // start catch_matchers.h
2885 
2886 #include <string>
2887 #include <vector>
2888 
2889 namespace Catch {
2890 namespace Matchers {
2891  namespace Impl {
2892 
2893  template<typename ArgT> struct MatchAllOf;
2894  template<typename ArgT> struct MatchAnyOf;
2895  template<typename ArgT> struct MatchNotOf;
2896 
2898  public:
2899  MatcherUntypedBase() = default;
2900  MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
2901  MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete;
2902  std::string toString() const;
2903 
2904  protected:
2905  virtual ~MatcherUntypedBase();
2906  virtual std::string describe() const = 0;
2907  mutable std::string m_cachedToString;
2908  };
2909 
2910 #ifdef __clang__
2911 # pragma clang diagnostic push
2912 # pragma clang diagnostic ignored "-Wnon-virtual-dtor"
2913 #endif
2914 
2915  template<typename ObjectT>
2916  struct MatcherMethod {
2917  virtual bool match( ObjectT const& arg ) const = 0;
2918  };
2919 
2920 #ifdef __clang__
2921 # pragma clang diagnostic pop
2922 #endif
2923 
2924  template<typename T>
2926 
2927  MatchAllOf<T> operator && ( MatcherBase const& other ) const;
2928  MatchAnyOf<T> operator || ( MatcherBase const& other ) const;
2929  MatchNotOf<T> operator ! () const;
2930  };
2931 
2932  template<typename ArgT>
2933  struct MatchAllOf : MatcherBase<ArgT> {
2934  bool match( ArgT const& arg ) const override {
2935  for( auto matcher : m_matchers ) {
2936  if (!matcher->match(arg))
2937  return false;
2938  }
2939  return true;
2940  }
2941  std::string describe() const override {
2942  std::string description;
2943  description.reserve( 4 + m_matchers.size()*32 );
2944  description += "( ";
2945  bool first = true;
2946  for( auto matcher : m_matchers ) {
2947  if( first )
2948  first = false;
2949  else
2950  description += " and ";
2951  description += matcher->toString();
2952  }
2953  description += " )";
2954  return description;
2955  }
2956 
2957  MatchAllOf<ArgT>& operator && ( MatcherBase<ArgT> const& other ) {
2958  m_matchers.push_back( &other );
2959  return *this;
2960  }
2961 
2962  std::vector<MatcherBase<ArgT> const*> m_matchers;
2963  };
2964  template<typename ArgT>
2965  struct MatchAnyOf : MatcherBase<ArgT> {
2966 
2967  bool match( ArgT const& arg ) const override {
2968  for( auto matcher : m_matchers ) {
2969  if (matcher->match(arg))
2970  return true;
2971  }
2972  return false;
2973  }
2974  std::string describe() const override {
2975  std::string description;
2976  description.reserve( 4 + m_matchers.size()*32 );
2977  description += "( ";
2978  bool first = true;
2979  for( auto matcher : m_matchers ) {
2980  if( first )
2981  first = false;
2982  else
2983  description += " or ";
2984  description += matcher->toString();
2985  }
2986  description += " )";
2987  return description;
2988  }
2989 
2990  MatchAnyOf<ArgT>& operator || ( MatcherBase<ArgT> const& other ) {
2991  m_matchers.push_back( &other );
2992  return *this;
2993  }
2994 
2995  std::vector<MatcherBase<ArgT> const*> m_matchers;
2996  };
2997 
2998  template<typename ArgT>
2999  struct MatchNotOf : MatcherBase<ArgT> {
3000 
3001  MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
3002 
3003  bool match( ArgT const& arg ) const override {
3004  return !m_underlyingMatcher.match( arg );
3005  }
3006 
3007  std::string describe() const override {
3008  return "not " + m_underlyingMatcher.toString();
3009  }
3011  };
3012 
3013  template<typename T>
3015  return MatchAllOf<T>() && *this && other;
3016  }
3017  template<typename T>
3019  return MatchAnyOf<T>() || *this || other;
3020  }
3021  template<typename T>
3023  return MatchNotOf<T>( *this );
3024  }
3025 
3026  } // namespace Impl
3027 
3028 } // namespace Matchers
3029 
3030 using namespace Matchers;
3032 
3033 } // namespace Catch
3034 
3035 // end catch_matchers.h
3036 // start catch_matchers_floating.h
3037 
3038 #include <type_traits>
3039 #include <cmath>
3040 
3041 namespace Catch {
3042 namespace Matchers {
3043 
3044  namespace Floating {
3045 
3046  enum class FloatingPointKind : uint8_t;
3047 
3048  struct WithinAbsMatcher : MatcherBase<double> {
3049  WithinAbsMatcher(double target, double margin);
3050  bool match(double const& matchee) const override;
3051  std::string describe() const override;
3052  private:
3053  double m_target;
3054  double m_margin;
3055  };
3056 
3057  struct WithinUlpsMatcher : MatcherBase<double> {
3058  WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType);
3059  bool match(double const& matchee) const override;
3060  std::string describe() const override;
3061  private:
3062  double m_target;
3063  int m_ulps;
3064  FloatingPointKind m_type;
3065  };
3066 
3067  } // namespace Floating
3068 
3069  // The following functions create the actual matcher objects.
3070  // This allows the types to be inferred
3071  Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff);
3072  Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff);
3073  Floating::WithinAbsMatcher WithinAbs(double target, double margin);
3074 
3075 } // namespace Matchers
3076 } // namespace Catch
3077 
3078 // end catch_matchers_floating.h
3079 // start catch_matchers_generic.hpp
3080 
3081 #include <functional>
3082 #include <string>
3083 
3084 namespace Catch {
3085 namespace Matchers {
3086 namespace Generic {
3087 
3088 namespace Detail {
3089  std::string finalizeDescription(const std::string& desc);
3090 }
3091 
3092 template <typename T>
3093 class PredicateMatcher : public MatcherBase<T> {
3094  std::function<bool(T const&)> m_predicate;
3095  std::string m_description;
3096 public:
3097 
3098  PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr)
3099  :m_predicate(std::move(elem)),
3100  m_description(Detail::finalizeDescription(descr))
3101  {}
3102 
3103  bool match( T const& item ) const override {
3104  return m_predicate(item);
3105  }
3106 
3107  std::string describe() const override {
3108  return m_description;
3109  }
3110 };
3111 
3112 } // namespace Generic
3113 
3114  // The following functions create the actual matcher objects.
3115  // The user has to explicitly specify type to the function, because
3116  // infering std::function<bool(T const&)> is hard (but possible) and
3117  // requires a lot of TMP.
3118  template<typename T>
3119  Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") {
3120  return Generic::PredicateMatcher<T>(predicate, description);
3121  }
3122 
3123 } // namespace Matchers
3124 } // namespace Catch
3125 
3126 // end catch_matchers_generic.hpp
3127 // start catch_matchers_string.h
3128 
3129 #include <string>
3130 
3131 namespace Catch {
3132 namespace Matchers {
3133 
3134  namespace StdString {
3135 
3137  {
3138  CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );
3139  std::string adjustString( std::string const& str ) const;
3140  std::string caseSensitivitySuffix() const;
3141 
3143  std::string m_str;
3144  };
3145 
3146  struct StringMatcherBase : MatcherBase<std::string> {
3147  StringMatcherBase( std::string const& operation, CasedString const& comparator );
3148  std::string describe() const override;
3149 
3151  std::string m_operation;
3152  };
3153 
3155  EqualsMatcher( CasedString const& comparator );
3156  bool match( std::string const& source ) const override;
3157  };
3159  ContainsMatcher( CasedString const& comparator );
3160  bool match( std::string const& source ) const override;
3161  };
3163  StartsWithMatcher( CasedString const& comparator );
3164  bool match( std::string const& source ) const override;
3165  };
3167  EndsWithMatcher( CasedString const& comparator );
3168  bool match( std::string const& source ) const override;
3169  };
3170 
3171  struct RegexMatcher : MatcherBase<std::string> {
3172  RegexMatcher( std::string regex, CaseSensitive::Choice caseSensitivity );
3173  bool match( std::string const& matchee ) const override;
3174  std::string describe() const override;
3175 
3176  private:
3177  std::string m_regex;
3179  };
3180 
3181  } // namespace StdString
3182 
3183  // The following functions create the actual matcher objects.
3184  // This allows the types to be inferred
3185 
3186  StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3187  StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3188  StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3189  StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3190  StdString::RegexMatcher Matches( std::string const& regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
3191 
3192 } // namespace Matchers
3193 } // namespace Catch
3194 
3195 // end catch_matchers_string.h
3196 // start catch_matchers_vector.h
3197 
3198 #include <algorithm>
3199 
3200 namespace Catch {
3201 namespace Matchers {
3202 
3203  namespace Vector {
3204  namespace Detail {
3205  template <typename InputIterator, typename T>
3206  size_t count(InputIterator first, InputIterator last, T const& item) {
3207  size_t cnt = 0;
3208  for (; first != last; ++first) {
3209  if (*first == item) {
3210  ++cnt;
3211  }
3212  }
3213  return cnt;
3214  }
3215  template <typename InputIterator, typename T>
3216  bool contains(InputIterator first, InputIterator last, T const& item) {
3217  for (; first != last; ++first) {
3218  if (*first == item) {
3219  return true;
3220  }
3221  }
3222  return false;
3223  }
3224  }
3225 
3226  template<typename T>
3227  struct ContainsElementMatcher : MatcherBase<std::vector<T>> {
3228 
3229  ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
3230 
3231  bool match(std::vector<T> const &v) const override {
3232  for (auto const& el : v) {
3233  if (el == m_comparator) {
3234  return true;
3235  }
3236  }
3237  return false;
3238  }
3239 
3240  std::string describe() const override {
3241  return "Contains: " + ::Catch::Detail::stringify( m_comparator );
3242  }
3243 
3244  T const& m_comparator;
3245  };
3246 
3247  template<typename T>
3248  struct ContainsMatcher : MatcherBase<std::vector<T>> {
3249 
3250  ContainsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
3251 
3252  bool match(std::vector<T> const &v) const override {
3253  // !TBD: see note in EqualsMatcher
3254  if (m_comparator.size() > v.size())
3255  return false;
3256  for (auto const& comparator : m_comparator) {
3257  auto present = false;
3258  for (const auto& el : v) {
3259  if (el == comparator) {
3260  present = true;
3261  break;
3262  }
3263  }
3264  if (!present) {
3265  return false;
3266  }
3267  }
3268  return true;
3269  }
3270  std::string describe() const override {
3271  return "Contains: " + ::Catch::Detail::stringify( m_comparator );
3272  }
3273 
3274  std::vector<T> const& m_comparator;
3275  };
3276 
3277  template<typename T>
3278  struct EqualsMatcher : MatcherBase<std::vector<T>> {
3279 
3280  EqualsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
3281 
3282  bool match(std::vector<T> const &v) const override {
3283  // !TBD: This currently works if all elements can be compared using !=
3284  // - a more general approach would be via a compare template that defaults
3285  // to using !=. but could be specialised for, e.g. std::vector<T> etc
3286  // - then just call that directly
3287  if (m_comparator.size() != v.size())
3288  return false;
3289  for (std::size_t i = 0; i < v.size(); ++i)
3290  if (m_comparator[i] != v[i])
3291  return false;
3292  return true;
3293  }
3294  std::string describe() const override {
3295  return "Equals: " + ::Catch::Detail::stringify( m_comparator );
3296  }
3297  std::vector<T> const& m_comparator;
3298  };
3299 
3300  template<typename T>
3301  struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>> {
3302  UnorderedEqualsMatcher(std::vector<T> const& target) : m_target(target) {}
3303  bool match(std::vector<T> const& vec) const override {
3304  // Note: This is a reimplementation of std::is_permutation,
3305  // because I don't want to include <algorithm> inside the common path
3306  if (m_target.size() != vec.size()) {
3307  return false;
3308  }
3309  auto lfirst = m_target.begin(), llast = m_target.end();
3310  auto rfirst = vec.begin(), rlast = vec.end();
3311  // Cut common prefix to optimize checking of permuted parts
3312  while (lfirst != llast && *lfirst == *rfirst) {
3313  ++lfirst; ++rfirst;
3314  }
3315  if (lfirst == llast) {
3316  return true;
3317  }
3318 
3319  for (auto mid = lfirst; mid != llast; ++mid) {
3320  // Skip already counted items
3321  if (Detail::contains(lfirst, mid, *mid)) {
3322  continue;
3323  }
3324  size_t num_vec = Detail::count(rfirst, rlast, *mid);
3325  if (num_vec == 0 || Detail::count(lfirst, llast, *mid) != num_vec) {
3326  return false;
3327  }
3328  }
3329 
3330  return true;
3331  }
3332 
3333  std::string describe() const override {
3334  return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
3335  }
3336  private:
3337  std::vector<T> const& m_target;
3338  };
3339 
3340  } // namespace Vector
3341 
3342  // The following functions create the actual matcher objects.
3343  // This allows the types to be inferred
3344 
3345  template<typename T>
3346  Vector::ContainsMatcher<T> Contains( std::vector<T> const& comparator ) {
3347  return Vector::ContainsMatcher<T>( comparator );
3348  }
3349 
3350  template<typename T>
3352  return Vector::ContainsElementMatcher<T>( comparator );
3353  }
3354 
3355  template<typename T>
3356  Vector::EqualsMatcher<T> Equals( std::vector<T> const& comparator ) {
3357  return Vector::EqualsMatcher<T>( comparator );
3358  }
3359 
3360  template<typename T>
3361  Vector::UnorderedEqualsMatcher<T> UnorderedEquals(std::vector<T> const& target) {
3362  return Vector::UnorderedEqualsMatcher<T>(target);
3363  }
3364 
3365 } // namespace Matchers
3366 } // namespace Catch
3367 
3368 // end catch_matchers_vector.h
3369 namespace Catch {
3370 
3371  template<typename ArgT, typename MatcherT>
3373  ArgT const& m_arg;
3374  MatcherT m_matcher;
3376  public:
3377  MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString )
3378  : ITransientExpression{ true, matcher.match( arg ) },
3379  m_arg( arg ),
3380  m_matcher( matcher ),
3381  m_matcherString( matcherString )
3382  {}
3383 
3384  void streamReconstructedExpression( std::ostream &os ) const override {
3385  auto matcherAsString = m_matcher.toString();
3386  os << Catch::Detail::stringify( m_arg ) << ' ';
3387  if( matcherAsString == Detail::unprintableString )
3388  os << m_matcherString;
3389  else
3390  os << matcherAsString;
3391  }
3392  };
3393 
3395 
3396  void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString );
3397 
3398  template<typename ArgT, typename MatcherT>
3399  auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString ) -> MatchExpr<ArgT, MatcherT> {
3400  return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );
3401  }
3402 
3403 } // namespace Catch
3404 
3406 #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
3407  do { \
3408  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
3409  INTERNAL_CATCH_TRY { \
3410  catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \
3411  } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
3412  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
3413  } while( false )
3414 
3416 #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
3417  do { \
3418  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
3419  if( catchAssertionHandler.allowThrows() ) \
3420  try { \
3421  static_cast<void>(__VA_ARGS__ ); \
3422  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
3423  } \
3424  catch( exceptionType const& ex ) { \
3425  catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \
3426  } \
3427  catch( ... ) { \
3428  catchAssertionHandler.handleUnexpectedInflightException(); \
3429  } \
3430  else \
3431  catchAssertionHandler.handleThrowingCallSkipped(); \
3432  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
3433  } while( false )
3434 
3435 // end catch_capture_matchers.h
3436 #endif
3437 // start catch_generators.hpp
3438 
3439 // start catch_interfaces_generatortracker.h
3440 
3441 
3442 #include <memory>
3443 
3444 namespace Catch {
3445 
3446  namespace Generators {
3448  public:
3449  GeneratorUntypedBase() = default;
3450  virtual ~GeneratorUntypedBase();
3451  // Attempts to move the generator to the next element
3452  //
3453  // Returns true iff the move succeeded (and a valid element
3454  // can be retrieved).
3455  virtual bool next() = 0;
3456  };
3457  using GeneratorBasePtr = std::unique_ptr<GeneratorUntypedBase>;
3458 
3459  } // namespace Generators
3460 
3462  virtual ~IGeneratorTracker();
3463  virtual auto hasGenerator() const -> bool = 0;
3464  virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;
3465  virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0;
3466  };
3467 
3468 } // namespace Catch
3469 
3470 // end catch_interfaces_generatortracker.h
3471 // start catch_enforce.h
3472 
3473 #include <stdexcept>
3474 
3475 namespace Catch {
3476 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
3477  template <typename Ex>
3478  [[noreturn]]
3479  void throw_exception(Ex const& e) {
3480  throw e;
3481  }
3482 #else // ^^ Exceptions are enabled // Exceptions are disabled vv
3483  [[noreturn]]
3484  void throw_exception(std::exception const& e);
3485 #endif
3486 } // namespace Catch;
3487 
3488 #define CATCH_PREPARE_EXCEPTION( type, msg ) \
3489  type( ( Catch::ReusableStringStream() << msg ).str() )
3490 #define CATCH_INTERNAL_ERROR( msg ) \
3491  Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg))
3492 #define CATCH_ERROR( msg ) \
3493  Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::domain_error, msg ))
3494 #define CATCH_RUNTIME_ERROR( msg ) \
3495  Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::runtime_error, msg ))
3496 #define CATCH_ENFORCE( condition, msg ) \
3497  do{ if( !(condition) ) CATCH_ERROR( msg ); } while(false)
3498 
3499 // end catch_enforce.h
3500 #include <memory>
3501 #include <vector>
3502 #include <cassert>
3503 
3504 #include <utility>
3505 #include <exception>
3506 
3507 namespace Catch {
3508 
3509 class GeneratorException : public std::exception {
3510  const char* const m_msg = "";
3511 
3512 public:
3513  GeneratorException(const char* msg):
3514  m_msg(msg)
3515  {}
3516 
3517  const char* what() const noexcept override final;
3518 };
3519 
3520 namespace Generators {
3521 
3522  // !TBD move this into its own location?
3523  namespace pf{
3524  template<typename T, typename... Args>
3525  std::unique_ptr<T> make_unique( Args&&... args ) {
3526  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
3527  }
3528  }
3529 
3530  template<typename T>
3532  virtual ~IGenerator() = default;
3533 
3534  // Returns the current element of the generator
3535  //
3536  // \Precondition The generator is either freshly constructed,
3537  // or the last call to `next()` returned true
3538  virtual T const& get() const = 0;
3539  using type = T;
3540  };
3541 
3542  template<typename T>
3543  class SingleValueGenerator final : public IGenerator<T> {
3545  public:
3546  SingleValueGenerator(T const& value) : m_value( value ) {}
3547  SingleValueGenerator(T&& value) : m_value(std::move(value)) {}
3548 
3549  T const& get() const override {
3550  return m_value;
3551  }
3552  bool next() override {
3553  return false;
3554  }
3555  };
3556 
3557  template<typename T>
3558  class FixedValuesGenerator final : public IGenerator<T> {
3559  std::vector<T> m_values;
3560  size_t m_idx = 0;
3561  public:
3562  FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {}
3563 
3564  T const& get() const override {
3565  return m_values[m_idx];
3566  }
3567  bool next() override {
3568  ++m_idx;
3569  return m_idx < m_values.size();
3570  }
3571  };
3572 
3573  template <typename T>
3574  class GeneratorWrapper final {
3575  std::unique_ptr<IGenerator<T>> m_generator;
3576  public:
3577  GeneratorWrapper(std::unique_ptr<IGenerator<T>> generator):
3578  m_generator(std::move(generator))
3579  {}
3580  T const& get() const {
3581  return m_generator->get();
3582  }
3583  bool next() {
3584  return m_generator->next();
3585  }
3586  };
3587 
3588  template <typename T>
3590  return GeneratorWrapper<T>(pf::make_unique<SingleValueGenerator<T>>(std::forward<T>(value)));
3591  }
3592  template <typename T>
3593  GeneratorWrapper<T> values(std::initializer_list<T> values) {
3594  return GeneratorWrapper<T>(pf::make_unique<FixedValuesGenerator<T>>(values));
3595  }
3596 
3597  template<typename T>
3598  class Generators : public IGenerator<T> {
3599  std::vector<GeneratorWrapper<T>> m_generators;
3600  size_t m_current = 0;
3601 
3602  void populate(GeneratorWrapper<T>&& generator) {
3603  m_generators.emplace_back(std::move(generator));
3604  }
3605  void populate(T&& val) {
3606  m_generators.emplace_back(value(std::move(val)));
3607  }
3608  template<typename U>
3609  void populate(U&& val) {
3610  populate(T(std::move(val)));
3611  }
3612  template<typename U, typename... Gs>
3613  void populate(U&& valueOrGenerator, Gs... moreGenerators) {
3614  populate(std::forward<U>(valueOrGenerator));
3615  populate(std::forward<Gs>(moreGenerators)...);
3616  }
3617 
3618  public:
3619  template <typename... Gs>
3620  Generators(Gs... moreGenerators) {
3621  m_generators.reserve(sizeof...(Gs));
3622  populate(std::forward<Gs>(moreGenerators)...);
3623  }
3624 
3625  T const& get() const override {
3626  return m_generators[m_current].get();
3627  }
3628 
3629  bool next() override {
3630  if (m_current >= m_generators.size()) {
3631  return false;
3632  }
3633  const bool current_status = m_generators[m_current].next();
3634  if (!current_status) {
3635  ++m_current;
3636  }
3637  return m_current < m_generators.size();
3638  }
3639  };
3640 
3641  template<typename... Ts>
3642  GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std::tuple<typename std::decay<Ts>::type...>> tuples ) {
3643  return values<std::tuple<Ts...>>( tuples );
3644  }
3645 
3646  // Tag type to signal that a generator sequence should convert arguments to a specific type
3647  template <typename T>
3648  struct as {};
3649 
3650  template<typename T, typename... Gs>
3651  auto makeGenerators( GeneratorWrapper<T>&& generator, Gs... moreGenerators ) -> Generators<T> {
3652  return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...);
3653  }
3654  template<typename T>
3656  return Generators<T>(std::move(generator));
3657  }
3658  template<typename T, typename... Gs>
3659  auto makeGenerators( T&& val, Gs... moreGenerators ) -> Generators<T> {
3660  return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );
3661  }
3662  template<typename T, typename U, typename... Gs>
3663  auto makeGenerators( as<T>, U&& val, Gs... moreGenerators ) -> Generators<T> {
3664  return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );
3665  }
3666 
3667  auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
3668 
3669  template<typename L>
3670  // Note: The type after -> is weird, because VS2015 cannot parse
3671  // the expression used in the typedef inside, when it is in
3672  // return type. Yeah.
3673  auto generate( SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) {
3674  using UnderlyingType = typename decltype(generatorExpression())::type;
3675 
3676  IGeneratorTracker& tracker = acquireGeneratorTracker( lineInfo );
3677  if (!tracker.hasGenerator()) {
3678  tracker.setGenerator(pf::make_unique<Generators<UnderlyingType>>(generatorExpression()));
3679  }
3680 
3681  auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() );
3682  return generator.get();
3683  }
3684 
3685 } // namespace Generators
3686 } // namespace Catch
3687 
3688 #define GENERATE( ... ) \
3689  Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, []{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
3690 
3691 // end catch_generators.hpp
3692 // start catch_generators_generic.hpp
3693 
3694 namespace Catch {
3695 namespace Generators {
3696 
3697  template <typename T>
3698  class TakeGenerator : public IGenerator<T> {
3700  size_t m_returned = 0;
3701  size_t m_target;
3702  public:
3703  TakeGenerator(size_t target, GeneratorWrapper<T>&& generator):
3704  m_generator(std::move(generator)),
3705  m_target(target)
3706  {
3707  assert(target != 0 && "Empty generators are not allowed");
3708  }
3709  T const& get() const override {
3710  return m_generator.get();
3711  }
3712  bool next() override {
3713  ++m_returned;
3714  if (m_returned >= m_target) {
3715  return false;
3716  }
3717 
3718  const auto success = m_generator.next();
3719  // If the underlying generator does not contain enough values
3720  // then we cut short as well
3721  if (!success) {
3722  m_returned = m_target;
3723  }
3724  return success;
3725  }
3726  };
3727 
3728  template <typename T>
3729  GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T>&& generator) {
3730  return GeneratorWrapper<T>(pf::make_unique<TakeGenerator<T>>(target, std::move(generator)));
3731  }
3732 
3733  template <typename T, typename Predicate>
3734  class FilterGenerator : public IGenerator<T> {
3737  public:
3738  template <typename P = Predicate>
3739  FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator):
3740  m_generator(std::move(generator)),
3741  m_predicate(std::forward<P>(pred))
3742  {
3743  if (!m_predicate(m_generator.get())) {
3744  // It might happen that there are no values that pass the
3745  // filter. In that case we throw an exception.
3746  auto has_initial_value = next();
3747  if (!has_initial_value) {
3748  Catch::throw_exception(GeneratorException("No valid value found in filtered generator"));
3749  }
3750  }
3751  }
3752 
3753  T const& get() const override {
3754  return m_generator.get();
3755  }
3756 
3757  bool next() override {
3758  bool success = m_generator.next();
3759  if (!success) {
3760  return false;
3761  }
3762  while (!m_predicate(m_generator.get()) && (success = m_generator.next()) == true);
3763  return success;
3764  }
3765  };
3766 
3767  template <typename T, typename Predicate>
3769  return GeneratorWrapper<T>(std::unique_ptr<IGenerator<T>>(pf::make_unique<FilterGenerator<T, Predicate>>(std::forward<Predicate>(pred), std::move(generator))));
3770  }
3771 
3772  template <typename T>
3773  class RepeatGenerator : public IGenerator<T> {
3775  mutable std::vector<T> m_returned;
3777  size_t m_current_repeat = 0;
3778  size_t m_repeat_index = 0;
3779  public:
3780  RepeatGenerator(size_t repeats, GeneratorWrapper<T>&& generator):
3781  m_generator(std::move(generator)),
3782  m_target_repeats(repeats)
3783  {
3784  assert(m_target_repeats > 0 && "Repeat generator must repeat at least once");
3785  }
3786 
3787  T const& get() const override {
3788  if (m_current_repeat == 0) {
3789  m_returned.push_back(m_generator.get());
3790  return m_returned.back();
3791  }
3792  return m_returned[m_repeat_index];
3793  }
3794 
3795  bool next() override {
3796  // There are 2 basic cases:
3797  // 1) We are still reading the generator
3798  // 2) We are reading our own cache
3799 
3800  // In the first case, we need to poke the underlying generator.
3801  // If it happily moves, we are left in that state, otherwise it is time to start reading from our cache
3802  if (m_current_repeat == 0) {
3803  const auto success = m_generator.next();
3804  if (!success) {
3805  ++m_current_repeat;
3806  }
3807  return m_current_repeat < m_target_repeats;
3808  }
3809 
3810  // In the second case, we need to move indices forward and check that we haven't run up against the end
3811  ++m_repeat_index;
3812  if (m_repeat_index == m_returned.size()) {
3813  m_repeat_index = 0;
3814  ++m_current_repeat;
3815  }
3816  return m_current_repeat < m_target_repeats;
3817  }
3818  };
3819 
3820  template <typename T>
3821  GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T>&& generator) {
3822  return GeneratorWrapper<T>(pf::make_unique<RepeatGenerator<T>>(repeats, std::move(generator)));
3823  }
3824 
3825  template <typename T, typename U, typename Func>
3826  class MapGenerator : public IGenerator<T> {
3827  // TBD: provide static assert for mapping function, for friendly error message
3830  // To avoid returning dangling reference, we have to save the values
3832  public:
3833  template <typename F2 = Func>
3834  MapGenerator(F2&& function, GeneratorWrapper<U>&& generator) :
3835  m_generator(std::move(generator)),
3836  m_function(std::forward<F2>(function)),
3837  m_cache(m_function(m_generator.get()))
3838  {}
3839 
3840  T const& get() const override {
3841  return m_cache;
3842  }
3843  bool next() override {
3844  const auto success = m_generator.next();
3845  if (success) {
3846  m_cache = m_function(m_generator.get());
3847  }
3848  return success;
3849  }
3850  };
3851 
3852  template <typename T, typename U, typename Func>
3853  GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
3854  return GeneratorWrapper<T>(
3855  pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
3856  );
3857  }
3858  template <typename T, typename Func>
3859  GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<T>&& generator) {
3860  return GeneratorWrapper<T>(
3861  pf::make_unique<MapGenerator<T, T, Func>>(std::forward<Func>(function), std::move(generator))
3862  );
3863  }
3864 
3865  template <typename T>
3866  class ChunkGenerator final : public IGenerator<std::vector<T>> {
3867  std::vector<T> m_chunk;
3870  bool m_used_up = false;
3871  public:
3872  ChunkGenerator(size_t size, GeneratorWrapper<T> generator) :
3873  m_chunk_size(size), m_generator(std::move(generator))
3874  {
3875  m_chunk.reserve(m_chunk_size);
3876  m_chunk.push_back(m_generator.get());
3877  for (size_t i = 1; i < m_chunk_size; ++i) {
3878  if (!m_generator.next()) {
3879  Catch::throw_exception(GeneratorException("Not enough values to initialize the first chunk"));
3880  }
3881  m_chunk.push_back(m_generator.get());
3882  }
3883  }
3884  std::vector<T> const& get() const override {
3885  return m_chunk;
3886  }
3887  bool next() override {
3888  m_chunk.clear();
3889  for (size_t idx = 0; idx < m_chunk_size; ++idx) {
3890  if (!m_generator.next()) {
3891  return false;
3892  }
3893  m_chunk.push_back(m_generator.get());
3894  }
3895  return true;
3896  }
3897  };
3898 
3899  template <typename T>
3902  pf::make_unique<ChunkGenerator<T>>(size, std::move(generator))
3903  );
3904  }
3905 
3906 } // namespace Generators
3907 } // namespace Catch
3908 
3909 // end catch_generators_generic.hpp
3910 // start catch_generators_specific.hpp
3911 
3912 // start catch_context.h
3913 
3914 #include <memory>
3915 
3916 namespace Catch {
3917 
3918  struct IResultCapture;
3919  struct IRunner;
3920  struct IConfig;
3921  struct IMutableContext;
3922 
3923  using IConfigPtr = std::shared_ptr<IConfig const>;
3924 
3925  struct IContext
3926  {
3927  virtual ~IContext();
3928 
3929  virtual IResultCapture* getResultCapture() = 0;
3930  virtual IRunner* getRunner() = 0;
3931  virtual IConfigPtr const& getConfig() const = 0;
3932  };
3933 
3935  {
3936  virtual ~IMutableContext();
3937  virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
3938  virtual void setRunner( IRunner* runner ) = 0;
3939  virtual void setConfig( IConfigPtr const& config ) = 0;
3940 
3941  private:
3944  friend void cleanUpContext();
3945  static void createContext();
3946  };
3947 
3949  {
3953  }
3954 
3956  {
3957  return getCurrentMutableContext();
3958  }
3959 
3960  void cleanUpContext();
3961 }
3962 
3963 // end catch_context.h
3964 // start catch_interfaces_config.h
3965 
3966 #include <iosfwd>
3967 #include <string>
3968 #include <vector>
3969 #include <memory>
3970 
3971 namespace Catch {
3972 
3973  enum class Verbosity {
3974  Quiet = 0,
3975  Normal,
3976  High
3977  };
3978 
3979  struct WarnAbout { enum What {
3980  Nothing = 0x00,
3981  NoAssertions = 0x01,
3982  NoTests = 0x02
3983  }; };
3984 
3985  struct ShowDurations { enum OrNot {
3988  Never
3989  }; };
3990  struct RunTests { enum InWhatOrder {
3993  InRandomOrder
3994  }; };
3995  struct UseColour { enum YesOrNo {
3998  No
3999  }; };
4000  struct WaitForKeypress { enum When {
4002  BeforeStart = 1,
4003  BeforeExit = 2,
4004  BeforeStartAndExit = BeforeStart | BeforeExit
4005  }; };
4006 
4007  class TestSpec;
4008 
4010 
4011  virtual ~IConfig();
4012 
4013  virtual bool allowThrows() const = 0;
4014  virtual std::ostream& stream() const = 0;
4015  virtual std::string name() const = 0;
4016  virtual bool includeSuccessfulResults() const = 0;
4017  virtual bool shouldDebugBreak() const = 0;
4018  virtual bool warnAboutMissingAssertions() const = 0;
4019  virtual bool warnAboutNoTests() const = 0;
4020  virtual int abortAfter() const = 0;
4021  virtual bool showInvisibles() const = 0;
4022  virtual ShowDurations::OrNot showDurations() const = 0;
4023  virtual TestSpec const& testSpec() const = 0;
4024  virtual bool hasTestFilters() const = 0;
4025  virtual RunTests::InWhatOrder runOrder() const = 0;
4026  virtual unsigned int rngSeed() const = 0;
4027  virtual int benchmarkResolutionMultiple() const = 0;
4028  virtual UseColour::YesOrNo useColour() const = 0;
4029  virtual std::vector<std::string> const& getSectionsToRun() const = 0;
4030  virtual Verbosity verbosity() const = 0;
4031  };
4032 
4033  using IConfigPtr = std::shared_ptr<IConfig const>;
4034 }
4035 
4036 // end catch_interfaces_config.h
4037 #include <random>
4038 
4039 namespace Catch {
4040 namespace Generators {
4041 
4042 template <typename Float>
4043 class RandomFloatingGenerator final : public IGenerator<Float> {
4044  // FIXME: What is the right seed?
4045  std::minstd_rand m_rand;
4046  std::uniform_real_distribution<Float> m_dist;
4048 public:
4049 
4050  RandomFloatingGenerator(Float a, Float b):
4051  m_rand(getCurrentContext().getConfig()->rngSeed()),
4052  m_dist(a, b) {
4053  static_cast<void>(next());
4054  }
4055 
4056  Float const& get() const override {
4057  return m_current_number;
4058  }
4059  bool next() override {
4060  m_current_number = m_dist(m_rand);
4061  return true;
4062  }
4063 };
4064 
4065 template <typename Integer>
4066 class RandomIntegerGenerator final : public IGenerator<Integer> {
4067  std::minstd_rand m_rand;
4068  std::uniform_int_distribution<Integer> m_dist;
4070 public:
4071 
4072  RandomIntegerGenerator(Integer a, Integer b):
4073  m_rand(getCurrentContext().getConfig()->rngSeed()),
4074  m_dist(a, b) {
4075  static_cast<void>(next());
4076  }
4077 
4078  Integer const& get() const override {
4079  return m_current_number;
4080  }
4081  bool next() override {
4082  m_current_number = m_dist(m_rand);
4083  return true;
4084  }
4085 };
4086 
4087 // TODO: Ideally this would be also constrained against the various char types,
4088 // but I don't expect users to run into that in practice.
4089 template <typename T>
4092 random(T a, T b) {
4093  return GeneratorWrapper<T>(
4094  pf::make_unique<RandomIntegerGenerator<T>>(a, b)
4095  );
4096 }
4097 
4098 template <typename T>
4100 GeneratorWrapper<T>>::type
4101 random(T a, T b) {
4102  return GeneratorWrapper<T>(
4103  pf::make_unique<RandomFloatingGenerator<T>>(a, b)
4104  );
4105 }
4106 
4107 template <typename T>
4108 class RangeGenerator final : public IGenerator<T> {
4113 
4114 public:
4115  RangeGenerator(T const& start, T const& end, T const& step):
4116  m_current(start),
4117  m_end(end),
4118  m_step(step),
4119  m_positive(m_step > T(0))
4120  {
4121  assert(m_current != m_end && "Range start and end cannot be equal");
4122  assert(m_step != T(0) && "Step size cannot be zero");
4123  assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && "Step moves away from end");
4124  }
4125 
4126  RangeGenerator(T const& start, T const& end):
4127  RangeGenerator(start, end, (start < end) ? T(1) : T(-1))
4128  {}
4129 
4130  T const& get() const override {
4131  return m_current;
4132  }
4133 
4134  bool next() override {
4135  m_current += m_step;
4136  return (m_positive) ? (m_current < m_end) : (m_current > m_end);
4137  }
4138 };
4139 
4140 template <typename T>
4141 GeneratorWrapper<T> range(T const& start, T const& end, T const& step) {
4142  static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
4143  return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end, step));
4144 }
4145 
4146 template <typename T>
4147 GeneratorWrapper<T> range(T const& start, T const& end) {
4148  static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
4149  return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end));
4150 }
4151 
4152 } // namespace Generators
4153 } // namespace Catch
4154 
4155 // end catch_generators_specific.hpp
4156 
4157 // These files are included here so the single_include script doesn't put them
4158 // in the conditionally compiled sections
4159 // start catch_test_case_info.h
4160 
4161 #include <string>
4162 #include <vector>
4163 #include <memory>
4164 
4165 #ifdef __clang__
4166 #pragma clang diagnostic push
4167 #pragma clang diagnostic ignored "-Wpadded"
4168 #endif
4169 
4170 namespace Catch {
4171 
4172  struct ITestInvoker;
4173 
4174  struct TestCaseInfo {
4176  None = 0,
4177  IsHidden = 1 << 1,
4178  ShouldFail = 1 << 2,
4179  MayFail = 1 << 3,
4180  Throws = 1 << 4,
4181  NonPortable = 1 << 5,
4182  Benchmark = 1 << 6
4183  };
4184 
4185  TestCaseInfo( std::string const& _name,
4186  std::string const& _className,
4187  std::string const& _description,
4188  std::vector<std::string> const& _tags,
4189  SourceLineInfo const& _lineInfo );
4190 
4191  friend void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags );
4192 
4193  bool isHidden() const;
4194  bool throws() const;
4195  bool okToFail() const;
4196  bool expectedToFail() const;
4197 
4198  std::string tagsAsString() const;
4199 
4200  std::string name;
4201  std::string className;
4202  std::string description;
4203  std::vector<std::string> tags;
4204  std::vector<std::string> lcaseTags;
4207  };
4208 
4209  class TestCase : public TestCaseInfo {
4210  public:
4211 
4212  TestCase( ITestInvoker* testCase, TestCaseInfo&& info );
4213 
4214  TestCase withName( std::string const& _newName ) const;
4215 
4216  void invoke() const;
4217 
4218  TestCaseInfo const& getTestCaseInfo() const;
4219 
4220  bool operator == ( TestCase const& other ) const;
4221  bool operator < ( TestCase const& other ) const;
4222 
4223  private:
4224  std::shared_ptr<ITestInvoker> test;
4225  };
4226 
4227  TestCase makeTestCase( ITestInvoker* testCase,
4228  std::string const& className,
4229  NameAndTags const& nameAndTags,
4230  SourceLineInfo const& lineInfo );
4231 }
4232 
4233 #ifdef __clang__
4234 #pragma clang diagnostic pop
4235 #endif
4236 
4237 // end catch_test_case_info.h
4238 // start catch_interfaces_runner.h
4239 
4240 namespace Catch {
4241 
4242  struct IRunner {
4243  virtual ~IRunner();
4244  virtual bool aborting() const = 0;
4245  };
4246 }
4247 
4248 // end catch_interfaces_runner.h
4249 
4250 #ifdef __OBJC__
4251 // start catch_objc.hpp
4252 
4253 #import <objc/runtime.h>
4254 
4255 #include <string>
4256 
4257 // NB. Any general catch headers included here must be included
4258 // in catch.hpp first to make sure they are included by the single
4259 // header for non obj-usage
4260 
4262 // This protocol is really only here for (self) documenting purposes, since
4263 // all its methods are optional.
4264 @protocol OcFixture
4265 
4266 @optional
4267 
4268 -(void) setUp;
4269 -(void) tearDown;
4270 
4271 @end
4272 
4273 namespace Catch {
4274 
4275  class OcMethod : public ITestInvoker {
4276 
4277  public:
4278  OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
4279 
4280  virtual void invoke() const {
4281  id obj = [[m_cls alloc] init];
4282 
4283  performOptionalSelector( obj, @selector(setUp) );
4284  performOptionalSelector( obj, m_sel );
4285  performOptionalSelector( obj, @selector(tearDown) );
4286 
4287  arcSafeRelease( obj );
4288  }
4289  private:
4290  virtual ~OcMethod() {}
4291 
4292  Class m_cls;
4293  SEL m_sel;
4294  };
4295 
4296  namespace Detail{
4297 
4298  inline std::string getAnnotation( Class cls,
4299  std::string const& annotationName,
4300  std::string const& testCaseName ) {
4301  NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
4302  SEL sel = NSSelectorFromString( selStr );
4303  arcSafeRelease( selStr );
4304  id value = performOptionalSelector( cls, sel );
4305  if( value )
4306  return [(NSString*)value UTF8String];
4307  return "";
4308  }
4309  }
4310 
4311  inline std::size_t registerTestMethods() {
4312  std::size_t noTestMethods = 0;
4313  int noClasses = objc_getClassList( nullptr, 0 );
4314 
4315  Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
4316  objc_getClassList( classes, noClasses );
4317 
4318  for( int c = 0; c < noClasses; c++ ) {
4319  Class cls = classes[c];
4320  {
4321  u_int count;
4322  Method* methods = class_copyMethodList( cls, &count );
4323  for( u_int m = 0; m < count ; m++ ) {
4324  SEL selector = method_getName(methods[m]);
4325  std::string methodName = sel_getName(selector);
4326  if( startsWith( methodName, "Catch_TestCase_" ) ) {
4327  std::string testCaseName = methodName.substr( 15 );
4328  std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
4329  std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
4330  const char* className = class_getName( cls );
4331 
4332  getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo("",0) ) );
4333  noTestMethods++;
4334  }
4335  }
4336  free(methods);
4337  }
4338  }
4339  return noTestMethods;
4340  }
4341 
4342 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
4343 
4344  namespace Matchers {
4345  namespace Impl {
4346  namespace NSStringMatchers {
4347 
4348  struct StringHolder : MatcherBase<NSString*>{
4349  StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
4350  StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
4351  StringHolder() {
4352  arcSafeRelease( m_substr );
4353  }
4354 
4355  bool match( NSString* arg ) const override {
4356  return false;
4357  }
4358 
4359  NSString* CATCH_ARC_STRONG m_substr;
4360  };
4361 
4362  struct Equals : StringHolder {
4363  Equals( NSString* substr ) : StringHolder( substr ){}
4364 
4365  bool match( NSString* str ) const override {
4366  return (str != nil || m_substr == nil ) &&
4367  [str isEqualToString:m_substr];
4368  }
4369 
4370  std::string describe() const override {
4371  return "equals string: " + Catch::Detail::stringify( m_substr );
4372  }
4373  };
4374 
4375  struct Contains : StringHolder {
4376  Contains( NSString* substr ) : StringHolder( substr ){}
4377 
4378  bool match( NSString* str ) const {
4379  return (str != nil || m_substr == nil ) &&
4380  [str rangeOfString:m_substr].location != NSNotFound;
4381  }
4382 
4383  std::string describe() const override {
4384  return "contains string: " + Catch::Detail::stringify( m_substr );
4385  }
4386  };
4387 
4388  struct StartsWith : StringHolder {
4389  StartsWith( NSString* substr ) : StringHolder( substr ){}
4390 
4391  bool match( NSString* str ) const override {
4392  return (str != nil || m_substr == nil ) &&
4393  [str rangeOfString:m_substr].location == 0;
4394  }
4395 
4396  std::string describe() const override {
4397  return "starts with: " + Catch::Detail::stringify( m_substr );
4398  }
4399  };
4400  struct EndsWith : StringHolder {
4401  EndsWith( NSString* substr ) : StringHolder( substr ){}
4402 
4403  bool match( NSString* str ) const override {
4404  return (str != nil || m_substr == nil ) &&
4405  [str rangeOfString:m_substr].location == [str length] - [m_substr length];
4406  }
4407 
4408  std::string describe() const override {
4409  return "ends with: " + Catch::Detail::stringify( m_substr );
4410  }
4411  };
4412 
4413  } // namespace NSStringMatchers
4414  } // namespace Impl
4415 
4417  Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
4418 
4420  Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
4421 
4423  StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
4424 
4426  EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
4427 
4428  } // namespace Matchers
4429 
4430  using namespace Matchers;
4431 
4432 #endif // CATCH_CONFIG_DISABLE_MATCHERS
4433 
4434 } // namespace Catch
4435 
4437 #define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix
4438 #define OC_TEST_CASE2( name, desc, uniqueSuffix ) \
4439 +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \
4440 { \
4441 return @ name; \
4442 } \
4443 +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \
4444 { \
4445 return @ desc; \
4446 } \
4447 -(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix )
4448 
4449 #define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ )
4450 
4451 // end catch_objc.hpp
4452 #endif
4453 
4454 #ifdef CATCH_CONFIG_EXTERNAL_INTERFACES
4455 // start catch_external_interfaces.h
4456 
4457 // start catch_reporter_bases.hpp
4458 
4459 // start catch_interfaces_reporter.h
4460 
4461 // start catch_config.hpp
4462 
4463 // start catch_test_spec_parser.h
4464 
4465 #ifdef __clang__
4466 #pragma clang diagnostic push
4467 #pragma clang diagnostic ignored "-Wpadded"
4468 #endif
4469 
4470 // start catch_test_spec.h
4471 
4472 #ifdef __clang__
4473 #pragma clang diagnostic push
4474 #pragma clang diagnostic ignored "-Wpadded"
4475 #endif
4476 
4477 // start catch_wildcard_pattern.h
4478 
4479 namespace Catch
4480 {
4481  class WildcardPattern {
4482  enum WildcardPosition {
4483  NoWildcard = 0,
4484  WildcardAtStart = 1,
4485  WildcardAtEnd = 2,
4486  WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
4487  };
4488 
4489  public:
4490 
4491  WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity );
4492  virtual ~WildcardPattern() = default;
4493  virtual bool matches( std::string const& str ) const;
4494 
4495  private:
4496  std::string adjustCase( std::string const& str ) const;
4497  CaseSensitive::Choice m_caseSensitivity;
4498  WildcardPosition m_wildcard = NoWildcard;
4499  std::string m_pattern;
4500  };
4501 }
4502 
4503 // end catch_wildcard_pattern.h
4504 #include <string>
4505 #include <vector>
4506 #include <memory>
4507 
4508 namespace Catch {
4509 
4510  class TestSpec {
4511  struct Pattern {
4512  virtual ~Pattern();
4513  virtual bool matches( TestCaseInfo const& testCase ) const = 0;
4514  };
4515  using PatternPtr = std::shared_ptr<Pattern>;
4516 
4517  class NamePattern : public Pattern {
4518  public:
4519  NamePattern( std::string const& name );
4520  virtual ~NamePattern();
4521  virtual bool matches( TestCaseInfo const& testCase ) const override;
4522  private:
4523  WildcardPattern m_wildcardPattern;
4524  };
4525 
4526  class TagPattern : public Pattern {
4527  public:
4528  TagPattern( std::string const& tag );
4529  virtual ~TagPattern();
4530  virtual bool matches( TestCaseInfo const& testCase ) const override;
4531  private:
4532  std::string m_tag;
4533  };
4534 
4535  class ExcludedPattern : public Pattern {
4536  public:
4537  ExcludedPattern( PatternPtr const& underlyingPattern );
4538  virtual ~ExcludedPattern();
4539  virtual bool matches( TestCaseInfo const& testCase ) const override;
4540  private:
4541  PatternPtr m_underlyingPattern;
4542  };
4543 
4544  struct Filter {
4545  std::vector<PatternPtr> m_patterns;
4546 
4547  bool matches( TestCaseInfo const& testCase ) const;
4548  };
4549 
4550  public:
4551  bool hasFilters() const;
4552  bool matches( TestCaseInfo const& testCase ) const;
4553 
4554  private:
4555  std::vector<Filter> m_filters;
4556 
4557  friend class TestSpecParser;
4558  };
4559 }
4560 
4561 #ifdef __clang__
4562 #pragma clang diagnostic pop
4563 #endif
4564 
4565 // end catch_test_spec.h
4566 // start catch_interfaces_tag_alias_registry.h
4567 
4568 #include <string>
4569 
4570 namespace Catch {
4571 
4572  struct TagAlias;
4573 
4574  struct ITagAliasRegistry {
4575  virtual ~ITagAliasRegistry();
4576  // Nullptr if not present
4577  virtual TagAlias const* find( std::string const& alias ) const = 0;
4578  virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
4579 
4580  static ITagAliasRegistry const& get();
4581  };
4582 
4583 } // end namespace Catch
4584 
4585 // end catch_interfaces_tag_alias_registry.h
4586 namespace Catch {
4587 
4588  class TestSpecParser {
4589  enum Mode{ None, Name, QuotedName, Tag, EscapedName };
4590  Mode m_mode = None;
4591  bool m_exclusion = false;
4592  std::size_t m_start = std::string::npos, m_pos = 0;
4593  std::string m_arg;
4594  std::vector<std::size_t> m_escapeChars;
4595  TestSpec::Filter m_currentFilter;
4596  TestSpec m_testSpec;
4597  ITagAliasRegistry const* m_tagAliases = nullptr;
4598 
4599  public:
4600  TestSpecParser( ITagAliasRegistry const& tagAliases );
4601 
4602  TestSpecParser& parse( std::string const& arg );
4603  TestSpec testSpec();
4604 
4605  private:
4606  void visitChar( char c );
4607  void startNewMode( Mode mode, std::size_t start );
4608  void escape();
4609  std::string subString() const;
4610 
4611  template<typename T>
4612  void addPattern() {
4613  std::string token = subString();
4614  for( std::size_t i = 0; i < m_escapeChars.size(); ++i )
4615  token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 );
4616  m_escapeChars.clear();
4617  if( startsWith( token, "exclude:" ) ) {
4618  m_exclusion = true;
4619  token = token.substr( 8 );
4620  }
4621  if( !token.empty() ) {
4622  TestSpec::PatternPtr pattern = std::make_shared<T>( token );
4623  if( m_exclusion )
4624  pattern = std::make_shared<TestSpec::ExcludedPattern>( pattern );
4625  m_currentFilter.m_patterns.push_back( pattern );
4626  }
4627  m_exclusion = false;
4628  m_mode = None;
4629  }
4630 
4631  void addFilter();
4632  };
4633  TestSpec parseTestSpec( std::string const& arg );
4634 
4635 } // namespace Catch
4636 
4637 #ifdef __clang__
4638 #pragma clang diagnostic pop
4639 #endif
4640 
4641 // end catch_test_spec_parser.h
4642 // Libstdc++ doesn't like incomplete classes for unique_ptr
4643 
4644 #include <memory>
4645 #include <vector>
4646 #include <string>
4647 
4648 #ifndef CATCH_CONFIG_CONSOLE_WIDTH
4649 #define CATCH_CONFIG_CONSOLE_WIDTH 80
4650 #endif
4651 
4652 namespace Catch {
4653 
4654  struct IStream;
4655 
4656  struct ConfigData {
4657  bool listTests = false;
4658  bool listTags = false;
4659  bool listReporters = false;
4660  bool listTestNamesOnly = false;
4661 
4662  bool showSuccessfulTests = false;
4663  bool shouldDebugBreak = false;
4664  bool noThrow = false;
4665  bool showHelp = false;
4666  bool showInvisibles = false;
4667  bool filenamesAsTags = false;
4668  bool libIdentify = false;
4669 
4670  int abortAfter = -1;
4671  unsigned int rngSeed = 0;
4672  int benchmarkResolutionMultiple = 100;
4673 
4674  Verbosity verbosity = Verbosity::Normal;
4678  UseColour::YesOrNo useColour = UseColour::Auto;
4680 
4681  std::string outputFilename;
4682  std::string name;
4683  std::string processName;
4684 #ifndef CATCH_CONFIG_DEFAULT_REPORTER
4685 #define CATCH_CONFIG_DEFAULT_REPORTER "console"
4686 #endif
4687  std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER;
4688 #undef CATCH_CONFIG_DEFAULT_REPORTER
4689 
4690  std::vector<std::string> testsOrTags;
4691  std::vector<std::string> sectionsToRun;
4692  };
4693 
4694  class Config : public IConfig {
4695  public:
4696 
4697  Config() = default;
4698  Config( ConfigData const& data );
4699  virtual ~Config() = default;
4700 
4701  std::string const& getFilename() const;
4702 
4703  bool listTests() const;
4704  bool listTestNamesOnly() const;
4705  bool listTags() const;
4706  bool listReporters() const;
4707 
4708  std::string getProcessName() const;
4709  std::string const& getReporterName() const;
4710 
4711  std::vector<std::string> const& getTestsOrTags() const;
4712  std::vector<std::string> const& getSectionsToRun() const override;
4713 
4714  virtual TestSpec const& testSpec() const override;
4715  bool hasTestFilters() const override;
4716 
4717  bool showHelp() const;
4718 
4719  // IConfig interface
4720  bool allowThrows() const override;
4721  std::ostream& stream() const override;
4722  std::string name() const override;
4723  bool includeSuccessfulResults() const override;
4724  bool warnAboutMissingAssertions() const override;
4725  bool warnAboutNoTests() const override;
4726  ShowDurations::OrNot showDurations() const override;
4727  RunTests::InWhatOrder runOrder() const override;
4728  unsigned int rngSeed() const override;
4729  int benchmarkResolutionMultiple() const override;
4730  UseColour::YesOrNo useColour() const override;
4731  bool shouldDebugBreak() const override;
4732  int abortAfter() const override;
4733  bool showInvisibles() const override;
4734  Verbosity verbosity() const override;
4735 
4736  private:
4737 
4738  IStream const* openStream();
4739  ConfigData m_data;
4740 
4741  std::unique_ptr<IStream const> m_stream;
4742  TestSpec m_testSpec;
4743  bool m_hasTestFilters = false;
4744  };
4745 
4746 } // end namespace Catch
4747 
4748 // end catch_config.hpp
4749 // start catch_assertionresult.h
4750 
4751 #include <string>
4752 
4753 namespace Catch {
4754 
4755  struct AssertionResultData
4756  {
4757  AssertionResultData() = delete;
4758 
4759  AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression );
4760 
4761  std::string message;
4762  mutable std::string reconstructedExpression;
4763  LazyExpression lazyExpression;
4764  ResultWas::OfType resultType;
4765 
4766  std::string reconstructExpression() const;
4767  };
4768 
4769  class AssertionResult {
4770  public:
4771  AssertionResult() = delete;
4772  AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
4773 
4774  bool isOk() const;
4775  bool succeeded() const;
4776  ResultWas::OfType getResultType() const;
4777  bool hasExpression() const;
4778  bool hasMessage() const;
4779  std::string getExpression() const;
4780  std::string getExpressionInMacro() const;
4781  bool hasExpandedExpression() const;
4782  std::string getExpandedExpression() const;
4783  std::string getMessage() const;
4784  SourceLineInfo getSourceInfo() const;
4785  StringRef getTestMacroName() const;
4786 
4787  //protected:
4788  AssertionInfo m_info;
4789  AssertionResultData m_resultData;
4790  };
4791 
4792 } // end namespace Catch
4793 
4794 // end catch_assertionresult.h
4795 // start catch_option.hpp
4796 
4797 namespace Catch {
4798 
4799  // An optional type
4800  template<typename T>
4801  class Option {
4802  public:
4803  Option() : nullableValue( nullptr ) {}
4804  Option( T const& _value )
4805  : nullableValue( new( storage ) T( _value ) )
4806  {}
4807  Option( Option const& _other )
4808  : nullableValue( _other ? new( storage ) T( *_other ) : nullptr )
4809  {}
4810 
4811  ~Option() {
4812  reset();
4813  }
4814 
4815  Option& operator= ( Option const& _other ) {
4816  if( &_other != this ) {
4817  reset();
4818  if( _other )
4819  nullableValue = new( storage ) T( *_other );
4820  }
4821  return *this;
4822  }
4823  Option& operator = ( T const& _value ) {
4824  reset();
4825  nullableValue = new( storage ) T( _value );
4826  return *this;
4827  }
4828 
4829  void reset() {
4830  if( nullableValue )
4831  nullableValue->~T();
4832  nullableValue = nullptr;
4833  }
4834 
4835  T& operator*() { return *nullableValue; }
4836  T const& operator*() const { return *nullableValue; }
4837  T* operator->() { return nullableValue; }
4838  const T* operator->() const { return nullableValue; }
4839 
4840  T valueOr( T const& defaultValue ) const {
4841  return nullableValue ? *nullableValue : defaultValue;
4842  }
4843 
4844  bool some() const { return nullableValue != nullptr; }
4845  bool none() const { return nullableValue == nullptr; }
4846 
4847  bool operator !() const { return nullableValue == nullptr; }
4848  explicit operator bool() const {
4849  return some();
4850  }
4851 
4852  private:
4853  T *nullableValue;
4854  alignas(alignof(T)) char storage[sizeof(T)];
4855  };
4856 
4857 } // end namespace Catch
4858 
4859 // end catch_option.hpp
4860 #include <string>
4861 #include <iosfwd>
4862 #include <map>
4863 #include <set>
4864 #include <memory>
4865 
4866 namespace Catch {
4867 
4868  struct ReporterConfig {
4869  explicit ReporterConfig( IConfigPtr const& _fullConfig );
4870 
4871  ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream );
4872 
4873  std::ostream& stream() const;
4874  IConfigPtr fullConfig() const;
4875 
4876  private:
4877  std::ostream* m_stream;
4878  IConfigPtr m_fullConfig;
4879  };
4880 
4881  struct ReporterPreferences {
4882  bool shouldRedirectStdOut = false;
4883  bool shouldReportAllAssertions = false;
4884  };
4885 
4886  template<typename T>
4887  struct LazyStat : Option<T> {
4888  LazyStat& operator=( T const& _value ) {
4889  Option<T>::operator=( _value );
4890  used = false;
4891  return *this;
4892  }
4893  void reset() {
4894  Option<T>::reset();
4895  used = false;
4896  }
4897  bool used = false;
4898  };
4899 
4900  struct TestRunInfo {
4901  TestRunInfo( std::string const& _name );
4902  std::string name;
4903  };
4904  struct GroupInfo {
4905  GroupInfo( std::string const& _name,
4906  std::size_t _groupIndex,
4907  std::size_t _groupsCount );
4908 
4909  std::string name;
4910  std::size_t groupIndex;
4911  std::size_t groupsCounts;
4912  };
4913 
4914  struct AssertionStats {
4915  AssertionStats( AssertionResult const& _assertionResult,
4916  std::vector<MessageInfo> const& _infoMessages,
4917  Totals const& _totals );
4918 
4919  AssertionStats( AssertionStats const& ) = default;
4920  AssertionStats( AssertionStats && ) = default;
4921  AssertionStats& operator = ( AssertionStats const& ) = delete;
4922  AssertionStats& operator = ( AssertionStats && ) = delete;
4923  virtual ~AssertionStats();
4924 
4925  AssertionResult assertionResult;
4926  std::vector<MessageInfo> infoMessages;
4927  Totals totals;
4928  };
4929 
4930  struct SectionStats {
4931  SectionStats( SectionInfo const& _sectionInfo,
4932  Counts const& _assertions,
4933  double _durationInSeconds,
4934  bool _missingAssertions );
4935  SectionStats( SectionStats const& ) = default;
4936  SectionStats( SectionStats && ) = default;
4937  SectionStats& operator = ( SectionStats const& ) = default;
4938  SectionStats& operator = ( SectionStats && ) = default;
4939  virtual ~SectionStats();
4940 
4941  SectionInfo sectionInfo;
4942  Counts assertions;
4943  double durationInSeconds;
4944  bool missingAssertions;
4945  };
4946 
4947  struct TestCaseStats {
4948  TestCaseStats( TestCaseInfo const& _testInfo,
4949  Totals const& _totals,
4950  std::string const& _stdOut,
4951  std::string const& _stdErr,
4952  bool _aborting );
4953 
4954  TestCaseStats( TestCaseStats const& ) = default;
4955  TestCaseStats( TestCaseStats && ) = default;
4956  TestCaseStats& operator = ( TestCaseStats const& ) = default;
4957  TestCaseStats& operator = ( TestCaseStats && ) = default;
4958  virtual ~TestCaseStats();
4959 
4960  TestCaseInfo testInfo;
4961  Totals totals;
4962  std::string stdOut;
4963  std::string stdErr;
4964  bool aborting;
4965  };
4966 
4967  struct TestGroupStats {
4968  TestGroupStats( GroupInfo const& _groupInfo,
4969  Totals const& _totals,
4970  bool _aborting );
4971  TestGroupStats( GroupInfo const& _groupInfo );
4972 
4973  TestGroupStats( TestGroupStats const& ) = default;
4974  TestGroupStats( TestGroupStats && ) = default;
4975  TestGroupStats& operator = ( TestGroupStats const& ) = default;
4976  TestGroupStats& operator = ( TestGroupStats && ) = default;
4977  virtual ~TestGroupStats();
4978 
4979  GroupInfo groupInfo;
4980  Totals totals;
4981  bool aborting;
4982  };
4983 
4984  struct TestRunStats {
4985  TestRunStats( TestRunInfo const& _runInfo,
4986  Totals const& _totals,
4987  bool _aborting );
4988 
4989  TestRunStats( TestRunStats const& ) = default;
4990  TestRunStats( TestRunStats && ) = default;
4991  TestRunStats& operator = ( TestRunStats const& ) = default;
4992  TestRunStats& operator = ( TestRunStats && ) = default;
4993  virtual ~TestRunStats();
4994 
4995  TestRunInfo runInfo;
4996  Totals totals;
4997  bool aborting;
4998  };
4999 
5000  struct BenchmarkInfo {
5001  std::string name;
5002  };
5003  struct BenchmarkStats {
5004  BenchmarkInfo info;
5005  std::size_t iterations;
5006  uint64_t elapsedTimeInNanoseconds;
5007  };
5008 
5009  struct IStreamingReporter {
5010  virtual ~IStreamingReporter() = default;
5011 
5012  // Implementing class must also provide the following static methods:
5013  // static std::string getDescription();
5014  // static std::set<Verbosity> getSupportedVerbosities()
5015 
5016  virtual ReporterPreferences getPreferences() const = 0;
5017 
5018  virtual void noMatchingTestCases( std::string const& spec ) = 0;
5019 
5020  virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
5021  virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
5022 
5023  virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
5024  virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
5025 
5026  // *** experimental ***
5027  virtual void benchmarkStarting( BenchmarkInfo const& ) {}
5028 
5029  virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
5030 
5031  // The return value indicates if the messages buffer should be cleared:
5032  virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
5033 
5034  // *** experimental ***
5035  virtual void benchmarkEnded( BenchmarkStats const& ) {}
5036 
5037  virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
5038  virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
5039  virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
5040  virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
5041 
5042  virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
5043 
5044  // Default empty implementation provided
5045  virtual void fatalErrorEncountered( StringRef name );
5046 
5047  virtual bool isMulti() const;
5048  };
5049  using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>;
5050 
5051  struct IReporterFactory {
5052  virtual ~IReporterFactory();
5053  virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0;
5054  virtual std::string getDescription() const = 0;
5055  };
5056  using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
5057 
5058  struct IReporterRegistry {
5059  using FactoryMap = std::map<std::string, IReporterFactoryPtr>;
5060  using Listeners = std::vector<IReporterFactoryPtr>;
5061 
5062  virtual ~IReporterRegistry();
5063  virtual IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const = 0;
5064  virtual FactoryMap const& getFactories() const = 0;
5065  virtual Listeners const& getListeners() const = 0;
5066  };
5067 
5068 } // end namespace Catch
5069 
5070 // end catch_interfaces_reporter.h
5071 #include <algorithm>
5072 #include <cstring>
5073 #include <cfloat>
5074 #include <cstdio>
5075 #include <cassert>
5076 #include <memory>
5077 #include <ostream>
5078 
5079 namespace Catch {
5080  void prepareExpandedExpression(AssertionResult& result);
5081 
5082  // Returns double formatted as %.3f (format expected on output)
5083  std::string getFormattedDuration( double duration );
5084 
5085  template<typename DerivedT>
5086  struct StreamingReporterBase : IStreamingReporter {
5087 
5088  StreamingReporterBase( ReporterConfig const& _config )
5089  : m_config( _config.fullConfig() ),
5090  stream( _config.stream() )
5091  {
5092  m_reporterPrefs.shouldRedirectStdOut = false;
5093  if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
5094  CATCH_ERROR( "Verbosity level not supported by this reporter" );
5095  }
5096 
5097  ReporterPreferences getPreferences() const override {
5098  return m_reporterPrefs;
5099  }
5100 
5101  static std::set<Verbosity> getSupportedVerbosities() {
5102  return { Verbosity::Normal };
5103  }
5104 
5105  ~StreamingReporterBase() override = default;
5106 
5107  void noMatchingTestCases(std::string const&) override {}
5108 
5109  void testRunStarting(TestRunInfo const& _testRunInfo) override {
5110  currentTestRunInfo = _testRunInfo;
5111  }
5112  void testGroupStarting(GroupInfo const& _groupInfo) override {
5113  currentGroupInfo = _groupInfo;
5114  }
5115 
5116  void testCaseStarting(TestCaseInfo const& _testInfo) override {
5117  currentTestCaseInfo = _testInfo;
5118  }
5119  void sectionStarting(SectionInfo const& _sectionInfo) override {
5120  m_sectionStack.push_back(_sectionInfo);
5121  }
5122 
5123  void sectionEnded(SectionStats const& /* _sectionStats */) override {
5124  m_sectionStack.pop_back();
5125  }
5126  void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {
5127  currentTestCaseInfo.reset();
5128  }
5129  void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override {
5130  currentGroupInfo.reset();
5131  }
5132  void testRunEnded(TestRunStats const& /* _testRunStats */) override {
5133  currentTestCaseInfo.reset();
5134  currentGroupInfo.reset();
5135  currentTestRunInfo.reset();
5136  }
5137 
5138  void skipTest(TestCaseInfo const&) override {
5139  // Don't do anything with this by default.
5140  // It can optionally be overridden in the derived class.
5141  }
5142 
5143  IConfigPtr m_config;
5144  std::ostream& stream;
5145 
5146  LazyStat<TestRunInfo> currentTestRunInfo;
5147  LazyStat<GroupInfo> currentGroupInfo;
5148  LazyStat<TestCaseInfo> currentTestCaseInfo;
5149 
5150  std::vector<SectionInfo> m_sectionStack;
5151  ReporterPreferences m_reporterPrefs;
5152  };
5153 
5154  template<typename DerivedT>
5155  struct CumulativeReporterBase : IStreamingReporter {
5156  template<typename T, typename ChildNodeT>
5157  struct Node {
5158  explicit Node( T const& _value ) : value( _value ) {}
5159  virtual ~Node() {}
5160 
5161  using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;
5162  T value;
5163  ChildNodes children;
5164  };
5165  struct SectionNode {
5166  explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}
5167  virtual ~SectionNode() = default;
5168 
5169  bool operator == (SectionNode const& other) const {
5170  return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
5171  }
5172  bool operator == (std::shared_ptr<SectionNode> const& other) const {
5173  return operator==(*other);
5174  }
5175 
5176  SectionStats stats;
5177  using ChildSections = std::vector<std::shared_ptr<SectionNode>>;
5178  using Assertions = std::vector<AssertionStats>;
5179  ChildSections childSections;
5180  Assertions assertions;
5181  std::string stdOut;
5182  std::string stdErr;
5183  };
5184 
5185  struct BySectionInfo {
5186  BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
5187  BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
5188  bool operator() (std::shared_ptr<SectionNode> const& node) const {
5189  return ((node->stats.sectionInfo.name == m_other.name) &&
5190  (node->stats.sectionInfo.lineInfo == m_other.lineInfo));
5191  }
5192  void operator=(BySectionInfo const&) = delete;
5193 
5194  private:
5195  SectionInfo const& m_other;
5196  };
5197 
5198  using TestCaseNode = Node<TestCaseStats, SectionNode>;
5199  using TestGroupNode = Node<TestGroupStats, TestCaseNode>;
5200  using TestRunNode = Node<TestRunStats, TestGroupNode>;
5201 
5202  CumulativeReporterBase( ReporterConfig const& _config )
5203  : m_config( _config.fullConfig() ),
5204  stream( _config.stream() )
5205  {
5206  m_reporterPrefs.shouldRedirectStdOut = false;
5207  if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
5208  CATCH_ERROR( "Verbosity level not supported by this reporter" );
5209  }
5210  ~CumulativeReporterBase() override = default;
5211 
5212  ReporterPreferences getPreferences() const override {
5213  return m_reporterPrefs;
5214  }
5215 
5216  static std::set<Verbosity> getSupportedVerbosities() {
5217  return { Verbosity::Normal };
5218  }
5219 
5220  void testRunStarting( TestRunInfo const& ) override {}
5221  void testGroupStarting( GroupInfo const& ) override {}
5222 
5223  void testCaseStarting( TestCaseInfo const& ) override {}
5224 
5225  void sectionStarting( SectionInfo const& sectionInfo ) override {
5226  SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
5227  std::shared_ptr<SectionNode> node;
5228  if( m_sectionStack.empty() ) {
5229  if( !m_rootSection )
5230  m_rootSection = std::make_shared<SectionNode>( incompleteStats );
5231  node = m_rootSection;
5232  }
5233  else {
5234  SectionNode& parentNode = *m_sectionStack.back();
5235  auto it =
5236  std::find_if( parentNode.childSections.begin(),
5237  parentNode.childSections.end(),
5238  BySectionInfo( sectionInfo ) );
5239  if( it == parentNode.childSections.end() ) {
5240  node = std::make_shared<SectionNode>( incompleteStats );
5241  parentNode.childSections.push_back( node );
5242  }
5243  else
5244  node = *it;
5245  }
5246  m_sectionStack.push_back( node );
5247  m_deepestSection = std::move(node);
5248  }
5249 
5250  void assertionStarting(AssertionInfo const&) override {}
5251 
5252  bool assertionEnded(AssertionStats const& assertionStats) override {
5253  assert(!m_sectionStack.empty());
5254  // AssertionResult holds a pointer to a temporary DecomposedExpression,
5255  // which getExpandedExpression() calls to build the expression string.
5256  // Our section stack copy of the assertionResult will likely outlive the
5257  // temporary, so it must be expanded or discarded now to avoid calling
5258  // a destroyed object later.
5259  prepareExpandedExpression(const_cast<AssertionResult&>( assertionStats.assertionResult ) );
5260  SectionNode& sectionNode = *m_sectionStack.back();
5261  sectionNode.assertions.push_back(assertionStats);
5262  return true;
5263  }
5264  void sectionEnded(SectionStats const& sectionStats) override {
5265  assert(!m_sectionStack.empty());
5266  SectionNode& node = *m_sectionStack.back();
5267  node.stats = sectionStats;
5268  m_sectionStack.pop_back();
5269  }
5270  void testCaseEnded(TestCaseStats const& testCaseStats) override {
5271  auto node = std::make_shared<TestCaseNode>(testCaseStats);
5272  assert(m_sectionStack.size() == 0);
5273  node->children.push_back(m_rootSection);
5274  m_testCases.push_back(node);
5275  m_rootSection.reset();
5276 
5277  assert(m_deepestSection);
5278  m_deepestSection->stdOut = testCaseStats.stdOut;
5279  m_deepestSection->stdErr = testCaseStats.stdErr;
5280  }
5281  void testGroupEnded(TestGroupStats const& testGroupStats) override {
5282  auto node = std::make_shared<TestGroupNode>(testGroupStats);
5283  node->children.swap(m_testCases);
5284  m_testGroups.push_back(node);
5285  }
5286  void testRunEnded(TestRunStats const& testRunStats) override {
5287  auto node = std::make_shared<TestRunNode>(testRunStats);
5288  node->children.swap(m_testGroups);
5289  m_testRuns.push_back(node);
5290  testRunEndedCumulative();
5291  }
5292  virtual void testRunEndedCumulative() = 0;
5293 
5294  void skipTest(TestCaseInfo const&) override {}
5295 
5296  IConfigPtr m_config;
5297  std::ostream& stream;
5298  std::vector<AssertionStats> m_assertions;
5299  std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;
5300  std::vector<std::shared_ptr<TestCaseNode>> m_testCases;
5301  std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;
5302 
5303  std::vector<std::shared_ptr<TestRunNode>> m_testRuns;
5304 
5305  std::shared_ptr<SectionNode> m_rootSection;
5306  std::shared_ptr<SectionNode> m_deepestSection;
5307  std::vector<std::shared_ptr<SectionNode>> m_sectionStack;
5308  ReporterPreferences m_reporterPrefs;
5309  };
5310 
5311  template<char C>
5312  char const* getLineOfChars() {
5313  static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
5314  if( !*line ) {
5315  std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
5316  line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
5317  }
5318  return line;
5319  }
5320 
5321  struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> {
5322  TestEventListenerBase( ReporterConfig const& _config );
5323 
5324  static std::set<Verbosity> getSupportedVerbosities();
5325 
5326  void assertionStarting(AssertionInfo const&) override;
5327  bool assertionEnded(AssertionStats const&) override;
5328  };
5329 
5330 } // end namespace Catch
5331 
5332 // end catch_reporter_bases.hpp
5333 // start catch_console_colour.h
5334 
5335 namespace Catch {
5336 
5337  struct Colour {
5338  enum Code {
5339  None = 0,
5340 
5341  White,
5342  Red,
5343  Green,
5344  Blue,
5345  Cyan,
5346  Yellow,
5347  Grey,
5348 
5349  Bright = 0x10,
5350 
5351  BrightRed = Bright | Red,
5352  BrightGreen = Bright | Green,
5353  LightGrey = Bright | Grey,
5354  BrightWhite = Bright | White,
5355  BrightYellow = Bright | Yellow,
5356 
5357  // By intention
5358  FileName = LightGrey,
5359  Warning = BrightYellow,
5360  ResultError = BrightRed,
5361  ResultSuccess = BrightGreen,
5362  ResultExpectedFailure = Warning,
5363 
5364  Error = BrightRed,
5365  Success = Green,
5366 
5367  OriginalExpression = Cyan,
5368  ReconstructedExpression = BrightYellow,
5369 
5370  SecondaryText = LightGrey,
5371  Headers = White
5372  };
5373 
5374  // Use constructed object for RAII guard
5375  Colour( Code _colourCode );
5376  Colour( Colour&& other ) noexcept;
5377  Colour& operator=( Colour&& other ) noexcept;
5378  ~Colour();
5379 
5380  // Use static method for one-shot changes
5381  static void use( Code _colourCode );
5382 
5383  private:
5384  bool m_moved = false;
5385  };
5386 
5387  std::ostream& operator << ( std::ostream& os, Colour const& );
5388 
5389 } // end namespace Catch
5390 
5391 // end catch_console_colour.h
5392 // start catch_reporter_registrars.hpp
5393 
5394 
5395 namespace Catch {
5396 
5397  template<typename T>
5398  class ReporterRegistrar {
5399 
5400  class ReporterFactory : public IReporterFactory {
5401 
5402  virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override {
5403  return std::unique_ptr<T>( new T( config ) );
5404  }
5405 
5406  virtual std::string getDescription() const override {
5407  return T::getDescription();
5408  }
5409  };
5410 
5411  public:
5412 
5413  explicit ReporterRegistrar( std::string const& name ) {
5414  getMutableRegistryHub().registerReporter( name, std::make_shared<ReporterFactory>() );
5415  }
5416  };
5417 
5418  template<typename T>
5419  class ListenerRegistrar {
5420 
5421  class ListenerFactory : public IReporterFactory {
5422 
5423  virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override {
5424  return std::unique_ptr<T>( new T( config ) );
5425  }
5426  virtual std::string getDescription() const override {
5427  return std::string();
5428  }
5429  };
5430 
5431  public:
5432 
5433  ListenerRegistrar() {
5434  getMutableRegistryHub().registerListener( std::make_shared<ListenerFactory>() );
5435  }
5436  };
5437 }
5438 
5439 #if !defined(CATCH_CONFIG_DISABLE)
5440 
5441 #define CATCH_REGISTER_REPORTER( name, reporterType ) \
5442  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
5443  namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \
5444  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
5445 
5446 #define CATCH_REGISTER_LISTENER( listenerType ) \
5447  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
5448  namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \
5449  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
5450 #else // CATCH_CONFIG_DISABLE
5451 
5452 #define CATCH_REGISTER_REPORTER(name, reporterType)
5453 #define CATCH_REGISTER_LISTENER(listenerType)
5454 
5455 #endif // CATCH_CONFIG_DISABLE
5456 
5457 // end catch_reporter_registrars.hpp
5458 // Allow users to base their work off existing reporters
5459 // start catch_reporter_compact.h
5460 
5461 namespace Catch {
5462 
5463  struct CompactReporter : StreamingReporterBase<CompactReporter> {
5464 
5465  using StreamingReporterBase::StreamingReporterBase;
5466 
5467  ~CompactReporter() override;
5468 
5469  static std::string getDescription();
5470 
5471  ReporterPreferences getPreferences() const override;
5472 
5473  void noMatchingTestCases(std::string const& spec) override;
5474 
5475  void assertionStarting(AssertionInfo const&) override;
5476 
5477  bool assertionEnded(AssertionStats const& _assertionStats) override;
5478 
5479  void sectionEnded(SectionStats const& _sectionStats) override;
5480 
5481  void testRunEnded(TestRunStats const& _testRunStats) override;
5482 
5483  };
5484 
5485 } // end namespace Catch
5486 
5487 // end catch_reporter_compact.h
5488 // start catch_reporter_console.h
5489 
5490 #if defined(_MSC_VER)
5491 #pragma warning(push)
5492 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
5493  // Note that 4062 (not all labels are handled
5494  // and default is missing) is enabled
5495 #endif
5496 
5497 namespace Catch {
5498  // Fwd decls
5499  struct SummaryColumn;
5500  class TablePrinter;
5501 
5502  struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> {
5503  std::unique_ptr<TablePrinter> m_tablePrinter;
5504 
5505  ConsoleReporter(ReporterConfig const& config);
5506  ~ConsoleReporter() override;
5507  static std::string getDescription();
5508 
5509  void noMatchingTestCases(std::string const& spec) override;
5510 
5511  void assertionStarting(AssertionInfo const&) override;
5512 
5513  bool assertionEnded(AssertionStats const& _assertionStats) override;
5514 
5515  void sectionStarting(SectionInfo const& _sectionInfo) override;
5516  void sectionEnded(SectionStats const& _sectionStats) override;
5517 
5518  void benchmarkStarting(BenchmarkInfo const& info) override;
5519  void benchmarkEnded(BenchmarkStats const& stats) override;
5520 
5521  void testCaseEnded(TestCaseStats const& _testCaseStats) override;
5522  void testGroupEnded(TestGroupStats const& _testGroupStats) override;
5523  void testRunEnded(TestRunStats const& _testRunStats) override;
5524 
5525  private:
5526 
5527  void lazyPrint();
5528 
5529  void lazyPrintWithoutClosingBenchmarkTable();
5530  void lazyPrintRunInfo();
5531  void lazyPrintGroupInfo();
5532  void printTestCaseAndSectionHeader();
5533 
5534  void printClosedHeader(std::string const& _name);
5535  void printOpenHeader(std::string const& _name);
5536 
5537  // if string has a : in first line will set indent to follow it on
5538  // subsequent lines
5539  void printHeaderString(std::string const& _string, std::size_t indent = 0);
5540 
5541  void printTotals(Totals const& totals);
5542  void printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row);
5543 
5544  void printTotalsDivider(Totals const& totals);
5545  void printSummaryDivider();
5546 
5547  private:
5548  bool m_headerPrinted = false;
5549  };
5550 
5551 } // end namespace Catch
5552 
5553 #if defined(_MSC_VER)
5554 #pragma warning(pop)
5555 #endif
5556 
5557 // end catch_reporter_console.h
5558 // start catch_reporter_junit.h
5559 
5560 // start catch_xmlwriter.h
5561 
5562 #include <vector>
5563 
5564 namespace Catch {
5565 
5566  class XmlEncode {
5567  public:
5568  enum ForWhat { ForTextNodes, ForAttributes };
5569 
5570  XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes );
5571 
5572  void encodeTo( std::ostream& os ) const;
5573 
5574  friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );
5575 
5576  private:
5577  std::string m_str;
5578  ForWhat m_forWhat;
5579  };
5580 
5581  class XmlWriter {
5582  public:
5583 
5584  class ScopedElement {
5585  public:
5586  ScopedElement( XmlWriter* writer );
5587 
5588  ScopedElement( ScopedElement&& other ) noexcept;
5589  ScopedElement& operator=( ScopedElement&& other ) noexcept;
5590 
5591  ~ScopedElement();
5592 
5593  ScopedElement& writeText( std::string const& text, bool indent = true );
5594 
5595  template<typename T>
5596  ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
5597  m_writer->writeAttribute( name, attribute );
5598  return *this;
5599  }
5600 
5601  private:
5602  mutable XmlWriter* m_writer = nullptr;
5603  };
5604 
5605  XmlWriter( std::ostream& os = Catch::cout() );
5606  ~XmlWriter();
5607 
5608  XmlWriter( XmlWriter const& ) = delete;
5609  XmlWriter& operator=( XmlWriter const& ) = delete;
5610 
5611  XmlWriter& startElement( std::string const& name );
5612 
5613  ScopedElement scopedElement( std::string const& name );
5614 
5615  XmlWriter& endElement();
5616 
5617  XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );
5618 
5619  XmlWriter& writeAttribute( std::string const& name, bool attribute );
5620 
5621  template<typename T>
5622  XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
5624  rss << attribute;
5625  return writeAttribute( name, rss.str() );
5626  }
5627 
5628  XmlWriter& writeText( std::string const& text, bool indent = true );
5629 
5630  XmlWriter& writeComment( std::string const& text );
5631 
5632  void writeStylesheetRef( std::string const& url );
5633 
5634  XmlWriter& writeBlankLine();
5635 
5636  void ensureTagClosed();
5637 
5638  private:
5639 
5640  void writeDeclaration();
5641 
5642  void newlineIfNecessary();
5643 
5644  bool m_tagIsOpen = false;
5645  bool m_needsNewline = false;
5646  std::vector<std::string> m_tags;
5647  std::string m_indent;
5648  std::ostream& m_os;
5649  };
5650 
5651 }
5652 
5653 // end catch_xmlwriter.h
5654 namespace Catch {
5655 
5656  class JunitReporter : public CumulativeReporterBase<JunitReporter> {
5657  public:
5658  JunitReporter(ReporterConfig const& _config);
5659 
5660  ~JunitReporter() override;
5661 
5662  static std::string getDescription();
5663 
5664  void noMatchingTestCases(std::string const& /*spec*/) override;
5665 
5666  void testRunStarting(TestRunInfo const& runInfo) override;
5667 
5668  void testGroupStarting(GroupInfo const& groupInfo) override;
5669 
5670  void testCaseStarting(TestCaseInfo const& testCaseInfo) override;
5671  bool assertionEnded(AssertionStats const& assertionStats) override;
5672 
5673  void testCaseEnded(TestCaseStats const& testCaseStats) override;
5674 
5675  void testGroupEnded(TestGroupStats const& testGroupStats) override;
5676 
5677  void testRunEndedCumulative() override;
5678 
5679  void writeGroup(TestGroupNode const& groupNode, double suiteTime);
5680 
5681  void writeTestCase(TestCaseNode const& testCaseNode);
5682 
5683  void writeSection(std::string const& className,
5684  std::string const& rootName,
5685  SectionNode const& sectionNode);
5686 
5687  void writeAssertions(SectionNode const& sectionNode);
5688  void writeAssertion(AssertionStats const& stats);
5689 
5690  XmlWriter xml;
5691  Timer suiteTimer;
5692  std::string stdOutForSuite;
5693  std::string stdErrForSuite;
5694  unsigned int unexpectedExceptions = 0;
5695  bool m_okToFail = false;
5696  };
5697 
5698 } // end namespace Catch
5699 
5700 // end catch_reporter_junit.h
5701 // start catch_reporter_xml.h
5702 
5703 namespace Catch {
5704  class XmlReporter : public StreamingReporterBase<XmlReporter> {
5705  public:
5706  XmlReporter(ReporterConfig const& _config);
5707 
5708  ~XmlReporter() override;
5709 
5710  static std::string getDescription();
5711 
5712  virtual std::string getStylesheetRef() const;
5713 
5714  void writeSourceInfo(SourceLineInfo const& sourceInfo);
5715 
5716  public: // StreamingReporterBase
5717 
5718  void noMatchingTestCases(std::string const& s) override;
5719 
5720  void testRunStarting(TestRunInfo const& testInfo) override;
5721 
5722  void testGroupStarting(GroupInfo const& groupInfo) override;
5723 
5724  void testCaseStarting(TestCaseInfo const& testInfo) override;
5725 
5726  void sectionStarting(SectionInfo const& sectionInfo) override;
5727 
5728  void assertionStarting(AssertionInfo const&) override;
5729 
5730  bool assertionEnded(AssertionStats const& assertionStats) override;
5731 
5732  void sectionEnded(SectionStats const& sectionStats) override;
5733 
5734  void testCaseEnded(TestCaseStats const& testCaseStats) override;
5735 
5736  void testGroupEnded(TestGroupStats const& testGroupStats) override;
5737 
5738  void testRunEnded(TestRunStats const& testRunStats) override;
5739 
5740  private:
5741  Timer m_testCaseTimer;
5742  XmlWriter m_xml;
5743  int m_sectionDepth = 0;
5744  };
5745 
5746 } // end namespace Catch
5747 
5748 // end catch_reporter_xml.h
5749 
5750 // end catch_external_interfaces.h
5751 #endif
5752 
5753 #endif // ! CATCH_CONFIG_IMPL_ONLY
5754 
5755 #ifdef CATCH_IMPL
5756 // start catch_impl.hpp
5757 
5758 #ifdef __clang__
5759 #pragma clang diagnostic push
5760 #pragma clang diagnostic ignored "-Wweak-vtables"
5761 #endif
5762 
5763 // Keep these here for external reporters
5764 // start catch_test_case_tracker.h
5765 
5766 #include <string>
5767 #include <vector>
5768 #include <memory>
5769 
5770 namespace Catch {
5771 namespace TestCaseTracking {
5772 
5773  struct NameAndLocation {
5774  std::string name;
5775  SourceLineInfo location;
5776 
5777  NameAndLocation( std::string const& _name, SourceLineInfo const& _location );
5778  };
5779 
5780  struct ITracker;
5781 
5782  using ITrackerPtr = std::shared_ptr<ITracker>;
5783 
5784  struct ITracker {
5785  virtual ~ITracker();
5786 
5787  // static queries
5788  virtual NameAndLocation const& nameAndLocation() const = 0;
5789 
5790  // dynamic queries
5791  virtual bool isComplete() const = 0; // Successfully completed or failed
5792  virtual bool isSuccessfullyCompleted() const = 0;
5793  virtual bool isOpen() const = 0; // Started but not complete
5794  virtual bool hasChildren() const = 0;
5795 
5796  virtual ITracker& parent() = 0;
5797 
5798  // actions
5799  virtual void close() = 0; // Successfully complete
5800  virtual void fail() = 0;
5801  virtual void markAsNeedingAnotherRun() = 0;
5802 
5803  virtual void addChild( ITrackerPtr const& child ) = 0;
5804  virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0;
5805  virtual void openChild() = 0;
5806 
5807  // Debug/ checking
5808  virtual bool isSectionTracker() const = 0;
5809  virtual bool isGeneratorTracker() const = 0;
5810  };
5811 
5812  class TrackerContext {
5813 
5814  enum RunState {
5815  NotStarted,
5816  Executing,
5817  CompletedCycle
5818  };
5819 
5820  ITrackerPtr m_rootTracker;
5821  ITracker* m_currentTracker = nullptr;
5822  RunState m_runState = NotStarted;
5823 
5824  public:
5825 
5826  static TrackerContext& instance();
5827 
5828  ITracker& startRun();
5829  void endRun();
5830 
5831  void startCycle();
5832  void completeCycle();
5833 
5834  bool completedCycle() const;
5835  ITracker& currentTracker();
5836  void setCurrentTracker( ITracker* tracker );
5837  };
5838 
5839  class TrackerBase : public ITracker {
5840  protected:
5841  enum CycleState {
5842  NotStarted,
5843  Executing,
5844  ExecutingChildren,
5845  NeedsAnotherRun,
5846  CompletedSuccessfully,
5847  Failed
5848  };
5849 
5850  using Children = std::vector<ITrackerPtr>;
5851  NameAndLocation m_nameAndLocation;
5852  TrackerContext& m_ctx;
5853  ITracker* m_parent;
5854  Children m_children;
5855  CycleState m_runState = NotStarted;
5856 
5857  public:
5858  TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
5859 
5860  NameAndLocation const& nameAndLocation() const override;
5861  bool isComplete() const override;
5862  bool isSuccessfullyCompleted() const override;
5863  bool isOpen() const override;
5864  bool hasChildren() const override;
5865 
5866  void addChild( ITrackerPtr const& child ) override;
5867 
5868  ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override;
5869  ITracker& parent() override;
5870 
5871  void openChild() override;
5872 
5873  bool isSectionTracker() const override;
5874  bool isGeneratorTracker() const override;
5875 
5876  void open();
5877 
5878  void close() override;
5879  void fail() override;
5880  void markAsNeedingAnotherRun() override;
5881 
5882  private:
5883  void moveToParent();
5884  void moveToThis();
5885  };
5886 
5887  class SectionTracker : public TrackerBase {
5888  std::vector<std::string> m_filters;
5889  public:
5890  SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
5891 
5892  bool isSectionTracker() const override;
5893 
5894  bool isComplete() const override;
5895 
5896  static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation );
5897 
5898  void tryOpen();
5899 
5900  void addInitialFilters( std::vector<std::string> const& filters );
5901  void addNextFilters( std::vector<std::string> const& filters );
5902  };
5903 
5904 } // namespace TestCaseTracking
5905 
5906 using TestCaseTracking::ITracker;
5907 using TestCaseTracking::TrackerContext;
5908 using TestCaseTracking::SectionTracker;
5909 
5910 } // namespace Catch
5911 
5912 // end catch_test_case_tracker.h
5913 
5914 // start catch_leak_detector.h
5915 
5916 namespace Catch {
5917 
5918  struct LeakDetector {
5919  LeakDetector();
5920  ~LeakDetector();
5921  };
5922 
5923 }
5924 // end catch_leak_detector.h
5925 // Cpp files will be included in the single-header file here
5926 // start catch_approx.cpp
5927 
5928 #include <cmath>
5929 #include <limits>
5930 
5931 namespace {
5932 
5933 // Performs equivalent check of std::fabs(lhs - rhs) <= margin
5934 // But without the subtraction to allow for INFINITY in comparison
5935 bool marginComparison(double lhs, double rhs, double margin) {
5936  return (lhs + margin >= rhs) && (rhs + margin >= lhs);
5937 }
5938 
5939 }
5940 
5941 namespace Catch {
5942 namespace Detail {
5943 
5944  Approx::Approx ( double value )
5945  : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
5946  m_margin( 0.0 ),
5947  m_scale( 0.0 ),
5948  m_value( value )
5949  {}
5950 
5951  Approx Approx::custom() {
5952  return Approx( 0 );
5953  }
5954 
5955  Approx Approx::operator-() const {
5956  auto temp(*this);
5957  temp.m_value = -temp.m_value;
5958  return temp;
5959  }
5960 
5961  std::string Approx::toString() const {
5963  rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
5964  return rss.str();
5965  }
5966 
5967  bool Approx::equalityComparisonImpl(const double other) const {
5968  // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
5969  // Thanks to Richard Harris for his help refining the scaled margin value
5970  return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
5971  }
5972 
5973  void Approx::setMargin(double margin) {
5974  CATCH_ENFORCE(margin >= 0,
5975  "Invalid Approx::margin: " << margin << '.'
5976  << " Approx::Margin has to be non-negative.");
5977  m_margin = margin;
5978  }
5979 
5980  void Approx::setEpsilon(double epsilon) {
5981  CATCH_ENFORCE(epsilon >= 0 && epsilon <= 1.0,
5982  "Invalid Approx::epsilon: " << epsilon << '.'
5983  << " Approx::epsilon has to be in [0, 1]");
5984  m_epsilon = epsilon;
5985  }
5986 
5987 } // end namespace Detail
5988 
5989 namespace literals {
5990  Detail::Approx operator "" _a(long double val) {
5991  return Detail::Approx(val);
5992  }
5993  Detail::Approx operator "" _a(unsigned long long val) {
5994  return Detail::Approx(val);
5995  }
5996 } // end namespace literals
5997 
5999  return value.toString();
6000 }
6001 
6002 } // end namespace Catch
6003 // end catch_approx.cpp
6004 // start catch_assertionhandler.cpp
6005 
6006 // start catch_debugger.h
6007 
6008 namespace Catch {
6009  bool isDebuggerActive();
6010 }
6011 
6012 #ifdef CATCH_PLATFORM_MAC
6013 
6014  #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
6015 
6016 #elif defined(CATCH_PLATFORM_LINUX)
6017  // If we can use inline assembler, do it because this allows us to break
6018  // directly at the location of the failing check instead of breaking inside
6019  // raise() called from it, i.e. one stack frame below.
6020  #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
6021  #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
6022  #else // Fall back to the generic way.
6023  #include <signal.h>
6024 
6025  #define CATCH_TRAP() raise(SIGTRAP)
6026  #endif
6027 #elif defined(_MSC_VER)
6028  #define CATCH_TRAP() __debugbreak()
6029 #elif defined(__MINGW32__)
6030  extern "C" __declspec(dllimport) void __stdcall DebugBreak();
6031  #define CATCH_TRAP() DebugBreak()
6032 #endif
6033 
6034 #ifdef CATCH_TRAP
6035  #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }()
6036 #else
6037  #define CATCH_BREAK_INTO_DEBUGGER() []{}()
6038 #endif
6039 
6040 // end catch_debugger.h
6041 // start catch_run_context.h
6042 
6043 // start catch_fatal_condition.h
6044 
6045 // start catch_windows_h_proxy.h
6046 
6047 
6048 #if defined(CATCH_PLATFORM_WINDOWS)
6049 
6050 #if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
6051 # define CATCH_DEFINED_NOMINMAX
6052 # define NOMINMAX
6053 #endif
6054 #if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
6055 # define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
6056 # define WIN32_LEAN_AND_MEAN
6057 #endif
6058 
6059 #ifdef __AFXDLL
6060 #include <AfxWin.h>
6061 #else
6062 #include <windows.h>
6063 #endif
6064 
6065 #ifdef CATCH_DEFINED_NOMINMAX
6066 # undef NOMINMAX
6067 #endif
6068 #ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
6069 # undef WIN32_LEAN_AND_MEAN
6070 #endif
6071 
6072 #endif // defined(CATCH_PLATFORM_WINDOWS)
6073 
6074 // end catch_windows_h_proxy.h
6075 #if defined( CATCH_CONFIG_WINDOWS_SEH )
6076 
6077 namespace Catch {
6078 
6079  struct FatalConditionHandler {
6080 
6081  static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
6082  FatalConditionHandler();
6083  static void reset();
6084  ~FatalConditionHandler();
6085 
6086  private:
6087  static bool isSet;
6088  static ULONG guaranteeSize;
6089  static PVOID exceptionHandlerHandle;
6090  };
6091 
6092 } // namespace Catch
6093 
6094 #elif defined ( CATCH_CONFIG_POSIX_SIGNALS )
6095 
6096 #include <signal.h>
6097 
6098 namespace Catch {
6099 
6100  struct FatalConditionHandler {
6101 
6102  static bool isSet;
6103  static struct sigaction oldSigActions[];
6104  static stack_t oldSigStack;
6105  static char altStackMem[];
6106 
6107  static void handleSignal( int sig );
6108 
6109  FatalConditionHandler();
6110  ~FatalConditionHandler();
6111  static void reset();
6112  };
6113 
6114 } // namespace Catch
6115 
6116 #else
6117 
6118 namespace Catch {
6119  struct FatalConditionHandler {
6120  void reset();
6121  };
6122 }
6123 
6124 #endif
6125 
6126 // end catch_fatal_condition.h
6127 #include <string>
6128 
6129 namespace Catch {
6130 
6131  struct IMutableContext;
6132 
6134 
6135  class RunContext : public IResultCapture, public IRunner {
6136 
6137  public:
6138  RunContext( RunContext const& ) = delete;
6139  RunContext& operator =( RunContext const& ) = delete;
6140 
6141  explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr&& reporter );
6142 
6143  ~RunContext() override;
6144 
6145  void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount );
6146  void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount );
6147 
6148  Totals runTest(TestCase const& testCase);
6149 
6150  IConfigPtr config() const;
6151  IStreamingReporter& reporter() const;
6152 
6153  public: // IResultCapture
6154 
6155  // Assertion handlers
6156  void handleExpr
6157  ( AssertionInfo const& info,
6158  ITransientExpression const& expr,
6159  AssertionReaction& reaction ) override;
6160  void handleMessage
6161  ( AssertionInfo const& info,
6162  ResultWas::OfType resultType,
6163  StringRef const& message,
6164  AssertionReaction& reaction ) override;
6165  void handleUnexpectedExceptionNotThrown
6166  ( AssertionInfo const& info,
6167  AssertionReaction& reaction ) override;
6168  void handleUnexpectedInflightException
6169  ( AssertionInfo const& info,
6170  std::string const& message,
6171  AssertionReaction& reaction ) override;
6172  void handleIncomplete
6173  ( AssertionInfo const& info ) override;
6174  void handleNonExpr
6175  ( AssertionInfo const &info,
6176  ResultWas::OfType resultType,
6177  AssertionReaction &reaction ) override;
6178 
6179  bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override;
6180 
6181  void sectionEnded( SectionEndInfo const& endInfo ) override;
6182  void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
6183 
6184  auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
6185 
6186  void benchmarkStarting( BenchmarkInfo const& info ) override;
6187  void benchmarkEnded( BenchmarkStats const& stats ) override;
6188 
6189  void pushScopedMessage( MessageInfo const& message ) override;
6190  void popScopedMessage( MessageInfo const& message ) override;
6191 
6192  void emplaceUnscopedMessage( MessageBuilder const& builder ) override;
6193 
6194  std::string getCurrentTestName() const override;
6195 
6196  const AssertionResult* getLastResult() const override;
6197 
6198  void exceptionEarlyReported() override;
6199 
6200  void handleFatalErrorCondition( StringRef message ) override;
6201 
6202  bool lastAssertionPassed() override;
6203 
6204  void assertionPassed() override;
6205 
6206  public:
6207  // !TBD We need to do this another way!
6208  bool aborting() const final;
6209 
6210  private:
6211 
6212  void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr );
6213  void invokeActiveTestCase();
6214 
6215  void resetAssertionInfo();
6216  bool testForMissingAssertions( Counts& assertions );
6217 
6218  void assertionEnded( AssertionResult const& result );
6219  void reportExpr
6220  ( AssertionInfo const &info,
6221  ResultWas::OfType resultType,
6222  ITransientExpression const *expr,
6223  bool negated );
6224 
6225  void populateReaction( AssertionReaction& reaction );
6226 
6227  private:
6228 
6229  void handleUnfinishedSections();
6230 
6231  TestRunInfo m_runInfo;
6232  IMutableContext& m_context;
6233  TestCase const* m_activeTestCase = nullptr;
6234  ITracker* m_testCaseTracker = nullptr;
6235  Option<AssertionResult> m_lastResult;
6236 
6237  IConfigPtr m_config;
6238  Totals m_totals;
6239  IStreamingReporterPtr m_reporter;
6240  std::vector<MessageInfo> m_messages;
6241  std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */
6242  AssertionInfo m_lastAssertionInfo;
6243  std::vector<SectionEndInfo> m_unfinishedSections;
6244  std::vector<ITracker*> m_activeSections;
6245  TrackerContext m_trackerContext;
6246  bool m_lastAssertionPassed = false;
6247  bool m_shouldReportUnexpected = true;
6248  bool m_includeSuccessfulResults;
6249  };
6250 
6251 } // end namespace Catch
6252 
6253 // end catch_run_context.h
6254 namespace Catch {
6255 
6256  namespace {
6257  auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
6258  expr.streamReconstructedExpression( os );
6259  return os;
6260  }
6261  }
6262 
6263  LazyExpression::LazyExpression( bool isNegated )
6264  : m_isNegated( isNegated )
6265  {}
6266 
6267  LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {}
6268 
6269  LazyExpression::operator bool() const {
6270  return m_transientExpression != nullptr;
6271  }
6272 
6273  auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& {
6274  if( lazyExpr.m_isNegated )
6275  os << "!";
6276 
6277  if( lazyExpr ) {
6278  if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() )
6279  os << "(" << *lazyExpr.m_transientExpression << ")";
6280  else
6281  os << *lazyExpr.m_transientExpression;
6282  }
6283  else {
6284  os << "{** error - unchecked empty expression requested **}";
6285  }
6286  return os;
6287  }
6288 
6290  ( StringRef const& macroName,
6291  SourceLineInfo const& lineInfo,
6292  StringRef capturedExpression,
6293  ResultDisposition::Flags resultDisposition )
6294  : m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },
6295  m_resultCapture( getResultCapture() )
6296  {}
6297 
6299  m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );
6300  }
6301  void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) {
6302  m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction );
6303  }
6304 
6305  auto AssertionHandler::allowThrows() const -> bool {
6306  return getCurrentContext().getConfig()->allowThrows();
6307  }
6308 
6310  setCompleted();
6311  if( m_reaction.shouldDebugBreak ) {
6312 
6313  // If you find your debugger stopping you here then go one level up on the
6314  // call-stack for the code that caused it (typically a failed assertion)
6315 
6316  // (To go back to the test and change execution, jump over the throw, next)
6317  CATCH_BREAK_INTO_DEBUGGER();
6318  }
6319  if (m_reaction.shouldThrow) {
6320 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
6322 #else
6323  CATCH_ERROR( "Test failure requires aborting test!" );
6324 #endif
6325  }
6326  }
6328  m_completed = true;
6329  }
6330 
6332  m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction );
6333  }
6334 
6336  m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
6337  }
6339  m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
6340  }
6341 
6343  m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction );
6344  }
6345 
6347  m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
6348  }
6349 
6350  // This is the overload that takes a string and infers the Equals matcher from it
6351  // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
6352  void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString ) {
6353  handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );
6354  }
6355 
6356 } // namespace Catch
6357 // end catch_assertionhandler.cpp
6358 // start catch_assertionresult.cpp
6359 
6360 namespace Catch {
6361  AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression):
6362  lazyExpression(_lazyExpression),
6363  resultType(_resultType) {}
6364 
6365  std::string AssertionResultData::reconstructExpression() const {
6366 
6367  if( reconstructedExpression.empty() ) {
6368  if( lazyExpression ) {
6370  rss << lazyExpression;
6371  reconstructedExpression = rss.str();
6372  }
6373  }
6374  return reconstructedExpression;
6375  }
6376 
6377  AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
6378  : m_info( info ),
6379  m_resultData( data )
6380  {}
6381 
6382  // Result was a success
6383  bool AssertionResult::succeeded() const {
6384  return Catch::isOk( m_resultData.resultType );
6385  }
6386 
6387  // Result was a success, or failure is suppressed
6388  bool AssertionResult::isOk() const {
6389  return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
6390  }
6391 
6392  ResultWas::OfType AssertionResult::getResultType() const {
6393  return m_resultData.resultType;
6394  }
6395 
6396  bool AssertionResult::hasExpression() const {
6397  return m_info.capturedExpression[0] != 0;
6398  }
6399 
6400  bool AssertionResult::hasMessage() const {
6401  return !m_resultData.message.empty();
6402  }
6403 
6404  std::string AssertionResult::getExpression() const {
6405  if( isFalseTest( m_info.resultDisposition ) )
6406  return "!(" + m_info.capturedExpression + ")";
6407  else
6408  return m_info.capturedExpression;
6409  }
6410 
6411  std::string AssertionResult::getExpressionInMacro() const {
6412  std::string expr;
6413  if( m_info.macroName[0] == 0 )
6414  expr = m_info.capturedExpression;
6415  else {
6416  expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
6417  expr += m_info.macroName;
6418  expr += "( ";
6419  expr += m_info.capturedExpression;
6420  expr += " )";
6421  }
6422  return expr;
6423  }
6424 
6425  bool AssertionResult::hasExpandedExpression() const {
6426  return hasExpression() && getExpandedExpression() != getExpression();
6427  }
6428 
6429  std::string AssertionResult::getExpandedExpression() const {
6430  std::string expr = m_resultData.reconstructExpression();
6431  return expr.empty()
6432  ? getExpression()
6433  : expr;
6434  }
6435 
6436  std::string AssertionResult::getMessage() const {
6437  return m_resultData.message;
6438  }
6439  SourceLineInfo AssertionResult::getSourceInfo() const {
6440  return m_info.lineInfo;
6441  }
6442 
6443  StringRef AssertionResult::getTestMacroName() const {
6444  return m_info.macroName;
6445  }
6446 
6447 } // end namespace Catch
6448 // end catch_assertionresult.cpp
6449 // start catch_benchmark.cpp
6450 
6451 namespace Catch {
6452 
6453  auto BenchmarkLooper::getResolution() -> uint64_t {
6454  return getEstimatedClockResolution() * getCurrentContext().getConfig()->benchmarkResolutionMultiple();
6455  }
6456 
6458  getResultCapture().benchmarkStarting( { m_name } );
6459  }
6460  auto BenchmarkLooper::needsMoreIterations() -> bool {
6461  auto elapsed = m_timer.getElapsedNanoseconds();
6462 
6463  // Exponentially increasing iterations until we're confident in our timer resolution
6464  if( elapsed < m_resolution ) {
6465  m_iterationsToRun *= 10;
6466  return true;
6467  }
6468 
6469  getResultCapture().benchmarkEnded( { { m_name }, m_count, elapsed } );
6470  return false;
6471  }
6472 
6473 } // end namespace Catch
6474 // end catch_benchmark.cpp
6475 // start catch_capture_matchers.cpp
6476 
6477 namespace Catch {
6478 
6480 
6481  // This is the general overload that takes a any string matcher
6482  // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
6483  // the Equals matcher (so the header does not mention matchers)
6484  void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString ) {
6485  std::string exceptionMessage = Catch::translateActiveException();
6486  MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );
6487  handler.handleExpr( expr );
6488  }
6489 
6490 } // namespace Catch
6491 // end catch_capture_matchers.cpp
6492 // start catch_commandline.cpp
6493 
6494 // start catch_commandline.h
6495 
6496 // start catch_clara.h
6497 
6498 // Use Catch's value for console width (store Clara's off to the side, if present)
6499 #ifdef CLARA_CONFIG_CONSOLE_WIDTH
6500 #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
6501 #undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
6502 #endif
6503 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1
6504 
6505 #ifdef __clang__
6506 #pragma clang diagnostic push
6507 #pragma clang diagnostic ignored "-Wweak-vtables"
6508 #pragma clang diagnostic ignored "-Wexit-time-destructors"
6509 #pragma clang diagnostic ignored "-Wshadow"
6510 #endif
6511 
6512 // start clara.hpp
6513 // Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
6514 //
6515 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6516 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6517 //
6518 // See https://github.com/philsquared/Clara for more details
6519 
6520 // Clara v1.1.5
6521 
6522 
6523 #ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
6524 #define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80
6525 #endif
6526 
6527 #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
6528 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH
6529 #endif
6530 
6531 #ifndef CLARA_CONFIG_OPTIONAL_TYPE
6532 #ifdef __has_include
6533 #if __has_include(<optional>) && __cplusplus >= 201703L
6534 #include <optional>
6535 #define CLARA_CONFIG_OPTIONAL_TYPE std::optional
6536 #endif
6537 #endif
6538 #endif
6539 
6540 // ----------- #included from clara_textflow.hpp -----------
6541 
6542 // TextFlowCpp
6543 //
6544 // A single-header library for wrapping and laying out basic text, by Phil Nash
6545 //
6546 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6547 // file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6548 //
6549 // This project is hosted at https://github.com/philsquared/textflowcpp
6550 
6551 
6552 #include <cassert>
6553 #include <ostream>
6554 #include <sstream>
6555 #include <vector>
6556 
6557 #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
6558 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80
6559 #endif
6560 
6561 namespace Catch {
6562 namespace clara {
6563 namespace TextFlow {
6564 
6565 inline auto isWhitespace(char c) -> bool {
6566  static std::string chars = " \t\n\r";
6567  return chars.find(c) != std::string::npos;
6568 }
6569 inline auto isBreakableBefore(char c) -> bool {
6570  static std::string chars = "[({<|";
6571  return chars.find(c) != std::string::npos;
6572 }
6573 inline auto isBreakableAfter(char c) -> bool {
6574  static std::string chars = "])}>.,:;*+-=&/\\";
6575  return chars.find(c) != std::string::npos;
6576 }
6577 
6578 class Columns;
6579 
6580 class Column {
6581  std::vector<std::string> m_strings;
6582  size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
6583  size_t m_indent = 0;
6584  size_t m_initialIndent = std::string::npos;
6585 
6586 public:
6587  class iterator {
6588  friend Column;
6589 
6590  Column const& m_column;
6591  size_t m_stringIndex = 0;
6592  size_t m_pos = 0;
6593 
6594  size_t m_len = 0;
6595  size_t m_end = 0;
6596  bool m_suffix = false;
6597 
6598  iterator(Column const& column, size_t stringIndex)
6599  : m_column(column),
6600  m_stringIndex(stringIndex) {}
6601 
6602  auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
6603 
6604  auto isBoundary(size_t at) const -> bool {
6605  assert(at > 0);
6606  assert(at <= line().size());
6607 
6608  return at == line().size() ||
6609  (isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) ||
6610  isBreakableBefore(line()[at]) ||
6611  isBreakableAfter(line()[at - 1]);
6612  }
6613 
6614  void calcLength() {
6615  assert(m_stringIndex < m_column.m_strings.size());
6616 
6617  m_suffix = false;
6618  auto width = m_column.m_width - indent();
6619  m_end = m_pos;
6620  while (m_end < line().size() && line()[m_end] != '\n')
6621  ++m_end;
6622 
6623  if (m_end < m_pos + width) {
6624  m_len = m_end - m_pos;
6625  } else {
6626  size_t len = width;
6627  while (len > 0 && !isBoundary(m_pos + len))
6628  --len;
6629  while (len > 0 && isWhitespace(line()[m_pos + len - 1]))
6630  --len;
6631 
6632  if (len > 0) {
6633  m_len = len;
6634  } else {
6635  m_suffix = true;
6636  m_len = width - 1;
6637  }
6638  }
6639  }
6640 
6641  auto indent() const -> size_t {
6642  auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
6643  return initial == std::string::npos ? m_column.m_indent : initial;
6644  }
6645 
6646  auto addIndentAndSuffix(std::string const &plain) const -> std::string {
6647  return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain);
6648  }
6649 
6650  public:
6651  using difference_type = std::ptrdiff_t;
6652  using value_type = std::string;
6653  using pointer = value_type * ;
6654  using reference = value_type & ;
6655  using iterator_category = std::forward_iterator_tag;
6656 
6657  explicit iterator(Column const& column) : m_column(column) {
6658  assert(m_column.m_width > m_column.m_indent);
6659  assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent);
6660  calcLength();
6661  if (m_len == 0)
6662  m_stringIndex++; // Empty string
6663  }
6664 
6665  auto operator *() const -> std::string {
6666  assert(m_stringIndex < m_column.m_strings.size());
6667  assert(m_pos <= m_end);
6668  return addIndentAndSuffix(line().substr(m_pos, m_len));
6669  }
6670 
6671  auto operator ++() -> iterator& {
6672  m_pos += m_len;
6673  if (m_pos < line().size() && line()[m_pos] == '\n')
6674  m_pos += 1;
6675  else
6676  while (m_pos < line().size() && isWhitespace(line()[m_pos]))
6677  ++m_pos;
6678 
6679  if (m_pos == line().size()) {
6680  m_pos = 0;
6681  ++m_stringIndex;
6682  }
6683  if (m_stringIndex < m_column.m_strings.size())
6684  calcLength();
6685  return *this;
6686  }
6687  auto operator ++(int) -> iterator {
6688  iterator prev(*this);
6689  operator++();
6690  return prev;
6691  }
6692 
6693  auto operator ==(iterator const& other) const -> bool {
6694  return
6695  m_pos == other.m_pos &&
6696  m_stringIndex == other.m_stringIndex &&
6697  &m_column == &other.m_column;
6698  }
6699  auto operator !=(iterator const& other) const -> bool {
6700  return !operator==(other);
6701  }
6702  };
6703  using const_iterator = iterator;
6704 
6705  explicit Column(std::string const& text) { m_strings.push_back(text); }
6706 
6707  auto width(size_t newWidth) -> Column& {
6708  assert(newWidth > 0);
6709  m_width = newWidth;
6710  return *this;
6711  }
6712  auto indent(size_t newIndent) -> Column& {
6713  m_indent = newIndent;
6714  return *this;
6715  }
6716  auto initialIndent(size_t newIndent) -> Column& {
6717  m_initialIndent = newIndent;
6718  return *this;
6719  }
6720 
6721  auto width() const -> size_t { return m_width; }
6722  auto begin() const -> iterator { return iterator(*this); }
6723  auto end() const -> iterator { return { *this, m_strings.size() }; }
6724 
6725  inline friend std::ostream& operator << (std::ostream& os, Column const& col) {
6726  bool first = true;
6727  for (auto line : col) {
6728  if (first)
6729  first = false;
6730  else
6731  os << "\n";
6732  os << line;
6733  }
6734  return os;
6735  }
6736 
6737  auto operator + (Column const& other)->Columns;
6738 
6739  auto toString() const -> std::string {
6740  std::ostringstream oss;
6741  oss << *this;
6742  return oss.str();
6743  }
6744 };
6745 
6746 class Spacer : public Column {
6747 
6748 public:
6749  explicit Spacer(size_t spaceWidth) : Column("") {
6750  width(spaceWidth);
6751  }
6752 };
6753 
6754 class Columns {
6755  std::vector<Column> m_columns;
6756 
6757 public:
6758 
6759  class iterator {
6760  friend Columns;
6761  struct EndTag {};
6762 
6763  std::vector<Column> const& m_columns;
6764  std::vector<Column::iterator> m_iterators;
6765  size_t m_activeIterators;
6766 
6767  iterator(Columns const& columns, EndTag)
6768  : m_columns(columns.m_columns),
6769  m_activeIterators(0) {
6770  m_iterators.reserve(m_columns.size());
6771 
6772  for (auto const& col : m_columns)
6773  m_iterators.push_back(col.end());
6774  }
6775 
6776  public:
6777  using difference_type = std::ptrdiff_t;
6778  using value_type = std::string;
6779  using pointer = value_type * ;
6780  using reference = value_type & ;
6781  using iterator_category = std::forward_iterator_tag;
6782 
6783  explicit iterator(Columns const& columns)
6784  : m_columns(columns.m_columns),
6785  m_activeIterators(m_columns.size()) {
6786  m_iterators.reserve(m_columns.size());
6787 
6788  for (auto const& col : m_columns)
6789  m_iterators.push_back(col.begin());
6790  }
6791 
6792  auto operator ==(iterator const& other) const -> bool {
6793  return m_iterators == other.m_iterators;
6794  }
6795  auto operator !=(iterator const& other) const -> bool {
6796  return m_iterators != other.m_iterators;
6797  }
6798  auto operator *() const -> std::string {
6799  std::string row, padding;
6800 
6801  for (size_t i = 0; i < m_columns.size(); ++i) {
6802  auto width = m_columns[i].width();
6803  if (m_iterators[i] != m_columns[i].end()) {
6804  std::string col = *m_iterators[i];
6805  row += padding + col;
6806  if (col.size() < width)
6807  padding = std::string(width - col.size(), ' ');
6808  else
6809  padding = "";
6810  } else {
6811  padding += std::string(width, ' ');
6812  }
6813  }
6814  return row;
6815  }
6816  auto operator ++() -> iterator& {
6817  for (size_t i = 0; i < m_columns.size(); ++i) {
6818  if (m_iterators[i] != m_columns[i].end())
6819  ++m_iterators[i];
6820  }
6821  return *this;
6822  }
6823  auto operator ++(int) -> iterator {
6824  iterator prev(*this);
6825  operator++();
6826  return prev;
6827  }
6828  };
6829  using const_iterator = iterator;
6830 
6831  auto begin() const -> iterator { return iterator(*this); }
6832  auto end() const -> iterator { return { *this, iterator::EndTag() }; }
6833 
6834  auto operator += (Column const& col) -> Columns& {
6835  m_columns.push_back(col);
6836  return *this;
6837  }
6838  auto operator + (Column const& col) -> Columns {
6839  Columns combined = *this;
6840  combined += col;
6841  return combined;
6842  }
6843 
6844  inline friend std::ostream& operator << (std::ostream& os, Columns const& cols) {
6845 
6846  bool first = true;
6847  for (auto line : cols) {
6848  if (first)
6849  first = false;
6850  else
6851  os << "\n";
6852  os << line;
6853  }
6854  return os;
6855  }
6856 
6857  auto toString() const -> std::string {
6858  std::ostringstream oss;
6859  oss << *this;
6860  return oss.str();
6861  }
6862 };
6863 
6864 inline auto Column::operator + (Column const& other) -> Columns {
6865  Columns cols;
6866  cols += *this;
6867  cols += other;
6868  return cols;
6869 }
6870 }
6871 
6872 }
6873 }
6874 
6875 // ----------- end of #include from clara_textflow.hpp -----------
6876 // ........... back in clara.hpp
6877 
6878 #include <cctype>
6879 #include <string>
6880 #include <memory>
6881 #include <set>
6882 #include <algorithm>
6883 
6884 #if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) )
6885 #define CATCH_PLATFORM_WINDOWS
6886 #endif
6887 
6888 namespace Catch { namespace clara {
6889 namespace detail {
6890 
6891  // Traits for extracting arg and return type of lambdas (for single argument lambdas)
6892  template<typename L>
6893  struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {};
6894 
6895  template<typename ClassT, typename ReturnT, typename... Args>
6896  struct UnaryLambdaTraits<ReturnT( ClassT::* )( Args... ) const> {
6897  static const bool isValid = false;
6898  };
6899 
6900  template<typename ClassT, typename ReturnT, typename ArgT>
6901  struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
6902  static const bool isValid = true;
6903  using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;
6904  using ReturnType = ReturnT;
6905  };
6906 
6907  class TokenStream;
6908 
6909  // Transport for raw args (copied from main args, or supplied via init list for testing)
6910  class Args {
6911  friend TokenStream;
6912  std::string m_exeName;
6913  std::vector<std::string> m_args;
6914 
6915  public:
6916  Args( int argc, char const* const* argv )
6917  : m_exeName(argv[0]),
6918  m_args(argv + 1, argv + argc) {}
6919 
6920  Args( std::initializer_list<std::string> args )
6921  : m_exeName( *args.begin() ),
6922  m_args( args.begin()+1, args.end() )
6923  {}
6924 
6925  auto exeName() const -> std::string {
6926  return m_exeName;
6927  }
6928  };
6929 
6930  // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string
6931  // may encode an option + its argument if the : or = form is used
6932  enum class TokenType {
6933  Option, Argument
6934  };
6935  struct Token {
6936  TokenType type;
6937  std::string token;
6938  };
6939 
6940  inline auto isOptPrefix( char c ) -> bool {
6941  return c == '-'
6942 #ifdef CATCH_PLATFORM_WINDOWS
6943  || c == '/'
6944 #endif
6945  ;
6946  }
6947 
6948  // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
6949  class TokenStream {
6950  using Iterator = std::vector<std::string>::const_iterator;
6951  Iterator it;
6952  Iterator itEnd;
6953  std::vector<Token> m_tokenBuffer;
6954 
6955  void loadBuffer() {
6956  m_tokenBuffer.resize( 0 );
6957 
6958  // Skip any empty strings
6959  while( it != itEnd && it->empty() )
6960  ++it;
6961 
6962  if( it != itEnd ) {
6963  auto const &next = *it;
6964  if( isOptPrefix( next[0] ) ) {
6965  auto delimiterPos = next.find_first_of( " :=" );
6966  if( delimiterPos != std::string::npos ) {
6967  m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
6968  m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } );
6969  } else {
6970  if( next[1] != '-' && next.size() > 2 ) {
6971  std::string opt = "- ";
6972  for( size_t i = 1; i < next.size(); ++i ) {
6973  opt[1] = next[i];
6974  m_tokenBuffer.push_back( { TokenType::Option, opt } );
6975  }
6976  } else {
6977  m_tokenBuffer.push_back( { TokenType::Option, next } );
6978  }
6979  }
6980  } else {
6981  m_tokenBuffer.push_back( { TokenType::Argument, next } );
6982  }
6983  }
6984  }
6985 
6986  public:
6987  explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {}
6988 
6989  TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) {
6990  loadBuffer();
6991  }
6992 
6993  explicit operator bool() const {
6994  return !m_tokenBuffer.empty() || it != itEnd;
6995  }
6996 
6997  auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); }
6998 
6999  auto operator*() const -> Token {
7000  assert( !m_tokenBuffer.empty() );
7001  return m_tokenBuffer.front();
7002  }
7003 
7004  auto operator->() const -> Token const * {
7005  assert( !m_tokenBuffer.empty() );
7006  return &m_tokenBuffer.front();
7007  }
7008 
7009  auto operator++() -> TokenStream & {
7010  if( m_tokenBuffer.size() >= 2 ) {
7011  m_tokenBuffer.erase( m_tokenBuffer.begin() );
7012  } else {
7013  if( it != itEnd )
7014  ++it;
7015  loadBuffer();
7016  }
7017  return *this;
7018  }
7019  };
7020 
7021  class ResultBase {
7022  public:
7023  enum Type {
7024  Ok, LogicError, RuntimeError
7025  };
7026 
7027  protected:
7028  ResultBase( Type type ) : m_type( type ) {}
7029  virtual ~ResultBase() = default;
7030 
7031  virtual void enforceOk() const = 0;
7032 
7033  Type m_type;
7034  };
7035 
7036  template<typename T>
7037  class ResultValueBase : public ResultBase {
7038  public:
7039  auto value() const -> T const & {
7040  enforceOk();
7041  return m_value;
7042  }
7043 
7044  protected:
7045  ResultValueBase( Type type ) : ResultBase( type ) {}
7046 
7047  ResultValueBase( ResultValueBase const &other ) : ResultBase( other ) {
7048  if( m_type == ResultBase::Ok )
7049  new( &m_value ) T( other.m_value );
7050  }
7051 
7052  ResultValueBase( Type, T const &value ) : ResultBase( Ok ) {
7053  new( &m_value ) T( value );
7054  }
7055 
7056  auto operator=( ResultValueBase const &other ) -> ResultValueBase & {
7057  if( m_type == ResultBase::Ok )
7058  m_value.~T();
7059  ResultBase::operator=(other);
7060  if( m_type == ResultBase::Ok )
7061  new( &m_value ) T( other.m_value );
7062  return *this;
7063  }
7064 
7065  ~ResultValueBase() override {
7066  if( m_type == Ok )
7067  m_value.~T();
7068  }
7069 
7070  union {
7071  T m_value;
7072  };
7073  };
7074 
7075  template<>
7076  class ResultValueBase<void> : public ResultBase {
7077  protected:
7078  using ResultBase::ResultBase;
7079  };
7080 
7081  template<typename T = void>
7082  class BasicResult : public ResultValueBase<T> {
7083  public:
7084  template<typename U>
7085  explicit BasicResult( BasicResult<U> const &other )
7086  : ResultValueBase<T>( other.type() ),
7087  m_errorMessage( other.errorMessage() )
7088  {
7089  assert( type() != ResultBase::Ok );
7090  }
7091 
7092  template<typename U>
7093  static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; }
7094  static auto ok() -> BasicResult { return { ResultBase::Ok }; }
7095  static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; }
7096  static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; }
7097 
7098  explicit operator bool() const { return m_type == ResultBase::Ok; }
7099  auto type() const -> ResultBase::Type { return m_type; }
7100  auto errorMessage() const -> std::string { return m_errorMessage; }
7101 
7102  protected:
7103  void enforceOk() const override {
7104 
7105  // Errors shouldn't reach this point, but if they do
7106  // the actual error message will be in m_errorMessage
7107  assert( m_type != ResultBase::LogicError );
7108  assert( m_type != ResultBase::RuntimeError );
7109  if( m_type != ResultBase::Ok )
7110  std::abort();
7111  }
7112 
7113  std::string m_errorMessage; // Only populated if resultType is an error
7114 
7115  BasicResult( ResultBase::Type type, std::string const &message )
7116  : ResultValueBase<T>(type),
7117  m_errorMessage(message)
7118  {
7119  assert( m_type != ResultBase::Ok );
7120  }
7121 
7122  using ResultValueBase<T>::ResultValueBase;
7123  using ResultBase::m_type;
7124  };
7125 
7126  enum class ParseResultType {
7127  Matched, NoMatch, ShortCircuitAll, ShortCircuitSame
7128  };
7129 
7130  class ParseState {
7131  public:
7132 
7133  ParseState( ParseResultType type, TokenStream const &remainingTokens )
7134  : m_type(type),
7135  m_remainingTokens( remainingTokens )
7136  {}
7137 
7138  auto type() const -> ParseResultType { return m_type; }
7139  auto remainingTokens() const -> TokenStream { return m_remainingTokens; }
7140 
7141  private:
7142  ParseResultType m_type;
7143  TokenStream m_remainingTokens;
7144  };
7145 
7146  using Result = BasicResult<void>;
7147  using ParserResult = BasicResult<ParseResultType>;
7148  using InternalParseResult = BasicResult<ParseState>;
7149 
7150  struct HelpColumns {
7151  std::string left;
7152  std::string right;
7153  };
7154 
7155  template<typename T>
7156  inline auto convertInto( std::string const &source, T& target ) -> ParserResult {
7157  std::stringstream ss;
7158  ss << source;
7159  ss >> target;
7160  if( ss.fail() )
7161  return ParserResult::runtimeError( "Unable to convert '" + source + "' to destination type" );
7162  else
7163  return ParserResult::ok( ParseResultType::Matched );
7164  }
7165  inline auto convertInto( std::string const &source, std::string& target ) -> ParserResult {
7166  target = source;
7167  return ParserResult::ok( ParseResultType::Matched );
7168  }
7169  inline auto convertInto( std::string const &source, bool &target ) -> ParserResult {
7170  std::string srcLC = source;
7171  std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast<char>( std::tolower(c) ); } );
7172  if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
7173  target = true;
7174  else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
7175  target = false;
7176  else
7177  return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" );
7178  return ParserResult::ok( ParseResultType::Matched );
7179  }
7180 #ifdef CLARA_CONFIG_OPTIONAL_TYPE
7181  template<typename T>
7182  inline auto convertInto( std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target ) -> ParserResult {
7183  T temp;
7184  auto result = convertInto( source, temp );
7185  if( result )
7186  target = std::move(temp);
7187  return result;
7188  }
7189 #endif // CLARA_CONFIG_OPTIONAL_TYPE
7190 
7191  struct NonCopyable {
7192  NonCopyable() = default;
7193  NonCopyable( NonCopyable const & ) = delete;
7194  NonCopyable( NonCopyable && ) = delete;
7195  NonCopyable &operator=( NonCopyable const & ) = delete;
7196  NonCopyable &operator=( NonCopyable && ) = delete;
7197  };
7198 
7199  struct BoundRef : NonCopyable {
7200  virtual ~BoundRef() = default;
7201  virtual auto isContainer() const -> bool { return false; }
7202  virtual auto isFlag() const -> bool { return false; }
7203  };
7204  struct BoundValueRefBase : BoundRef {
7205  virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
7206  };
7207  struct BoundFlagRefBase : BoundRef {
7208  virtual auto setFlag( bool flag ) -> ParserResult = 0;
7209  virtual auto isFlag() const -> bool { return true; }
7210  };
7211 
7212  template<typename T>
7213  struct BoundValueRef : BoundValueRefBase {
7214  T &m_ref;
7215 
7216  explicit BoundValueRef( T &ref ) : m_ref( ref ) {}
7217 
7218  auto setValue( std::string const &arg ) -> ParserResult override {
7219  return convertInto( arg, m_ref );
7220  }
7221  };
7222 
7223  template<typename T>
7224  struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
7225  std::vector<T> &m_ref;
7226 
7227  explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {}
7228 
7229  auto isContainer() const -> bool override { return true; }
7230 
7231  auto setValue( std::string const &arg ) -> ParserResult override {
7232  T temp;
7233  auto result = convertInto( arg, temp );
7234  if( result )
7235  m_ref.push_back( temp );
7236  return result;
7237  }
7238  };
7239 
7240  struct BoundFlagRef : BoundFlagRefBase {
7241  bool &m_ref;
7242 
7243  explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {}
7244 
7245  auto setFlag( bool flag ) -> ParserResult override {
7246  m_ref = flag;
7247  return ParserResult::ok( ParseResultType::Matched );
7248  }
7249  };
7250 
7251  template<typename ReturnType>
7252  struct LambdaInvoker {
7253  static_assert( std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult" );
7254 
7255  template<typename L, typename ArgType>
7256  static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
7257  return lambda( arg );
7258  }
7259  };
7260 
7261  template<>
7262  struct LambdaInvoker<void> {
7263  template<typename L, typename ArgType>
7264  static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
7265  lambda( arg );
7266  return ParserResult::ok( ParseResultType::Matched );
7267  }
7268  };
7269 
7270  template<typename ArgType, typename L>
7271  inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
7272  ArgType temp{};
7273  auto result = convertInto( arg, temp );
7274  return !result
7275  ? result
7276  : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
7277  }
7278 
7279  template<typename L>
7280  struct BoundLambda : BoundValueRefBase {
7281  L m_lambda;
7282 
7283  static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
7284  explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {}
7285 
7286  auto setValue( std::string const &arg ) -> ParserResult override {
7287  return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>( m_lambda, arg );
7288  }
7289  };
7290 
7291  template<typename L>
7292  struct BoundFlagLambda : BoundFlagRefBase {
7293  L m_lambda;
7294 
7295  static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
7296  static_assert( std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, "flags must be boolean" );
7297 
7298  explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {}
7299 
7300  auto setFlag( bool flag ) -> ParserResult override {
7301  return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( m_lambda, flag );
7302  }
7303  };
7304 
7305  enum class Optionality { Optional, Required };
7306 
7307  struct Parser;
7308 
7309  class ParserBase {
7310  public:
7311  virtual ~ParserBase() = default;
7312  virtual auto validate() const -> Result { return Result::ok(); }
7313  virtual auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult = 0;
7314  virtual auto cardinality() const -> size_t { return 1; }
7315 
7316  auto parse( Args const &args ) const -> InternalParseResult {
7317  return parse( args.exeName(), TokenStream( args ) );
7318  }
7319  };
7320 
7321  template<typename DerivedT>
7322  class ComposableParserImpl : public ParserBase {
7323  public:
7324  template<typename T>
7325  auto operator|( T const &other ) const -> Parser;
7326 
7327  template<typename T>
7328  auto operator+( T const &other ) const -> Parser;
7329  };
7330 
7331  // Common code and state for Args and Opts
7332  template<typename DerivedT>
7333  class ParserRefImpl : public ComposableParserImpl<DerivedT> {
7334  protected:
7335  Optionality m_optionality = Optionality::Optional;
7336  std::shared_ptr<BoundRef> m_ref;
7337  std::string m_hint;
7338  std::string m_description;
7339 
7340  explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {}
7341 
7342  public:
7343  template<typename T>
7344  ParserRefImpl( T &ref, std::string const &hint )
7345  : m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
7346  m_hint( hint )
7347  {}
7348 
7349  template<typename LambdaT>
7350  ParserRefImpl( LambdaT const &ref, std::string const &hint )
7351  : m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),
7352  m_hint(hint)
7353  {}
7354 
7355  auto operator()( std::string const &description ) -> DerivedT & {
7356  m_description = description;
7357  return static_cast<DerivedT &>( *this );
7358  }
7359 
7360  auto optional() -> DerivedT & {
7361  m_optionality = Optionality::Optional;
7362  return static_cast<DerivedT &>( *this );
7363  };
7364 
7365  auto required() -> DerivedT & {
7366  m_optionality = Optionality::Required;
7367  return static_cast<DerivedT &>( *this );
7368  };
7369 
7370  auto isOptional() const -> bool {
7371  return m_optionality == Optionality::Optional;
7372  }
7373 
7374  auto cardinality() const -> size_t override {
7375  if( m_ref->isContainer() )
7376  return 0;
7377  else
7378  return 1;
7379  }
7380 
7381  auto hint() const -> std::string { return m_hint; }
7382  };
7383 
7384  class ExeName : public ComposableParserImpl<ExeName> {
7385  std::shared_ptr<std::string> m_name;
7386  std::shared_ptr<BoundValueRefBase> m_ref;
7387 
7388  template<typename LambdaT>
7389  static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {
7390  return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
7391  }
7392 
7393  public:
7394  ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
7395 
7396  explicit ExeName( std::string &ref ) : ExeName() {
7397  m_ref = std::make_shared<BoundValueRef<std::string>>( ref );
7398  }
7399 
7400  template<typename LambdaT>
7401  explicit ExeName( LambdaT const& lambda ) : ExeName() {
7402  m_ref = std::make_shared<BoundLambda<LambdaT>>( lambda );
7403  }
7404 
7405  // The exe name is not parsed out of the normal tokens, but is handled specially
7406  auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
7407  return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
7408  }
7409 
7410  auto name() const -> std::string { return *m_name; }
7411  auto set( std::string const& newName ) -> ParserResult {
7412 
7413  auto lastSlash = newName.find_last_of( "\\/" );
7414  auto filename = ( lastSlash == std::string::npos )
7415  ? newName
7416  : newName.substr( lastSlash+1 );
7417 
7418  *m_name = filename;
7419  if( m_ref )
7420  return m_ref->setValue( filename );
7421  else
7422  return ParserResult::ok( ParseResultType::Matched );
7423  }
7424  };
7425 
7426  class Arg : public ParserRefImpl<Arg> {
7427  public:
7428  using ParserRefImpl::ParserRefImpl;
7429 
7430  auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override {
7431  auto validationResult = validate();
7432  if( !validationResult )
7433  return InternalParseResult( validationResult );
7434 
7435  auto remainingTokens = tokens;
7436  auto const &token = *remainingTokens;
7437  if( token.type != TokenType::Argument )
7438  return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
7439 
7440  assert( !m_ref->isFlag() );
7441  auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
7442 
7443  auto result = valueRef->setValue( remainingTokens->token );
7444  if( !result )
7445  return InternalParseResult( result );
7446  else
7447  return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
7448  }
7449  };
7450 
7451  inline auto normaliseOpt( std::string const &optName ) -> std::string {
7452 #ifdef CATCH_PLATFORM_WINDOWS
7453  if( optName[0] == '/' )
7454  return "-" + optName.substr( 1 );
7455  else
7456 #endif
7457  return optName;
7458  }
7459 
7460  class Opt : public ParserRefImpl<Opt> {
7461  protected:
7462  std::vector<std::string> m_optNames;
7463 
7464  public:
7465  template<typename LambdaT>
7466  explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared<BoundFlagLambda<LambdaT>>( ref ) ) {}
7467 
7468  explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared<BoundFlagRef>( ref ) ) {}
7469 
7470  template<typename LambdaT>
7471  Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
7472 
7473  template<typename T>
7474  Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
7475 
7476  auto operator[]( std::string const &optName ) -> Opt & {
7477  m_optNames.push_back( optName );
7478  return *this;
7479  }
7480 
7481  auto getHelpColumns() const -> std::vector<HelpColumns> {
7482  std::ostringstream oss;
7483  bool first = true;
7484  for( auto const &opt : m_optNames ) {
7485  if (first)
7486  first = false;
7487  else
7488  oss << ", ";
7489  oss << opt;
7490  }
7491  if( !m_hint.empty() )
7492  oss << " <" << m_hint << ">";
7493  return { { oss.str(), m_description } };
7494  }
7495 
7496  auto isMatch( std::string const &optToken ) const -> bool {
7497  auto normalisedToken = normaliseOpt( optToken );
7498  for( auto const &name : m_optNames ) {
7499  if( normaliseOpt( name ) == normalisedToken )
7500  return true;
7501  }
7502  return false;
7503  }
7504 
7505  using ParserBase::parse;
7506 
7507  auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
7508  auto validationResult = validate();
7509  if( !validationResult )
7510  return InternalParseResult( validationResult );
7511 
7512  auto remainingTokens = tokens;
7513  if( remainingTokens && remainingTokens->type == TokenType::Option ) {
7514  auto const &token = *remainingTokens;
7515  if( isMatch(token.token ) ) {
7516  if( m_ref->isFlag() ) {
7517  auto flagRef = static_cast<detail::BoundFlagRefBase*>( m_ref.get() );
7518  auto result = flagRef->setFlag( true );
7519  if( !result )
7520  return InternalParseResult( result );
7521  if( result.value() == ParseResultType::ShortCircuitAll )
7522  return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
7523  } else {
7524  auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
7525  ++remainingTokens;
7526  if( !remainingTokens )
7527  return InternalParseResult::runtimeError( "Expected argument following " + token.token );
7528  auto const &argToken = *remainingTokens;
7529  if( argToken.type != TokenType::Argument )
7530  return InternalParseResult::runtimeError( "Expected argument following " + token.token );
7531  auto result = valueRef->setValue( argToken.token );
7532  if( !result )
7533  return InternalParseResult( result );
7534  if( result.value() == ParseResultType::ShortCircuitAll )
7535  return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
7536  }
7537  return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
7538  }
7539  }
7540  return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
7541  }
7542 
7543  auto validate() const -> Result override {
7544  if( m_optNames.empty() )
7545  return Result::logicError( "No options supplied to Opt" );
7546  for( auto const &name : m_optNames ) {
7547  if( name.empty() )
7548  return Result::logicError( "Option name cannot be empty" );
7549 #ifdef CATCH_PLATFORM_WINDOWS
7550  if( name[0] != '-' && name[0] != '/' )
7551  return Result::logicError( "Option name must begin with '-' or '/'" );
7552 #else
7553  if( name[0] != '-' )
7554  return Result::logicError( "Option name must begin with '-'" );
7555 #endif
7556  }
7557  return ParserRefImpl::validate();
7558  }
7559  };
7560 
7561  struct Help : Opt {
7562  Help( bool &showHelpFlag )
7563  : Opt([&]( bool flag ) {
7564  showHelpFlag = flag;
7565  return ParserResult::ok( ParseResultType::ShortCircuitAll );
7566  })
7567  {
7568  static_cast<Opt &>( *this )
7569  ("display usage information")
7570  ["-?"]["-h"]["--help"]
7571  .optional();
7572  }
7573  };
7574 
7575  struct Parser : ParserBase {
7576 
7577  mutable ExeName m_exeName;
7578  std::vector<Opt> m_options;
7579  std::vector<Arg> m_args;
7580 
7581  auto operator|=( ExeName const &exeName ) -> Parser & {
7582  m_exeName = exeName;
7583  return *this;
7584  }
7585 
7586  auto operator|=( Arg const &arg ) -> Parser & {
7587  m_args.push_back(arg);
7588  return *this;
7589  }
7590 
7591  auto operator|=( Opt const &opt ) -> Parser & {
7592  m_options.push_back(opt);
7593  return *this;
7594  }
7595 
7596  auto operator|=( Parser const &other ) -> Parser & {
7597  m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
7598  m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
7599  return *this;
7600  }
7601 
7602  template<typename T>
7603  auto operator|( T const &other ) const -> Parser {
7604  return Parser( *this ) |= other;
7605  }
7606 
7607  // Forward deprecated interface with '+' instead of '|'
7608  template<typename T>
7609  auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }
7610  template<typename T>
7611  auto operator+( T const &other ) const -> Parser { return operator|( other ); }
7612 
7613  auto getHelpColumns() const -> std::vector<HelpColumns> {
7614  std::vector<HelpColumns> cols;
7615  for (auto const &o : m_options) {
7616  auto childCols = o.getHelpColumns();
7617  cols.insert( cols.end(), childCols.begin(), childCols.end() );
7618  }
7619  return cols;
7620  }
7621 
7622  void writeToStream( std::ostream &os ) const {
7623  if (!m_exeName.name().empty()) {
7624  os << "usage:\n" << " " << m_exeName.name() << " ";
7625  bool required = true, first = true;
7626  for( auto const &arg : m_args ) {
7627  if (first)
7628  first = false;
7629  else
7630  os << " ";
7631  if( arg.isOptional() && required ) {
7632  os << "[";
7633  required = false;
7634  }
7635  os << "<" << arg.hint() << ">";
7636  if( arg.cardinality() == 0 )
7637  os << " ... ";
7638  }
7639  if( !required )
7640  os << "]";
7641  if( !m_options.empty() )
7642  os << " options";
7643  os << "\n\nwhere options are:" << std::endl;
7644  }
7645 
7646  auto rows = getHelpColumns();
7647  size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
7648  size_t optWidth = 0;
7649  for( auto const &cols : rows )
7650  optWidth = (std::max)(optWidth, cols.left.size() + 2);
7651 
7652  optWidth = (std::min)(optWidth, consoleWidth/2);
7653 
7654  for( auto const &cols : rows ) {
7655  auto row =
7656  TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
7657  TextFlow::Spacer(4) +
7658  TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth );
7659  os << row << std::endl;
7660  }
7661  }
7662 
7663  friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream& {
7664  parser.writeToStream( os );
7665  return os;
7666  }
7667 
7668  auto validate() const -> Result override {
7669  for( auto const &opt : m_options ) {
7670  auto result = opt.validate();
7671  if( !result )
7672  return result;
7673  }
7674  for( auto const &arg : m_args ) {
7675  auto result = arg.validate();
7676  if( !result )
7677  return result;
7678  }
7679  return Result::ok();
7680  }
7681 
7682  using ParserBase::parse;
7683 
7684  auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override {
7685 
7686  struct ParserInfo {
7687  ParserBase const* parser = nullptr;
7688  size_t count = 0;
7689  };
7690  const size_t totalParsers = m_options.size() + m_args.size();
7691  assert( totalParsers < 512 );
7692  // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do
7693  ParserInfo parseInfos[512];
7694 
7695  {
7696  size_t i = 0;
7697  for (auto const &opt : m_options) parseInfos[i++].parser = &opt;
7698  for (auto const &arg : m_args) parseInfos[i++].parser = &arg;
7699  }
7700 
7701  m_exeName.set( exeName );
7702 
7703  auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
7704  while( result.value().remainingTokens() ) {
7705  bool tokenParsed = false;
7706 
7707  for( size_t i = 0; i < totalParsers; ++i ) {
7708  auto& parseInfo = parseInfos[i];
7709  if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) {
7710  result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
7711  if (!result)
7712  return result;
7713  if (result.value().type() != ParseResultType::NoMatch) {
7714  tokenParsed = true;
7715  ++parseInfo.count;
7716  break;
7717  }
7718  }
7719  }
7720 
7721  if( result.value().type() == ParseResultType::ShortCircuitAll )
7722  return result;
7723  if( !tokenParsed )
7724  return InternalParseResult::runtimeError( "Unrecognised token: " + result.value().remainingTokens()->token );
7725  }
7726  // !TBD Check missing required options
7727  return result;
7728  }
7729  };
7730 
7731  template<typename DerivedT>
7732  template<typename T>
7733  auto ComposableParserImpl<DerivedT>::operator|( T const &other ) const -> Parser {
7734  return Parser() | static_cast<DerivedT const &>( *this ) | other;
7735  }
7736 } // namespace detail
7737 
7738 // A Combined parser
7739 using detail::Parser;
7740 
7741 // A parser for options
7742 using detail::Opt;
7743 
7744 // A parser for arguments
7745 using detail::Arg;
7746 
7747 // Wrapper for argc, argv from main()
7748 using detail::Args;
7749 
7750 // Specifies the name of the executable
7751 using detail::ExeName;
7752 
7753 // Convenience wrapper for option parser that specifies the help option
7754 using detail::Help;
7755 
7756 // enum of result types from a parse
7757 using detail::ParseResultType;
7758 
7759 // Result type for parser operation
7760 using detail::ParserResult;
7761 
7762 }} // namespace Catch::clara
7763 
7764 // end clara.hpp
7765 #ifdef __clang__
7766 #pragma clang diagnostic pop
7767 #endif
7768 
7769 // Restore Clara's value for console width, if present
7770 #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
7771 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
7772 #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
7773 #endif
7774 
7775 // end catch_clara.h
7776 namespace Catch {
7777 
7778  clara::Parser makeCommandLineParser( ConfigData& config );
7779 
7780 } // end namespace Catch
7781 
7782 // end catch_commandline.h
7783 #include <fstream>
7784 #include <ctime>
7785 
7786 namespace Catch {
7787 
7788  clara::Parser makeCommandLineParser( ConfigData& config ) {
7789 
7790  using namespace clara;
7791 
7792  auto const setWarning = [&]( std::string const& warning ) {
7793  auto warningSet = [&]() {
7794  if( warning == "NoAssertions" )
7795  return WarnAbout::NoAssertions;
7796 
7797  if ( warning == "NoTests" )
7798  return WarnAbout::NoTests;
7799 
7800  return WarnAbout::Nothing;
7801  }();
7802 
7803  if (warningSet == WarnAbout::Nothing)
7804  return ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" );
7805  config.warnings = static_cast<WarnAbout::What>( config.warnings | warningSet );
7806  return ParserResult::ok( ParseResultType::Matched );
7807  };
7808  auto const loadTestNamesFromFile = [&]( std::string const& filename ) {
7809  std::ifstream f( filename.c_str() );
7810  if( !f.is_open() )
7811  return ParserResult::runtimeError( "Unable to load input file: '" + filename + "'" );
7812 
7813  std::string line;
7814  while( std::getline( f, line ) ) {
7815  line = trim(line);
7816  if( !line.empty() && !startsWith( line, '#' ) ) {
7817  if( !startsWith( line, '"' ) )
7818  line = '"' + line + '"';
7819  config.testsOrTags.push_back( line + ',' );
7820  }
7821  }
7822  return ParserResult::ok( ParseResultType::Matched );
7823  };
7824  auto const setTestOrder = [&]( std::string const& order ) {
7825  if( startsWith( "declared", order ) )
7826  config.runOrder = RunTests::InDeclarationOrder;
7827  else if( startsWith( "lexical", order ) )
7828  config.runOrder = RunTests::InLexicographicalOrder;
7829  else if( startsWith( "random", order ) )
7830  config.runOrder = RunTests::InRandomOrder;
7831  else
7832  return clara::ParserResult::runtimeError( "Unrecognised ordering: '" + order + "'" );
7833  return ParserResult::ok( ParseResultType::Matched );
7834  };
7835  auto const setRngSeed = [&]( std::string const& seed ) {
7836  if( seed != "time" )
7837  return clara::detail::convertInto( seed, config.rngSeed );
7838  config.rngSeed = static_cast<unsigned int>( std::time(nullptr) );
7839  return ParserResult::ok( ParseResultType::Matched );
7840  };
7841  auto const setColourUsage = [&]( std::string const& useColour ) {
7842  auto mode = toLower( useColour );
7843 
7844  if( mode == "yes" )
7845  config.useColour = UseColour::Yes;
7846  else if( mode == "no" )
7847  config.useColour = UseColour::No;
7848  else if( mode == "auto" )
7849  config.useColour = UseColour::Auto;
7850  else
7851  return ParserResult::runtimeError( "colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised" );
7852  return ParserResult::ok( ParseResultType::Matched );
7853  };
7854  auto const setWaitForKeypress = [&]( std::string const& keypress ) {
7855  auto keypressLc = toLower( keypress );
7856  if( keypressLc == "start" )
7857  config.waitForKeypress = WaitForKeypress::BeforeStart;
7858  else if( keypressLc == "exit" )
7859  config.waitForKeypress = WaitForKeypress::BeforeExit;
7860  else if( keypressLc == "both" )
7861  config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
7862  else
7863  return ParserResult::runtimeError( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" );
7864  return ParserResult::ok( ParseResultType::Matched );
7865  };
7866  auto const setVerbosity = [&]( std::string const& verbosity ) {
7867  auto lcVerbosity = toLower( verbosity );
7868  if( lcVerbosity == "quiet" )
7869  config.verbosity = Verbosity::Quiet;
7870  else if( lcVerbosity == "normal" )
7871  config.verbosity = Verbosity::Normal;
7872  else if( lcVerbosity == "high" )
7873  config.verbosity = Verbosity::High;
7874  else
7875  return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" );
7876  return ParserResult::ok( ParseResultType::Matched );
7877  };
7878  auto const setReporter = [&]( std::string const& reporter ) {
7879  IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
7880 
7881  auto lcReporter = toLower( reporter );
7882  auto result = factories.find( lcReporter );
7883 
7884  if( factories.end() != result )
7885  config.reporterName = lcReporter;
7886  else
7887  return ParserResult::runtimeError( "Unrecognized reporter, '" + reporter + "'. Check available with --list-reporters" );
7888  return ParserResult::ok( ParseResultType::Matched );
7889  };
7890 
7891  auto cli
7892  = ExeName( config.processName )
7893  | Help( config.showHelp )
7894  | Opt( config.listTests )
7895  ["-l"]["--list-tests"]
7896  ( "list all/matching test cases" )
7897  | Opt( config.listTags )
7898  ["-t"]["--list-tags"]
7899  ( "list all/matching tags" )
7900  | Opt( config.showSuccessfulTests )
7901  ["-s"]["--success"]
7902  ( "include successful tests in output" )
7903  | Opt( config.shouldDebugBreak )
7904  ["-b"]["--break"]
7905  ( "break into debugger on failure" )
7906  | Opt( config.noThrow )
7907  ["-e"]["--nothrow"]
7908  ( "skip exception tests" )
7909  | Opt( config.showInvisibles )
7910  ["-i"]["--invisibles"]
7911  ( "show invisibles (tabs, newlines)" )
7912  | Opt( config.outputFilename, "filename" )
7913  ["-o"]["--out"]
7914  ( "output filename" )
7915  | Opt( setReporter, "name" )
7916  ["-r"]["--reporter"]
7917  ( "reporter to use (defaults to console)" )
7918  | Opt( config.name, "name" )
7919  ["-n"]["--name"]
7920  ( "suite name" )
7921  | Opt( [&]( bool ){ config.abortAfter = 1; } )
7922  ["-a"]["--abort"]
7923  ( "abort at first failure" )
7924  | Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" )
7925  ["-x"]["--abortx"]
7926  ( "abort after x failures" )
7927  | Opt( setWarning, "warning name" )
7928  ["-w"]["--warn"]
7929  ( "enable warnings" )
7930  | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" )
7931  ["-d"]["--durations"]
7932  ( "show test durations" )
7933  | Opt( loadTestNamesFromFile, "filename" )
7934  ["-f"]["--input-file"]
7935  ( "load test names to run from a file" )
7936  | Opt( config.filenamesAsTags )
7937  ["-#"]["--filenames-as-tags"]
7938  ( "adds a tag for the filename" )
7939  | Opt( config.sectionsToRun, "section name" )
7940  ["-c"]["--section"]
7941  ( "specify section to run" )
7942  | Opt( setVerbosity, "quiet|normal|high" )
7943  ["-v"]["--verbosity"]
7944  ( "set output verbosity" )
7945  | Opt( config.listTestNamesOnly )
7946  ["--list-test-names-only"]
7947  ( "list all/matching test cases names only" )
7948  | Opt( config.listReporters )
7949  ["--list-reporters"]
7950  ( "list all reporters" )
7951  | Opt( setTestOrder, "decl|lex|rand" )
7952  ["--order"]
7953  ( "test case order (defaults to decl)" )
7954  | Opt( setRngSeed, "'time'|number" )
7955  ["--rng-seed"]
7956  ( "set a specific seed for random numbers" )
7957  | Opt( setColourUsage, "yes|no" )
7958  ["--use-colour"]
7959  ( "should output be colourised" )
7960  | Opt( config.libIdentify )
7961  ["--libidentify"]
7962  ( "report name and version according to libidentify standard" )
7963  | Opt( setWaitForKeypress, "start|exit|both" )
7964  ["--wait-for-keypress"]
7965  ( "waits for a keypress before exiting" )
7966  | Opt( config.benchmarkResolutionMultiple, "multiplier" )
7967  ["--benchmark-resolution-multiple"]
7968  ( "multiple of clock resolution to run benchmarks" )
7969 
7970  | Arg( config.testsOrTags, "test name|pattern|tags" )
7971  ( "which test or tests to use" );
7972 
7973  return cli;
7974  }
7975 
7976 } // end namespace Catch
7977 // end catch_commandline.cpp
7978 // start catch_common.cpp
7979 
7980 #include <cstring>
7981 #include <ostream>
7982 
7983 namespace Catch {
7984 
7985  bool SourceLineInfo::empty() const noexcept {
7986  return file[0] == '\0';
7987  }
7988  bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept {
7989  return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
7990  }
7991  bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept {
7992  // We can assume that the same file will usually have the same pointer.
7993  // Thus, if the pointers are the same, there is no point in calling the strcmp
7994  return line < other.line || ( line == other.line && file != other.file && (std::strcmp(file, other.file) < 0));
7995  }
7996 
7997  std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
7998 #ifndef __GNUG__
7999  os << info.file << '(' << info.line << ')';
8000 #else
8001  os << info.file << ':' << info.line;
8002 #endif
8003  return os;
8004  }
8005 
8006  std::string StreamEndStop::operator+() const {
8007  return std::string();
8008  }
8009 
8010  NonCopyable::NonCopyable() = default;
8011  NonCopyable::~NonCopyable() = default;
8012 
8013 }
8014 // end catch_common.cpp
8015 // start catch_config.cpp
8016 
8017 namespace Catch {
8018 
8019  Config::Config( ConfigData const& data )
8020  : m_data( data ),
8021  m_stream( openStream() )
8022  {
8023  TestSpecParser parser(ITagAliasRegistry::get());
8024  if (data.testsOrTags.empty()) {
8025  parser.parse("~[.]"); // All not hidden tests
8026  }
8027  else {
8028  m_hasTestFilters = true;
8029  for( auto const& testOrTags : data.testsOrTags )
8030  parser.parse( testOrTags );
8031  }
8032  m_testSpec = parser.testSpec();
8033  }
8034 
8035  std::string const& Config::getFilename() const {
8036  return m_data.outputFilename ;
8037  }
8038 
8039  bool Config::listTests() const { return m_data.listTests; }
8040  bool Config::listTestNamesOnly() const { return m_data.listTestNamesOnly; }
8041  bool Config::listTags() const { return m_data.listTags; }
8042  bool Config::listReporters() const { return m_data.listReporters; }
8043 
8044  std::string Config::getProcessName() const { return m_data.processName; }
8045  std::string const& Config::getReporterName() const { return m_data.reporterName; }
8046 
8047  std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }
8048  std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
8049 
8050  TestSpec const& Config::testSpec() const { return m_testSpec; }
8051  bool Config::hasTestFilters() const { return m_hasTestFilters; }
8052 
8053  bool Config::showHelp() const { return m_data.showHelp; }
8054 
8055  // IConfig interface
8056  bool Config::allowThrows() const { return !m_data.noThrow; }
8057  std::ostream& Config::stream() const { return m_stream->stream(); }
8058  std::string Config::name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
8059  bool Config::includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
8060  bool Config::warnAboutMissingAssertions() const { return !!(m_data.warnings & WarnAbout::NoAssertions); }
8061  bool Config::warnAboutNoTests() const { return !!(m_data.warnings & WarnAbout::NoTests); }
8062  ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }
8063  RunTests::InWhatOrder Config::runOrder() const { return m_data.runOrder; }
8064  unsigned int Config::rngSeed() const { return m_data.rngSeed; }
8065  int Config::benchmarkResolutionMultiple() const { return m_data.benchmarkResolutionMultiple; }
8066  UseColour::YesOrNo Config::useColour() const { return m_data.useColour; }
8067  bool Config::shouldDebugBreak() const { return m_data.shouldDebugBreak; }
8068  int Config::abortAfter() const { return m_data.abortAfter; }
8069  bool Config::showInvisibles() const { return m_data.showInvisibles; }
8070  Verbosity Config::verbosity() const { return m_data.verbosity; }
8071 
8072  IStream const* Config::openStream() {
8073  return Catch::makeStream(m_data.outputFilename);
8074  }
8075 
8076 } // end namespace Catch
8077 // end catch_config.cpp
8078 // start catch_console_colour.cpp
8079 
8080 #if defined(__clang__)
8081 # pragma clang diagnostic push
8082 # pragma clang diagnostic ignored "-Wexit-time-destructors"
8083 #endif
8084 
8085 // start catch_errno_guard.h
8086 
8087 namespace Catch {
8088 
8089  class ErrnoGuard {
8090  public:
8091  ErrnoGuard();
8092  ~ErrnoGuard();
8093  private:
8094  int m_oldErrno;
8095  };
8096 
8097 }
8098 
8099 // end catch_errno_guard.h
8100 #include <sstream>
8101 
8102 namespace Catch {
8103  namespace {
8104 
8105  struct IColourImpl {
8106  virtual ~IColourImpl() = default;
8107  virtual void use( Colour::Code _colourCode ) = 0;
8108  };
8109 
8110  struct NoColourImpl : IColourImpl {
8111  void use( Colour::Code ) {}
8112 
8113  static IColourImpl* instance() {
8114  static NoColourImpl s_instance;
8115  return &s_instance;
8116  }
8117  };
8118 
8119  } // anon namespace
8120 } // namespace Catch
8121 
8122 #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
8123 # ifdef CATCH_PLATFORM_WINDOWS
8124 # define CATCH_CONFIG_COLOUR_WINDOWS
8125 # else
8126 # define CATCH_CONFIG_COLOUR_ANSI
8127 # endif
8128 #endif
8129 
8130 #if defined ( CATCH_CONFIG_COLOUR_WINDOWS )
8131 
8132 namespace Catch {
8133 namespace {
8134 
8135  class Win32ColourImpl : public IColourImpl {
8136  public:
8137  Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
8138  {
8139  CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
8140  GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
8141  originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
8142  originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
8143  }
8144 
8145  virtual void use( Colour::Code _colourCode ) override {
8146  switch( _colourCode ) {
8147  case Colour::None: return setTextAttribute( originalForegroundAttributes );
8148  case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
8149  case Colour::Red: return setTextAttribute( FOREGROUND_RED );
8150  case Colour::Green: return setTextAttribute( FOREGROUND_GREEN );
8151  case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE );
8152  case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
8153  case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
8154  case Colour::Grey: return setTextAttribute( 0 );
8155 
8156  case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY );
8157  case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
8158  case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
8159  case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
8160  case Colour::BrightYellow: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN );
8161 
8162  case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
8163 
8164  default:
8165  CATCH_ERROR( "Unknown colour requested" );
8166  }
8167  }
8168 
8169  private:
8170  void setTextAttribute( WORD _textAttribute ) {
8171  SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
8172  }
8173  HANDLE stdoutHandle;
8174  WORD originalForegroundAttributes;
8175  WORD originalBackgroundAttributes;
8176  };
8177 
8178  IColourImpl* platformColourInstance() {
8179  static Win32ColourImpl s_instance;
8180 
8182  UseColour::YesOrNo colourMode = config
8183  ? config->useColour()
8184  : UseColour::Auto;
8185  if( colourMode == UseColour::Auto )
8186  colourMode = UseColour::Yes;
8187  return colourMode == UseColour::Yes
8188  ? &s_instance
8189  : NoColourImpl::instance();
8190  }
8191 
8192 } // end anon namespace
8193 } // end namespace Catch
8194 
8195 #elif defined( CATCH_CONFIG_COLOUR_ANSI )
8196 
8197 #include <unistd.h>
8198 
8199 namespace Catch {
8200 namespace {
8201 
8202  // use POSIX/ ANSI console terminal codes
8203  // Thanks to Adam Strzelecki for original contribution
8204  // (http://github.com/nanoant)
8205  // https://github.com/philsquared/Catch/pull/131
8206  class PosixColourImpl : public IColourImpl {
8207  public:
8208  virtual void use( Colour::Code _colourCode ) override {
8209  switch( _colourCode ) {
8210  case Colour::None:
8211  case Colour::White: return setColour( "[0m" );
8212  case Colour::Red: return setColour( "[0;31m" );
8213  case Colour::Green: return setColour( "[0;32m" );
8214  case Colour::Blue: return setColour( "[0;34m" );
8215  case Colour::Cyan: return setColour( "[0;36m" );
8216  case Colour::Yellow: return setColour( "[0;33m" );
8217  case Colour::Grey: return setColour( "[1;30m" );
8218 
8219  case Colour::LightGrey: return setColour( "[0;37m" );
8220  case Colour::BrightRed: return setColour( "[1;31m" );
8221  case Colour::BrightGreen: return setColour( "[1;32m" );
8222  case Colour::BrightWhite: return setColour( "[1;37m" );
8223  case Colour::BrightYellow: return setColour( "[1;33m" );
8224 
8225  case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
8226  default: CATCH_INTERNAL_ERROR( "Unknown colour requested" );
8227  }
8228  }
8229  static IColourImpl* instance() {
8230  static PosixColourImpl s_instance;
8231  return &s_instance;
8232  }
8233 
8234  private:
8235  void setColour( const char* _escapeCode ) {
8236  getCurrentContext().getConfig()->stream()
8237  << '\033' << _escapeCode;
8238  }
8239  };
8240 
8241  bool useColourOnPlatform() {
8242  return
8243 #ifdef CATCH_PLATFORM_MAC
8244  !isDebuggerActive() &&
8245 #endif
8246 #if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
8247  isatty(STDOUT_FILENO)
8248 #else
8249  false
8250 #endif
8251  ;
8252  }
8253  IColourImpl* platformColourInstance() {
8254  ErrnoGuard guard;
8256  UseColour::YesOrNo colourMode = config
8257  ? config->useColour()
8258  : UseColour::Auto;
8259  if( colourMode == UseColour::Auto )
8260  colourMode = useColourOnPlatform()
8261  ? UseColour::Yes
8262  : UseColour::No;
8263  return colourMode == UseColour::Yes
8264  ? PosixColourImpl::instance()
8265  : NoColourImpl::instance();
8266  }
8267 
8268 } // end anon namespace
8269 } // end namespace Catch
8270 
8271 #else // not Windows or ANSI
8272 
8273 namespace Catch {
8274 
8275  static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
8276 
8277 } // end namespace Catch
8278 
8279 #endif // Windows/ ANSI/ None
8280 
8281 namespace Catch {
8282 
8283  Colour::Colour( Code _colourCode ) { use( _colourCode ); }
8284  Colour::Colour( Colour&& rhs ) noexcept {
8285  m_moved = rhs.m_moved;
8286  rhs.m_moved = true;
8287  }
8288  Colour& Colour::operator=( Colour&& rhs ) noexcept {
8289  m_moved = rhs.m_moved;
8290  rhs.m_moved = true;
8291  return *this;
8292  }
8293 
8294  Colour::~Colour(){ if( !m_moved ) use( None ); }
8295 
8296  void Colour::use( Code _colourCode ) {
8297  static IColourImpl* impl = platformColourInstance();
8298  impl->use( _colourCode );
8299  }
8300 
8301  std::ostream& operator << ( std::ostream& os, Colour const& ) {
8302  return os;
8303  }
8304 
8305 } // end namespace Catch
8306 
8307 #if defined(__clang__)
8308 # pragma clang diagnostic pop
8309 #endif
8310 
8311 // end catch_console_colour.cpp
8312 // start catch_context.cpp
8313 
8314 namespace Catch {
8315 
8316  class Context : public IMutableContext, NonCopyable {
8317 
8318  public: // IContext
8319  virtual IResultCapture* getResultCapture() override {
8320  return m_resultCapture;
8321  }
8322  virtual IRunner* getRunner() override {
8323  return m_runner;
8324  }
8325 
8326  virtual IConfigPtr const& getConfig() const override {
8327  return m_config;
8328  }
8329 
8330  virtual ~Context() override;
8331 
8332  public: // IMutableContext
8333  virtual void setResultCapture( IResultCapture* resultCapture ) override {
8334  m_resultCapture = resultCapture;
8335  }
8336  virtual void setRunner( IRunner* runner ) override {
8337  m_runner = runner;
8338  }
8339  virtual void setConfig( IConfigPtr const& config ) override {
8340  m_config = config;
8341  }
8342 
8344 
8345  private:
8346  IConfigPtr m_config;
8347  IRunner* m_runner = nullptr;
8348  IResultCapture* m_resultCapture = nullptr;
8349  };
8350 
8352 
8354  {
8355  currentContext = new Context();
8356  }
8357 
8358  void cleanUpContext() {
8360  IMutableContext::currentContext = nullptr;
8361  }
8362  IContext::~IContext() = default;
8364  Context::~Context() = default;
8365 }
8366 // end catch_context.cpp
8367 // start catch_debug_console.cpp
8368 
8369 // start catch_debug_console.h
8370 
8371 #include <string>
8372 
8373 namespace Catch {
8374  void writeToDebugConsole( std::string const& text );
8375 }
8376 
8377 // end catch_debug_console.h
8378 #ifdef CATCH_PLATFORM_WINDOWS
8379 
8380  namespace Catch {
8381  void writeToDebugConsole( std::string const& text ) {
8382  ::OutputDebugStringA( text.c_str() );
8383  }
8384  }
8385 
8386 #else
8387 
8388  namespace Catch {
8389  void writeToDebugConsole( std::string const& text ) {
8390  // !TBD: Need a version for Mac/ XCode and other IDEs
8391  Catch::cout() << text;
8392  }
8393  }
8394 
8395 #endif // Platform
8396 // end catch_debug_console.cpp
8397 // start catch_debugger.cpp
8398 
8399 #ifdef CATCH_PLATFORM_MAC
8400 
8401 # include <assert.h>
8402 # include <stdbool.h>
8403 # include <sys/types.h>
8404 # include <unistd.h>
8405 # include <sys/sysctl.h>
8406 # include <cstddef>
8407 # include <ostream>
8408 
8409 namespace Catch {
8410 
8411  // The following function is taken directly from the following technical note:
8412  // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
8413 
8414  // Returns true if the current process is being debugged (either
8415  // running under the debugger or has a debugger attached post facto).
8416  bool isDebuggerActive(){
8417 
8418  int mib[4];
8419  struct kinfo_proc info;
8420  std::size_t size;
8421 
8422  // Initialize the flags so that, if sysctl fails for some bizarre
8423  // reason, we get a predictable result.
8424 
8425  info.kp_proc.p_flag = 0;
8426 
8427  // Initialize mib, which tells sysctl the info we want, in this case
8428  // we're looking for information about a specific process ID.
8429 
8430  mib[0] = CTL_KERN;
8431  mib[1] = KERN_PROC;
8432  mib[2] = KERN_PROC_PID;
8433  mib[3] = getpid();
8434 
8435  // Call sysctl.
8436 
8437  size = sizeof(info);
8438  if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) {
8439  Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
8440  return false;
8441  }
8442 
8443  // We're being debugged if the P_TRACED flag is set.
8444 
8445  return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
8446  }
8447  } // namespace Catch
8448 
8449 #elif defined(CATCH_PLATFORM_LINUX)
8450  #include <fstream>
8451  #include <string>
8452 
8453  namespace Catch{
8454  // The standard POSIX way of detecting a debugger is to attempt to
8455  // ptrace() the process, but this needs to be done from a child and not
8456  // this process itself to still allow attaching to this process later
8457  // if wanted, so is rather heavy. Under Linux we have the PID of the
8458  // "debugger" (which doesn't need to be gdb, of course, it could also
8459  // be strace, for example) in /proc/$PID/status, so just get it from
8460  // there instead.
8461  bool isDebuggerActive(){
8462  // Libstdc++ has a bug, where std::ifstream sets errno to 0
8463  // This way our users can properly assert over errno values
8464  ErrnoGuard guard;
8465  std::ifstream in("/proc/self/status");
8466  for( std::string line; std::getline(in, line); ) {
8467  static const int PREFIX_LEN = 11;
8468  if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
8469  // We're traced if the PID is not 0 and no other PID starts
8470  // with 0 digit, so it's enough to check for just a single
8471  // character.
8472  return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
8473  }
8474  }
8475 
8476  return false;
8477  }
8478  } // namespace Catch
8479 #elif defined(_MSC_VER)
8480  extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
8481  namespace Catch {
8482  bool isDebuggerActive() {
8483  return IsDebuggerPresent() != 0;
8484  }
8485  }
8486 #elif defined(__MINGW32__)
8487  extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
8488  namespace Catch {
8489  bool isDebuggerActive() {
8490  return IsDebuggerPresent() != 0;
8491  }
8492  }
8493 #else
8494  namespace Catch {
8495  bool isDebuggerActive() { return false; }
8496  }
8497 #endif // Platform
8498 // end catch_debugger.cpp
8499 // start catch_decomposer.cpp
8500 
8501 namespace Catch {
8502 
8504 
8505  void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {
8506  if( lhs.size() + rhs.size() < 40 &&
8507  lhs.find('\n') == std::string::npos &&
8508  rhs.find('\n') == std::string::npos )
8509  os << lhs << " " << op << " " << rhs;
8510  else
8511  os << lhs << "\n" << op << "\n" << rhs;
8512  }
8513 }
8514 // end catch_decomposer.cpp
8515 // start catch_enforce.cpp
8516 
8517 namespace Catch {
8518 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)
8519  [[noreturn]]
8520  void throw_exception(std::exception const& e) {
8521  Catch::cerr() << "Catch will terminate because it needed to throw an exception.\n"
8522  << "The message was: " << e.what() << '\n';
8523  std::terminate();
8524  }
8525 #endif
8526 } // namespace Catch;
8527 // end catch_enforce.cpp
8528 // start catch_errno_guard.cpp
8529 
8530 #include <cerrno>
8531 
8532 namespace Catch {
8533  ErrnoGuard::ErrnoGuard():m_oldErrno(errno){}
8534  ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }
8535 }
8536 // end catch_errno_guard.cpp
8537 // start catch_exception_translator_registry.cpp
8538 
8539 // start catch_exception_translator_registry.h
8540 
8541 #include <vector>
8542 #include <string>
8543 #include <memory>
8544 
8545 namespace Catch {
8546 
8547  class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
8548  public:
8549  ~ExceptionTranslatorRegistry();
8550  virtual void registerTranslator( const IExceptionTranslator* translator );
8551  virtual std::string translateActiveException() const override;
8552  std::string tryTranslators() const;
8553 
8554  private:
8555  std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators;
8556  };
8557 }
8558 
8559 // end catch_exception_translator_registry.h
8560 #ifdef __OBJC__
8561 #import "Foundation/Foundation.h"
8562 #endif
8563 
8564 namespace Catch {
8565 
8566  ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {
8567  }
8568 
8569  void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) {
8570  m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );
8571  }
8572 
8573 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
8575  try {
8576 #ifdef __OBJC__
8577  // In Objective-C try objective-c exceptions first
8578  @try {
8579  return tryTranslators();
8580  }
8581  @catch (NSException *exception) {
8582  return Catch::Detail::stringify( [exception description] );
8583  }
8584 #else
8585  // Compiling a mixed mode project with MSVC means that CLR
8586  // exceptions will be caught in (...) as well. However, these
8587  // do not fill-in std::current_exception and thus lead to crash
8588  // when attempting rethrow.
8589  // /EHa switch also causes structured exceptions to be caught
8590  // here, but they fill-in current_exception properly, so
8591  // at worst the output should be a little weird, instead of
8592  // causing a crash.
8593  if (std::current_exception() == nullptr) {
8594  return "Non C++ exception. Possibly a CLR exception.";
8595  }
8596  return tryTranslators();
8597 #endif
8598  }
8599  catch( TestFailureException& ) {
8600  std::rethrow_exception(std::current_exception());
8601  }
8602  catch( std::exception& ex ) {
8603  return ex.what();
8604  }
8605  catch( std::string& msg ) {
8606  return msg;
8607  }
8608  catch( const char* msg ) {
8609  return msg;
8610  }
8611  catch(...) {
8612  return "Unknown exception";
8613  }
8614  }
8615 
8616  std::string ExceptionTranslatorRegistry::tryTranslators() const {
8617  if (m_translators.empty()) {
8618  std::rethrow_exception(std::current_exception());
8619  } else {
8620  return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end());
8621  }
8622  }
8623 
8624 #else // ^^ Exceptions are enabled // Exceptions are disabled vv
8626  CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
8627  }
8628 
8629  std::string ExceptionTranslatorRegistry::tryTranslators() const {
8630  CATCH_INTERNAL_ERROR("Attempted to use exception translators under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
8631  }
8632 #endif
8633 
8634 }
8635 // end catch_exception_translator_registry.cpp
8636 // start catch_fatal_condition.cpp
8637 
8638 #if defined(__GNUC__)
8639 # pragma GCC diagnostic push
8640 # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
8641 #endif
8642 
8643 #if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )
8644 
8645 namespace {
8646  // Report the error condition
8647  void reportFatal( char const * const message ) {
8649  }
8650 }
8651 
8652 #endif // signals/SEH handling
8653 
8654 #if defined( CATCH_CONFIG_WINDOWS_SEH )
8655 
8656 namespace Catch {
8657  struct SignalDefs { DWORD id; const char* name; };
8658 
8659  // There is no 1-1 mapping between signals and windows exceptions.
8660  // Windows can easily distinguish between SO and SigSegV,
8661  // but SigInt, SigTerm, etc are handled differently.
8662  static SignalDefs signalDefs[] = {
8663  { EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal" },
8664  { EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" },
8665  { EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" },
8666  { EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" },
8667  };
8668 
8669  LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
8670  for (auto const& def : signalDefs) {
8671  if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
8672  reportFatal(def.name);
8673  }
8674  }
8675  // If its not an exception we care about, pass it along.
8676  // This stops us from eating debugger breaks etc.
8677  return EXCEPTION_CONTINUE_SEARCH;
8678  }
8679 
8680  FatalConditionHandler::FatalConditionHandler() {
8681  isSet = true;
8682  // 32k seems enough for Catch to handle stack overflow,
8683  // but the value was found experimentally, so there is no strong guarantee
8684  guaranteeSize = 32 * 1024;
8685  exceptionHandlerHandle = nullptr;
8686  // Register as first handler in current chain
8687  exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
8688  // Pass in guarantee size to be filled
8689  SetThreadStackGuarantee(&guaranteeSize);
8690  }
8691 
8692  void FatalConditionHandler::reset() {
8693  if (isSet) {
8694  RemoveVectoredExceptionHandler(exceptionHandlerHandle);
8695  SetThreadStackGuarantee(&guaranteeSize);
8696  exceptionHandlerHandle = nullptr;
8697  isSet = false;
8698  }
8699  }
8700 
8701  FatalConditionHandler::~FatalConditionHandler() {
8702  reset();
8703  }
8704 
8705 bool FatalConditionHandler::isSet = false;
8706 ULONG FatalConditionHandler::guaranteeSize = 0;
8707 PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;
8708 
8709 } // namespace Catch
8710 
8711 #elif defined( CATCH_CONFIG_POSIX_SIGNALS )
8712 
8713 namespace Catch {
8714 
8715  struct SignalDefs {
8716  int id;
8717  const char* name;
8718  };
8719 
8720  // 32kb for the alternate stack seems to be sufficient. However, this value
8721  // is experimentally determined, so that's not guaranteed.
8722  constexpr static std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
8723 
8724  static SignalDefs signalDefs[] = {
8725  { SIGINT, "SIGINT - Terminal interrupt signal" },
8726  { SIGILL, "SIGILL - Illegal instruction signal" },
8727  { SIGFPE, "SIGFPE - Floating point error signal" },
8728  { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
8729  { SIGTERM, "SIGTERM - Termination request signal" },
8730  { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
8731  };
8732 
8733  void FatalConditionHandler::handleSignal( int sig ) {
8734  char const * name = "<unknown signal>";
8735  for (auto const& def : signalDefs) {
8736  if (sig == def.id) {
8737  name = def.name;
8738  break;
8739  }
8740  }
8741  reset();
8742  reportFatal(name);
8743  raise( sig );
8744  }
8745 
8746  FatalConditionHandler::FatalConditionHandler() {
8747  isSet = true;
8748  stack_t sigStack;
8749  sigStack.ss_sp = altStackMem;
8750  sigStack.ss_size = sigStackSize;
8751  sigStack.ss_flags = 0;
8752  sigaltstack(&sigStack, &oldSigStack);
8753  struct sigaction sa = { };
8754 
8755  sa.sa_handler = handleSignal;
8756  sa.sa_flags = SA_ONSTACK;
8757  for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {
8758  sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
8759  }
8760  }
8761 
8762  FatalConditionHandler::~FatalConditionHandler() {
8763  reset();
8764  }
8765 
8766  void FatalConditionHandler::reset() {
8767  if( isSet ) {
8768  // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
8769  for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
8770  sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
8771  }
8772  // Return the old stack
8773  sigaltstack(&oldSigStack, nullptr);
8774  isSet = false;
8775  }
8776  }
8777 
8778  bool FatalConditionHandler::isSet = false;
8779  struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
8780  stack_t FatalConditionHandler::oldSigStack = {};
8781  char FatalConditionHandler::altStackMem[sigStackSize] = {};
8782 
8783 } // namespace Catch
8784 
8785 #else
8786 
8787 namespace Catch {
8788  void FatalConditionHandler::reset() {}
8789 }
8790 
8791 #endif // signals/SEH handling
8792 
8793 #if defined(__GNUC__)
8794 # pragma GCC diagnostic pop
8795 #endif
8796 // end catch_fatal_condition.cpp
8797 // start catch_generators.cpp
8798 
8799 // start catch_random_number_generator.h
8800 
8801 #include <algorithm>
8802 #include <random>
8803 
8804 namespace Catch {
8805 
8806  struct IConfig;
8807 
8808  std::mt19937& rng();
8809  void seedRng( IConfig const& config );
8810  unsigned int rngSeed();
8811 
8812 }
8813 
8814 // end catch_random_number_generator.h
8815 #include <limits>
8816 #include <set>
8817 
8818 namespace Catch {
8819 
8821 
8822 const char* GeneratorException::what() const noexcept {
8823  return m_msg;
8824 }
8825 
8826 namespace Generators {
8827 
8828  GeneratorUntypedBase::~GeneratorUntypedBase() {}
8829 
8830  auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
8831  return getResultCapture().acquireGeneratorTracker( lineInfo );
8832  }
8833 
8834 } // namespace Generators
8835 } // namespace Catch
8836 // end catch_generators.cpp
8837 // start catch_interfaces_capture.cpp
8838 
8839 namespace Catch {
8840  IResultCapture::~IResultCapture() = default;
8841 }
8842 // end catch_interfaces_capture.cpp
8843 // start catch_interfaces_config.cpp
8844 
8845 namespace Catch {
8846  IConfig::~IConfig() = default;
8847 }
8848 // end catch_interfaces_config.cpp
8849 // start catch_interfaces_exception.cpp
8850 
8851 namespace Catch {
8854 }
8855 // end catch_interfaces_exception.cpp
8856 // start catch_interfaces_registry_hub.cpp
8857 
8858 namespace Catch {
8859  IRegistryHub::~IRegistryHub() = default;
8861 }
8862 // end catch_interfaces_registry_hub.cpp
8863 // start catch_interfaces_reporter.cpp
8864 
8865 // start catch_reporter_listening.h
8866 
8867 namespace Catch {
8868 
8869  class ListeningReporter : public IStreamingReporter {
8870  using Reporters = std::vector<IStreamingReporterPtr>;
8871  Reporters m_listeners;
8872  IStreamingReporterPtr m_reporter = nullptr;
8873  ReporterPreferences m_preferences;
8874 
8875  public:
8876  ListeningReporter();
8877 
8878  void addListener( IStreamingReporterPtr&& listener );
8879  void addReporter( IStreamingReporterPtr&& reporter );
8880 
8881  public: // IStreamingReporter
8882 
8883  ReporterPreferences getPreferences() const override;
8884 
8885  void noMatchingTestCases( std::string const& spec ) override;
8886 
8887  static std::set<Verbosity> getSupportedVerbosities();
8888 
8889  void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;
8890  void benchmarkEnded( BenchmarkStats const& benchmarkStats ) override;
8891 
8892  void testRunStarting( TestRunInfo const& testRunInfo ) override;
8893  void testGroupStarting( GroupInfo const& groupInfo ) override;
8894  void testCaseStarting( TestCaseInfo const& testInfo ) override;
8895  void sectionStarting( SectionInfo const& sectionInfo ) override;
8896  void assertionStarting( AssertionInfo const& assertionInfo ) override;
8897 
8898  // The return value indicates if the messages buffer should be cleared:
8899  bool assertionEnded( AssertionStats const& assertionStats ) override;
8900  void sectionEnded( SectionStats const& sectionStats ) override;
8901  void testCaseEnded( TestCaseStats const& testCaseStats ) override;
8902  void testGroupEnded( TestGroupStats const& testGroupStats ) override;
8903  void testRunEnded( TestRunStats const& testRunStats ) override;
8904 
8905  void skipTest( TestCaseInfo const& testInfo ) override;
8906  bool isMulti() const override;
8907 
8908  };
8909 
8910 } // end namespace Catch
8911 
8912 // end catch_reporter_listening.h
8913 namespace Catch {
8914 
8915  ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig )
8916  : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
8917 
8918  ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream )
8919  : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
8920 
8921  std::ostream& ReporterConfig::stream() const { return *m_stream; }
8922  IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; }
8923 
8924  TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {}
8925 
8926  GroupInfo::GroupInfo( std::string const& _name,
8927  std::size_t _groupIndex,
8928  std::size_t _groupsCount )
8929  : name( _name ),
8930  groupIndex( _groupIndex ),
8931  groupsCounts( _groupsCount )
8932  {}
8933 
8934  AssertionStats::AssertionStats( AssertionResult const& _assertionResult,
8935  std::vector<MessageInfo> const& _infoMessages,
8936  Totals const& _totals )
8937  : assertionResult( _assertionResult ),
8938  infoMessages( _infoMessages ),
8939  totals( _totals )
8940  {
8941  assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;
8942 
8943  if( assertionResult.hasMessage() ) {
8944  // Copy message into messages list.
8945  // !TBD This should have been done earlier, somewhere
8946  MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
8947  builder << assertionResult.getMessage();
8948  builder.m_info.message = builder.m_stream.str();
8949 
8950  infoMessages.push_back( builder.m_info );
8951  }
8952  }
8953 
8954  AssertionStats::~AssertionStats() = default;
8955 
8956  SectionStats::SectionStats( SectionInfo const& _sectionInfo,
8957  Counts const& _assertions,
8958  double _durationInSeconds,
8959  bool _missingAssertions )
8960  : sectionInfo( _sectionInfo ),
8961  assertions( _assertions ),
8962  durationInSeconds( _durationInSeconds ),
8963  missingAssertions( _missingAssertions )
8964  {}
8965 
8966  SectionStats::~SectionStats() = default;
8967 
8968  TestCaseStats::TestCaseStats( TestCaseInfo const& _testInfo,
8969  Totals const& _totals,
8970  std::string const& _stdOut,
8971  std::string const& _stdErr,
8972  bool _aborting )
8973  : testInfo( _testInfo ),
8974  totals( _totals ),
8975  stdOut( _stdOut ),
8976  stdErr( _stdErr ),
8977  aborting( _aborting )
8978  {}
8979 
8980  TestCaseStats::~TestCaseStats() = default;
8981 
8982  TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo,
8983  Totals const& _totals,
8984  bool _aborting )
8985  : groupInfo( _groupInfo ),
8986  totals( _totals ),
8987  aborting( _aborting )
8988  {}
8989 
8990  TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo )
8991  : groupInfo( _groupInfo ),
8992  aborting( false )
8993  {}
8994 
8995  TestGroupStats::~TestGroupStats() = default;
8996 
8997  TestRunStats::TestRunStats( TestRunInfo const& _runInfo,
8998  Totals const& _totals,
8999  bool _aborting )
9000  : runInfo( _runInfo ),
9001  totals( _totals ),
9002  aborting( _aborting )
9003  {}
9004 
9005  TestRunStats::~TestRunStats() = default;
9006 
9007  void IStreamingReporter::fatalErrorEncountered( StringRef ) {}
9008  bool IStreamingReporter::isMulti() const { return false; }
9009 
9010  IReporterFactory::~IReporterFactory() = default;
9011  IReporterRegistry::~IReporterRegistry() = default;
9012 
9013 } // end namespace Catch
9014 // end catch_interfaces_reporter.cpp
9015 // start catch_interfaces_runner.cpp
9016 
9017 namespace Catch {
9018  IRunner::~IRunner() = default;
9019 }
9020 // end catch_interfaces_runner.cpp
9021 // start catch_interfaces_testcase.cpp
9022 
9023 namespace Catch {
9024  ITestInvoker::~ITestInvoker() = default;
9026 }
9027 // end catch_interfaces_testcase.cpp
9028 // start catch_leak_detector.cpp
9029 
9030 #ifdef CATCH_CONFIG_WINDOWS_CRTDBG
9031 #include <crtdbg.h>
9032 
9033 namespace Catch {
9034 
9035  LeakDetector::LeakDetector() {
9036  int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
9037  flag |= _CRTDBG_LEAK_CHECK_DF;
9038  flag |= _CRTDBG_ALLOC_MEM_DF;
9039  _CrtSetDbgFlag(flag);
9040  _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
9041  _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
9042  // Change this to leaking allocation's number to break there
9043  _CrtSetBreakAlloc(-1);
9044  }
9045 }
9046 
9047 #else
9048 
9049  Catch::LeakDetector::LeakDetector() {}
9050 
9051 #endif
9052 
9053 Catch::LeakDetector::~LeakDetector() {
9054  Catch::cleanUp();
9055 }
9056 // end catch_leak_detector.cpp
9057 // start catch_list.cpp
9058 
9059 // start catch_list.h
9060 
9061 #include <set>
9062 
9063 namespace Catch {
9064 
9065  std::size_t listTests( Config const& config );
9066 
9067  std::size_t listTestsNamesOnly( Config const& config );
9068 
9069  struct TagInfo {
9070  void add( std::string const& spelling );
9071  std::string all() const;
9072 
9073  std::set<std::string> spellings;
9074  std::size_t count = 0;
9075  };
9076 
9077  std::size_t listTags( Config const& config );
9078 
9079  std::size_t listReporters();
9080 
9081  Option<std::size_t> list( std::shared_ptr<Config> const& config );
9082 
9083 } // end namespace Catch
9084 
9085 // end catch_list.h
9086 // start catch_text.h
9087 
9088 namespace Catch {
9089  using namespace clara::TextFlow;
9090 }
9091 
9092 // end catch_text.h
9093 #include <limits>
9094 #include <algorithm>
9095 #include <iomanip>
9096 
9097 namespace Catch {
9098 
9099  std::size_t listTests( Config const& config ) {
9100  TestSpec testSpec = config.testSpec();
9101  if( config.hasTestFilters() )
9102  Catch::cout() << "Matching test cases:\n";
9103  else {
9104  Catch::cout() << "All available test cases:\n";
9105  }
9106 
9107  auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
9108  for( auto const& testCaseInfo : matchedTestCases ) {
9109  Colour::Code colour = testCaseInfo.isHidden()
9110  ? Colour::SecondaryText
9111  : Colour::None;
9112  Colour colourGuard( colour );
9113 
9114  Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << "\n";
9115  if( config.verbosity() >= Verbosity::High ) {
9116  Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl;
9117  std::string description = testCaseInfo.description;
9118  if( description.empty() )
9119  description = "(NO DESCRIPTION)";
9120  Catch::cout() << Column( description ).indent(4) << std::endl;
9121  }
9122  if( !testCaseInfo.tags.empty() )
9123  Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << "\n";
9124  }
9125 
9126  if( !config.hasTestFilters() )
9127  Catch::cout() << pluralise( matchedTestCases.size(), "test case" ) << '\n' << std::endl;
9128  else
9129  Catch::cout() << pluralise( matchedTestCases.size(), "matching test case" ) << '\n' << std::endl;
9130  return matchedTestCases.size();
9131  }
9132 
9133  std::size_t listTestsNamesOnly( Config const& config ) {
9134  TestSpec testSpec = config.testSpec();
9135  std::size_t matchedTests = 0;
9136  std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
9137  for( auto const& testCaseInfo : matchedTestCases ) {
9138  matchedTests++;
9139  if( startsWith( testCaseInfo.name, '#' ) )
9140  Catch::cout() << '"' << testCaseInfo.name << '"';
9141  else
9142  Catch::cout() << testCaseInfo.name;
9143  if ( config.verbosity() >= Verbosity::High )
9144  Catch::cout() << "\t@" << testCaseInfo.lineInfo;
9145  Catch::cout() << std::endl;
9146  }
9147  return matchedTests;
9148  }
9149 
9150  void TagInfo::add( std::string const& spelling ) {
9151  ++count;
9152  spellings.insert( spelling );
9153  }
9154 
9155  std::string TagInfo::all() const {
9156  std::string out;
9157  for( auto const& spelling : spellings )
9158  out += "[" + spelling + "]";
9159  return out;
9160  }
9161 
9162  std::size_t listTags( Config const& config ) {
9163  TestSpec testSpec = config.testSpec();
9164  if( config.hasTestFilters() )
9165  Catch::cout() << "Tags for matching test cases:\n";
9166  else {
9167  Catch::cout() << "All available tags:\n";
9168  }
9169 
9170  std::map<std::string, TagInfo> tagCounts;
9171 
9172  std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
9173  for( auto const& testCase : matchedTestCases ) {
9174  for( auto const& tagName : testCase.getTestCaseInfo().tags ) {
9175  std::string lcaseTagName = toLower( tagName );
9176  auto countIt = tagCounts.find( lcaseTagName );
9177  if( countIt == tagCounts.end() )
9178  countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
9179  countIt->second.add( tagName );
9180  }
9181  }
9182 
9183  for( auto const& tagCount : tagCounts ) {
9185  rss << " " << std::setw(2) << tagCount.second.count << " ";
9186  auto str = rss.str();
9187  auto wrapper = Column( tagCount.second.all() )
9188  .initialIndent( 0 )
9189  .indent( str.size() )
9190  .width( CATCH_CONFIG_CONSOLE_WIDTH-10 );
9191  Catch::cout() << str << wrapper << '\n';
9192  }
9193  Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl;
9194  return tagCounts.size();
9195  }
9196 
9197  std::size_t listReporters() {
9198  Catch::cout() << "Available reporters:\n";
9199  IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
9200  std::size_t maxNameLen = 0;
9201  for( auto const& factoryKvp : factories )
9202  maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() );
9203 
9204  for( auto const& factoryKvp : factories ) {
9205  Catch::cout()
9206  << Column( factoryKvp.first + ":" )
9207  .indent(2)
9208  .width( 5+maxNameLen )
9209  + Column( factoryKvp.second->getDescription() )
9210  .initialIndent(0)
9211  .indent(2)
9212  .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 )
9213  << "\n";
9214  }
9215  Catch::cout() << std::endl;
9216  return factories.size();
9217  }
9218 
9219  Option<std::size_t> list( std::shared_ptr<Config> const& config ) {
9220  Option<std::size_t> listedCount;
9221  getCurrentMutableContext().setConfig( config );
9222  if( config->listTests() )
9223  listedCount = listedCount.valueOr(0) + listTests( *config );
9224  if( config->listTestNamesOnly() )
9225  listedCount = listedCount.valueOr(0) + listTestsNamesOnly( *config );
9226  if( config->listTags() )
9227  listedCount = listedCount.valueOr(0) + listTags( *config );
9228  if( config->listReporters() )
9229  listedCount = listedCount.valueOr(0) + listReporters();
9230  return listedCount;
9231  }
9232 
9233 } // end namespace Catch
9234 // end catch_list.cpp
9235 // start catch_matchers.cpp
9236 
9237 namespace Catch {
9238 namespace Matchers {
9239  namespace Impl {
9240 
9241  std::string MatcherUntypedBase::toString() const {
9242  if( m_cachedToString.empty() )
9243  m_cachedToString = describe();
9244  return m_cachedToString;
9245  }
9246 
9247  MatcherUntypedBase::~MatcherUntypedBase() = default;
9248 
9249  } // namespace Impl
9250 } // namespace Matchers
9251 
9252 using namespace Matchers;
9254 
9255 } // namespace Catch
9256 // end catch_matchers.cpp
9257 // start catch_matchers_floating.cpp
9258 
9259 // start catch_polyfills.hpp
9260 
9261 namespace Catch {
9262  bool isnan(float f);
9263  bool isnan(double d);
9264 }
9265 
9266 // end catch_polyfills.hpp
9267 // start catch_to_string.hpp
9268 
9269 #include <string>
9270 
9271 namespace Catch {
9272  template <typename T>
9273  std::string to_string(T const& t) {
9274 #if defined(CATCH_CONFIG_CPP11_TO_STRING)
9275  return std::to_string(t);
9276 #else
9278  rss << t;
9279  return rss.str();
9280 #endif
9281  }
9282 } // end namespace Catch
9283 
9284 // end catch_to_string.hpp
9285 #include <cstdlib>
9286 #include <cstdint>
9287 #include <cstring>
9288 
9289 namespace Catch {
9290 namespace Matchers {
9291 namespace Floating {
9292 enum class FloatingPointKind : uint8_t {
9293  Float,
9294  Double
9295 };
9296 }
9297 }
9298 }
9299 
9300 namespace {
9301 
9302 template <typename T>
9303 struct Converter;
9304 
9305 template <>
9306 struct Converter<float> {
9307  static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
9308  Converter(float f) {
9309  std::memcpy(&i, &f, sizeof(f));
9310  }
9311  int32_t i;
9312 };
9313 
9314 template <>
9315 struct Converter<double> {
9316  static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
9317  Converter(double d) {
9318  std::memcpy(&i, &d, sizeof(d));
9319  }
9320  int64_t i;
9321 };
9322 
9323 template <typename T>
9324 auto convert(T t) -> Converter<T> {
9325  return Converter<T>(t);
9326 }
9327 
9328 template <typename FP>
9329 bool almostEqualUlps(FP lhs, FP rhs, int maxUlpDiff) {
9330  // Comparison with NaN should always be false.
9331  // This way we can rule it out before getting into the ugly details
9332  if (Catch::isnan(lhs) || Catch::isnan(rhs)) {
9333  return false;
9334  }
9335 
9336  auto lc = convert(lhs);
9337  auto rc = convert(rhs);
9338 
9339  if ((lc.i < 0) != (rc.i < 0)) {
9340  // Potentially we can have +0 and -0
9341  return lhs == rhs;
9342  }
9343 
9344  auto ulpDiff = std::abs(lc.i - rc.i);
9345  return ulpDiff <= maxUlpDiff;
9346 }
9347 
9348 }
9349 
9350 namespace Catch {
9351 namespace Matchers {
9352 namespace Floating {
9353  WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
9354  :m_target{ target }, m_margin{ margin } {
9355  CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.'
9356  << " Margin has to be non-negative.");
9357  }
9358 
9359  // Performs equivalent check of std::fabs(lhs - rhs) <= margin
9360  // But without the subtraction to allow for INFINITY in comparison
9361  bool WithinAbsMatcher::match(double const& matchee) const {
9362  return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);
9363  }
9364 
9365  std::string WithinAbsMatcher::describe() const {
9366  return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target);
9367  }
9368 
9369  WithinUlpsMatcher::WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType)
9370  :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
9371  CATCH_ENFORCE(ulps >= 0, "Invalid ULP setting: " << ulps << '.'
9372  << " ULPs have to be non-negative.");
9373  }
9374 
9375 #if defined(__clang__)
9376 #pragma clang diagnostic push
9377 // Clang <3.5 reports on the default branch in the switch below
9378 #pragma clang diagnostic ignored "-Wunreachable-code"
9379 #endif
9380 
9381  bool WithinUlpsMatcher::match(double const& matchee) const {
9382  switch (m_type) {
9383  case FloatingPointKind::Float:
9384  return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps);
9385  case FloatingPointKind::Double:
9386  return almostEqualUlps<double>(matchee, m_target, m_ulps);
9387  default:
9388  CATCH_INTERNAL_ERROR( "Unknown FloatingPointKind value" );
9389  }
9390  }
9391 
9392 #if defined(__clang__)
9393 #pragma clang diagnostic pop
9394 #endif
9395 
9396  std::string WithinUlpsMatcher::describe() const {
9397  return "is within " + Catch::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : "");
9398  }
9399 
9400 }// namespace Floating
9401 
9402 Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff) {
9403  return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
9404 }
9405 
9406 Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff) {
9407  return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
9408 }
9409 
9410 Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
9411  return Floating::WithinAbsMatcher(target, margin);
9412 }
9413 
9414 } // namespace Matchers
9415 } // namespace Catch
9416 
9417 // end catch_matchers_floating.cpp
9418 // start catch_matchers_generic.cpp
9419 
9420 std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) {
9421  if (desc.empty()) {
9422  return "matches undescribed predicate";
9423  } else {
9424  return "matches predicate: \"" + desc + '"';
9425  }
9426 }
9427 // end catch_matchers_generic.cpp
9428 // start catch_matchers_string.cpp
9429 
9430 #include <regex>
9431 
9432 namespace Catch {
9433 namespace Matchers {
9434 
9435  namespace StdString {
9436 
9437  CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
9438  : m_caseSensitivity( caseSensitivity ),
9439  m_str( adjustString( str ) )
9440  {}
9441  std::string CasedString::adjustString( std::string const& str ) const {
9442  return m_caseSensitivity == CaseSensitive::No
9443  ? toLower( str )
9444  : str;
9445  }
9446  std::string CasedString::caseSensitivitySuffix() const {
9447  return m_caseSensitivity == CaseSensitive::No
9448  ? " (case insensitive)"
9449  : std::string();
9450  }
9451 
9452  StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )
9453  : m_comparator( comparator ),
9454  m_operation( operation ) {
9455  }
9456 
9457  std::string StringMatcherBase::describe() const {
9458  std::string description;
9459  description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +
9460  m_comparator.caseSensitivitySuffix().size());
9461  description += m_operation;
9462  description += ": \"";
9463  description += m_comparator.m_str;
9464  description += "\"";
9465  description += m_comparator.caseSensitivitySuffix();
9466  return description;
9467  }
9468 
9469  EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {}
9470 
9471  bool EqualsMatcher::match( std::string const& source ) const {
9472  return m_comparator.adjustString( source ) == m_comparator.m_str;
9473  }
9474 
9475  ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {}
9476 
9477  bool ContainsMatcher::match( std::string const& source ) const {
9478  return contains( m_comparator.adjustString( source ), m_comparator.m_str );
9479  }
9480 
9481  StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {}
9482 
9483  bool StartsWithMatcher::match( std::string const& source ) const {
9484  return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );
9485  }
9486 
9487  EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {}
9488 
9489  bool EndsWithMatcher::match( std::string const& source ) const {
9490  return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );
9491  }
9492 
9493  RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity): m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {}
9494 
9495  bool RegexMatcher::match(std::string const& matchee) const {
9496  auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway
9497  if (m_caseSensitivity == CaseSensitive::Choice::No) {
9498  flags |= std::regex::icase;
9499  }
9500  auto reg = std::regex(m_regex, flags);
9501  return std::regex_match(matchee, reg);
9502  }
9503 
9504  std::string RegexMatcher::describe() const {
9505  return "matches " + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? " case sensitively" : " case insensitively");
9506  }
9507 
9508  } // namespace StdString
9509 
9510  StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
9511  return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );
9512  }
9513  StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
9514  return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );
9515  }
9516  StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
9517  return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );
9518  }
9519  StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
9520  return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );
9521  }
9522 
9523  StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity) {
9524  return StdString::RegexMatcher(regex, caseSensitivity);
9525  }
9526 
9527 } // namespace Matchers
9528 } // namespace Catch
9529 // end catch_matchers_string.cpp
9530 // start catch_message.cpp
9531 
9532 // start catch_uncaught_exceptions.h
9533 
9534 namespace Catch {
9535  bool uncaught_exceptions();
9536 } // end namespace Catch
9537 
9538 // end catch_uncaught_exceptions.h
9539 #include <cassert>
9540 #include <stack>
9541 
9542 namespace Catch {
9543 
9544  MessageInfo::MessageInfo( StringRef const& _macroName,
9545  SourceLineInfo const& _lineInfo,
9546  ResultWas::OfType _type )
9547  : macroName( _macroName ),
9548  lineInfo( _lineInfo ),
9549  type( _type ),
9550  sequence( ++globalCount )
9551  {}
9552 
9553  bool MessageInfo::operator==( MessageInfo const& other ) const {
9554  return sequence == other.sequence;
9555  }
9556 
9557  bool MessageInfo::operator<( MessageInfo const& other ) const {
9558  return sequence < other.sequence;
9559  }
9560 
9561  // This may need protecting if threading support is added
9562  unsigned int MessageInfo::globalCount = 0;
9563 
9565 
9567  SourceLineInfo const& lineInfo,
9568  ResultWas::OfType type )
9569  :m_info(macroName, lineInfo, type) {}
9570 
9572 
9574  : m_info( builder.m_info ), m_moved()
9575  {
9576  m_info.message = builder.m_stream.str();
9577  getResultCapture().pushScopedMessage( m_info );
9578  }
9579 
9581  : m_info( old.m_info ), m_moved()
9582  {
9583  old.m_moved = true;
9584  }
9585 
9587  if ( !uncaught_exceptions() && !m_moved ){
9589  }
9590  }
9591 
9592  Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {
9593  auto trimmed = [&] (size_t start, size_t end) {
9594  while (names[start] == ',' || isspace(names[start])) {
9595  ++start;
9596  }
9597  while (names[end] == ',' || isspace(names[end])) {
9598  --end;
9599  }
9600  return names.substr(start, end - start + 1);
9601  };
9602 
9603  size_t start = 0;
9604  std::stack<char> openings;
9605  for (size_t pos = 0; pos < names.size(); ++pos) {
9606  char c = names[pos];
9607  switch (c) {
9608  case '[':
9609  case '{':
9610  case '(':
9611  // It is basically impossible to disambiguate between
9612  // comparison and start of template args in this context
9613 // case '<':
9614  openings.push(c);
9615  break;
9616  case ']':
9617  case '}':
9618  case ')':
9619 // case '>':
9620  openings.pop();
9621  break;
9622  case ',':
9623  if (start != pos && openings.size() == 0) {
9624  m_messages.emplace_back(macroName, lineInfo, resultType);
9625  m_messages.back().message = trimmed(start, pos);
9626  m_messages.back().message += " := ";
9627  start = pos;
9628  }
9629  }
9630  }
9631  assert(openings.size() == 0 && "Mismatched openings");
9632  m_messages.emplace_back(macroName, lineInfo, resultType);
9633  m_messages.back().message = trimmed(start, names.size() - 1);
9634  m_messages.back().message += " := ";
9635  }
9637  if ( !uncaught_exceptions() ){
9638  assert( m_captured == m_messages.size() );
9639  for( size_t i = 0; i < m_captured; ++i )
9640  m_resultCapture.popScopedMessage( m_messages[i] );
9641  }
9642  }
9643 
9644  void Capturer::captureValue( size_t index, std::string const& value ) {
9645  assert( index < m_messages.size() );
9646  m_messages[index].message += value;
9647  m_resultCapture.pushScopedMessage( m_messages[index] );
9648  m_captured++;
9649  }
9650 
9651 } // end namespace Catch
9652 // end catch_message.cpp
9653 // start catch_output_redirect.cpp
9654 
9655 // start catch_output_redirect.h
9656 #ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
9657 #define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
9658 
9659 #include <cstdio>
9660 #include <iosfwd>
9661 #include <string>
9662 
9663 namespace Catch {
9664 
9665  class RedirectedStream {
9666  std::ostream& m_originalStream;
9667  std::ostream& m_redirectionStream;
9668  std::streambuf* m_prevBuf;
9669 
9670  public:
9671  RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream );
9672  ~RedirectedStream();
9673  };
9674 
9675  class RedirectedStdOut {
9676  ReusableStringStream m_rss;
9677  RedirectedStream m_cout;
9678  public:
9679  RedirectedStdOut();
9680  auto str() const -> std::string;
9681  };
9682 
9683  // StdErr has two constituent streams in C++, std::cerr and std::clog
9684  // This means that we need to redirect 2 streams into 1 to keep proper
9685  // order of writes
9686  class RedirectedStdErr {
9687  ReusableStringStream m_rss;
9688  RedirectedStream m_cerr;
9689  RedirectedStream m_clog;
9690  public:
9691  RedirectedStdErr();
9692  auto str() const -> std::string;
9693  };
9694 
9695  class RedirectedStreams {
9696  public:
9697  RedirectedStreams(RedirectedStreams const&) = delete;
9698  RedirectedStreams& operator=(RedirectedStreams const&) = delete;
9699  RedirectedStreams(RedirectedStreams&&) = delete;
9700  RedirectedStreams& operator=(RedirectedStreams&&) = delete;
9701 
9702  RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr);
9703  ~RedirectedStreams();
9704  private:
9705  std::string& m_redirectedCout;
9706  std::string& m_redirectedCerr;
9707  RedirectedStdOut m_redirectedStdOut;
9708  RedirectedStdErr m_redirectedStdErr;
9709  };
9710 
9711 #if defined(CATCH_CONFIG_NEW_CAPTURE)
9712 
9713  // Windows's implementation of std::tmpfile is terrible (it tries
9714  // to create a file inside system folder, thus requiring elevated
9715  // privileges for the binary), so we have to use tmpnam(_s) and
9716  // create the file ourselves there.
9717  class TempFile {
9718  public:
9719  TempFile(TempFile const&) = delete;
9720  TempFile& operator=(TempFile const&) = delete;
9721  TempFile(TempFile&&) = delete;
9722  TempFile& operator=(TempFile&&) = delete;
9723 
9724  TempFile();
9725  ~TempFile();
9726 
9727  std::FILE* getFile();
9728  std::string getContents();
9729 
9730  private:
9731  std::FILE* m_file = nullptr;
9732  #if defined(_MSC_VER)
9733  char m_buffer[L_tmpnam] = { 0 };
9734  #endif
9735  };
9736 
9737  class OutputRedirect {
9738  public:
9739  OutputRedirect(OutputRedirect const&) = delete;
9740  OutputRedirect& operator=(OutputRedirect const&) = delete;
9741  OutputRedirect(OutputRedirect&&) = delete;
9742  OutputRedirect& operator=(OutputRedirect&&) = delete;
9743 
9744  OutputRedirect(std::string& stdout_dest, std::string& stderr_dest);
9745  ~OutputRedirect();
9746 
9747  private:
9748  int m_originalStdout = -1;
9749  int m_originalStderr = -1;
9750  TempFile m_stdoutFile;
9751  TempFile m_stderrFile;
9752  std::string& m_stdoutDest;
9753  std::string& m_stderrDest;
9754  };
9755 
9756 #endif
9757 
9758 } // end namespace Catch
9759 
9760 #endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
9761 // end catch_output_redirect.h
9762 #include <cstdio>
9763 #include <cstring>
9764 #include <fstream>
9765 #include <sstream>
9766 #include <stdexcept>
9767 
9768 #if defined(CATCH_CONFIG_NEW_CAPTURE)
9769  #if defined(_MSC_VER)
9770  #include <io.h> //_dup and _dup2
9771  #define dup _dup
9772  #define dup2 _dup2
9773  #define fileno _fileno
9774  #else
9775  #include <unistd.h> // dup and dup2
9776  #endif
9777 #endif
9778 
9779 namespace Catch {
9780 
9781  RedirectedStream::RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream )
9782  : m_originalStream( originalStream ),
9783  m_redirectionStream( redirectionStream ),
9784  m_prevBuf( m_originalStream.rdbuf() )
9785  {
9786  m_originalStream.rdbuf( m_redirectionStream.rdbuf() );
9787  }
9788 
9789  RedirectedStream::~RedirectedStream() {
9790  m_originalStream.rdbuf( m_prevBuf );
9791  }
9792 
9793  RedirectedStdOut::RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {}
9794  auto RedirectedStdOut::str() const -> std::string { return m_rss.str(); }
9795 
9796  RedirectedStdErr::RedirectedStdErr()
9797  : m_cerr( Catch::cerr(), m_rss.get() ),
9798  m_clog( Catch::clog(), m_rss.get() )
9799  {}
9800  auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }
9801 
9802  RedirectedStreams::RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr)
9803  : m_redirectedCout(redirectedCout),
9804  m_redirectedCerr(redirectedCerr)
9805  {}
9806 
9807  RedirectedStreams::~RedirectedStreams() {
9808  m_redirectedCout += m_redirectedStdOut.str();
9809  m_redirectedCerr += m_redirectedStdErr.str();
9810  }
9811 
9812 #if defined(CATCH_CONFIG_NEW_CAPTURE)
9813 
9814 #if defined(_MSC_VER)
9815  TempFile::TempFile() {
9816  if (tmpnam_s(m_buffer)) {
9817  CATCH_RUNTIME_ERROR("Could not get a temp filename");
9818  }
9819  if (fopen_s(&m_file, m_buffer, "w")) {
9820  char buffer[100];
9821  if (strerror_s(buffer, errno)) {
9822  CATCH_RUNTIME_ERROR("Could not translate errno to a string");
9823  }
9824  CATCH_RUNTIME_ERROR("Coul dnot open the temp file: '" << m_buffer << "' because: " << buffer);
9825  }
9826  }
9827 #else
9828  TempFile::TempFile() {
9829  m_file = std::tmpfile();
9830  if (!m_file) {
9831  CATCH_RUNTIME_ERROR("Could not create a temp file.");
9832  }
9833  }
9834 
9835 #endif
9836 
9837  TempFile::~TempFile() {
9838  // TBD: What to do about errors here?
9839  std::fclose(m_file);
9840  // We manually create the file on Windows only, on Linux
9841  // it will be autodeleted
9842 #if defined(_MSC_VER)
9843  std::remove(m_buffer);
9844 #endif
9845  }
9846 
9847  FILE* TempFile::getFile() {
9848  return m_file;
9849  }
9850 
9851  std::string TempFile::getContents() {
9852  std::stringstream sstr;
9853  char buffer[100] = {};
9854  std::rewind(m_file);
9855  while (std::fgets(buffer, sizeof(buffer), m_file)) {
9856  sstr << buffer;
9857  }
9858  return sstr.str();
9859  }
9860 
9861  OutputRedirect::OutputRedirect(std::string& stdout_dest, std::string& stderr_dest) :
9862  m_originalStdout(dup(1)),
9863  m_originalStderr(dup(2)),
9864  m_stdoutDest(stdout_dest),
9865  m_stderrDest(stderr_dest) {
9866  dup2(fileno(m_stdoutFile.getFile()), 1);
9867  dup2(fileno(m_stderrFile.getFile()), 2);
9868  }
9869 
9870  OutputRedirect::~OutputRedirect() {
9871  Catch::cout() << std::flush;
9872  fflush(stdout);
9873  // Since we support overriding these streams, we flush cerr
9874  // even though std::cerr is unbuffered
9875  Catch::cerr() << std::flush;
9876  Catch::clog() << std::flush;
9877  fflush(stderr);
9878 
9879  dup2(m_originalStdout, 1);
9880  dup2(m_originalStderr, 2);
9881 
9882  m_stdoutDest += m_stdoutFile.getContents();
9883  m_stderrDest += m_stderrFile.getContents();
9884  }
9885 
9886 #endif // CATCH_CONFIG_NEW_CAPTURE
9887 
9888 } // namespace Catch
9889 
9890 #if defined(CATCH_CONFIG_NEW_CAPTURE)
9891  #if defined(_MSC_VER)
9892  #undef dup
9893  #undef dup2
9894  #undef fileno
9895  #endif
9896 #endif
9897 // end catch_output_redirect.cpp
9898 // start catch_polyfills.cpp
9899 
9900 #include <cmath>
9901 
9902 namespace Catch {
9903 
9904 #if !defined(CATCH_CONFIG_POLYFILL_ISNAN)
9905  bool isnan(float f) {
9906  return std::isnan(f);
9907  }
9908  bool isnan(double d) {
9909  return std::isnan(d);
9910  }
9911 #else
9912  // For now we only use this for embarcadero
9913  bool isnan(float f) {
9914  return std::_isnan(f);
9915  }
9916  bool isnan(double d) {
9917  return std::_isnan(d);
9918  }
9919 #endif
9920 
9921 } // end namespace Catch
9922 // end catch_polyfills.cpp
9923 // start catch_random_number_generator.cpp
9924 
9925 namespace Catch {
9926 
9927  std::mt19937& rng() {
9928  static std::mt19937 s_rng;
9929  return s_rng;
9930  }
9931 
9932  void seedRng( IConfig const& config ) {
9933  if( config.rngSeed() != 0 ) {
9934  std::srand( config.rngSeed() );
9935  rng().seed( config.rngSeed() );
9936  }
9937  }
9938 
9939  unsigned int rngSeed() {
9940  return getCurrentContext().getConfig()->rngSeed();
9941  }
9942 }
9943 // end catch_random_number_generator.cpp
9944 // start catch_registry_hub.cpp
9945 
9946 // start catch_test_case_registry_impl.h
9947 
9948 #include <vector>
9949 #include <set>
9950 #include <algorithm>
9951 #include <ios>
9952 
9953 namespace Catch {
9954 
9955  class TestCase;
9956  struct IConfig;
9957 
9958  std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases );
9959  bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
9960 
9961  void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions );
9962 
9963  std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
9964  std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
9965 
9966  class TestRegistry : public ITestCaseRegistry {
9967  public:
9968  virtual ~TestRegistry() = default;
9969 
9970  virtual void registerTest( TestCase const& testCase );
9971 
9972  std::vector<TestCase> const& getAllTests() const override;
9973  std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const override;
9974 
9975  private:
9976  std::vector<TestCase> m_functions;
9977  mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;
9978  mutable std::vector<TestCase> m_sortedFunctions;
9979  std::size_t m_unnamedCount = 0;
9980  std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
9981  };
9982 
9984 
9985  class TestInvokerAsFunction : public ITestInvoker {
9986  void(*m_testAsFunction)();
9987  public:
9988  TestInvokerAsFunction( void(*testAsFunction)() ) noexcept;
9989 
9990  void invoke() const override;
9991  };
9992 
9993  std::string extractClassName( StringRef const& classOrQualifiedMethodName );
9994 
9996 
9997 } // end namespace Catch
9998 
9999 // end catch_test_case_registry_impl.h
10000 // start catch_reporter_registry.h
10001 
10002 #include <map>
10003 
10004 namespace Catch {
10005 
10006  class ReporterRegistry : public IReporterRegistry {
10007 
10008  public:
10009 
10010  ~ReporterRegistry() override;
10011 
10012  IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const override;
10013 
10014  void registerReporter( std::string const& name, IReporterFactoryPtr const& factory );
10015  void registerListener( IReporterFactoryPtr const& factory );
10016 
10017  FactoryMap const& getFactories() const override;
10018  Listeners const& getListeners() const override;
10019 
10020  private:
10021  FactoryMap m_factories;
10022  Listeners m_listeners;
10023  };
10024 }
10025 
10026 // end catch_reporter_registry.h
10027 // start catch_tag_alias_registry.h
10028 
10029 // start catch_tag_alias.h
10030 
10031 #include <string>
10032 
10033 namespace Catch {
10034 
10035  struct TagAlias {
10036  TagAlias(std::string const& _tag, SourceLineInfo _lineInfo);
10037 
10038  std::string tag;
10039  SourceLineInfo lineInfo;
10040  };
10041 
10042 } // end namespace Catch
10043 
10044 // end catch_tag_alias.h
10045 #include <map>
10046 
10047 namespace Catch {
10048 
10049  class TagAliasRegistry : public ITagAliasRegistry {
10050  public:
10051  ~TagAliasRegistry() override;
10052  TagAlias const* find( std::string const& alias ) const override;
10053  std::string expandAliases( std::string const& unexpandedTestSpec ) const override;
10054  void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
10055 
10056  private:
10057  std::map<std::string, TagAlias> m_registry;
10058  };
10059 
10060 } // end namespace Catch
10061 
10062 // end catch_tag_alias_registry.h
10063 // start catch_startup_exception_registry.h
10064 
10065 #include <vector>
10066 #include <exception>
10067 
10068 namespace Catch {
10069 
10070  class StartupExceptionRegistry {
10071  public:
10072  void add(std::exception_ptr const& exception) noexcept;
10073  std::vector<std::exception_ptr> const& getExceptions() const noexcept;
10074  private:
10075  std::vector<std::exception_ptr> m_exceptions;
10076  };
10077 
10078 } // end namespace Catch
10079 
10080 // end catch_startup_exception_registry.h
10081 // start catch_singletons.hpp
10082 
10083 namespace Catch {
10084 
10085  struct ISingleton {
10086  virtual ~ISingleton();
10087  };
10088 
10089  void addSingleton( ISingleton* singleton );
10090  void cleanupSingletons();
10091 
10092  template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>
10093  class Singleton : SingletonImplT, public ISingleton {
10094 
10095  static auto getInternal() -> Singleton* {
10096  static Singleton* s_instance = nullptr;
10097  if( !s_instance ) {
10098  s_instance = new Singleton;
10099  addSingleton( s_instance );
10100  }
10101  return s_instance;
10102  }
10103 
10104  public:
10105  static auto get() -> InterfaceT const& {
10106  return *getInternal();
10107  }
10108  static auto getMutable() -> MutableInterfaceT& {
10109  return *getInternal();
10110  }
10111  };
10112 
10113 } // namespace Catch
10114 
10115 // end catch_singletons.hpp
10116 namespace Catch {
10117 
10118  namespace {
10119 
10120  class RegistryHub : public IRegistryHub, public IMutableRegistryHub,
10121  private NonCopyable {
10122 
10123  public: // IRegistryHub
10124  RegistryHub() = default;
10125  IReporterRegistry const& getReporterRegistry() const override {
10126  return m_reporterRegistry;
10127  }
10128  ITestCaseRegistry const& getTestCaseRegistry() const override {
10129  return m_testCaseRegistry;
10130  }
10131  IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override {
10132  return m_exceptionTranslatorRegistry;
10133  }
10134  ITagAliasRegistry const& getTagAliasRegistry() const override {
10135  return m_tagAliasRegistry;
10136  }
10137  StartupExceptionRegistry const& getStartupExceptionRegistry() const override {
10138  return m_exceptionRegistry;
10139  }
10140 
10141  public: // IMutableRegistryHub
10142  void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) override {
10143  m_reporterRegistry.registerReporter( name, factory );
10144  }
10145  void registerListener( IReporterFactoryPtr const& factory ) override {
10146  m_reporterRegistry.registerListener( factory );
10147  }
10148  void registerTest( TestCase const& testInfo ) override {
10149  m_testCaseRegistry.registerTest( testInfo );
10150  }
10151  void registerTranslator( const IExceptionTranslator* translator ) override {
10152  m_exceptionTranslatorRegistry.registerTranslator( translator );
10153  }
10154  void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override {
10155  m_tagAliasRegistry.add( alias, tag, lineInfo );
10156  }
10157  void registerStartupException() noexcept override {
10158  m_exceptionRegistry.add(std::current_exception());
10159  }
10160 
10161  private:
10162  TestRegistry m_testCaseRegistry;
10163  ReporterRegistry m_reporterRegistry;
10164  ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
10165  TagAliasRegistry m_tagAliasRegistry;
10166  StartupExceptionRegistry m_exceptionRegistry;
10167  };
10168  }
10169 
10170  using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>;
10171 
10172  IRegistryHub const& getRegistryHub() {
10173  return RegistryHubSingleton::get();
10174  }
10176  return RegistryHubSingleton::getMutable();
10177  }
10178  void cleanUp() {
10179  cleanupSingletons();
10180  cleanUpContext();
10181  }
10182  std::string translateActiveException() {
10184  }
10185 
10186 } // end namespace Catch
10187 // end catch_registry_hub.cpp
10188 // start catch_reporter_registry.cpp
10189 
10190 namespace Catch {
10191 
10192  ReporterRegistry::~ReporterRegistry() = default;
10193 
10194  IStreamingReporterPtr ReporterRegistry::create( std::string const& name, IConfigPtr const& config ) const {
10195  auto it = m_factories.find( name );
10196  if( it == m_factories.end() )
10197  return nullptr;
10198  return it->second->create( ReporterConfig( config ) );
10199  }
10200 
10201  void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) {
10202  m_factories.emplace(name, factory);
10203  }
10204  void ReporterRegistry::registerListener( IReporterFactoryPtr const& factory ) {
10205  m_listeners.push_back( factory );
10206  }
10207 
10208  IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const {
10209  return m_factories;
10210  }
10211  IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const {
10212  return m_listeners;
10213  }
10214 
10215 }
10216 // end catch_reporter_registry.cpp
10217 // start catch_result_type.cpp
10218 
10219 namespace Catch {
10220 
10221  bool isOk( ResultWas::OfType resultType ) {
10222  return ( resultType & ResultWas::FailureBit ) == 0;
10223  }
10224  bool isJustInfo( int flags ) {
10225  return flags == ResultWas::Info;
10226  }
10227 
10229  return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
10230  }
10231 
10232  bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
10233  bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
10234 
10235 } // end namespace Catch
10236 // end catch_result_type.cpp
10237 // start catch_run_context.cpp
10238 
10239 #include <cassert>
10240 #include <algorithm>
10241 #include <sstream>
10242 
10243 namespace Catch {
10244 
10245  namespace Generators {
10246  struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {
10247  GeneratorBasePtr m_generator;
10248 
10249  GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
10250  : TrackerBase( nameAndLocation, ctx, parent )
10251  {}
10252  ~GeneratorTracker();
10253 
10254  static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {
10255  std::shared_ptr<GeneratorTracker> tracker;
10256 
10257  ITracker& currentTracker = ctx.currentTracker();
10258  if( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
10259  assert( childTracker );
10260  assert( childTracker->isGeneratorTracker() );
10261  tracker = std::static_pointer_cast<GeneratorTracker>( childTracker );
10262  }
10263  else {
10264  tracker = std::make_shared<GeneratorTracker>( nameAndLocation, ctx, &currentTracker );
10265  currentTracker.addChild( tracker );
10266  }
10267 
10268  if( !ctx.completedCycle() && !tracker->isComplete() ) {
10269  tracker->open();
10270  }
10271 
10272  return *tracker;
10273  }
10274 
10275  // TrackerBase interface
10276  bool isGeneratorTracker() const override { return true; }
10277  auto hasGenerator() const -> bool override {
10278  return !!m_generator;
10279  }
10280  void close() override {
10282  // Generator interface only finds out if it has another item on atual move
10283  if (m_runState == CompletedSuccessfully && m_generator->next()) {
10284  m_children.clear();
10285  m_runState = Executing;
10286  }
10287  }
10288 
10289  // IGeneratorTracker interface
10290  auto getGenerator() const -> GeneratorBasePtr const& override {
10291  return m_generator;
10292  }
10293  void setGenerator( GeneratorBasePtr&& generator ) override {
10294  m_generator = std::move( generator );
10295  }
10296  };
10297  GeneratorTracker::~GeneratorTracker() {}
10298  }
10299 
10300  RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
10301  : m_runInfo(_config->name()),
10302  m_context(getCurrentMutableContext()),
10303  m_config(_config),
10304  m_reporter(std::move(reporter)),
10305  m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
10306  m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )
10307  {
10308  m_context.setRunner(this);
10309  m_context.setConfig(m_config);
10310  m_context.setResultCapture(this);
10311  m_reporter->testRunStarting(m_runInfo);
10312  }
10313 
10314  RunContext::~RunContext() {
10315  m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
10316  }
10317 
10318  void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) {
10319  m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));
10320  }
10321 
10322  void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) {
10323  m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));
10324  }
10325 
10326  Totals RunContext::runTest(TestCase const& testCase) {
10327  Totals prevTotals = m_totals;
10328 
10329  std::string redirectedCout;
10330  std::string redirectedCerr;
10331 
10332  auto const& testInfo = testCase.getTestCaseInfo();
10333 
10334  m_reporter->testCaseStarting(testInfo);
10335 
10336  m_activeTestCase = &testCase;
10337 
10338  ITracker& rootTracker = m_trackerContext.startRun();
10339  assert(rootTracker.isSectionTracker());
10340  static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun());
10341  do {
10342  m_trackerContext.startCycle();
10343  m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));
10344  runCurrentTest(redirectedCout, redirectedCerr);
10345  } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());
10346 
10347  Totals deltaTotals = m_totals.delta(prevTotals);
10348  if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) {
10349  deltaTotals.assertions.failed++;
10350  deltaTotals.testCases.passed--;
10351  deltaTotals.testCases.failed++;
10352  }
10353  m_totals.testCases += deltaTotals.testCases;
10354  m_reporter->testCaseEnded(TestCaseStats(testInfo,
10355  deltaTotals,
10356  redirectedCout,
10357  redirectedCerr,
10358  aborting()));
10359 
10360  m_activeTestCase = nullptr;
10361  m_testCaseTracker = nullptr;
10362 
10363  return deltaTotals;
10364  }
10365 
10366  IConfigPtr RunContext::config() const {
10367  return m_config;
10368  }
10369 
10370  IStreamingReporter& RunContext::reporter() const {
10371  return *m_reporter;
10372  }
10373 
10374  void RunContext::assertionEnded(AssertionResult const & result) {
10375  if (result.getResultType() == ResultWas::Ok) {
10376  m_totals.assertions.passed++;
10377  m_lastAssertionPassed = true;
10378  } else if (!result.isOk()) {
10379  m_lastAssertionPassed = false;
10380  if( m_activeTestCase->getTestCaseInfo().okToFail() )
10381  m_totals.assertions.failedButOk++;
10382  else
10383  m_totals.assertions.failed++;
10384  }
10385  else {
10386  m_lastAssertionPassed = true;
10387  }
10388 
10389  // We have no use for the return value (whether messages should be cleared), because messages were made scoped
10390  // and should be let to clear themselves out.
10391  static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
10392 
10393  if (result.getResultType() != ResultWas::Warning)
10394  m_messageScopes.clear();
10395 
10396  // Reset working state
10397  resetAssertionInfo();
10398  m_lastResult = result;
10399  }
10400  void RunContext::resetAssertionInfo() {
10401  m_lastAssertionInfo.macroName = StringRef();
10402  m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
10403  }
10404 
10405  bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) {
10406  ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));
10407  if (!sectionTracker.isOpen())
10408  return false;
10409  m_activeSections.push_back(&sectionTracker);
10410 
10411  m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
10412 
10413  m_reporter->sectionStarting(sectionInfo);
10414 
10415  assertions = m_totals.assertions;
10416 
10417  return true;
10418  }
10420  using namespace Generators;
10421  GeneratorTracker& tracker = GeneratorTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( "generator", lineInfo ) );
10422  assert( tracker.isOpen() );
10423  m_lastAssertionInfo.lineInfo = lineInfo;
10424  return tracker;
10425  }
10426 
10427  bool RunContext::testForMissingAssertions(Counts& assertions) {
10428  if (assertions.total() != 0)
10429  return false;
10430  if (!m_config->warnAboutMissingAssertions())
10431  return false;
10432  if (m_trackerContext.currentTracker().hasChildren())
10433  return false;
10434  m_totals.assertions.failed++;
10435  assertions.failed++;
10436  return true;
10437  }
10438 
10439  void RunContext::sectionEnded(SectionEndInfo const & endInfo) {
10440  Counts assertions = m_totals.assertions - endInfo.prevAssertions;
10441  bool missingAssertions = testForMissingAssertions(assertions);
10442 
10443  if (!m_activeSections.empty()) {
10444  m_activeSections.back()->close();
10445  m_activeSections.pop_back();
10446  }
10447 
10448  m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
10449  m_messages.clear();
10450  m_messageScopes.clear();
10451  }
10452 
10453  void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {
10454  if (m_unfinishedSections.empty())
10455  m_activeSections.back()->fail();
10456  else
10457  m_activeSections.back()->close();
10458  m_activeSections.pop_back();
10459 
10460  m_unfinishedSections.push_back(endInfo);
10461  }
10462  void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {
10463  m_reporter->benchmarkStarting( info );
10464  }
10465  void RunContext::benchmarkEnded( BenchmarkStats const& stats ) {
10466  m_reporter->benchmarkEnded( stats );
10467  }
10468 
10469  void RunContext::pushScopedMessage(MessageInfo const & message) {
10470  m_messages.push_back(message);
10471  }
10472 
10473  void RunContext::popScopedMessage(MessageInfo const & message) {
10474  m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
10475  }
10476 
10477  void RunContext::emplaceUnscopedMessage( MessageBuilder const& builder ) {
10478  m_messageScopes.emplace_back( builder );
10479  }
10480 
10481  std::string RunContext::getCurrentTestName() const {
10482  return m_activeTestCase
10483  ? m_activeTestCase->getTestCaseInfo().name
10484  : std::string();
10485  }
10486 
10487  const AssertionResult * RunContext::getLastResult() const {
10488  return &(*m_lastResult);
10489  }
10490 
10491  void RunContext::exceptionEarlyReported() {
10492  m_shouldReportUnexpected = false;
10493  }
10494 
10495  void RunContext::handleFatalErrorCondition( StringRef message ) {
10496  // First notify reporter that bad things happened
10497  m_reporter->fatalErrorEncountered(message);
10498 
10499  // Don't rebuild the result -- the stringification itself can cause more fatal errors
10500  // Instead, fake a result data.
10501  AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );
10502  tempResult.message = message;
10503  AssertionResult result(m_lastAssertionInfo, tempResult);
10504 
10505  assertionEnded(result);
10506 
10507  handleUnfinishedSections();
10508 
10509  // Recreate section for test case (as we will lose the one that was in scope)
10510  auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
10511  SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
10512 
10513  Counts assertions;
10514  assertions.failed = 1;
10515  SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);
10516  m_reporter->sectionEnded(testCaseSectionStats);
10517 
10518  auto const& testInfo = m_activeTestCase->getTestCaseInfo();
10519 
10520  Totals deltaTotals;
10521  deltaTotals.testCases.failed = 1;
10522  deltaTotals.assertions.failed = 1;
10523  m_reporter->testCaseEnded(TestCaseStats(testInfo,
10524  deltaTotals,
10525  std::string(),
10526  std::string(),
10527  false));
10528  m_totals.testCases.failed++;
10529  testGroupEnded(std::string(), m_totals, 1, 1);
10530  m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
10531  }
10532 
10533  bool RunContext::lastAssertionPassed() {
10534  return m_lastAssertionPassed;
10535  }
10536 
10537  void RunContext::assertionPassed() {
10538  m_lastAssertionPassed = true;
10539  ++m_totals.assertions.passed;
10540  resetAssertionInfo();
10541  m_messageScopes.clear();
10542  }
10543 
10544  bool RunContext::aborting() const {
10545  return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter());
10546  }
10547 
10548  void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
10549  auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
10550  SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
10551  m_reporter->sectionStarting(testCaseSection);
10552  Counts prevAssertions = m_totals.assertions;
10553  double duration = 0;
10554  m_shouldReportUnexpected = true;
10555  m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal };
10556 
10557  seedRng(*m_config);
10558 
10559  Timer timer;
10560  CATCH_TRY {
10561  if (m_reporter->getPreferences().shouldRedirectStdOut) {
10562 #if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
10563  RedirectedStreams redirectedStreams(redirectedCout, redirectedCerr);
10564 
10565  timer.start();
10566  invokeActiveTestCase();
10567 #else
10568  OutputRedirect r(redirectedCout, redirectedCerr);
10569  timer.start();
10570  invokeActiveTestCase();
10571 #endif
10572  } else {
10573  timer.start();
10574  invokeActiveTestCase();
10575  }
10576  duration = timer.getElapsedSeconds();
10578  // This just means the test was aborted due to failure
10579  } CATCH_CATCH_ALL {
10580  // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
10581  // are reported without translation at the point of origin.
10582  if( m_shouldReportUnexpected ) {
10583  AssertionReaction dummyReaction;
10584  handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction );
10585  }
10586  }
10587  Counts assertions = m_totals.assertions - prevAssertions;
10588  bool missingAssertions = testForMissingAssertions(assertions);
10589 
10590  m_testCaseTracker->close();
10591  handleUnfinishedSections();
10592  m_messages.clear();
10593  m_messageScopes.clear();
10594 
10595  SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
10596  m_reporter->sectionEnded(testCaseSectionStats);
10597  }
10598 
10599  void RunContext::invokeActiveTestCase() {
10600  FatalConditionHandler fatalConditionHandler; // Handle signals
10601  m_activeTestCase->invoke();
10602  fatalConditionHandler.reset();
10603  }
10604 
10605  void RunContext::handleUnfinishedSections() {
10606  // If sections ended prematurely due to an exception we stored their
10607  // infos here so we can tear them down outside the unwind process.
10608  for (auto it = m_unfinishedSections.rbegin(),
10609  itEnd = m_unfinishedSections.rend();
10610  it != itEnd;
10611  ++it)
10612  sectionEnded(*it);
10613  m_unfinishedSections.clear();
10614  }
10615 
10616  void RunContext::handleExpr(
10617  AssertionInfo const& info,
10618  ITransientExpression const& expr,
10619  AssertionReaction& reaction
10620  ) {
10621  m_reporter->assertionStarting( info );
10622 
10623  bool negated = isFalseTest( info.resultDisposition );
10624  bool result = expr.getResult() != negated;
10625 
10626  if( result ) {
10627  if (!m_includeSuccessfulResults) {
10628  assertionPassed();
10629  }
10630  else {
10631  reportExpr(info, ResultWas::Ok, &expr, negated);
10632  }
10633  }
10634  else {
10635  reportExpr(info, ResultWas::ExpressionFailed, &expr, negated );
10636  populateReaction( reaction );
10637  }
10638  }
10639  void RunContext::reportExpr(
10640  AssertionInfo const &info,
10641  ResultWas::OfType resultType,
10642  ITransientExpression const *expr,
10643  bool negated ) {
10644 
10645  m_lastAssertionInfo = info;
10646  AssertionResultData data( resultType, LazyExpression( negated ) );
10647 
10648  AssertionResult assertionResult{ info, data };
10649  assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;
10650 
10651  assertionEnded( assertionResult );
10652  }
10653 
10654  void RunContext::handleMessage(
10655  AssertionInfo const& info,
10656  ResultWas::OfType resultType,
10657  StringRef const& message,
10658  AssertionReaction& reaction
10659  ) {
10660  m_reporter->assertionStarting( info );
10661 
10662  m_lastAssertionInfo = info;
10663 
10664  AssertionResultData data( resultType, LazyExpression( false ) );
10665  data.message = message;
10666  AssertionResult assertionResult{ m_lastAssertionInfo, data };
10667  assertionEnded( assertionResult );
10668  if( !assertionResult.isOk() )
10669  populateReaction( reaction );
10670  }
10671  void RunContext::handleUnexpectedExceptionNotThrown(
10672  AssertionInfo const& info,
10673  AssertionReaction& reaction
10674  ) {
10675  handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction);
10676  }
10677 
10678  void RunContext::handleUnexpectedInflightException(
10679  AssertionInfo const& info,
10680  std::string const& message,
10681  AssertionReaction& reaction
10682  ) {
10683  m_lastAssertionInfo = info;
10684 
10685  AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
10686  data.message = message;
10687  AssertionResult assertionResult{ info, data };
10688  assertionEnded( assertionResult );
10689  populateReaction( reaction );
10690  }
10691 
10692  void RunContext::populateReaction( AssertionReaction& reaction ) {
10693  reaction.shouldDebugBreak = m_config->shouldDebugBreak();
10694  reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal);
10695  }
10696 
10697  void RunContext::handleIncomplete(
10698  AssertionInfo const& info
10699  ) {
10700  m_lastAssertionInfo = info;
10701 
10702  AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
10703  data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
10704  AssertionResult assertionResult{ info, data };
10705  assertionEnded( assertionResult );
10706  }
10707  void RunContext::handleNonExpr(
10708  AssertionInfo const &info,
10709  ResultWas::OfType resultType,
10710  AssertionReaction &reaction
10711  ) {
10712  m_lastAssertionInfo = info;
10713 
10714  AssertionResultData data( resultType, LazyExpression( false ) );
10715  AssertionResult assertionResult{ info, data };
10716  assertionEnded( assertionResult );
10717 
10718  if( !assertionResult.isOk() )
10719  populateReaction( reaction );
10720  }
10721 
10723  if (auto* capture = getCurrentContext().getResultCapture())
10724  return *capture;
10725  else
10726  CATCH_INTERNAL_ERROR("No result capture instance");
10727  }
10728 }
10729 // end catch_run_context.cpp
10730 // start catch_section.cpp
10731 
10732 namespace Catch {
10733 
10734  Section::Section( SectionInfo const& info )
10735  : m_info( info ),
10736  m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
10737  {
10738  m_timer.start();
10739  }
10740 
10741  Section::~Section() {
10742  if( m_sectionIncluded ) {
10743  SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };
10744  if( uncaught_exceptions() )
10745  getResultCapture().sectionEndedEarly( endInfo );
10746  else
10747  getResultCapture().sectionEnded( endInfo );
10748  }
10749  }
10750 
10751  // This indicates whether the section should be executed or not
10752  Section::operator bool() const {
10753  return m_sectionIncluded;
10754  }
10755 
10756 } // end namespace Catch
10757 // end catch_section.cpp
10758 // start catch_section_info.cpp
10759 
10760 namespace Catch {
10761 
10763  ( SourceLineInfo const& _lineInfo,
10764  std::string const& _name )
10765  : name( _name ),
10766  lineInfo( _lineInfo )
10767  {}
10768 
10769 } // end namespace Catch
10770 // end catch_section_info.cpp
10771 // start catch_session.cpp
10772 
10773 // start catch_session.h
10774 
10775 #include <memory>
10776 
10777 namespace Catch {
10778 
10779  class Session : NonCopyable {
10780  public:
10781 
10782  Session();
10783  ~Session() override;
10784 
10785  void showHelp() const;
10786  void libIdentify();
10787 
10788  int applyCommandLine( int argc, char const * const * argv );
10789  #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
10790  int applyCommandLine( int argc, wchar_t const * const * argv );
10791  #endif
10792 
10793  void useConfigData( ConfigData const& configData );
10794 
10795  template<typename CharT>
10796  int run(int argc, CharT const * const argv[]) {
10797  if (m_startupExceptions)
10798  return 1;
10799  int returnCode = applyCommandLine(argc, argv);
10800  if (returnCode == 0)
10801  returnCode = run();
10802  return returnCode;
10803  }
10804 
10805  int run();
10806 
10807  clara::Parser const& cli() const;
10808  void cli( clara::Parser const& newParser );
10809  ConfigData& configData();
10810  Config& config();
10811  private:
10812  int runInternal();
10813 
10814  clara::Parser m_cli;
10815  ConfigData m_configData;
10816  std::shared_ptr<Config> m_config;
10817  bool m_startupExceptions = false;
10818  };
10819 
10820 } // end namespace Catch
10821 
10822 // end catch_session.h
10823 // start catch_version.h
10824 
10825 #include <iosfwd>
10826 
10827 namespace Catch {
10828 
10829  // Versioning information
10830  struct Version {
10831  Version( Version const& ) = delete;
10832  Version& operator=( Version const& ) = delete;
10833  Version( unsigned int _majorVersion,
10834  unsigned int _minorVersion,
10835  unsigned int _patchNumber,
10836  char const * const _branchName,
10837  unsigned int _buildNumber );
10838 
10839  unsigned int const majorVersion;
10840  unsigned int const minorVersion;
10841  unsigned int const patchNumber;
10842 
10843  // buildNumber is only used if branchName is not null
10844  char const * const branchName;
10845  unsigned int const buildNumber;
10846 
10847  friend std::ostream& operator << ( std::ostream& os, Version const& version );
10848  };
10849 
10850  Version const& libraryVersion();
10851 }
10852 
10853 // end catch_version.h
10854 #include <cstdlib>
10855 #include <iomanip>
10856 
10857 namespace Catch {
10858 
10859  namespace {
10860  const int MaxExitCode = 255;
10861 
10862  IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) {
10863  auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config);
10864  CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'");
10865 
10866  return reporter;
10867  }
10868 
10869  IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) {
10870  if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) {
10871  return createReporter(config->getReporterName(), config);
10872  }
10873 
10874  // On older platforms, returning std::unique_ptr<ListeningReporter>
10875  // when the return type is std::unique_ptr<IStreamingReporter>
10876  // doesn't compile without a std::move call. However, this causes
10877  // a warning on newer platforms. Thus, we have to work around
10878  // it a bit and downcast the pointer manually.
10879  auto ret = std::unique_ptr<IStreamingReporter>(new ListeningReporter);
10880  auto& multi = static_cast<ListeningReporter&>(*ret);
10881  auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();
10882  for (auto const& listener : listeners) {
10883  multi.addListener(listener->create(Catch::ReporterConfig(config)));
10884  }
10885  multi.addReporter(createReporter(config->getReporterName(), config));
10886  return ret;
10887  }
10888 
10889  Catch::Totals runTests(std::shared_ptr<Config> const& config) {
10890  auto reporter = makeReporter(config);
10891 
10892  RunContext context(config, std::move(reporter));
10893 
10894  Totals totals;
10895 
10896  context.testGroupStarting(config->name(), 1, 1);
10897 
10898  TestSpec testSpec = config->testSpec();
10899 
10900  auto const& allTestCases = getAllTestCasesSorted(*config);
10901  for (auto const& testCase : allTestCases) {
10902  if (!context.aborting() && matchTest(testCase, testSpec, *config))
10903  totals += context.runTest(testCase);
10904  else
10905  context.reporter().skipTest(testCase);
10906  }
10907 
10908  if (config->warnAboutNoTests() && totals.testCases.total() == 0) {
10909  ReusableStringStream testConfig;
10910 
10911  bool first = true;
10912  for (const auto& input : config->getTestsOrTags()) {
10913  if (!first) { testConfig << ' '; }
10914  first = false;
10915  testConfig << input;
10916  }
10917 
10918  context.reporter().noMatchingTestCases(testConfig.str());
10919  totals.error = -1;
10920  }
10921 
10922  context.testGroupEnded(config->name(), totals, 1, 1);
10923  return totals;
10924  }
10925 
10926  void applyFilenamesAsTags(Catch::IConfig const& config) {
10927  auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));
10928  for (auto& testCase : tests) {
10929  auto tags = testCase.tags;
10930 
10931  std::string filename = testCase.lineInfo.file;
10932  auto lastSlash = filename.find_last_of("\\/");
10933  if (lastSlash != std::string::npos) {
10934  filename.erase(0, lastSlash);
10935  filename[0] = '#';
10936  }
10937 
10938  auto lastDot = filename.find_last_of('.');
10939  if (lastDot != std::string::npos) {
10940  filename.erase(lastDot);
10941  }
10942 
10943  tags.push_back(std::move(filename));
10944  setTags(testCase, tags);
10945  }
10946  }
10947 
10948  } // anon namespace
10949 
10950  Session::Session() {
10951  static bool alreadyInstantiated = false;
10952  if( alreadyInstantiated ) {
10953  CATCH_TRY { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
10955  }
10956 
10957  // There cannot be exceptions at startup in no-exception mode.
10958 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
10959  const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
10960  if ( !exceptions.empty() ) {
10961  m_startupExceptions = true;
10962  Colour colourGuard( Colour::Red );
10963  Catch::cerr() << "Errors occurred during startup!" << '\n';
10964  // iterate over all exceptions and notify user
10965  for ( const auto& ex_ptr : exceptions ) {
10966  try {
10967  std::rethrow_exception(ex_ptr);
10968  } catch ( std::exception const& ex ) {
10969  Catch::cerr() << Column( ex.what() ).indent(2) << '\n';
10970  }
10971  }
10972  }
10973 #endif
10974 
10975  alreadyInstantiated = true;
10976  m_cli = makeCommandLineParser( m_configData );
10977  }
10978  Session::~Session() {
10979  Catch::cleanUp();
10980  }
10981 
10982  void Session::showHelp() const {
10983  Catch::cout()
10984  << "\nCatch v" << libraryVersion() << "\n"
10985  << m_cli << std::endl
10986  << "For more detailed usage please see the project docs\n" << std::endl;
10987  }
10988  void Session::libIdentify() {
10989  Catch::cout()
10990  << std::left << std::setw(16) << "description: " << "A Catch test executable\n"
10991  << std::left << std::setw(16) << "category: " << "testframework\n"
10992  << std::left << std::setw(16) << "framework: " << "Catch Test\n"
10993  << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
10994  }
10995 
10996  int Session::applyCommandLine( int argc, char const * const * argv ) {
10997  if( m_startupExceptions )
10998  return 1;
10999 
11000  auto result = m_cli.parse( clara::Args( argc, argv ) );
11001  if( !result ) {
11002  config();
11003  getCurrentMutableContext().setConfig(m_config);
11004  Catch::cerr()
11005  << Colour( Colour::Red )
11006  << "\nError(s) in input:\n"
11007  << Column( result.errorMessage() ).indent( 2 )
11008  << "\n\n";
11009  Catch::cerr() << "Run with -? for usage\n" << std::endl;
11010  return MaxExitCode;
11011  }
11012 
11013  if( m_configData.showHelp )
11014  showHelp();
11015  if( m_configData.libIdentify )
11016  libIdentify();
11017  m_config.reset();
11018  return 0;
11019  }
11020 
11021 #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
11022  int Session::applyCommandLine( int argc, wchar_t const * const * argv ) {
11023 
11024  char **utf8Argv = new char *[ argc ];
11025 
11026  for ( int i = 0; i < argc; ++i ) {
11027  int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL );
11028 
11029  utf8Argv[ i ] = new char[ bufSize ];
11030 
11031  WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL );
11032  }
11033 
11034  int returnCode = applyCommandLine( argc, utf8Argv );
11035 
11036  for ( int i = 0; i < argc; ++i )
11037  delete [] utf8Argv[ i ];
11038 
11039  delete [] utf8Argv;
11040 
11041  return returnCode;
11042  }
11043 #endif
11044 
11045  void Session::useConfigData( ConfigData const& configData ) {
11046  m_configData = configData;
11047  m_config.reset();
11048  }
11049 
11050  int Session::run() {
11051  if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {
11052  Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
11053  static_cast<void>(std::getchar());
11054  }
11055  int exitCode = runInternal();
11056  if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {
11057  Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
11058  static_cast<void>(std::getchar());
11059  }
11060  return exitCode;
11061  }
11062 
11063  clara::Parser const& Session::cli() const {
11064  return m_cli;
11065  }
11066  void Session::cli( clara::Parser const& newParser ) {
11067  m_cli = newParser;
11068  }
11069  ConfigData& Session::configData() {
11070  return m_configData;
11071  }
11072  Config& Session::config() {
11073  if( !m_config )
11074  m_config = std::make_shared<Config>( m_configData );
11075  return *m_config;
11076  }
11077 
11078  int Session::runInternal() {
11079  if( m_startupExceptions )
11080  return 1;
11081 
11082  if (m_configData.showHelp || m_configData.libIdentify) {
11083  return 0;
11084  }
11085 
11086  CATCH_TRY {
11087  config(); // Force config to be constructed
11088 
11089  seedRng( *m_config );
11090 
11091  if( m_configData.filenamesAsTags )
11092  applyFilenamesAsTags( *m_config );
11093 
11094  // Handle list request
11095  if( Option<std::size_t> listed = list( m_config ) )
11096  return static_cast<int>( *listed );
11097 
11098  auto totals = runTests( m_config );
11099  // Note that on unices only the lower 8 bits are usually used, clamping
11100  // the return value to 255 prevents false negative when some multiple
11101  // of 256 tests has failed
11102  return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed)));
11103  }
11104 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
11105  catch( std::exception& ex ) {
11106  Catch::cerr() << ex.what() << std::endl;
11107  return MaxExitCode;
11108  }
11109 #endif
11110  }
11111 
11112 } // end namespace Catch
11113 // end catch_session.cpp
11114 // start catch_singletons.cpp
11115 
11116 #include <vector>
11117 
11118 namespace Catch {
11119 
11120  namespace {
11121  static auto getSingletons() -> std::vector<ISingleton*>*& {
11122  static std::vector<ISingleton*>* g_singletons = nullptr;
11123  if( !g_singletons )
11124  g_singletons = new std::vector<ISingleton*>();
11125  return g_singletons;
11126  }
11127  }
11128 
11129  ISingleton::~ISingleton() {}
11130 
11131  void addSingleton(ISingleton* singleton ) {
11132  getSingletons()->push_back( singleton );
11133  }
11134  void cleanupSingletons() {
11135  auto& singletons = getSingletons();
11136  for( auto singleton : *singletons )
11137  delete singleton;
11138  delete singletons;
11139  singletons = nullptr;
11140  }
11141 
11142 } // namespace Catch
11143 // end catch_singletons.cpp
11144 // start catch_startup_exception_registry.cpp
11145 
11146 namespace Catch {
11147 void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
11148  CATCH_TRY {
11149  m_exceptions.push_back(exception);
11150  } CATCH_CATCH_ALL {
11151  // If we run out of memory during start-up there's really not a lot more we can do about it
11152  std::terminate();
11153  }
11154  }
11155 
11156  std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept {
11157  return m_exceptions;
11158  }
11159 
11160 } // end namespace Catch
11161 // end catch_startup_exception_registry.cpp
11162 // start catch_stream.cpp
11163 
11164 #include <cstdio>
11165 #include <iostream>
11166 #include <fstream>
11167 #include <sstream>
11168 #include <vector>
11169 #include <memory>
11170 
11171 namespace Catch {
11172 
11173  Catch::IStream::~IStream() = default;
11174 
11175  namespace detail { namespace {
11176  template<typename WriterF, std::size_t bufferSize=256>
11177  class StreamBufImpl : public std::streambuf {
11178  char data[bufferSize];
11179  WriterF m_writer;
11180 
11181  public:
11182  StreamBufImpl() {
11183  setp( data, data + sizeof(data) );
11184  }
11185 
11186  ~StreamBufImpl() noexcept {
11188  }
11189 
11190  private:
11191  int overflow( int c ) override {
11192  sync();
11193 
11194  if( c != EOF ) {
11195  if( pbase() == epptr() )
11196  m_writer( std::string( 1, static_cast<char>( c ) ) );
11197  else
11198  sputc( static_cast<char>( c ) );
11199  }
11200  return 0;
11201  }
11202 
11203  int sync() override {
11204  if( pbase() != pptr() ) {
11205  m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
11206  setp( pbase(), epptr() );
11207  }
11208  return 0;
11209  }
11210  };
11211 
11213 
11214  struct OutputDebugWriter {
11215 
11216  void operator()( std::string const&str ) {
11217  writeToDebugConsole( str );
11218  }
11219  };
11220 
11222 
11223  class FileStream : public IStream {
11224  mutable std::ofstream m_ofs;
11225  public:
11226  FileStream( StringRef filename ) {
11227  m_ofs.open( filename.c_str() );
11228  CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << "'" );
11229  }
11230  ~FileStream() override = default;
11231  public: // IStream
11232  std::ostream& stream() const override {
11233  return m_ofs;
11234  }
11235  };
11236 
11238 
11239  class CoutStream : public IStream {
11240  mutable std::ostream m_os;
11241  public:
11242  // Store the streambuf from cout up-front because
11243  // cout may get redirected when running tests
11244  CoutStream() : m_os( Catch::cout().rdbuf() ) {}
11245  ~CoutStream() override = default;
11246 
11247  public: // IStream
11248  std::ostream& stream() const override { return m_os; }
11249  };
11250 
11252 
11253  class DebugOutStream : public IStream {
11254  std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf;
11255  mutable std::ostream m_os;
11256  public:
11257  DebugOutStream()
11258  : m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
11259  m_os( m_streamBuf.get() )
11260  {}
11261 
11262  ~DebugOutStream() override = default;
11263 
11264  public: // IStream
11265  std::ostream& stream() const override { return m_os; }
11266  };
11267 
11268  }} // namespace anon::detail
11269 
11271 
11272  auto makeStream( StringRef const &filename ) -> IStream const* {
11273  if( filename.empty() )
11274  return new detail::CoutStream();
11275  else if( filename[0] == '%' ) {
11276  if( filename == "%debug" )
11277  return new detail::DebugOutStream();
11278  else
11279  CATCH_ERROR( "Unrecognised stream: '" << filename << "'" );
11280  }
11281  else
11282  return new detail::FileStream( filename );
11283  }
11284 
11285  // This class encapsulates the idea of a pool of ostringstreams that can be reused.
11286  struct StringStreams {
11287  std::vector<std::unique_ptr<std::ostringstream>> m_streams;
11288  std::vector<std::size_t> m_unused;
11289  std::ostringstream m_referenceStream; // Used for copy state/ flags from
11290 
11291  auto add() -> std::size_t {
11292  if( m_unused.empty() ) {
11293  m_streams.push_back( std::unique_ptr<std::ostringstream>( new std::ostringstream ) );
11294  return m_streams.size()-1;
11295  }
11296  else {
11297  auto index = m_unused.back();
11298  m_unused.pop_back();
11299  return index;
11300  }
11301  }
11302 
11303  void release( std::size_t index ) {
11304  m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state
11305  m_unused.push_back(index);
11306  }
11307  };
11308 
11310  : m_index( Singleton<StringStreams>::getMutable().add() ),
11311  m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].get() )
11312  {}
11313 
11315  static_cast<std::ostringstream*>( m_oss )->str("");
11316  m_oss->clear();
11317  Singleton<StringStreams>::getMutable().release( m_index );
11318  }
11319 
11320  auto ReusableStringStream::str() const -> std::string {
11321  return static_cast<std::ostringstream*>( m_oss )->str();
11322  }
11323 
11325 
11326 #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
11327  std::ostream& cout() { return std::cout; }
11328  std::ostream& cerr() { return std::cerr; }
11329  std::ostream& clog() { return std::clog; }
11330 #endif
11331 }
11332 // end catch_stream.cpp
11333 // start catch_string_manip.cpp
11334 
11335 #include <algorithm>
11336 #include <ostream>
11337 #include <cstring>
11338 #include <cctype>
11339 
11340 namespace Catch {
11341 
11342  namespace {
11343  char toLowerCh(char c) {
11344  return static_cast<char>( std::tolower( c ) );
11345  }
11346  }
11347 
11348  bool startsWith( std::string const& s, std::string const& prefix ) {
11349  return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
11350  }
11351  bool startsWith( std::string const& s, char prefix ) {
11352  return !s.empty() && s[0] == prefix;
11353  }
11354  bool endsWith( std::string const& s, std::string const& suffix ) {
11355  return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
11356  }
11357  bool endsWith( std::string const& s, char suffix ) {
11358  return !s.empty() && s[s.size()-1] == suffix;
11359  }
11360  bool contains( std::string const& s, std::string const& infix ) {
11361  return s.find( infix ) != std::string::npos;
11362  }
11363  void toLowerInPlace( std::string& s ) {
11364  std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
11365  }
11366  std::string toLower( std::string const& s ) {
11367  std::string lc = s;
11368  toLowerInPlace( lc );
11369  return lc;
11370  }
11371  std::string trim( std::string const& str ) {
11372  static char const* whitespaceChars = "\n\r\t ";
11373  std::string::size_type start = str.find_first_not_of( whitespaceChars );
11374  std::string::size_type end = str.find_last_not_of( whitespaceChars );
11375 
11376  return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
11377  }
11378 
11379  bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
11380  bool replaced = false;
11381  std::size_t i = str.find( replaceThis );
11382  while( i != std::string::npos ) {
11383  replaced = true;
11384  str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
11385  if( i < str.size()-withThis.size() )
11386  i = str.find( replaceThis, i+withThis.size() );
11387  else
11388  i = std::string::npos;
11389  }
11390  return replaced;
11391  }
11392 
11393  pluralise::pluralise( std::size_t count, std::string const& label )
11394  : m_count( count ),
11395  m_label( label )
11396  {}
11397 
11398  std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
11399  os << pluraliser.m_count << ' ' << pluraliser.m_label;
11400  if( pluraliser.m_count != 1 )
11401  os << 's';
11402  return os;
11403  }
11404 
11405 }
11406 // end catch_string_manip.cpp
11407 // start catch_stringref.cpp
11408 
11409 #if defined(__clang__)
11410 # pragma clang diagnostic push
11411 # pragma clang diagnostic ignored "-Wexit-time-destructors"
11412 #endif
11413 
11414 #include <ostream>
11415 #include <cstring>
11416 #include <cstdint>
11417 
11418 namespace {
11419  const uint32_t byte_2_lead = 0xC0;
11420  const uint32_t byte_3_lead = 0xE0;
11421  const uint32_t byte_4_lead = 0xF0;
11422 }
11423 
11424 namespace Catch {
11425  StringRef::StringRef( char const* rawChars ) noexcept
11426  : StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) )
11427  {}
11428 
11429  StringRef::operator std::string() const {
11430  return std::string( m_start, m_size );
11431  }
11432 
11433  void StringRef::swap( StringRef& other ) noexcept {
11434  std::swap( m_start, other.m_start );
11435  std::swap( m_size, other.m_size );
11436  std::swap( m_data, other.m_data );
11437  }
11438 
11439  auto StringRef::c_str() const -> char const* {
11440  if( isSubstring() )
11441  const_cast<StringRef*>( this )->takeOwnership();
11442  return m_start;
11443  }
11444  auto StringRef::currentData() const noexcept -> char const* {
11445  return m_start;
11446  }
11447 
11448  auto StringRef::isOwned() const noexcept -> bool {
11449  return m_data != nullptr;
11450  }
11451  auto StringRef::isSubstring() const noexcept -> bool {
11452  return m_start[m_size] != '\0';
11453  }
11454 
11455  void StringRef::takeOwnership() {
11456  if( !isOwned() ) {
11457  m_data = new char[m_size+1];
11458  memcpy( m_data, m_start, m_size );
11459  m_data[m_size] = '\0';
11460  m_start = m_data;
11461  }
11462  }
11463  auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {
11464  if( start < m_size )
11465  return StringRef( m_start+start, size );
11466  else
11467  return StringRef();
11468  }
11469  auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool {
11470  return
11471  size() == other.size() &&
11472  (std::strncmp( m_start, other.m_start, size() ) == 0);
11473  }
11474  auto StringRef::operator != ( StringRef const& other ) const noexcept -> bool {
11475  return !operator==( other );
11476  }
11477 
11478  auto StringRef::operator[](size_type index) const noexcept -> char {
11479  return m_start[index];
11480  }
11481 
11482  auto StringRef::numberOfCharacters() const noexcept -> size_type {
11483  size_type noChars = m_size;
11484  // Make adjustments for uft encodings
11485  for( size_type i=0; i < m_size; ++i ) {
11486  char c = m_start[i];
11487  if( ( c & byte_2_lead ) == byte_2_lead ) {
11488  noChars--;
11489  if (( c & byte_3_lead ) == byte_3_lead )
11490  noChars--;
11491  if( ( c & byte_4_lead ) == byte_4_lead )
11492  noChars--;
11493  }
11494  }
11495  return noChars;
11496  }
11497 
11498  auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string {
11499  std::string str;
11500  str.reserve( lhs.size() + rhs.size() );
11501  str += lhs;
11502  str += rhs;
11503  return str;
11504  }
11505  auto operator + ( StringRef const& lhs, const char* rhs ) -> std::string {
11506  return std::string( lhs ) + std::string( rhs );
11507  }
11508  auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string {
11509  return std::string( lhs ) + std::string( rhs );
11510  }
11511 
11512  auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {
11513  return os.write(str.currentData(), str.size());
11514  }
11515 
11516  auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& {
11517  lhs.append(rhs.currentData(), rhs.size());
11518  return lhs;
11519  }
11520 
11521 } // namespace Catch
11522 
11523 #if defined(__clang__)
11524 # pragma clang diagnostic pop
11525 #endif
11526 // end catch_stringref.cpp
11527 // start catch_tag_alias.cpp
11528 
11529 namespace Catch {
11530  TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {}
11531 }
11532 // end catch_tag_alias.cpp
11533 // start catch_tag_alias_autoregistrar.cpp
11534 
11535 namespace Catch {
11536 
11537  RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {
11538  CATCH_TRY {
11539  getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
11540  } CATCH_CATCH_ALL {
11541  // Do not throw when constructing global objects, instead register the exception to be processed later
11543  }
11544  }
11545 
11546 }
11547 // end catch_tag_alias_autoregistrar.cpp
11548 // start catch_tag_alias_registry.cpp
11549 
11550 #include <sstream>
11551 
11552 namespace Catch {
11553 
11554  TagAliasRegistry::~TagAliasRegistry() {}
11555 
11556  TagAlias const* TagAliasRegistry::find( std::string const& alias ) const {
11557  auto it = m_registry.find( alias );
11558  if( it != m_registry.end() )
11559  return &(it->second);
11560  else
11561  return nullptr;
11562  }
11563 
11564  std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
11565  std::string expandedTestSpec = unexpandedTestSpec;
11566  for( auto const& registryKvp : m_registry ) {
11567  std::size_t pos = expandedTestSpec.find( registryKvp.first );
11568  if( pos != std::string::npos ) {
11569  expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
11570  registryKvp.second.tag +
11571  expandedTestSpec.substr( pos + registryKvp.first.size() );
11572  }
11573  }
11574  return expandedTestSpec;
11575  }
11576 
11577  void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) {
11578  CATCH_ENFORCE( startsWith(alias, "[@") && endsWith(alias, ']'),
11579  "error: tag alias, '" << alias << "' is not of the form [@alias name].\n" << lineInfo );
11580 
11581  CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,
11582  "error: tag alias, '" << alias << "' already registered.\n"
11583  << "\tFirst seen at: " << find(alias)->lineInfo << "\n"
11584  << "\tRedefined at: " << lineInfo );
11585  }
11586 
11587  ITagAliasRegistry::~ITagAliasRegistry() {}
11588 
11589  ITagAliasRegistry const& ITagAliasRegistry::get() {
11591  }
11592 
11593 } // end namespace Catch
11594 // end catch_tag_alias_registry.cpp
11595 // start catch_test_case_info.cpp
11596 
11597 #include <cctype>
11598 #include <exception>
11599 #include <algorithm>
11600 #include <sstream>
11601 
11602 namespace Catch {
11603 
11604  namespace {
11605  TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
11606  if( startsWith( tag, '.' ) ||
11607  tag == "!hide" )
11608  return TestCaseInfo::IsHidden;
11609  else if( tag == "!throws" )
11610  return TestCaseInfo::Throws;
11611  else if( tag == "!shouldfail" )
11612  return TestCaseInfo::ShouldFail;
11613  else if( tag == "!mayfail" )
11614  return TestCaseInfo::MayFail;
11615  else if( tag == "!nonportable" )
11617  else if( tag == "!benchmark" )
11619  else
11620  return TestCaseInfo::None;
11621  }
11622  bool isReservedTag( std::string const& tag ) {
11623  return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) );
11624  }
11625  void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
11626  CATCH_ENFORCE( !isReservedTag(tag),
11627  "Tag name: [" << tag << "] is not allowed.\n"
11628  << "Tag names starting with non alpha-numeric characters are reserved\n"
11629  << _lineInfo );
11630  }
11631  }
11632 
11633  TestCase makeTestCase( ITestInvoker* _testCase,
11634  std::string const& _className,
11635  NameAndTags const& nameAndTags,
11636  SourceLineInfo const& _lineInfo )
11637  {
11638  bool isHidden = false;
11639 
11640  // Parse out tags
11641  std::vector<std::string> tags;
11642  std::string desc, tag;
11643  bool inTag = false;
11644  std::string _descOrTags = nameAndTags.tags;
11645  for (char c : _descOrTags) {
11646  if( !inTag ) {
11647  if( c == '[' )
11648  inTag = true;
11649  else
11650  desc += c;
11651  }
11652  else {
11653  if( c == ']' ) {
11654  TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
11655  if( ( prop & TestCaseInfo::IsHidden ) != 0 )
11656  isHidden = true;
11657  else if( prop == TestCaseInfo::None )
11658  enforceNotReservedTag( tag, _lineInfo );
11659 
11660  tags.push_back( tag );
11661  tag.clear();
11662  inTag = false;
11663  }
11664  else
11665  tag += c;
11666  }
11667  }
11668  if( isHidden ) {
11669  tags.push_back( "." );
11670  }
11671 
11672  TestCaseInfo info( nameAndTags.name, _className, desc, tags, _lineInfo );
11673  return TestCase( _testCase, std::move(info) );
11674  }
11675 
11676  void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ) {
11677  std::sort(begin(tags), end(tags));
11678  tags.erase(std::unique(begin(tags), end(tags)), end(tags));
11679  testCaseInfo.lcaseTags.clear();
11680 
11681  for( auto const& tag : tags ) {
11682  std::string lcaseTag = toLower( tag );
11683  testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
11684  testCaseInfo.lcaseTags.push_back( lcaseTag );
11685  }
11686  testCaseInfo.tags = std::move(tags);
11687  }
11688 
11689  TestCaseInfo::TestCaseInfo( std::string const& _name,
11690  std::string const& _className,
11691  std::string const& _description,
11692  std::vector<std::string> const& _tags,
11693  SourceLineInfo const& _lineInfo )
11694  : name( _name ),
11695  className( _className ),
11696  description( _description ),
11697  lineInfo( _lineInfo ),
11698  properties( None )
11699  {
11700  setTags( *this, _tags );
11701  }
11702 
11703  bool TestCaseInfo::isHidden() const {
11704  return ( properties & IsHidden ) != 0;
11705  }
11706  bool TestCaseInfo::throws() const {
11707  return ( properties & Throws ) != 0;
11708  }
11709  bool TestCaseInfo::okToFail() const {
11710  return ( properties & (ShouldFail | MayFail ) ) != 0;
11711  }
11712  bool TestCaseInfo::expectedToFail() const {
11713  return ( properties & (ShouldFail ) ) != 0;
11714  }
11715 
11716  std::string TestCaseInfo::tagsAsString() const {
11717  std::string ret;
11718  // '[' and ']' per tag
11719  std::size_t full_size = 2 * tags.size();
11720  for (const auto& tag : tags) {
11721  full_size += tag.size();
11722  }
11723  ret.reserve(full_size);
11724  for (const auto& tag : tags) {
11725  ret.push_back('[');
11726  ret.append(tag);
11727  ret.push_back(']');
11728  }
11729 
11730  return ret;
11731  }
11732 
11733  TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( std::move(info) ), test( testCase ) {}
11734 
11735  TestCase TestCase::withName( std::string const& _newName ) const {
11736  TestCase other( *this );
11737  other.name = _newName;
11738  return other;
11739  }
11740 
11741  void TestCase::invoke() const {
11742  test->invoke();
11743  }
11744 
11745  bool TestCase::operator == ( TestCase const& other ) const {
11746  return test.get() == other.test.get() &&
11747  name == other.name &&
11748  className == other.className;
11749  }
11750 
11751  bool TestCase::operator < ( TestCase const& other ) const {
11752  return name < other.name;
11753  }
11754 
11756  {
11757  return *this;
11758  }
11759 
11760 } // end namespace Catch
11761 // end catch_test_case_info.cpp
11762 // start catch_test_case_registry_impl.cpp
11763 
11764 #include <sstream>
11765 
11766 namespace Catch {
11767 
11768  std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
11769 
11770  std::vector<TestCase> sorted = unsortedTestCases;
11771 
11772  switch( config.runOrder() ) {
11774  std::sort( sorted.begin(), sorted.end() );
11775  break;
11777  seedRng( config );
11778  std::shuffle( sorted.begin(), sorted.end(), rng() );
11779  break;
11781  // already in declaration order
11782  break;
11783  }
11784  return sorted;
11785  }
11786  bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
11787  return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
11788  }
11789 
11790  void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
11791  std::set<TestCase> seenFunctions;
11792  for( auto const& function : functions ) {
11793  auto prev = seenFunctions.insert( function );
11794  CATCH_ENFORCE( prev.second,
11795  "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n"
11796  << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
11797  << "\tRedefined at " << function.getTestCaseInfo().lineInfo );
11798  }
11799  }
11800 
11801  std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
11802  std::vector<TestCase> filtered;
11803  filtered.reserve( testCases.size() );
11804  for( auto const& testCase : testCases )
11805  if( matchTest( testCase, testSpec, config ) )
11806  filtered.push_back( testCase );
11807  return filtered;
11808  }
11809  std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
11811  }
11812 
11813  void TestRegistry::registerTest( TestCase const& testCase ) {
11814  std::string name = testCase.getTestCaseInfo().name;
11815  if( name.empty() ) {
11817  rss << "Anonymous test case " << ++m_unnamedCount;
11818  return registerTest( testCase.withName( rss.str() ) );
11819  }
11820  m_functions.push_back( testCase );
11821  }
11822 
11823  std::vector<TestCase> const& TestRegistry::getAllTests() const {
11824  return m_functions;
11825  }
11826  std::vector<TestCase> const& TestRegistry::getAllTestsSorted( IConfig const& config ) const {
11827  if( m_sortedFunctions.empty() )
11828  enforceNoDuplicateTestCases( m_functions );
11829 
11830  if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
11831  m_sortedFunctions = sortTests( config, m_functions );
11832  m_currentSortOrder = config.runOrder();
11833  }
11834  return m_sortedFunctions;
11835  }
11836 
11838  TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {}
11839 
11840  void TestInvokerAsFunction::invoke() const {
11841  m_testAsFunction();
11842  }
11843 
11844  std::string extractClassName( StringRef const& classOrQualifiedMethodName ) {
11845  std::string className = classOrQualifiedMethodName;
11846  if( startsWith( className, '&' ) )
11847  {
11848  std::size_t lastColons = className.rfind( "::" );
11849  std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
11850  if( penultimateColons == std::string::npos )
11851  penultimateColons = 1;
11852  className = className.substr( penultimateColons, lastColons-penultimateColons );
11853  }
11854  return className;
11855  }
11856 
11857 } // end namespace Catch
11858 // end catch_test_case_registry_impl.cpp
11859 // start catch_test_case_tracker.cpp
11860 
11861 #include <algorithm>
11862 #include <cassert>
11863 #include <stdexcept>
11864 #include <memory>
11865 #include <sstream>
11866 
11867 #if defined(__clang__)
11868 # pragma clang diagnostic push
11869 # pragma clang diagnostic ignored "-Wexit-time-destructors"
11870 #endif
11871 
11872 namespace Catch {
11873 namespace TestCaseTracking {
11874 
11875  NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location )
11876  : name( _name ),
11877  location( _location )
11878  {}
11879 
11880  ITracker::~ITracker() = default;
11881 
11882  TrackerContext& TrackerContext::instance() {
11883  static TrackerContext s_instance;
11884  return s_instance;
11885  }
11886 
11887  ITracker& TrackerContext::startRun() {
11888  m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr );
11889  m_currentTracker = nullptr;
11890  m_runState = Executing;
11891  return *m_rootTracker;
11892  }
11893 
11894  void TrackerContext::endRun() {
11895  m_rootTracker.reset();
11896  m_currentTracker = nullptr;
11897  m_runState = NotStarted;
11898  }
11899 
11900  void TrackerContext::startCycle() {
11901  m_currentTracker = m_rootTracker.get();
11902  m_runState = Executing;
11903  }
11904  void TrackerContext::completeCycle() {
11905  m_runState = CompletedCycle;
11906  }
11907 
11908  bool TrackerContext::completedCycle() const {
11909  return m_runState == CompletedCycle;
11910  }
11911  ITracker& TrackerContext::currentTracker() {
11912  return *m_currentTracker;
11913  }
11914  void TrackerContext::setCurrentTracker( ITracker* tracker ) {
11915  m_currentTracker = tracker;
11916  }
11917 
11918  TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
11919  : m_nameAndLocation( nameAndLocation ),
11920  m_ctx( ctx ),
11921  m_parent( parent )
11922  {}
11923 
11924  NameAndLocation const& TrackerBase::nameAndLocation() const {
11925  return m_nameAndLocation;
11926  }
11927  bool TrackerBase::isComplete() const {
11928  return m_runState == CompletedSuccessfully || m_runState == Failed;
11929  }
11930  bool TrackerBase::isSuccessfullyCompleted() const {
11931  return m_runState == CompletedSuccessfully;
11932  }
11933  bool TrackerBase::isOpen() const {
11934  return m_runState != NotStarted && !isComplete();
11935  }
11936  bool TrackerBase::hasChildren() const {
11937  return !m_children.empty();
11938  }
11939 
11940  void TrackerBase::addChild( ITrackerPtr const& child ) {
11941  m_children.push_back( child );
11942  }
11943 
11944  ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) {
11945  auto it = std::find_if( m_children.begin(), m_children.end(),
11946  [&nameAndLocation]( ITrackerPtr const& tracker ){
11947  return
11948  tracker->nameAndLocation().location == nameAndLocation.location &&
11949  tracker->nameAndLocation().name == nameAndLocation.name;
11950  } );
11951  return( it != m_children.end() )
11952  ? *it
11953  : nullptr;
11954  }
11955  ITracker& TrackerBase::parent() {
11956  assert( m_parent ); // Should always be non-null except for root
11957  return *m_parent;
11958  }
11959 
11960  void TrackerBase::openChild() {
11961  if( m_runState != ExecutingChildren ) {
11962  m_runState = ExecutingChildren;
11963  if( m_parent )
11964  m_parent->openChild();
11965  }
11966  }
11967 
11968  bool TrackerBase::isSectionTracker() const { return false; }
11969  bool TrackerBase::isGeneratorTracker() const { return false; }
11970 
11971  void TrackerBase::open() {
11972  m_runState = Executing;
11973  moveToThis();
11974  if( m_parent )
11975  m_parent->openChild();
11976  }
11977 
11978  void TrackerBase::close() {
11979 
11980  // Close any still open children (e.g. generators)
11981  while( &m_ctx.currentTracker() != this )
11982  m_ctx.currentTracker().close();
11983 
11984  switch( m_runState ) {
11985  case NeedsAnotherRun:
11986  break;
11987 
11988  case Executing:
11989  m_runState = CompletedSuccessfully;
11990  break;
11991  case ExecutingChildren:
11992  if( m_children.empty() || m_children.back()->isComplete() )
11993  m_runState = CompletedSuccessfully;
11994  break;
11995 
11996  case NotStarted:
11997  case CompletedSuccessfully:
11998  case Failed:
11999  CATCH_INTERNAL_ERROR( "Illogical state: " << m_runState );
12000 
12001  default:
12002  CATCH_INTERNAL_ERROR( "Unknown state: " << m_runState );
12003  }
12004  moveToParent();
12005  m_ctx.completeCycle();
12006  }
12007  void TrackerBase::fail() {
12008  m_runState = Failed;
12009  if( m_parent )
12010  m_parent->markAsNeedingAnotherRun();
12011  moveToParent();
12012  m_ctx.completeCycle();
12013  }
12014  void TrackerBase::markAsNeedingAnotherRun() {
12015  m_runState = NeedsAnotherRun;
12016  }
12017 
12018  void TrackerBase::moveToParent() {
12019  assert( m_parent );
12020  m_ctx.setCurrentTracker( m_parent );
12021  }
12022  void TrackerBase::moveToThis() {
12023  m_ctx.setCurrentTracker( this );
12024  }
12025 
12026  SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
12027  : TrackerBase( nameAndLocation, ctx, parent )
12028  {
12029  if( parent ) {
12030  while( !parent->isSectionTracker() )
12031  parent = &parent->parent();
12032 
12033  SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );
12034  addNextFilters( parentSection.m_filters );
12035  }
12036  }
12037 
12038  bool SectionTracker::isComplete() const {
12039  bool complete = true;
12040 
12041  if ((m_filters.empty() || m_filters[0] == "") ||
12042  std::find(m_filters.begin(), m_filters.end(),
12043  m_nameAndLocation.name) != m_filters.end())
12044  complete = TrackerBase::isComplete();
12045  return complete;
12046 
12047  }
12048 
12049  bool SectionTracker::isSectionTracker() const { return true; }
12050 
12051  SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {
12052  std::shared_ptr<SectionTracker> section;
12053 
12054  ITracker& currentTracker = ctx.currentTracker();
12055  if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
12056  assert( childTracker );
12057  assert( childTracker->isSectionTracker() );
12058  section = std::static_pointer_cast<SectionTracker>( childTracker );
12059  }
12060  else {
12061  section = std::make_shared<SectionTracker>( nameAndLocation, ctx, &currentTracker );
12062  currentTracker.addChild( section );
12063  }
12064  if( !ctx.completedCycle() )
12065  section->tryOpen();
12066  return *section;
12067  }
12068 
12069  void SectionTracker::tryOpen() {
12070  if( !isComplete() && (m_filters.empty() || m_filters[0].empty() || m_filters[0] == m_nameAndLocation.name ) )
12071  open();
12072  }
12073 
12074  void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) {
12075  if( !filters.empty() ) {
12076  m_filters.push_back(""); // Root - should never be consulted
12077  m_filters.push_back(""); // Test Case - not a section filter
12078  m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
12079  }
12080  }
12081  void SectionTracker::addNextFilters( std::vector<std::string> const& filters ) {
12082  if( filters.size() > 1 )
12083  m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() );
12084  }
12085 
12086 } // namespace TestCaseTracking
12087 
12088 using TestCaseTracking::ITracker;
12089 using TestCaseTracking::TrackerContext;
12090 using TestCaseTracking::SectionTracker;
12091 
12092 } // namespace Catch
12093 
12094 #if defined(__clang__)
12095 # pragma clang diagnostic pop
12096 #endif
12097 // end catch_test_case_tracker.cpp
12098 // start catch_test_registry.cpp
12099 
12100 namespace Catch {
12101 
12102  auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker* {
12103  return new(std::nothrow) TestInvokerAsFunction( testAsFunction );
12104  }
12105 
12106  NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {}
12107 
12108  AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept {
12109  CATCH_TRY {
12111  .registerTest(
12112  makeTestCase(
12113  invoker,
12114  extractClassName( classOrMethod ),
12115  nameAndTags,
12116  lineInfo));
12117  } CATCH_CATCH_ALL {
12118  // Do not throw when constructing global objects, instead register the exception to be processed later
12120  }
12121  }
12122 
12123  AutoReg::~AutoReg() = default;
12124 }
12125 // end catch_test_registry.cpp
12126 // start catch_test_spec.cpp
12127 
12128 #include <algorithm>
12129 #include <string>
12130 #include <vector>
12131 #include <memory>
12132 
12133 namespace Catch {
12134 
12135  TestSpec::Pattern::~Pattern() = default;
12136  TestSpec::NamePattern::~NamePattern() = default;
12137  TestSpec::TagPattern::~TagPattern() = default;
12138  TestSpec::ExcludedPattern::~ExcludedPattern() = default;
12139 
12140  TestSpec::NamePattern::NamePattern( std::string const& name )
12141  : m_wildcardPattern( toLower( name ), CaseSensitive::No )
12142  {}
12143  bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const {
12144  return m_wildcardPattern.matches( toLower( testCase.name ) );
12145  }
12146 
12147  TestSpec::TagPattern::TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
12148  bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const {
12149  return std::find(begin(testCase.lcaseTags),
12150  end(testCase.lcaseTags),
12151  m_tag) != end(testCase.lcaseTags);
12152  }
12153 
12154  TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
12155  bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
12156 
12157  bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const {
12158  // All patterns in a filter must match for the filter to be a match
12159  for( auto const& pattern : m_patterns ) {
12160  if( !pattern->matches( testCase ) )
12161  return false;
12162  }
12163  return true;
12164  }
12165 
12166  bool TestSpec::hasFilters() const {
12167  return !m_filters.empty();
12168  }
12169  bool TestSpec::matches( TestCaseInfo const& testCase ) const {
12170  // A TestSpec matches if any filter matches
12171  for( auto const& filter : m_filters )
12172  if( filter.matches( testCase ) )
12173  return true;
12174  return false;
12175  }
12176 }
12177 // end catch_test_spec.cpp
12178 // start catch_test_spec_parser.cpp
12179 
12180 namespace Catch {
12181 
12182  TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
12183 
12184  TestSpecParser& TestSpecParser::parse( std::string const& arg ) {
12185  m_mode = None;
12186  m_exclusion = false;
12187  m_start = std::string::npos;
12188  m_arg = m_tagAliases->expandAliases( arg );
12189  m_escapeChars.clear();
12190  for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
12191  visitChar( m_arg[m_pos] );
12192  if( m_mode == Name )
12193  addPattern<TestSpec::NamePattern>();
12194  return *this;
12195  }
12196  TestSpec TestSpecParser::testSpec() {
12197  addFilter();
12198  return m_testSpec;
12199  }
12200 
12201  void TestSpecParser::visitChar( char c ) {
12202  if( m_mode == None ) {
12203  switch( c ) {
12204  case ' ': return;
12205  case '~': m_exclusion = true; return;
12206  case '[': return startNewMode( Tag, ++m_pos );
12207  case '"': return startNewMode( QuotedName, ++m_pos );
12208  case '\\': return escape();
12209  default: startNewMode( Name, m_pos ); break;
12210  }
12211  }
12212  if( m_mode == Name ) {
12213  if( c == ',' ) {
12214  addPattern<TestSpec::NamePattern>();
12215  addFilter();
12216  }
12217  else if( c == '[' ) {
12218  if( subString() == "exclude:" )
12219  m_exclusion = true;
12220  else
12221  addPattern<TestSpec::NamePattern>();
12222  startNewMode( Tag, ++m_pos );
12223  }
12224  else if( c == '\\' )
12225  escape();
12226  }
12227  else if( m_mode == EscapedName )
12228  m_mode = Name;
12229  else if( m_mode == QuotedName && c == '"' )
12230  addPattern<TestSpec::NamePattern>();
12231  else if( m_mode == Tag && c == ']' )
12232  addPattern<TestSpec::TagPattern>();
12233  }
12234  void TestSpecParser::startNewMode( Mode mode, std::size_t start ) {
12235  m_mode = mode;
12236  m_start = start;
12237  }
12238  void TestSpecParser::escape() {
12239  if( m_mode == None )
12240  m_start = m_pos;
12241  m_mode = EscapedName;
12242  m_escapeChars.push_back( m_pos );
12243  }
12244  std::string TestSpecParser::subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
12245 
12246  void TestSpecParser::addFilter() {
12247  if( !m_currentFilter.m_patterns.empty() ) {
12248  m_testSpec.m_filters.push_back( m_currentFilter );
12249  m_currentFilter = TestSpec::Filter();
12250  }
12251  }
12252 
12253  TestSpec parseTestSpec( std::string const& arg ) {
12254  return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
12255  }
12256 
12257 } // namespace Catch
12258 // end catch_test_spec_parser.cpp
12259 // start catch_timer.cpp
12260 
12261 #include <chrono>
12262 
12263 static const uint64_t nanosecondsInSecond = 1000000000;
12264 
12265 namespace Catch {
12266 
12267  auto getCurrentNanosecondsSinceEpoch() -> uint64_t {
12268  return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
12269  }
12270 
12271  namespace {
12272  auto estimateClockResolution() -> uint64_t {
12273  uint64_t sum = 0;
12274  static const uint64_t iterations = 1000000;
12275 
12276  auto startTime = getCurrentNanosecondsSinceEpoch();
12277 
12278  for( std::size_t i = 0; i < iterations; ++i ) {
12279 
12280  uint64_t ticks;
12281  uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
12282  do {
12284  } while( ticks == baseTicks );
12285 
12286  auto delta = ticks - baseTicks;
12287  sum += delta;
12288 
12289  // If we have been calibrating for over 3 seconds -- the clock
12290  // is terrible and we should move on.
12291  // TBD: How to signal that the measured resolution is probably wrong?
12292  if (ticks > startTime + 3 * nanosecondsInSecond) {
12293  return sum / ( i + 1u );
12294  }
12295  }
12296 
12297  // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
12298  // - and potentially do more iterations if there's a high variance.
12299  return sum/iterations;
12300  }
12301  }
12302  auto getEstimatedClockResolution() -> uint64_t {
12303  static auto s_resolution = estimateClockResolution();
12304  return s_resolution;
12305  }
12306 
12307  void Timer::start() {
12308  m_nanoseconds = getCurrentNanosecondsSinceEpoch();
12309  }
12310  auto Timer::getElapsedNanoseconds() const -> uint64_t {
12311  return getCurrentNanosecondsSinceEpoch() - m_nanoseconds;
12312  }
12313  auto Timer::getElapsedMicroseconds() const -> uint64_t {
12314  return getElapsedNanoseconds()/1000;
12315  }
12316  auto Timer::getElapsedMilliseconds() const -> unsigned int {
12317  return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
12318  }
12319  auto Timer::getElapsedSeconds() const -> double {
12320  return getElapsedMicroseconds()/1000000.0;
12321  }
12322 
12323 } // namespace Catch
12324 // end catch_timer.cpp
12325 // start catch_tostring.cpp
12326 
12327 #if defined(__clang__)
12328 # pragma clang diagnostic push
12329 # pragma clang diagnostic ignored "-Wexit-time-destructors"
12330 # pragma clang diagnostic ignored "-Wglobal-constructors"
12331 #endif
12332 
12333 // Enable specific decls locally
12334 #if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
12335 #define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
12336 #endif
12337 
12338 #include <cmath>
12339 #include <iomanip>
12340 
12341 namespace Catch {
12342 
12343 namespace Detail {
12344 
12345  const std::string unprintableString = "{?}";
12346 
12347  namespace {
12348  const int hexThreshold = 255;
12349 
12350  struct Endianness {
12351  enum Arch { Big, Little };
12352 
12353  static Arch which() {
12354  union _{
12355  int asInt;
12356  char asChar[sizeof (int)];
12357  } u;
12358 
12359  u.asInt = 1;
12360  return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
12361  }
12362  };
12363  }
12364 
12365  std::string rawMemoryToString( const void *object, std::size_t size ) {
12366  // Reverse order for little endian architectures
12367  int i = 0, end = static_cast<int>( size ), inc = 1;
12368  if( Endianness::which() == Endianness::Little ) {
12369  i = end-1;
12370  end = inc = -1;
12371  }
12372 
12373  unsigned char const *bytes = static_cast<unsigned char const *>(object);
12375  rss << "0x" << std::setfill('0') << std::hex;
12376  for( ; i != end; i += inc )
12377  rss << std::setw(2) << static_cast<unsigned>(bytes[i]);
12378  return rss.str();
12379  }
12380 }
12381 
12382 template<typename T>
12383 std::string fpToString( T value, int precision ) {
12384  if (Catch::isnan(value)) {
12385  return "nan";
12386  }
12387 
12389  rss << std::setprecision( precision )
12390  << std::fixed
12391  << value;
12392  std::string d = rss.str();
12393  std::size_t i = d.find_last_not_of( '0' );
12394  if( i != std::string::npos && i != d.size()-1 ) {
12395  if( d[i] == '.' )
12396  i++;
12397  d = d.substr( 0, i+1 );
12398  }
12399  return d;
12400 }
12401 
12403 //
12404 // Out-of-line defs for full specialization of StringMaker
12405 //
12407 
12408 std::string StringMaker<std::string>::convert(const std::string& str) {
12409  if (!getCurrentContext().getConfig()->showInvisibles()) {
12410  return '"' + str + '"';
12411  }
12412 
12413  std::string s("\"");
12414  for (char c : str) {
12415  switch (c) {
12416  case '\n':
12417  s.append("\\n");
12418  break;
12419  case '\t':
12420  s.append("\\t");
12421  break;
12422  default:
12423  s.push_back(c);
12424  break;
12425  }
12426  }
12427  s.append("\"");
12428  return s;
12429 }
12430 
12431 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
12432 std::string StringMaker<std::string_view>::convert(std::string_view str) {
12433  return ::Catch::Detail::stringify(std::string{ str });
12434 }
12435 #endif
12436 
12437 std::string StringMaker<char const*>::convert(char const* str) {
12438  if (str) {
12439  return ::Catch::Detail::stringify(std::string{ str });
12440  } else {
12441  return{ "{null string}" };
12442  }
12443 }
12444 std::string StringMaker<char*>::convert(char* str) {
12445  if (str) {
12446  return ::Catch::Detail::stringify(std::string{ str });
12447  } else {
12448  return{ "{null string}" };
12449  }
12450 }
12451 
12452 #ifdef CATCH_CONFIG_WCHAR
12453 std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
12454  std::string s;
12455  s.reserve(wstr.size());
12456  for (auto c : wstr) {
12457  s += (c <= 0xff) ? static_cast<char>(c) : '?';
12458  }
12460 }
12461 
12462 # ifdef CATCH_CONFIG_CPP17_STRING_VIEW
12463 std::string StringMaker<std::wstring_view>::convert(std::wstring_view str) {
12464  return StringMaker<std::wstring>::convert(std::wstring(str));
12465 }
12466 # endif
12467 
12468 std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {
12469  if (str) {
12470  return ::Catch::Detail::stringify(std::wstring{ str });
12471  } else {
12472  return{ "{null string}" };
12473  }
12474 }
12475 std::string StringMaker<wchar_t *>::convert(wchar_t * str) {
12476  if (str) {
12477  return ::Catch::Detail::stringify(std::wstring{ str });
12478  } else {
12479  return{ "{null string}" };
12480  }
12481 }
12482 #endif
12483 
12484 std::string StringMaker<int>::convert(int value) {
12485  return ::Catch::Detail::stringify(static_cast<long long>(value));
12486 }
12487 std::string StringMaker<long>::convert(long value) {
12488  return ::Catch::Detail::stringify(static_cast<long long>(value));
12489 }
12490 std::string StringMaker<long long>::convert(long long value) {
12492  rss << value;
12493  if (value > Detail::hexThreshold) {
12494  rss << " (0x" << std::hex << value << ')';
12495  }
12496  return rss.str();
12497 }
12498 
12499 std::string StringMaker<unsigned int>::convert(unsigned int value) {
12500  return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
12501 }
12502 std::string StringMaker<unsigned long>::convert(unsigned long value) {
12503  return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
12504 }
12505 std::string StringMaker<unsigned long long>::convert(unsigned long long value) {
12507  rss << value;
12508  if (value > Detail::hexThreshold) {
12509  rss << " (0x" << std::hex << value << ')';
12510  }
12511  return rss.str();
12512 }
12513 
12514 std::string StringMaker<bool>::convert(bool b) {
12515  return b ? "true" : "false";
12516 }
12517 
12518 std::string StringMaker<signed char>::convert(signed char value) {
12519  if (value == '\r') {
12520  return "'\\r'";
12521  } else if (value == '\f') {
12522  return "'\\f'";
12523  } else if (value == '\n') {
12524  return "'\\n'";
12525  } else if (value == '\t') {
12526  return "'\\t'";
12527  } else if ('\0' <= value && value < ' ') {
12528  return ::Catch::Detail::stringify(static_cast<unsigned int>(value));
12529  } else {
12530  char chstr[] = "' '";
12531  chstr[1] = value;
12532  return chstr;
12533  }
12534 }
12535 std::string StringMaker<char>::convert(char c) {
12536  return ::Catch::Detail::stringify(static_cast<signed char>(c));
12537 }
12538 std::string StringMaker<unsigned char>::convert(unsigned char c) {
12539  return ::Catch::Detail::stringify(static_cast<char>(c));
12540 }
12541 
12542 std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) {
12543  return "nullptr";
12544 }
12545 
12546 std::string StringMaker<float>::convert(float value) {
12547  return fpToString(value, 5) + 'f';
12548 }
12549 std::string StringMaker<double>::convert(double value) {
12550  return fpToString(value, 10);
12551 }
12552 
12553 std::string ratio_string<std::atto>::symbol() { return "a"; }
12554 std::string ratio_string<std::femto>::symbol() { return "f"; }
12555 std::string ratio_string<std::pico>::symbol() { return "p"; }
12556 std::string ratio_string<std::nano>::symbol() { return "n"; }
12557 std::string ratio_string<std::micro>::symbol() { return "u"; }
12558 std::string ratio_string<std::milli>::symbol() { return "m"; }
12559 
12560 } // end namespace Catch
12561 
12562 #if defined(__clang__)
12563 # pragma clang diagnostic pop
12564 #endif
12565 
12566 // end catch_tostring.cpp
12567 // start catch_totals.cpp
12568 
12569 namespace Catch {
12570 
12571  Counts Counts::operator - ( Counts const& other ) const {
12572  Counts diff;
12573  diff.passed = passed - other.passed;
12574  diff.failed = failed - other.failed;
12575  diff.failedButOk = failedButOk - other.failedButOk;
12576  return diff;
12577  }
12578 
12579  Counts& Counts::operator += ( Counts const& other ) {
12580  passed += other.passed;
12581  failed += other.failed;
12582  failedButOk += other.failedButOk;
12583  return *this;
12584  }
12585 
12586  std::size_t Counts::total() const {
12587  return passed + failed + failedButOk;
12588  }
12589  bool Counts::allPassed() const {
12590  return failed == 0 && failedButOk == 0;
12591  }
12592  bool Counts::allOk() const {
12593  return failed == 0;
12594  }
12595 
12596  Totals Totals::operator - ( Totals const& other ) const {
12597  Totals diff;
12598  diff.assertions = assertions - other.assertions;
12599  diff.testCases = testCases - other.testCases;
12600  return diff;
12601  }
12602 
12603  Totals& Totals::operator += ( Totals const& other ) {
12604  assertions += other.assertions;
12605  testCases += other.testCases;
12606  return *this;
12607  }
12608 
12609  Totals Totals::delta( Totals const& prevTotals ) const {
12610  Totals diff = *this - prevTotals;
12611  if( diff.assertions.failed > 0 )
12612  ++diff.testCases.failed;
12613  else if( diff.assertions.failedButOk > 0 )
12614  ++diff.testCases.failedButOk;
12615  else
12616  ++diff.testCases.passed;
12617  return diff;
12618  }
12619 
12620 }
12621 // end catch_totals.cpp
12622 // start catch_uncaught_exceptions.cpp
12623 
12624 #include <exception>
12625 
12626 namespace Catch {
12627  bool uncaught_exceptions() {
12628 #if defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
12629  return std::uncaught_exceptions() > 0;
12630 #else
12631  return std::uncaught_exception();
12632 #endif
12633  }
12634 } // end namespace Catch
12635 // end catch_uncaught_exceptions.cpp
12636 // start catch_version.cpp
12637 
12638 #include <ostream>
12639 
12640 namespace Catch {
12641 
12642  Version::Version
12643  ( unsigned int _majorVersion,
12644  unsigned int _minorVersion,
12645  unsigned int _patchNumber,
12646  char const * const _branchName,
12647  unsigned int _buildNumber )
12648  : majorVersion( _majorVersion ),
12649  minorVersion( _minorVersion ),
12650  patchNumber( _patchNumber ),
12651  branchName( _branchName ),
12652  buildNumber( _buildNumber )
12653  {}
12654 
12655  std::ostream& operator << ( std::ostream& os, Version const& version ) {
12656  os << version.majorVersion << '.'
12657  << version.minorVersion << '.'
12658  << version.patchNumber;
12659  // branchName is never null -> 0th char is \0 if it is empty
12660  if (version.branchName[0]) {
12661  os << '-' << version.branchName
12662  << '.' << version.buildNumber;
12663  }
12664  return os;
12665  }
12666 
12667  Version const& libraryVersion() {
12668  static Version version( 2, 7, 0, "", 0 );
12669  return version;
12670  }
12671 
12672 }
12673 // end catch_version.cpp
12674 // start catch_wildcard_pattern.cpp
12675 
12676 #include <sstream>
12677 
12678 namespace Catch {
12679 
12680  WildcardPattern::WildcardPattern( std::string const& pattern,
12681  CaseSensitive::Choice caseSensitivity )
12682  : m_caseSensitivity( caseSensitivity ),
12683  m_pattern( adjustCase( pattern ) )
12684  {
12685  if( startsWith( m_pattern, '*' ) ) {
12686  m_pattern = m_pattern.substr( 1 );
12687  m_wildcard = WildcardAtStart;
12688  }
12689  if( endsWith( m_pattern, '*' ) ) {
12690  m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
12691  m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
12692  }
12693  }
12694 
12695  bool WildcardPattern::matches( std::string const& str ) const {
12696  switch( m_wildcard ) {
12697  case NoWildcard:
12698  return m_pattern == adjustCase( str );
12699  case WildcardAtStart:
12700  return endsWith( adjustCase( str ), m_pattern );
12701  case WildcardAtEnd:
12702  return startsWith( adjustCase( str ), m_pattern );
12703  case WildcardAtBothEnds:
12704  return contains( adjustCase( str ), m_pattern );
12705  default:
12706  CATCH_INTERNAL_ERROR( "Unknown enum" );
12707  }
12708  }
12709 
12710  std::string WildcardPattern::adjustCase( std::string const& str ) const {
12711  return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;
12712  }
12713 }
12714 // end catch_wildcard_pattern.cpp
12715 // start catch_xmlwriter.cpp
12716 
12717 #include <iomanip>
12718 
12719 using uchar = unsigned char;
12720 
12721 namespace Catch {
12722 
12723 namespace {
12724 
12725  size_t trailingBytes(unsigned char c) {
12726  if ((c & 0xE0) == 0xC0) {
12727  return 2;
12728  }
12729  if ((c & 0xF0) == 0xE0) {
12730  return 3;
12731  }
12732  if ((c & 0xF8) == 0xF0) {
12733  return 4;
12734  }
12735  CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
12736  }
12737 
12738  uint32_t headerValue(unsigned char c) {
12739  if ((c & 0xE0) == 0xC0) {
12740  return c & 0x1F;
12741  }
12742  if ((c & 0xF0) == 0xE0) {
12743  return c & 0x0F;
12744  }
12745  if ((c & 0xF8) == 0xF0) {
12746  return c & 0x07;
12747  }
12748  CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
12749  }
12750 
12751  void hexEscapeChar(std::ostream& os, unsigned char c) {
12752  std::ios_base::fmtflags f(os.flags());
12753  os << "\\x"
12754  << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
12755  << static_cast<int>(c);
12756  os.flags(f);
12757  }
12758 
12759 } // anonymous namespace
12760 
12761  XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )
12762  : m_str( str ),
12763  m_forWhat( forWhat )
12764  {}
12765 
12766  void XmlEncode::encodeTo( std::ostream& os ) const {
12767  // Apostrophe escaping not necessary if we always use " to write attributes
12768  // (see: http://www.w3.org/TR/xml/#syntax)
12769 
12770  for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
12771  uchar c = m_str[idx];
12772  switch (c) {
12773  case '<': os << "&lt;"; break;
12774  case '&': os << "&amp;"; break;
12775 
12776  case '>':
12777  // See: http://www.w3.org/TR/xml/#syntax
12778  if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
12779  os << "&gt;";
12780  else
12781  os << c;
12782  break;
12783 
12784  case '\"':
12785  if (m_forWhat == ForAttributes)
12786  os << "&quot;";
12787  else
12788  os << c;
12789  break;
12790 
12791  default:
12792  // Check for control characters and invalid utf-8
12793 
12794  // Escape control characters in standard ascii
12795  // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
12796  if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
12797  hexEscapeChar(os, c);
12798  break;
12799  }
12800 
12801  // Plain ASCII: Write it to stream
12802  if (c < 0x7F) {
12803  os << c;
12804  break;
12805  }
12806 
12807  // UTF-8 territory
12808  // Check if the encoding is valid and if it is not, hex escape bytes.
12809  // Important: We do not check the exact decoded values for validity, only the encoding format
12810  // First check that this bytes is a valid lead byte:
12811  // This means that it is not encoded as 1111 1XXX
12812  // Or as 10XX XXXX
12813  if (c < 0xC0 ||
12814  c >= 0xF8) {
12815  hexEscapeChar(os, c);
12816  break;
12817  }
12818 
12819  auto encBytes = trailingBytes(c);
12820  // Are there enough bytes left to avoid accessing out-of-bounds memory?
12821  if (idx + encBytes - 1 >= m_str.size()) {
12822  hexEscapeChar(os, c);
12823  break;
12824  }
12825  // The header is valid, check data
12826  // The next encBytes bytes must together be a valid utf-8
12827  // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)
12828  bool valid = true;
12829  uint32_t value = headerValue(c);
12830  for (std::size_t n = 1; n < encBytes; ++n) {
12831  uchar nc = m_str[idx + n];
12832  valid &= ((nc & 0xC0) == 0x80);
12833  value = (value << 6) | (nc & 0x3F);
12834  }
12835 
12836  if (
12837  // Wrong bit pattern of following bytes
12838  (!valid) ||
12839  // Overlong encodings
12840  (value < 0x80) ||
12841  (0x80 <= value && value < 0x800 && encBytes > 2) ||
12842  (0x800 < value && value < 0x10000 && encBytes > 3) ||
12843  // Encoded value out of range
12844  (value >= 0x110000)
12845  ) {
12846  hexEscapeChar(os, c);
12847  break;
12848  }
12849 
12850  // If we got here, this is in fact a valid(ish) utf-8 sequence
12851  for (std::size_t n = 0; n < encBytes; ++n) {
12852  os << m_str[idx + n];
12853  }
12854  idx += encBytes - 1;
12855  break;
12856  }
12857  }
12858  }
12859 
12860  std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
12861  xmlEncode.encodeTo( os );
12862  return os;
12863  }
12864 
12865  XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer )
12866  : m_writer( writer )
12867  {}
12868 
12869  XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept
12870  : m_writer( other.m_writer ){
12871  other.m_writer = nullptr;
12872  }
12873  XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept {
12874  if ( m_writer ) {
12875  m_writer->endElement();
12876  }
12877  m_writer = other.m_writer;
12878  other.m_writer = nullptr;
12879  return *this;
12880  }
12881 
12882  XmlWriter::ScopedElement::~ScopedElement() {
12883  if( m_writer )
12884  m_writer->endElement();
12885  }
12886 
12887  XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, bool indent ) {
12888  m_writer->writeText( text, indent );
12889  return *this;
12890  }
12891 
12892  XmlWriter::XmlWriter( std::ostream& os ) : m_os( os )
12893  {
12894  writeDeclaration();
12895  }
12896 
12897  XmlWriter::~XmlWriter() {
12898  while( !m_tags.empty() )
12899  endElement();
12900  }
12901 
12902  XmlWriter& XmlWriter::startElement( std::string const& name ) {
12903  ensureTagClosed();
12904  newlineIfNecessary();
12905  m_os << m_indent << '<' << name;
12906  m_tags.push_back( name );
12907  m_indent += " ";
12908  m_tagIsOpen = true;
12909  return *this;
12910  }
12911 
12912  XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name ) {
12913  ScopedElement scoped( this );
12914  startElement( name );
12915  return scoped;
12916  }
12917 
12918  XmlWriter& XmlWriter::endElement() {
12919  newlineIfNecessary();
12920  m_indent = m_indent.substr( 0, m_indent.size()-2 );
12921  if( m_tagIsOpen ) {
12922  m_os << "/>";
12923  m_tagIsOpen = false;
12924  }
12925  else {
12926  m_os << m_indent << "</" << m_tags.back() << ">";
12927  }
12928  m_os << std::endl;
12929  m_tags.pop_back();
12930  return *this;
12931  }
12932 
12933  XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) {
12934  if( !name.empty() && !attribute.empty() )
12935  m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
12936  return *this;
12937  }
12938 
12939  XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) {
12940  m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
12941  return *this;
12942  }
12943 
12944  XmlWriter& XmlWriter::writeText( std::string const& text, bool indent ) {
12945  if( !text.empty() ){
12946  bool tagWasOpen = m_tagIsOpen;
12947  ensureTagClosed();
12948  if( tagWasOpen && indent )
12949  m_os << m_indent;
12950  m_os << XmlEncode( text );
12951  m_needsNewline = true;
12952  }
12953  return *this;
12954  }
12955 
12956  XmlWriter& XmlWriter::writeComment( std::string const& text ) {
12957  ensureTagClosed();
12958  m_os << m_indent << "<!--" << text << "-->";
12959  m_needsNewline = true;
12960  return *this;
12961  }
12962 
12963  void XmlWriter::writeStylesheetRef( std::string const& url ) {
12964  m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
12965  }
12966 
12967  XmlWriter& XmlWriter::writeBlankLine() {
12968  ensureTagClosed();
12969  m_os << '\n';
12970  return *this;
12971  }
12972 
12973  void XmlWriter::ensureTagClosed() {
12974  if( m_tagIsOpen ) {
12975  m_os << ">" << std::endl;
12976  m_tagIsOpen = false;
12977  }
12978  }
12979 
12980  void XmlWriter::writeDeclaration() {
12981  m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
12982  }
12983 
12984  void XmlWriter::newlineIfNecessary() {
12985  if( m_needsNewline ) {
12986  m_os << std::endl;
12987  m_needsNewline = false;
12988  }
12989  }
12990 }
12991 // end catch_xmlwriter.cpp
12992 // start catch_reporter_bases.cpp
12993 
12994 #include <cstring>
12995 #include <cfloat>
12996 #include <cstdio>
12997 #include <cassert>
12998 #include <memory>
12999 
13000 namespace Catch {
13001  void prepareExpandedExpression(AssertionResult& result) {
13002  result.getExpandedExpression();
13003  }
13004 
13005  // Because formatting using c++ streams is stateful, drop down to C is required
13006  // Alternatively we could use stringstream, but its performance is... not good.
13007  std::string getFormattedDuration( double duration ) {
13008  // Max exponent + 1 is required to represent the whole part
13009  // + 1 for decimal point
13010  // + 3 for the 3 decimal places
13011  // + 1 for null terminator
13012  const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
13013  char buffer[maxDoubleSize];
13014 
13015  // Save previous errno, to prevent sprintf from overwriting it
13016  ErrnoGuard guard;
13017 #ifdef _MSC_VER
13018  sprintf_s(buffer, "%.3f", duration);
13019 #else
13020  std::sprintf(buffer, "%.3f", duration);
13021 #endif
13022  return std::string(buffer);
13023  }
13024 
13025  TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)
13026  :StreamingReporterBase(_config) {}
13027 
13028  std::set<Verbosity> TestEventListenerBase::getSupportedVerbosities() {
13030  }
13031 
13032  void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}
13033 
13034  bool TestEventListenerBase::assertionEnded(AssertionStats const &) {
13035  return false;
13036  }
13037 
13038 } // end namespace Catch
13039 // end catch_reporter_bases.cpp
13040 // start catch_reporter_compact.cpp
13041 
13042 namespace {
13043 
13044 #ifdef CATCH_PLATFORM_MAC
13045  const char* failedString() { return "FAILED"; }
13046  const char* passedString() { return "PASSED"; }
13047 #else
13048  const char* failedString() { return "failed"; }
13049  const char* passedString() { return "passed"; }
13050 #endif
13051 
13052  // Colour::LightGrey
13053  Catch::Colour::Code dimColour() { return Catch::Colour::FileName; }
13054 
13055  std::string bothOrAll( std::size_t count ) {
13056  return count == 1 ? std::string() :
13057  count == 2 ? "both " : "all " ;
13058  }
13059 
13060 } // anon namespace
13061 
13062 namespace Catch {
13063 namespace {
13064 // Colour, message variants:
13065 // - white: No tests ran.
13066 // - red: Failed [both/all] N test cases, failed [both/all] M assertions.
13067 // - white: Passed [both/all] N test cases (no assertions).
13068 // - red: Failed N tests cases, failed M assertions.
13069 // - green: Passed [both/all] N tests cases with M assertions.
13070 void printTotals(std::ostream& out, const Totals& totals) {
13071  if (totals.testCases.total() == 0) {
13072  out << "No tests ran.";
13073  } else if (totals.testCases.failed == totals.testCases.total()) {
13074  Colour colour(Colour::ResultError);
13075  const std::string qualify_assertions_failed =
13076  totals.assertions.failed == totals.assertions.total() ?
13077  bothOrAll(totals.assertions.failed) : std::string();
13078  out <<
13079  "Failed " << bothOrAll(totals.testCases.failed)
13080  << pluralise(totals.testCases.failed, "test case") << ", "
13081  "failed " << qualify_assertions_failed <<
13082  pluralise(totals.assertions.failed, "assertion") << '.';
13083  } else if (totals.assertions.total() == 0) {
13084  out <<
13085  "Passed " << bothOrAll(totals.testCases.total())
13086  << pluralise(totals.testCases.total(), "test case")
13087  << " (no assertions).";
13088  } else if (totals.assertions.failed) {
13089  Colour colour(Colour::ResultError);
13090  out <<
13091  "Failed " << pluralise(totals.testCases.failed, "test case") << ", "
13092  "failed " << pluralise(totals.assertions.failed, "assertion") << '.';
13093  } else {
13094  Colour colour(Colour::ResultSuccess);
13095  out <<
13096  "Passed " << bothOrAll(totals.testCases.passed)
13097  << pluralise(totals.testCases.passed, "test case") <<
13098  " with " << pluralise(totals.assertions.passed, "assertion") << '.';
13099  }
13100 }
13101 
13102 // Implementation of CompactReporter formatting
13103 class AssertionPrinter {
13104 public:
13105  AssertionPrinter& operator= (AssertionPrinter const&) = delete;
13106  AssertionPrinter(AssertionPrinter const&) = delete;
13107  AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
13108  : stream(_stream)
13109  , result(_stats.assertionResult)
13110  , messages(_stats.infoMessages)
13111  , itMessage(_stats.infoMessages.begin())
13112  , printInfoMessages(_printInfoMessages) {}
13113 
13114  void print() {
13115  printSourceInfo();
13116 
13117  itMessage = messages.begin();
13118 
13119  switch (result.getResultType()) {
13120  case ResultWas::Ok:
13121  printResultType(Colour::ResultSuccess, passedString());
13122  printOriginalExpression();
13123  printReconstructedExpression();
13124  if (!result.hasExpression())
13125  printRemainingMessages(Colour::None);
13126  else
13127  printRemainingMessages();
13128  break;
13130  if (result.isOk())
13131  printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok"));
13132  else
13133  printResultType(Colour::Error, failedString());
13134  printOriginalExpression();
13135  printReconstructedExpression();
13136  printRemainingMessages();
13137  break;
13139  printResultType(Colour::Error, failedString());
13140  printIssue("unexpected exception with message:");
13141  printMessage();
13142  printExpressionWas();
13143  printRemainingMessages();
13144  break;
13146  printResultType(Colour::Error, failedString());
13147  printIssue("fatal error condition with message:");
13148  printMessage();
13149  printExpressionWas();
13150  printRemainingMessages();
13151  break;
13153  printResultType(Colour::Error, failedString());
13154  printIssue("expected exception, got none");
13155  printExpressionWas();
13156  printRemainingMessages();
13157  break;
13158  case ResultWas::Info:
13159  printResultType(Colour::None, "info");
13160  printMessage();
13161  printRemainingMessages();
13162  break;
13163  case ResultWas::Warning:
13164  printResultType(Colour::None, "warning");
13165  printMessage();
13166  printRemainingMessages();
13167  break;
13169  printResultType(Colour::Error, failedString());
13170  printIssue("explicitly");
13171  printRemainingMessages(Colour::None);
13172  break;
13173  // These cases are here to prevent compiler warnings
13174  case ResultWas::Unknown:
13175  case ResultWas::FailureBit:
13176  case ResultWas::Exception:
13177  printResultType(Colour::Error, "** internal error **");
13178  break;
13179  }
13180  }
13181 
13182 private:
13183  void printSourceInfo() const {
13184  Colour colourGuard(Colour::FileName);
13185  stream << result.getSourceInfo() << ':';
13186  }
13187 
13188  void printResultType(Colour::Code colour, std::string const& passOrFail) const {
13189  if (!passOrFail.empty()) {
13190  {
13191  Colour colourGuard(colour);
13192  stream << ' ' << passOrFail;
13193  }
13194  stream << ':';
13195  }
13196  }
13197 
13198  void printIssue(std::string const& issue) const {
13199  stream << ' ' << issue;
13200  }
13201 
13202  void printExpressionWas() {
13203  if (result.hasExpression()) {
13204  stream << ';';
13205  {
13206  Colour colour(dimColour());
13207  stream << " expression was:";
13208  }
13209  printOriginalExpression();
13210  }
13211  }
13212 
13213  void printOriginalExpression() const {
13214  if (result.hasExpression()) {
13215  stream << ' ' << result.getExpression();
13216  }
13217  }
13218 
13219  void printReconstructedExpression() const {
13220  if (result.hasExpandedExpression()) {
13221  {
13222  Colour colour(dimColour());
13223  stream << " for: ";
13224  }
13225  stream << result.getExpandedExpression();
13226  }
13227  }
13228 
13229  void printMessage() {
13230  if (itMessage != messages.end()) {
13231  stream << " '" << itMessage->message << '\'';
13232  ++itMessage;
13233  }
13234  }
13235 
13236  void printRemainingMessages(Colour::Code colour = dimColour()) {
13237  if (itMessage == messages.end())
13238  return;
13239 
13240  // using messages.end() directly yields (or auto) compilation error:
13241  std::vector<MessageInfo>::const_iterator itEnd = messages.end();
13242  const std::size_t N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
13243 
13244  {
13245  Colour colourGuard(colour);
13246  stream << " with " << pluralise(N, "message") << ':';
13247  }
13248 
13249  for (; itMessage != itEnd; ) {
13250  // If this assertion is a warning ignore any INFO messages
13251  if (printInfoMessages || itMessage->type != ResultWas::Info) {
13252  stream << " '" << itMessage->message << '\'';
13253  if (++itMessage != itEnd) {
13254  Colour colourGuard(dimColour());
13255  stream << " and";
13256  }
13257  }
13258  }
13259  }
13260 
13261 private:
13262  std::ostream& stream;
13263  AssertionResult const& result;
13264  std::vector<MessageInfo> messages;
13265  std::vector<MessageInfo>::const_iterator itMessage;
13266  bool printInfoMessages;
13267 };
13268 
13269 } // anon namespace
13270 
13271  std::string CompactReporter::getDescription() {
13272  return "Reports test results on a single line, suitable for IDEs";
13273  }
13274 
13275  ReporterPreferences CompactReporter::getPreferences() const {
13276  return m_reporterPrefs;
13277  }
13278 
13279  void CompactReporter::noMatchingTestCases( std::string const& spec ) {
13280  stream << "No test cases matched '" << spec << '\'' << std::endl;
13281  }
13282 
13283  void CompactReporter::assertionStarting( AssertionInfo const& ) {}
13284 
13285  bool CompactReporter::assertionEnded( AssertionStats const& _assertionStats ) {
13286  AssertionResult const& result = _assertionStats.assertionResult;
13287 
13288  bool printInfoMessages = true;
13289 
13290  // Drop out if result was successful and we're not printing those
13291  if( !m_config->includeSuccessfulResults() && result.isOk() ) {
13292  if( result.getResultType() != ResultWas::Warning )
13293  return false;
13294  printInfoMessages = false;
13295  }
13296 
13297  AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
13298  printer.print();
13299 
13300  stream << std::endl;
13301  return true;
13302  }
13303 
13304  void CompactReporter::sectionEnded(SectionStats const& _sectionStats) {
13305  if (m_config->showDurations() == ShowDurations::Always) {
13306  stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
13307  }
13308  }
13309 
13310  void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) {
13311  printTotals( stream, _testRunStats.totals );
13312  stream << '\n' << std::endl;
13313  StreamingReporterBase::testRunEnded( _testRunStats );
13314  }
13315 
13316  CompactReporter::~CompactReporter() {}
13317 
13318  CATCH_REGISTER_REPORTER( "compact", CompactReporter )
13319 
13320 } // end namespace Catch
13321 // end catch_reporter_compact.cpp
13322 // start catch_reporter_console.cpp
13323 
13324 #include <cfloat>
13325 #include <cstdio>
13326 
13327 #if defined(_MSC_VER)
13328 #pragma warning(push)
13329 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
13330  // Note that 4062 (not all labels are handled
13331  // and default is missing) is enabled
13332 #endif
13333 
13334 namespace Catch {
13335 
13336 namespace {
13337 
13338 // Formatter impl for ConsoleReporter
13339 class ConsoleAssertionPrinter {
13340 public:
13341  ConsoleAssertionPrinter& operator= (ConsoleAssertionPrinter const&) = delete;
13342  ConsoleAssertionPrinter(ConsoleAssertionPrinter const&) = delete;
13343  ConsoleAssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
13344  : stream(_stream),
13345  stats(_stats),
13346  result(_stats.assertionResult),
13347  colour(Colour::None),
13348  message(result.getMessage()),
13349  messages(_stats.infoMessages),
13350  printInfoMessages(_printInfoMessages) {
13351  switch (result.getResultType()) {
13352  case ResultWas::Ok:
13353  colour = Colour::Success;
13354  passOrFail = "PASSED";
13355  //if( result.hasMessage() )
13356  if (_stats.infoMessages.size() == 1)
13357  messageLabel = "with message";
13358  if (_stats.infoMessages.size() > 1)
13359  messageLabel = "with messages";
13360  break;
13362  if (result.isOk()) {
13363  colour = Colour::Success;
13364  passOrFail = "FAILED - but was ok";
13365  } else {
13366  colour = Colour::Error;
13367  passOrFail = "FAILED";
13368  }
13369  if (_stats.infoMessages.size() == 1)
13370  messageLabel = "with message";
13371  if (_stats.infoMessages.size() > 1)
13372  messageLabel = "with messages";
13373  break;
13375  colour = Colour::Error;
13376  passOrFail = "FAILED";
13377  messageLabel = "due to unexpected exception with ";
13378  if (_stats.infoMessages.size() == 1)
13379  messageLabel += "message";
13380  if (_stats.infoMessages.size() > 1)
13381  messageLabel += "messages";
13382  break;
13384  colour = Colour::Error;
13385  passOrFail = "FAILED";
13386  messageLabel = "due to a fatal error condition";
13387  break;
13389  colour = Colour::Error;
13390  passOrFail = "FAILED";
13391  messageLabel = "because no exception was thrown where one was expected";
13392  break;
13393  case ResultWas::Info:
13394  messageLabel = "info";
13395  break;
13396  case ResultWas::Warning:
13397  messageLabel = "warning";
13398  break;
13400  passOrFail = "FAILED";
13401  colour = Colour::Error;
13402  if (_stats.infoMessages.size() == 1)
13403  messageLabel = "explicitly with message";
13404  if (_stats.infoMessages.size() > 1)
13405  messageLabel = "explicitly with messages";
13406  break;
13407  // These cases are here to prevent compiler warnings
13408  case ResultWas::Unknown:
13409  case ResultWas::FailureBit:
13410  case ResultWas::Exception:
13411  passOrFail = "** internal error **";
13412  colour = Colour::Error;
13413  break;
13414  }
13415  }
13416 
13417  void print() const {
13418  printSourceInfo();
13419  if (stats.totals.assertions.total() > 0) {
13420  printResultType();
13421  printOriginalExpression();
13422  printReconstructedExpression();
13423  } else {
13424  stream << '\n';
13425  }
13426  printMessage();
13427  }
13428 
13429 private:
13430  void printResultType() const {
13431  if (!passOrFail.empty()) {
13432  Colour colourGuard(colour);
13433  stream << passOrFail << ":\n";
13434  }
13435  }
13436  void printOriginalExpression() const {
13437  if (result.hasExpression()) {
13438  Colour colourGuard(Colour::OriginalExpression);
13439  stream << " ";
13440  stream << result.getExpressionInMacro();
13441  stream << '\n';
13442  }
13443  }
13444  void printReconstructedExpression() const {
13445  if (result.hasExpandedExpression()) {
13446  stream << "with expansion:\n";
13447  Colour colourGuard(Colour::ReconstructedExpression);
13448  stream << Column(result.getExpandedExpression()).indent(2) << '\n';
13449  }
13450  }
13451  void printMessage() const {
13452  if (!messageLabel.empty())
13453  stream << messageLabel << ':' << '\n';
13454  for (auto const& msg : messages) {
13455  // If this assertion is a warning ignore any INFO messages
13456  if (printInfoMessages || msg.type != ResultWas::Info)
13457  stream << Column(msg.message).indent(2) << '\n';
13458  }
13459  }
13460  void printSourceInfo() const {
13461  Colour colourGuard(Colour::FileName);
13462  stream << result.getSourceInfo() << ": ";
13463  }
13464 
13465  std::ostream& stream;
13466  AssertionStats const& stats;
13467  AssertionResult const& result;
13468  Colour::Code colour;
13469  std::string passOrFail;
13470  std::string messageLabel;
13471  std::string message;
13472  std::vector<MessageInfo> messages;
13473  bool printInfoMessages;
13474 };
13475 
13476 std::size_t makeRatio(std::size_t number, std::size_t total) {
13477  std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0;
13478  return (ratio == 0 && number > 0) ? 1 : ratio;
13479 }
13480 
13481 std::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k) {
13482  if (i > j && i > k)
13483  return i;
13484  else if (j > k)
13485  return j;
13486  else
13487  return k;
13488 }
13489 
13490 struct ColumnInfo {
13491  enum Justification { Left, Right };
13492  std::string name;
13493  int width;
13494  Justification justification;
13495 };
13496 struct ColumnBreak {};
13497 struct RowBreak {};
13498 
13499 class Duration {
13500  enum class Unit {
13501  Auto,
13502  Nanoseconds,
13503  Microseconds,
13504  Milliseconds,
13505  Seconds,
13506  Minutes
13507  };
13508  static const uint64_t s_nanosecondsInAMicrosecond = 1000;
13509  static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond;
13510  static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;
13511  static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;
13512 
13513  uint64_t m_inNanoseconds;
13514  Unit m_units;
13515 
13516 public:
13517  explicit Duration(uint64_t inNanoseconds, Unit units = Unit::Auto)
13518  : m_inNanoseconds(inNanoseconds),
13519  m_units(units) {
13520  if (m_units == Unit::Auto) {
13521  if (m_inNanoseconds < s_nanosecondsInAMicrosecond)
13522  m_units = Unit::Nanoseconds;
13523  else if (m_inNanoseconds < s_nanosecondsInAMillisecond)
13524  m_units = Unit::Microseconds;
13525  else if (m_inNanoseconds < s_nanosecondsInASecond)
13526  m_units = Unit::Milliseconds;
13527  else if (m_inNanoseconds < s_nanosecondsInAMinute)
13528  m_units = Unit::Seconds;
13529  else
13530  m_units = Unit::Minutes;
13531  }
13532 
13533  }
13534 
13535  auto value() const -> double {
13536  switch (m_units) {
13537  case Unit::Microseconds:
13538  return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond);
13539  case Unit::Milliseconds:
13540  return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond);
13541  case Unit::Seconds:
13542  return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond);
13543  case Unit::Minutes:
13544  return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute);
13545  default:
13546  return static_cast<double>(m_inNanoseconds);
13547  }
13548  }
13549  auto unitsAsString() const -> std::string {
13550  switch (m_units) {
13551  case Unit::Nanoseconds:
13552  return "ns";
13553  case Unit::Microseconds:
13554  return "us";
13555  case Unit::Milliseconds:
13556  return "ms";
13557  case Unit::Seconds:
13558  return "s";
13559  case Unit::Minutes:
13560  return "m";
13561  default:
13562  return "** internal error **";
13563  }
13564 
13565  }
13566  friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& {
13567  return os << duration.value() << " " << duration.unitsAsString();
13568  }
13569 };
13570 } // end anon namespace
13571 
13572 class TablePrinter {
13573  std::ostream& m_os;
13574  std::vector<ColumnInfo> m_columnInfos;
13575  std::ostringstream m_oss;
13576  int m_currentColumn = -1;
13577  bool m_isOpen = false;
13578 
13579 public:
13580  TablePrinter( std::ostream& os, std::vector<ColumnInfo> columnInfos )
13581  : m_os( os ),
13582  m_columnInfos( std::move( columnInfos ) ) {}
13583 
13584  auto columnInfos() const -> std::vector<ColumnInfo> const& {
13585  return m_columnInfos;
13586  }
13587 
13588  void open() {
13589  if (!m_isOpen) {
13590  m_isOpen = true;
13591  *this << RowBreak();
13592  for (auto const& info : m_columnInfos)
13593  *this << info.name << ColumnBreak();
13594  *this << RowBreak();
13595  m_os << Catch::getLineOfChars<'-'>() << "\n";
13596  }
13597  }
13598  void close() {
13599  if (m_isOpen) {
13600  *this << RowBreak();
13601  m_os << std::endl;
13602  m_isOpen = false;
13603  }
13604  }
13605 
13606  template<typename T>
13607  friend TablePrinter& operator << (TablePrinter& tp, T const& value) {
13608  tp.m_oss << value;
13609  return tp;
13610  }
13611 
13612  friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) {
13613  auto colStr = tp.m_oss.str();
13614  // This takes account of utf8 encodings
13615  auto strSize = Catch::StringRef(colStr).numberOfCharacters();
13616  tp.m_oss.str("");
13617  tp.open();
13618  if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) {
13619  tp.m_currentColumn = -1;
13620  tp.m_os << "\n";
13621  }
13622  tp.m_currentColumn++;
13623 
13624  auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
13625  auto padding = (strSize + 2 < static_cast<std::size_t>(colInfo.width))
13626  ? std::string(colInfo.width - (strSize + 2), ' ')
13627  : std::string();
13628  if (colInfo.justification == ColumnInfo::Left)
13629  tp.m_os << colStr << padding << " ";
13630  else
13631  tp.m_os << padding << colStr << " ";
13632  return tp;
13633  }
13634 
13635  friend TablePrinter& operator << (TablePrinter& tp, RowBreak) {
13636  if (tp.m_currentColumn > 0) {
13637  tp.m_os << "\n";
13638  tp.m_currentColumn = -1;
13639  }
13640  return tp;
13641  }
13642 };
13643 
13644 ConsoleReporter::ConsoleReporter(ReporterConfig const& config)
13645  : StreamingReporterBase(config),
13646  m_tablePrinter(new TablePrinter(config.stream(),
13647  {
13648  { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 32, ColumnInfo::Left },
13649  { "iters", 8, ColumnInfo::Right },
13650  { "elapsed ns", 14, ColumnInfo::Right },
13651  { "average", 14, ColumnInfo::Right }
13652  })) {}
13653 ConsoleReporter::~ConsoleReporter() = default;
13654 
13655 std::string ConsoleReporter::getDescription() {
13656  return "Reports test results as plain lines of text";
13657 }
13658 
13659 void ConsoleReporter::noMatchingTestCases(std::string const& spec) {
13660  stream << "No test cases matched '" << spec << '\'' << std::endl;
13661 }
13662 
13663 void ConsoleReporter::assertionStarting(AssertionInfo const&) {}
13664 
13665 bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {
13666  AssertionResult const& result = _assertionStats.assertionResult;
13667 
13668  bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
13669 
13670  // Drop out if result was successful but we're not printing them.
13671  if (!includeResults && result.getResultType() != ResultWas::Warning)
13672  return false;
13673 
13674  lazyPrint();
13675 
13676  ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults);
13677  printer.print();
13678  stream << std::endl;
13679  return true;
13680 }
13681 
13682 void ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) {
13683  m_headerPrinted = false;
13684  StreamingReporterBase::sectionStarting(_sectionInfo);
13685 }
13686 void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) {
13687  m_tablePrinter->close();
13688  if (_sectionStats.missingAssertions) {
13689  lazyPrint();
13690  Colour colour(Colour::ResultError);
13691  if (m_sectionStack.size() > 1)
13692  stream << "\nNo assertions in section";
13693  else
13694  stream << "\nNo assertions in test case";
13695  stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
13696  }
13697  if (m_config->showDurations() == ShowDurations::Always) {
13698  stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
13699  }
13700  if (m_headerPrinted) {
13701  m_headerPrinted = false;
13702  }
13703  StreamingReporterBase::sectionEnded(_sectionStats);
13704 }
13705 
13706 void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {
13707  lazyPrintWithoutClosingBenchmarkTable();
13708 
13709  auto nameCol = Column( info.name ).width( static_cast<std::size_t>( m_tablePrinter->columnInfos()[0].width - 2 ) );
13710 
13711  bool firstLine = true;
13712  for (auto line : nameCol) {
13713  if (!firstLine)
13714  (*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();
13715  else
13716  firstLine = false;
13717 
13718  (*m_tablePrinter) << line << ColumnBreak();
13719  }
13720 }
13721 void ConsoleReporter::benchmarkEnded(BenchmarkStats const& stats) {
13722  Duration average(stats.elapsedTimeInNanoseconds / stats.iterations);
13723  (*m_tablePrinter)
13724  << stats.iterations << ColumnBreak()
13725  << stats.elapsedTimeInNanoseconds << ColumnBreak()
13726  << average << ColumnBreak();
13727 }
13728 
13729 void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {
13730  m_tablePrinter->close();
13731  StreamingReporterBase::testCaseEnded(_testCaseStats);
13732  m_headerPrinted = false;
13733 }
13734 void ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats) {
13735  if (currentGroupInfo.used) {
13736  printSummaryDivider();
13737  stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
13738  printTotals(_testGroupStats.totals);
13739  stream << '\n' << std::endl;
13740  }
13741  StreamingReporterBase::testGroupEnded(_testGroupStats);
13742 }
13743 void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
13744  printTotalsDivider(_testRunStats.totals);
13745  printTotals(_testRunStats.totals);
13746  stream << std::endl;
13747  StreamingReporterBase::testRunEnded(_testRunStats);
13748 }
13749 
13750 void ConsoleReporter::lazyPrint() {
13751 
13752  m_tablePrinter->close();
13753  lazyPrintWithoutClosingBenchmarkTable();
13754 }
13755 
13756 void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() {
13757 
13758  if (!currentTestRunInfo.used)
13759  lazyPrintRunInfo();
13760  if (!currentGroupInfo.used)
13761  lazyPrintGroupInfo();
13762 
13763  if (!m_headerPrinted) {
13764  printTestCaseAndSectionHeader();
13765  m_headerPrinted = true;
13766  }
13767 }
13768 void ConsoleReporter::lazyPrintRunInfo() {
13769  stream << '\n' << getLineOfChars<'~'>() << '\n';
13770  Colour colour(Colour::SecondaryText);
13771  stream << currentTestRunInfo->name
13772  << " is a Catch v" << libraryVersion() << " host application.\n"
13773  << "Run with -? for options\n\n";
13774 
13775  if (m_config->rngSeed() != 0)
13776  stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
13777 
13778  currentTestRunInfo.used = true;
13779 }
13780 void ConsoleReporter::lazyPrintGroupInfo() {
13781  if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) {
13782  printClosedHeader("Group: " + currentGroupInfo->name);
13783  currentGroupInfo.used = true;
13784  }
13785 }
13786 void ConsoleReporter::printTestCaseAndSectionHeader() {
13787  assert(!m_sectionStack.empty());
13788  printOpenHeader(currentTestCaseInfo->name);
13789 
13790  if (m_sectionStack.size() > 1) {
13791  Colour colourGuard(Colour::Headers);
13792 
13793  auto
13794  it = m_sectionStack.begin() + 1, // Skip first section (test case)
13795  itEnd = m_sectionStack.end();
13796  for (; it != itEnd; ++it)
13797  printHeaderString(it->name, 2);
13798  }
13799 
13800  SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
13801 
13802  if (!lineInfo.empty()) {
13803  stream << getLineOfChars<'-'>() << '\n';
13804  Colour colourGuard(Colour::FileName);
13805  stream << lineInfo << '\n';
13806  }
13807  stream << getLineOfChars<'.'>() << '\n' << std::endl;
13808 }
13809 
13810 void ConsoleReporter::printClosedHeader(std::string const& _name) {
13811  printOpenHeader(_name);
13812  stream << getLineOfChars<'.'>() << '\n';
13813 }
13814 void ConsoleReporter::printOpenHeader(std::string const& _name) {
13815  stream << getLineOfChars<'-'>() << '\n';
13816  {
13817  Colour colourGuard(Colour::Headers);
13818  printHeaderString(_name);
13819  }
13820 }
13821 
13822 // if string has a : in first line will set indent to follow it on
13823 // subsequent lines
13824 void ConsoleReporter::printHeaderString(std::string const& _string, std::size_t indent) {
13825  std::size_t i = _string.find(": ");
13826  if (i != std::string::npos)
13827  i += 2;
13828  else
13829  i = 0;
13830  stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n';
13831 }
13832 
13833 struct SummaryColumn {
13834 
13835  SummaryColumn( std::string _label, Colour::Code _colour )
13836  : label( std::move( _label ) ),
13837  colour( _colour ) {}
13838  SummaryColumn addRow( std::size_t count ) {
13840  rss << count;
13841  std::string row = rss.str();
13842  for (auto& oldRow : rows) {
13843  while (oldRow.size() < row.size())
13844  oldRow = ' ' + oldRow;
13845  while (oldRow.size() > row.size())
13846  row = ' ' + row;
13847  }
13848  rows.push_back(row);
13849  return *this;
13850  }
13851 
13852  std::string label;
13853  Colour::Code colour;
13854  std::vector<std::string> rows;
13855 
13856 };
13857 
13858 void ConsoleReporter::printTotals( Totals const& totals ) {
13859  if (totals.testCases.total() == 0) {
13860  stream << Colour(Colour::Warning) << "No tests ran\n";
13861  } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) {
13862  stream << Colour(Colour::ResultSuccess) << "All tests passed";
13863  stream << " ("
13864  << pluralise(totals.assertions.passed, "assertion") << " in "
13865  << pluralise(totals.testCases.passed, "test case") << ')'
13866  << '\n';
13867  } else {
13868 
13869  std::vector<SummaryColumn> columns;
13870  columns.push_back(SummaryColumn("", Colour::None)
13871  .addRow(totals.testCases.total())
13872  .addRow(totals.assertions.total()));
13873  columns.push_back(SummaryColumn("passed", Colour::Success)
13874  .addRow(totals.testCases.passed)
13875  .addRow(totals.assertions.passed));
13876  columns.push_back(SummaryColumn("failed", Colour::ResultError)
13877  .addRow(totals.testCases.failed)
13878  .addRow(totals.assertions.failed));
13879  columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure)
13880  .addRow(totals.testCases.failedButOk)
13881  .addRow(totals.assertions.failedButOk));
13882 
13883  printSummaryRow("test cases", columns, 0);
13884  printSummaryRow("assertions", columns, 1);
13885  }
13886 }
13887 void ConsoleReporter::printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row) {
13888  for (auto col : cols) {
13889  std::string value = col.rows[row];
13890  if (col.label.empty()) {
13891  stream << label << ": ";
13892  if (value != "0")
13893  stream << value;
13894  else
13895  stream << Colour(Colour::Warning) << "- none -";
13896  } else if (value != "0") {
13897  stream << Colour(Colour::LightGrey) << " | ";
13898  stream << Colour(col.colour)
13899  << value << ' ' << col.label;
13900  }
13901  }
13902  stream << '\n';
13903 }
13904 
13905 void ConsoleReporter::printTotalsDivider(Totals const& totals) {
13906  if (totals.testCases.total() > 0) {
13907  std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());
13908  std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());
13909  std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());
13910  while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
13911  findMax(failedRatio, failedButOkRatio, passedRatio)++;
13912  while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)
13913  findMax(failedRatio, failedButOkRatio, passedRatio)--;
13914 
13915  stream << Colour(Colour::Error) << std::string(failedRatio, '=');
13916  stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '=');
13917  if (totals.testCases.allPassed())
13918  stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '=');
13919  else
13920  stream << Colour(Colour::Success) << std::string(passedRatio, '=');
13921  } else {
13922  stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '=');
13923  }
13924  stream << '\n';
13925 }
13926 void ConsoleReporter::printSummaryDivider() {
13927  stream << getLineOfChars<'-'>() << '\n';
13928 }
13929 
13930 CATCH_REGISTER_REPORTER("console", ConsoleReporter)
13931 
13932 } // end namespace Catch
13933 
13934 #if defined(_MSC_VER)
13935 #pragma warning(pop)
13936 #endif
13937 // end catch_reporter_console.cpp
13938 // start catch_reporter_junit.cpp
13939 
13940 #include <cassert>
13941 #include <sstream>
13942 #include <ctime>
13943 #include <algorithm>
13944 
13945 namespace Catch {
13946 
13947  namespace {
13948  std::string getCurrentTimestamp() {
13949  // Beware, this is not reentrant because of backward compatibility issues
13950  // Also, UTC only, again because of backward compatibility (%z is C++11)
13951  time_t rawtime;
13952  std::time(&rawtime);
13953  auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
13954 
13955 #ifdef _MSC_VER
13956  std::tm timeInfo = {};
13957  gmtime_s(&timeInfo, &rawtime);
13958 #else
13959  std::tm* timeInfo;
13960  timeInfo = std::gmtime(&rawtime);
13961 #endif
13962 
13963  char timeStamp[timeStampSize];
13964  const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
13965 
13966 #ifdef _MSC_VER
13967  std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
13968 #else
13969  std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
13970 #endif
13971  return std::string(timeStamp);
13972  }
13973 
13974  std::string fileNameTag(const std::vector<std::string> &tags) {
13975  auto it = std::find_if(begin(tags),
13976  end(tags),
13977  [] (std::string const& tag) {return tag.front() == '#'; });
13978  if (it != tags.end())
13979  return it->substr(1);
13980  return std::string();
13981  }
13982  } // anonymous namespace
13983 
13984  JunitReporter::JunitReporter( ReporterConfig const& _config )
13985  : CumulativeReporterBase( _config ),
13986  xml( _config.stream() )
13987  {
13988  m_reporterPrefs.shouldRedirectStdOut = true;
13989  m_reporterPrefs.shouldReportAllAssertions = true;
13990  }
13991 
13992  JunitReporter::~JunitReporter() {}
13993 
13994  std::string JunitReporter::getDescription() {
13995  return "Reports test results in an XML format that looks like Ant's junitreport target";
13996  }
13997 
13998  void JunitReporter::noMatchingTestCases( std::string const& /*spec*/ ) {}
13999 
14000  void JunitReporter::testRunStarting( TestRunInfo const& runInfo ) {
14001  CumulativeReporterBase::testRunStarting( runInfo );
14002  xml.startElement( "testsuites" );
14003  if( m_config->rngSeed() != 0 ) {
14004  xml.startElement( "properties" );
14005  xml.scopedElement( "property" )
14006  .writeAttribute( "name", "random-seed" )
14007  .writeAttribute( "value", m_config->rngSeed() );
14008  xml.endElement();
14009  }
14010  }
14011 
14012  void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) {
14013  suiteTimer.start();
14014  stdOutForSuite.clear();
14015  stdErrForSuite.clear();
14016  unexpectedExceptions = 0;
14017  CumulativeReporterBase::testGroupStarting( groupInfo );
14018  }
14019 
14020  void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) {
14021  m_okToFail = testCaseInfo.okToFail();
14022  }
14023 
14024  bool JunitReporter::assertionEnded( AssertionStats const& assertionStats ) {
14025  if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
14026  unexpectedExceptions++;
14027  return CumulativeReporterBase::assertionEnded( assertionStats );
14028  }
14029 
14030  void JunitReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
14031  stdOutForSuite += testCaseStats.stdOut;
14032  stdErrForSuite += testCaseStats.stdErr;
14033  CumulativeReporterBase::testCaseEnded( testCaseStats );
14034  }
14035 
14036  void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
14037  double suiteTime = suiteTimer.getElapsedSeconds();
14038  CumulativeReporterBase::testGroupEnded( testGroupStats );
14039  writeGroup( *m_testGroups.back(), suiteTime );
14040  }
14041 
14042  void JunitReporter::testRunEndedCumulative() {
14043  xml.endElement();
14044  }
14045 
14046  void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
14047  XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
14048  TestGroupStats const& stats = groupNode.value;
14049  xml.writeAttribute( "name", stats.groupInfo.name );
14050  xml.writeAttribute( "errors", unexpectedExceptions );
14051  xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
14052  xml.writeAttribute( "tests", stats.totals.assertions.total() );
14053  xml.writeAttribute( "hostname", "tbd" ); // !TBD
14054  if( m_config->showDurations() == ShowDurations::Never )
14055  xml.writeAttribute( "time", "" );
14056  else
14057  xml.writeAttribute( "time", suiteTime );
14058  xml.writeAttribute( "timestamp", getCurrentTimestamp() );
14059 
14060  // Write test cases
14061  for( auto const& child : groupNode.children )
14062  writeTestCase( *child );
14063 
14064  xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), false );
14065  xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), false );
14066  }
14067 
14068  void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) {
14069  TestCaseStats const& stats = testCaseNode.value;
14070 
14071  // All test cases have exactly one section - which represents the
14072  // test case itself. That section may have 0-n nested sections
14073  assert( testCaseNode.children.size() == 1 );
14074  SectionNode const& rootSection = *testCaseNode.children.front();
14075 
14076  std::string className = stats.testInfo.className;
14077 
14078  if( className.empty() ) {
14079  className = fileNameTag(stats.testInfo.tags);
14080  if ( className.empty() )
14081  className = "global";
14082  }
14083 
14084  if ( !m_config->name().empty() )
14085  className = m_config->name() + "." + className;
14086 
14087  writeSection( className, "", rootSection );
14088  }
14089 
14090  void JunitReporter::writeSection( std::string const& className,
14091  std::string const& rootName,
14092  SectionNode const& sectionNode ) {
14093  std::string name = trim( sectionNode.stats.sectionInfo.name );
14094  if( !rootName.empty() )
14095  name = rootName + '/' + name;
14096 
14097  if( !sectionNode.assertions.empty() ||
14098  !sectionNode.stdOut.empty() ||
14099  !sectionNode.stdErr.empty() ) {
14100  XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
14101  if( className.empty() ) {
14102  xml.writeAttribute( "classname", name );
14103  xml.writeAttribute( "name", "root" );
14104  }
14105  else {
14106  xml.writeAttribute( "classname", className );
14107  xml.writeAttribute( "name", name );
14108  }
14109  xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) );
14110 
14111  writeAssertions( sectionNode );
14112 
14113  if( !sectionNode.stdOut.empty() )
14114  xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
14115  if( !sectionNode.stdErr.empty() )
14116  xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
14117  }
14118  for( auto const& childNode : sectionNode.childSections )
14119  if( className.empty() )
14120  writeSection( name, "", *childNode );
14121  else
14122  writeSection( className, name, *childNode );
14123  }
14124 
14125  void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {
14126  for( auto const& assertion : sectionNode.assertions )
14127  writeAssertion( assertion );
14128  }
14129 
14130  void JunitReporter::writeAssertion( AssertionStats const& stats ) {
14131  AssertionResult const& result = stats.assertionResult;
14132  if( !result.isOk() ) {
14133  std::string elementName;
14134  switch( result.getResultType() ) {
14137  elementName = "error";
14138  break;
14140  elementName = "failure";
14141  break;
14143  elementName = "failure";
14144  break;
14146  elementName = "failure";
14147  break;
14148 
14149  // We should never see these here:
14150  case ResultWas::Info:
14151  case ResultWas::Warning:
14152  case ResultWas::Ok:
14153  case ResultWas::Unknown:
14154  case ResultWas::FailureBit:
14155  case ResultWas::Exception:
14156  elementName = "internalError";
14157  break;
14158  }
14159 
14160  XmlWriter::ScopedElement e = xml.scopedElement( elementName );
14161 
14162  xml.writeAttribute( "message", result.getExpandedExpression() );
14163  xml.writeAttribute( "type", result.getTestMacroName() );
14164 
14166  if( !result.getMessage().empty() )
14167  rss << result.getMessage() << '\n';
14168  for( auto const& msg : stats.infoMessages )
14169  if( msg.type == ResultWas::Info )
14170  rss << msg.message << '\n';
14171 
14172  rss << "at " << result.getSourceInfo();
14173  xml.writeText( rss.str(), false );
14174  }
14175  }
14176 
14177  CATCH_REGISTER_REPORTER( "junit", JunitReporter )
14178 
14179 } // end namespace Catch
14180 // end catch_reporter_junit.cpp
14181 // start catch_reporter_listening.cpp
14182 
14183 #include <cassert>
14184 
14185 namespace Catch {
14186 
14187  ListeningReporter::ListeningReporter() {
14188  // We will assume that listeners will always want all assertions
14189  m_preferences.shouldReportAllAssertions = true;
14190  }
14191 
14192  void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) {
14193  m_listeners.push_back( std::move( listener ) );
14194  }
14195 
14196  void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {
14197  assert(!m_reporter && "Listening reporter can wrap only 1 real reporter");
14198  m_reporter = std::move( reporter );
14199  m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;
14200  }
14201 
14202  ReporterPreferences ListeningReporter::getPreferences() const {
14203  return m_preferences;
14204  }
14205 
14206  std::set<Verbosity> ListeningReporter::getSupportedVerbosities() {
14207  return std::set<Verbosity>{ };
14208  }
14209 
14210  void ListeningReporter::noMatchingTestCases( std::string const& spec ) {
14211  for ( auto const& listener : m_listeners ) {
14212  listener->noMatchingTestCases( spec );
14213  }
14214  m_reporter->noMatchingTestCases( spec );
14215  }
14216 
14217  void ListeningReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {
14218  for ( auto const& listener : m_listeners ) {
14219  listener->benchmarkStarting( benchmarkInfo );
14220  }
14221  m_reporter->benchmarkStarting( benchmarkInfo );
14222  }
14223  void ListeningReporter::benchmarkEnded( BenchmarkStats const& benchmarkStats ) {
14224  for ( auto const& listener : m_listeners ) {
14225  listener->benchmarkEnded( benchmarkStats );
14226  }
14227  m_reporter->benchmarkEnded( benchmarkStats );
14228  }
14229 
14230  void ListeningReporter::testRunStarting( TestRunInfo const& testRunInfo ) {
14231  for ( auto const& listener : m_listeners ) {
14232  listener->testRunStarting( testRunInfo );
14233  }
14234  m_reporter->testRunStarting( testRunInfo );
14235  }
14236 
14237  void ListeningReporter::testGroupStarting( GroupInfo const& groupInfo ) {
14238  for ( auto const& listener : m_listeners ) {
14239  listener->testGroupStarting( groupInfo );
14240  }
14241  m_reporter->testGroupStarting( groupInfo );
14242  }
14243 
14244  void ListeningReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
14245  for ( auto const& listener : m_listeners ) {
14246  listener->testCaseStarting( testInfo );
14247  }
14248  m_reporter->testCaseStarting( testInfo );
14249  }
14250 
14251  void ListeningReporter::sectionStarting( SectionInfo const& sectionInfo ) {
14252  for ( auto const& listener : m_listeners ) {
14253  listener->sectionStarting( sectionInfo );
14254  }
14255  m_reporter->sectionStarting( sectionInfo );
14256  }
14257 
14258  void ListeningReporter::assertionStarting( AssertionInfo const& assertionInfo ) {
14259  for ( auto const& listener : m_listeners ) {
14260  listener->assertionStarting( assertionInfo );
14261  }
14262  m_reporter->assertionStarting( assertionInfo );
14263  }
14264 
14265  // The return value indicates if the messages buffer should be cleared:
14266  bool ListeningReporter::assertionEnded( AssertionStats const& assertionStats ) {
14267  for( auto const& listener : m_listeners ) {
14268  static_cast<void>( listener->assertionEnded( assertionStats ) );
14269  }
14270  return m_reporter->assertionEnded( assertionStats );
14271  }
14272 
14273  void ListeningReporter::sectionEnded( SectionStats const& sectionStats ) {
14274  for ( auto const& listener : m_listeners ) {
14275  listener->sectionEnded( sectionStats );
14276  }
14277  m_reporter->sectionEnded( sectionStats );
14278  }
14279 
14280  void ListeningReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
14281  for ( auto const& listener : m_listeners ) {
14282  listener->testCaseEnded( testCaseStats );
14283  }
14284  m_reporter->testCaseEnded( testCaseStats );
14285  }
14286 
14287  void ListeningReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
14288  for ( auto const& listener : m_listeners ) {
14289  listener->testGroupEnded( testGroupStats );
14290  }
14291  m_reporter->testGroupEnded( testGroupStats );
14292  }
14293 
14294  void ListeningReporter::testRunEnded( TestRunStats const& testRunStats ) {
14295  for ( auto const& listener : m_listeners ) {
14296  listener->testRunEnded( testRunStats );
14297  }
14298  m_reporter->testRunEnded( testRunStats );
14299  }
14300 
14301  void ListeningReporter::skipTest( TestCaseInfo const& testInfo ) {
14302  for ( auto const& listener : m_listeners ) {
14303  listener->skipTest( testInfo );
14304  }
14305  m_reporter->skipTest( testInfo );
14306  }
14307 
14308  bool ListeningReporter::isMulti() const {
14309  return true;
14310  }
14311 
14312 } // end namespace Catch
14313 // end catch_reporter_listening.cpp
14314 // start catch_reporter_xml.cpp
14315 
14316 #if defined(_MSC_VER)
14317 #pragma warning(push)
14318 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
14319  // Note that 4062 (not all labels are handled
14320  // and default is missing) is enabled
14321 #endif
14322 
14323 namespace Catch {
14324  XmlReporter::XmlReporter( ReporterConfig const& _config )
14325  : StreamingReporterBase( _config ),
14326  m_xml(_config.stream())
14327  {
14328  m_reporterPrefs.shouldRedirectStdOut = true;
14329  m_reporterPrefs.shouldReportAllAssertions = true;
14330  }
14331 
14332  XmlReporter::~XmlReporter() = default;
14333 
14334  std::string XmlReporter::getDescription() {
14335  return "Reports test results as an XML document";
14336  }
14337 
14338  std::string XmlReporter::getStylesheetRef() const {
14339  return std::string();
14340  }
14341 
14342  void XmlReporter::writeSourceInfo( SourceLineInfo const& sourceInfo ) {
14343  m_xml
14344  .writeAttribute( "filename", sourceInfo.file )
14345  .writeAttribute( "line", sourceInfo.line );
14346  }
14347 
14348  void XmlReporter::noMatchingTestCases( std::string const& s ) {
14349  StreamingReporterBase::noMatchingTestCases( s );
14350  }
14351 
14352  void XmlReporter::testRunStarting( TestRunInfo const& testInfo ) {
14353  StreamingReporterBase::testRunStarting( testInfo );
14354  std::string stylesheetRef = getStylesheetRef();
14355  if( !stylesheetRef.empty() )
14356  m_xml.writeStylesheetRef( stylesheetRef );
14357  m_xml.startElement( "Catch" );
14358  if( !m_config->name().empty() )
14359  m_xml.writeAttribute( "name", m_config->name() );
14360  if( m_config->rngSeed() != 0 )
14361  m_xml.scopedElement( "Randomness" )
14362  .writeAttribute( "seed", m_config->rngSeed() );
14363  }
14364 
14365  void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) {
14366  StreamingReporterBase::testGroupStarting( groupInfo );
14367  m_xml.startElement( "Group" )
14368  .writeAttribute( "name", groupInfo.name );
14369  }
14370 
14371  void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
14372  StreamingReporterBase::testCaseStarting(testInfo);
14373  m_xml.startElement( "TestCase" )
14374  .writeAttribute( "name", trim( testInfo.name ) )
14375  .writeAttribute( "description", testInfo.description )
14376  .writeAttribute( "tags", testInfo.tagsAsString() );
14377 
14378  writeSourceInfo( testInfo.lineInfo );
14379 
14380  if ( m_config->showDurations() == ShowDurations::Always )
14381  m_testCaseTimer.start();
14382  m_xml.ensureTagClosed();
14383  }
14384 
14385  void XmlReporter::sectionStarting( SectionInfo const& sectionInfo ) {
14386  StreamingReporterBase::sectionStarting( sectionInfo );
14387  if( m_sectionDepth++ > 0 ) {
14388  m_xml.startElement( "Section" )
14389  .writeAttribute( "name", trim( sectionInfo.name ) );
14390  writeSourceInfo( sectionInfo.lineInfo );
14391  m_xml.ensureTagClosed();
14392  }
14393  }
14394 
14395  void XmlReporter::assertionStarting( AssertionInfo const& ) { }
14396 
14397  bool XmlReporter::assertionEnded( AssertionStats const& assertionStats ) {
14398 
14399  AssertionResult const& result = assertionStats.assertionResult;
14400 
14401  bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
14402 
14403  if( includeResults || result.getResultType() == ResultWas::Warning ) {
14404  // Print any info messages in <Info> tags.
14405  for( auto const& msg : assertionStats.infoMessages ) {
14406  if( msg.type == ResultWas::Info && includeResults ) {
14407  m_xml.scopedElement( "Info" )
14408  .writeText( msg.message );
14409  } else if ( msg.type == ResultWas::Warning ) {
14410  m_xml.scopedElement( "Warning" )
14411  .writeText( msg.message );
14412  }
14413  }
14414  }
14415 
14416  // Drop out if result was successful but we're not printing them.
14417  if( !includeResults && result.getResultType() != ResultWas::Warning )
14418  return true;
14419 
14420  // Print the expression if there is one.
14421  if( result.hasExpression() ) {
14422  m_xml.startElement( "Expression" )
14423  .writeAttribute( "success", result.succeeded() )
14424  .writeAttribute( "type", result.getTestMacroName() );
14425 
14426  writeSourceInfo( result.getSourceInfo() );
14427 
14428  m_xml.scopedElement( "Original" )
14429  .writeText( result.getExpression() );
14430  m_xml.scopedElement( "Expanded" )
14431  .writeText( result.getExpandedExpression() );
14432  }
14433 
14434  // And... Print a result applicable to each result type.
14435  switch( result.getResultType() ) {
14437  m_xml.startElement( "Exception" );
14438  writeSourceInfo( result.getSourceInfo() );
14439  m_xml.writeText( result.getMessage() );
14440  m_xml.endElement();
14441  break;
14443  m_xml.startElement( "FatalErrorCondition" );
14444  writeSourceInfo( result.getSourceInfo() );
14445  m_xml.writeText( result.getMessage() );
14446  m_xml.endElement();
14447  break;
14448  case ResultWas::Info:
14449  m_xml.scopedElement( "Info" )
14450  .writeText( result.getMessage() );
14451  break;
14452  case ResultWas::Warning:
14453  // Warning will already have been written
14454  break;
14456  m_xml.startElement( "Failure" );
14457  writeSourceInfo( result.getSourceInfo() );
14458  m_xml.writeText( result.getMessage() );
14459  m_xml.endElement();
14460  break;
14461  default:
14462  break;
14463  }
14464 
14465  if( result.hasExpression() )
14466  m_xml.endElement();
14467 
14468  return true;
14469  }
14470 
14471  void XmlReporter::sectionEnded( SectionStats const& sectionStats ) {
14472  StreamingReporterBase::sectionEnded( sectionStats );
14473  if( --m_sectionDepth > 0 ) {
14474  XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
14475  e.writeAttribute( "successes", sectionStats.assertions.passed );
14476  e.writeAttribute( "failures", sectionStats.assertions.failed );
14477  e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
14478 
14479  if ( m_config->showDurations() == ShowDurations::Always )
14480  e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
14481 
14482  m_xml.endElement();
14483  }
14484  }
14485 
14486  void XmlReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
14487  StreamingReporterBase::testCaseEnded( testCaseStats );
14488  XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
14489  e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
14490 
14491  if ( m_config->showDurations() == ShowDurations::Always )
14492  e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
14493 
14494  if( !testCaseStats.stdOut.empty() )
14495  m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false );
14496  if( !testCaseStats.stdErr.empty() )
14497  m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false );
14498 
14499  m_xml.endElement();
14500  }
14501 
14502  void XmlReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
14503  StreamingReporterBase::testGroupEnded( testGroupStats );
14504  // TODO: Check testGroupStats.aborting and act accordingly.
14505  m_xml.scopedElement( "OverallResults" )
14506  .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
14507  .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
14508  .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
14509  m_xml.endElement();
14510  }
14511 
14512  void XmlReporter::testRunEnded( TestRunStats const& testRunStats ) {
14513  StreamingReporterBase::testRunEnded( testRunStats );
14514  m_xml.scopedElement( "OverallResults" )
14515  .writeAttribute( "successes", testRunStats.totals.assertions.passed )
14516  .writeAttribute( "failures", testRunStats.totals.assertions.failed )
14517  .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
14518  m_xml.endElement();
14519  }
14520 
14521  CATCH_REGISTER_REPORTER( "xml", XmlReporter )
14522 
14523 } // end namespace Catch
14524 
14525 #if defined(_MSC_VER)
14526 #pragma warning(pop)
14527 #endif
14528 // end catch_reporter_xml.cpp
14529 
14530 namespace Catch {
14531  LeakDetector leakDetector;
14532 }
14533 
14534 #ifdef __clang__
14535 #pragma clang diagnostic pop
14536 #endif
14537 
14538 // end catch_impl.hpp
14539 #endif
14540 
14541 #ifdef CATCH_CONFIG_MAIN
14542 // start catch_default_main.hpp
14543 
14544 #ifndef __OBJC__
14545 
14546 #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
14547 // Standard C/C++ Win32 Unicode wmain entry point
14548 extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
14549 #else
14550 // Standard C/C++ main entry point
14551 int main (int argc, char * argv[]) {
14552 #endif
14553 
14554  return Catch::Session().run( argc, argv );
14555 }
14556 
14557 #else // __OBJC__
14558 
14559 // Objective-C entry point
14560 int main (int argc, char * const argv[]) {
14561 #if !CATCH_ARC_ENABLED
14562  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
14563 #endif
14564 
14565  Catch::registerTestMethods();
14566  int result = Catch::Session().run( argc, (char**)argv );
14567 
14568 #if !CATCH_ARC_ENABLED
14569  [pool drain];
14570 #endif
14571 
14572  return result;
14573 }
14574 
14575 #endif // __OBJC__
14576 
14577 // end catch_default_main.hpp
14578 #endif
14579 
14580 #if !defined(CATCH_CONFIG_IMPL_ONLY)
14581 
14582 #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
14583 # undef CLARA_CONFIG_MAIN
14584 #endif
14585 
14586 #if !defined(CATCH_CONFIG_DISABLE)
14587 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
14589 #ifdef CATCH_CONFIG_PREFIX_ALL
14590 
14591 #define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
14592 #define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
14593 
14594 #define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
14595 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
14596 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
14597 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14598 #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
14599 #endif// CATCH_CONFIG_DISABLE_MATCHERS
14600 #define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
14601 
14602 #define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14603 #define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
14604 #define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14605 #define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14606 #define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
14607 
14608 #define CATCH_CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14609 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
14610 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
14611 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14612 #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
14613 #endif // CATCH_CONFIG_DISABLE_MATCHERS
14614 #define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14615 
14616 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14617 #define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
14618 
14619 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
14620 #endif // CATCH_CONFIG_DISABLE_MATCHERS
14621 
14622 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
14623 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
14624 #define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE",__VA_ARGS__ )
14625 
14626 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
14627 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
14628 #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
14629 #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
14630 #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
14631 #define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
14632 #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
14633 #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14634 #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14635 
14636 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
14637 
14638 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
14639 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
14640 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
14641 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
14642 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
14643 #else
14644 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
14645 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
14646 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
14647 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
14648 #endif
14649 
14650 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
14651 #define CATCH_STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__ , #__VA_ARGS__ ); CATCH_SUCCEED( #__VA_ARGS__ )
14652 #define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ )
14653 #else
14654 #define CATCH_STATIC_REQUIRE( ... ) CATCH_REQUIRE( __VA_ARGS__ )
14655 #define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ )
14656 #endif
14657 
14658 // "BDD-style" convenience wrappers
14659 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
14660 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
14661 #define CATCH_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
14662 #define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
14663 #define CATCH_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
14664 #define CATCH_AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
14665 #define CATCH_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
14666 #define CATCH_AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )
14667 
14668 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
14669 #else
14670 
14671 #define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
14672 #define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
14673 
14674 #define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
14675 #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
14676 #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
14677 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14678 #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
14679 #endif // CATCH_CONFIG_DISABLE_MATCHERS
14680 #define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
14681 
14682 #define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14683 #define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
14684 #define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14685 #define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14686 #define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
14687 
14688 #define CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14689 #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
14690 #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
14691 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14692 #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
14693 #endif // CATCH_CONFIG_DISABLE_MATCHERS
14694 #define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14695 
14696 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14697 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
14698 
14699 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
14700 #endif // CATCH_CONFIG_DISABLE_MATCHERS
14701 
14702 #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
14703 #define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "UNSCOPED_INFO", msg )
14704 #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
14705 #define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ )
14706 
14707 #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
14708 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
14709 #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
14710 #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
14711 #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
14712 #define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
14713 #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
14714 #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14715 #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14716 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
14717 
14718 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
14719 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
14720 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
14721 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )
14722 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )
14723 #else
14724 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
14725 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
14726 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )
14727 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
14728 #endif
14729 
14730 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
14731 #define STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__, #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ )
14732 #define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" )
14733 #else
14734 #define STATIC_REQUIRE( ... ) REQUIRE( __VA_ARGS__ )
14735 #define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ )
14736 #endif
14737 
14738 #endif
14739 
14740 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
14741 
14742 // "BDD-style" convenience wrappers
14743 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
14744 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
14745 
14746 #define GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
14747 #define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
14748 #define WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
14749 #define AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
14750 #define THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
14751 #define AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )
14752 
14753 using Catch::Detail::Approx;
14754 
14755 #else // CATCH_CONFIG_DISABLE
14756 
14758 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
14759 #ifdef CATCH_CONFIG_PREFIX_ALL
14760 
14761 #define CATCH_REQUIRE( ... ) (void)(0)
14762 #define CATCH_REQUIRE_FALSE( ... ) (void)(0)
14763 
14764 #define CATCH_REQUIRE_THROWS( ... ) (void)(0)
14765 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
14766 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
14767 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14768 #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
14769 #endif// CATCH_CONFIG_DISABLE_MATCHERS
14770 #define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)
14771 
14772 #define CATCH_CHECK( ... ) (void)(0)
14773 #define CATCH_CHECK_FALSE( ... ) (void)(0)
14774 #define CATCH_CHECKED_IF( ... ) if (__VA_ARGS__)
14775 #define CATCH_CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
14776 #define CATCH_CHECK_NOFAIL( ... ) (void)(0)
14777 
14778 #define CATCH_CHECK_THROWS( ... ) (void)(0)
14779 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
14780 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) (void)(0)
14781 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14782 #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
14783 #endif // CATCH_CONFIG_DISABLE_MATCHERS
14784 #define CATCH_CHECK_NOTHROW( ... ) (void)(0)
14785 
14786 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14787 #define CATCH_CHECK_THAT( arg, matcher ) (void)(0)
14788 
14789 #define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
14790 #endif // CATCH_CONFIG_DISABLE_MATCHERS
14791 
14792 #define CATCH_INFO( msg ) (void)(0)
14793 #define CATCH_WARN( msg ) (void)(0)
14794 #define CATCH_CAPTURE( msg ) (void)(0)
14795 
14796 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
14797 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
14798 #define CATCH_METHOD_AS_TEST_CASE( method, ... )
14799 #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
14800 #define CATCH_SECTION( ... )
14801 #define CATCH_DYNAMIC_SECTION( ... )
14802 #define CATCH_FAIL( ... ) (void)(0)
14803 #define CATCH_FAIL_CHECK( ... ) (void)(0)
14804 #define CATCH_SUCCEED( ... ) (void)(0)
14805 
14806 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
14807 
14808 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
14809 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) )
14810 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className )
14811 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
14812 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
14813 #else
14814 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) ) )
14815 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className ) )
14816 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
14817 #define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
14818 #endif
14819 
14820 // "BDD-style" convenience wrappers
14821 #define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
14822 #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 )
14823 #define CATCH_GIVEN( desc )
14824 #define CATCH_AND_GIVEN( desc )
14825 #define CATCH_WHEN( desc )
14826 #define CATCH_AND_WHEN( desc )
14827 #define CATCH_THEN( desc )
14828 #define CATCH_AND_THEN( desc )
14829 
14830 #define CATCH_STATIC_REQUIRE( ... ) (void)(0)
14831 #define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0)
14832 
14833 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
14834 #else
14835 
14836 #define REQUIRE( ... ) (void)(0)
14837 #define REQUIRE_FALSE( ... ) (void)(0)
14838 
14839 #define REQUIRE_THROWS( ... ) (void)(0)
14840 #define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
14841 #define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
14842 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14843 #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
14844 #endif // CATCH_CONFIG_DISABLE_MATCHERS
14845 #define REQUIRE_NOTHROW( ... ) (void)(0)
14846 
14847 #define CHECK( ... ) (void)(0)
14848 #define CHECK_FALSE( ... ) (void)(0)
14849 #define CHECKED_IF( ... ) if (__VA_ARGS__)
14850 #define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
14851 #define CHECK_NOFAIL( ... ) (void)(0)
14852 
14853 #define CHECK_THROWS( ... ) (void)(0)
14854 #define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
14855 #define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
14856 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14857 #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
14858 #endif // CATCH_CONFIG_DISABLE_MATCHERS
14859 #define CHECK_NOTHROW( ... ) (void)(0)
14860 
14861 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14862 #define CHECK_THAT( arg, matcher ) (void)(0)
14863 
14864 #define REQUIRE_THAT( arg, matcher ) (void)(0)
14865 #endif // CATCH_CONFIG_DISABLE_MATCHERS
14866 
14867 #define INFO( msg ) (void)(0)
14868 #define WARN( msg ) (void)(0)
14869 #define CAPTURE( msg ) (void)(0)
14870 
14871 #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
14872 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
14873 #define METHOD_AS_TEST_CASE( method, ... )
14874 #define REGISTER_TEST_CASE( Function, ... ) (void)(0)
14875 #define SECTION( ... )
14876 #define DYNAMIC_SECTION( ... )
14877 #define FAIL( ... ) (void)(0)
14878 #define FAIL_CHECK( ... ) (void)(0)
14879 #define SUCCEED( ... ) (void)(0)
14880 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
14881 
14882 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
14883 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) )
14884 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className )
14885 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
14886 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
14887 #else
14888 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) ) )
14889 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className ) )
14890 #define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )
14891 #define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
14892 #endif
14893 
14894 #define STATIC_REQUIRE( ... ) (void)(0)
14895 #define STATIC_REQUIRE_FALSE( ... ) (void)(0)
14896 
14897 #endif
14898 
14899 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
14900 
14901 // "BDD-style" convenience wrappers
14902 #define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) )
14903 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
14904 
14905 #define GIVEN( desc )
14906 #define AND_GIVEN( desc )
14907 #define WHEN( desc )
14908 #define AND_WHEN( desc )
14909 #define THEN( desc )
14910 #define AND_THEN( desc )
14911 
14912 using Catch::Detail::Approx;
14913 
14914 #endif
14915 
14916 #endif // ! CATCH_CONFIG_IMPL_ONLY
14917 
14918 // start catch_reenable_warnings.h
14919 
14920 
14921 #ifdef __clang__
14922 # ifdef __ICC // icpc defines the __clang__ macro
14923 # pragma warning(pop)
14924 # else
14925 # pragma clang diagnostic pop
14926 # endif
14927 #elif defined __GNUC__
14928 # pragma GCC diagnostic pop
14929 #endif
14930 
14931 // end catch_reenable_warnings.h
14932 // end catch.hpp
14933 #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
14934 
EqualsMatcher(std::vector< T > const &comparator)
Definition: catch.hpp:3280
virtual T const & get() const =0
d
virtual void setGenerator(Generators::GeneratorBasePtr &&generator)=0
Error
void handleExpression(ITransientExpression const &expr)
bool matchTest(TestCase const &testCase, TestSpec const &testSpec, IConfig const &config)
virtual void benchmarkEnded(BenchmarkStats const &stats)=0
SourceLineInfo lineInfo
Definition: catch.hpp:2231
auto operator==(StringRef const &other) const noexcept -> bool
TFSIMD_FORCE_INLINE Vector3 operator*(const Matrix3x3 &m, const Vector3 &v)
std::size_t m_count
Definition: catch.hpp:2875
unsigned short WORD
Definition: integer.h:27
auto getResult() const -> bool
Definition: catch.hpp:1850
unsigned int sequence
Definition: catch.hpp:2233
Totals & operator+=(Totals const &other)
ChunkGenerator(size_t size, GeneratorWrapper< T > generator)
Definition: catch.hpp:3872
std::vector< MatcherBase< ArgT > const * > m_matchers
Definition: catch.hpp:2962
std::string rawMemoryToString(const T &object)
Definition: catch.hpp:1233
std::unique_ptr< GeneratorUntypedBase > GeneratorBasePtr
Definition: catch.hpp:3457
filename
MessageInfo m_info
Definition: catch.hpp:2263
std::ostream * m_oss
Definition: catch.hpp:1152
virtual ~NonCopyable()
FixedValuesGenerator(std::initializer_list< T > values)
Definition: catch.hpp:3562
const char * what() const noexcept override final
CaseSensitive::Choice m_caseSensitivity
Definition: catch.hpp:3178
bool isFalseTest(int flags)
Definition: catch.hpp:1098
double epsilon
ExceptionTranslatorRegistrar(std::string(*translateFunction)(T &))
Definition: catch.hpp:2714
TestCase(ITestInvoker *testCase, TestCaseInfo &&info)
bool operator>(const TiXmlString &a, const TiXmlString &b)
Definition: tinystr.h:266
bool match(std::vector< T > const &v) const override
Definition: catch.hpp:3231
Counts testCases
Definition: catch.hpp:2475
Counts assertions
Definition: catch.hpp:2474
GeneratorWrapper< T > map(Func &&function, GeneratorWrapper< T > &&generator)
Definition: catch.hpp:3859
static std::enable_if<!::Catch::Detail::IsStreamInsertable< Fake >::value, std::string >::type convert(const Fake &value)
Definition: catch.hpp:1304
#define CATCH_ENFORCE(condition, msg)
Definition: catch.hpp:3496
virtual void registerTest(TestCase const &testInfo)=0
char * m_data
Definition: catch.hpp:532
TFSIMD_FORCE_INLINE Quaternion operator-(const Quaternion &q)
void toLowerInPlace(std::string &s)
virtual StartupExceptionRegistry const & getStartupExceptionRegistry() const =0
std::vector< std::unique_ptr< IExceptionTranslator const > > ExceptionTranslators
Definition: catch.hpp:2674
std::shared_ptr< ITestInvoker > test
Definition: catch.hpp:4224
StringRef tags
Definition: catch.hpp:837
void handleMessage(ResultWas::OfType resultType, StringRef const &message)
std::string name
Definition: catch.hpp:4200
ROSCPP_DECL void start()
void handleExceptionNotThrownAsExpected()
void populate(U &&valueOrGenerator, Gs... moreGenerators)
Definition: catch.hpp:3613
LazyExpression(bool isNegated)
auto c_str() const -> char const *
ResultDisposition::Flags operator|(ResultDisposition::Flags lhs, ResultDisposition::Flags rhs)
TestCase makeTestCase(ITestInvoker *testCase, std::string const &className, NameAndTags const &nameAndTags, SourceLineInfo const &lineInfo)
void run(class_loader::ClassLoader *loader)
std::ostream & operator<<(std::ostream &os, SourceLineInfo const &info)
virtual void registerTagAlias(std::string const &alias, std::string const &tag, SourceLineInfo const &lineInfo)=0
void cleanUpContext()
GeneratorWrapper< std::tuple< Ts... > > table(std::initializer_list< std::tuple< typename std::decay< Ts >::type... >> tuples)
Definition: catch.hpp:3642
virtual auto acquireGeneratorTracker(SourceLineInfo const &lineInfo) -> IGeneratorTracker &=0
bool contains(std::string const &s, std::string const &infix)
StringRef(char const *rawChars, size_type size) noexcept
Definition: catch.hpp:558
bool match(T const &item) const override
Definition: catch.hpp:3103
CaseSensitive::Choice m_caseSensitivity
Definition: catch.hpp:3142
bool operator<(const TiXmlString &a, const TiXmlString &b)
Definition: tinystr.h:260
Verbosity
Definition: catch.hpp:3973
std::string m_name
Definition: catch.hpp:2546
f
unsigned int rngSeed()
PredicateMatcher(std::function< bool(T const &)> const &elem, std::string const &descr)
Definition: catch.hpp:3098
uint32_t used
Definition: USBD.h:95
auto makeUnaryExpr() const -> UnaryExpr< LhsT >
Definition: catch.hpp:2036
std::vector< double > values
SectionInfo m_info
Definition: catch.hpp:2544
#define sprintf
Definition: test_suite.cpp:72
GeneratorWrapper< T > m_generator
Definition: catch.hpp:3699
virtual void registerReporter(std::string const &name, IReporterFactoryPtr const &factory)=0
#define CATCH_TRY
Definition: catch.hpp:369
ros::Time * timeStamp(M &m)
virtual IConfigPtr const & getConfig() const =0
auto compareNotEqual(LhsT const &lhs, RhsT &&rhs) -> bool
Definition: catch.hpp:1973
auto getCurrentNanosecondsSinceEpoch() -> uint64_t
T const & operator+(T const &value, StreamEndStop)
Definition: catch.hpp:453
auto getEstimatedClockResolution() -> uint64_t
SpecialProperties properties
Definition: catch.hpp:4206
bool match(ArgT const &arg) const override
Definition: catch.hpp:2934
std::size_t failedButOk
Definition: catch.hpp:2463
GeneratorWrapper(std::unique_ptr< IGenerator< T >> generator)
Definition: catch.hpp:3577
GeneratorWrapper< U > m_generator
Definition: catch.hpp:3828
typename append< Final<>, typename rewrap< Containers, Types... >::type... >::type type
Definition: catch.hpp:802
not_this_one end(...)
std::string toString() const
virtual ~ITestInvoker()
ContainsMatcher(std::vector< T > const &comparator)
Definition: catch.hpp:3250
TestInvokerAsMethod(void(C::*testAsMethod)()) noexcept
Definition: catch.hpp:819
bool match(std::vector< T > const &vec) const override
Definition: catch.hpp:3303
SourceLineInfo(char const *_file, std::size_t _line) noexcept
Definition: catch.hpp:420
virtual void popScopedMessage(MessageInfo const &message)=0
IResultCapture & getResultCapture()
std::string(*)() exceptionTranslateFunction
Definition: catch.hpp:2671
Approx & epsilon(T const &newEpsilon)
Definition: catch.hpp:2811
Capturer(StringRef macroName, SourceLineInfo const &lineInfo, ResultWas::OfType resultType, StringRef names)
static std::string convert(T const(&arr)[SZ])
Definition: catch.hpp:1706
std::string m_name
Definition: catch.hpp:2574
std::vector< std::string > lcaseTags
Definition: catch.hpp:4204
XmlRpcServer s
GeneratorWrapper< T > value(T &&value)
Definition: catch.hpp:3589
StdString::RegexMatcher Matches(std::string const &regex, CaseSensitive::Choice caseSensitivity=CaseSensitive::Yes)
auto operator!=(StringRef const &other) const noexcept -> bool
GeneratorWrapper< std::vector< T > > chunk(size_t size, GeneratorWrapper< T > &&generator)
Definition: catch.hpp:3900
long LONG
Definition: integer.h:31
double durationInSeconds
Definition: catch.hpp:2503
virtual auto hasGenerator() const -> bool=0
SectionInfo(SourceLineInfo const &_lineInfo, std::string const &_name)
virtual RunTests::InWhatOrder runOrder() const =0
#define CATCH_RUNTIME_ERROR(msg)
Definition: catch.hpp:3494
bool replaceInPlace(std::string &str, std::string const &replaceThis, std::string const &withThis)
size_t count(InputIterator first, InputIterator last, T const &item)
Definition: catch.hpp:3206
StringRef(StringRef const &other) noexcept
Definition: catch.hpp:543
virtual std::vector< TestCase > const & getAllTestsSorted(IConfig const &config) const =0
std::string finalizeDescription(const std::string &desc)
bool operator==(SourceLineInfo const &other) const noexcept
Definition: catch.hpp:95
Approx operator()(T const &value)
Definition: catch.hpp:2757
static auto getResolution() -> uint64_t
SectionInfo sectionInfo
Definition: catch.hpp:2501
virtual void handleFatalErrorCondition(StringRef message)=0
GeneratorWrapper< T > m_generator
Definition: catch.hpp:3774
std::enable_if< std::is_floating_point< T >::value, GeneratorWrapper< T > >::type random(T a, T b)
Definition: catch.hpp:4101
UnaryExpr(LhsT lhs)
Definition: catch.hpp:1954
std::uniform_int_distribution< Integer > m_dist
Definition: catch.hpp:4068
virtual auto getGenerator() const -> Generators::GeneratorBasePtr const &=0
Counts m_assertions
Definition: catch.hpp:2547
Unknown
StringRef(std::string const &stdString) noexcept
Definition: catch.hpp:563
#define NULL
Definition: nm_bsp.h:52
typename append< L1< E1..., E2... >, Rest... >::type type
Definition: catch.hpp:772
std::vector< std::string > tags
Definition: catch.hpp:4203
std::string operator+() const
#define CATCH_INTERNAL_ERROR(msg)
Definition: catch.hpp:3490
ExprLhs(LhsT lhs)
Definition: catch.hpp:1987
static std::string convert(signed char const *str)
Definition: catch.hpp:1392
IMutableRegistryHub & getMutableRegistryHub()
Counts & operator+=(Counts const &other)
Vector::ContainsMatcher< T > Contains(std::vector< T > const &comparator)
Definition: catch.hpp:3346
void formatReconstructedExpression(std::ostream &os, std::string const &lhs, StringRef op, std::string const &rhs)
bool empty() const noexcept
void swap(Bag &a, Bag &b)
#define max(a, b)
Takes the maximal value of a and b.
Definition: compiler.h:823
ITransientExpression(bool isBinaryExpression, bool result)
Definition: catch.hpp:1853
ScopedMessage(MessageBuilder const &builder)
std::string stringify(const T &e)
Definition: catch.hpp:1318
StdString::EqualsMatcher Equals(std::string const &str, CaseSensitive::Choice caseSensitivity=CaseSensitive::Yes)
auto makeGenerators(as< T >, U &&val, Gs... moreGenerators) -> Generators< T >
Definition: catch.hpp:3663
std::vector< T > const & m_comparator
Definition: catch.hpp:3274
bool add(const actionlib::TwoIntsGoal &req, actionlib::TwoIntsResult &res)
auto isSubstring() const noexcept -> bool
static std::string convert(U *p)
Definition: catch.hpp:1463
virtual void registerStartupException() noexcept=0
auto operator[](size_type index) const noexcept -> char
std::vector< GeneratorWrapper< T > > m_generators
Definition: catch.hpp:3599
virtual void pushScopedMessage(MessageInfo const &message)=0
virtual ~IStream()
auto getElapsedSeconds() const -> double
GeneratorWrapper< T > filter(Predicate &&pred, GeneratorWrapper< T > &&generator)
Definition: catch.hpp:3768
ROSCONSOLE_DECL void print(FilterBase *filter, void *logger, Level level, const char *file, int line, const char *function, const char *fmt,...) ROSCONSOLE_PRINTF_ATTRIBUTE(7
auto operator+(char const *lhs, StringRef const &rhs) -> std::string
std::string describe() const override
Definition: catch.hpp:3270
ResultDisposition::Flags resultDisposition
Definition: catch.hpp:1111
std::vector< TestCase > const & getAllTestCasesSorted(IConfig const &config)
ExceptionTranslator(std::string(*translateFunction)(T &))
Definition: catch.hpp:2692
void streamReconstructedExpression(std::ostream &os) const override
Definition: catch.hpp:1949
bool shouldContinueOnFailure(int flags)
virtual ~IConfig()
bool expectedToFail() const
auto str() const -> std::string
std::unique_ptr< T > make_unique(Args &&... args)
Definition: catch.hpp:3525
bool isJustInfo(int flags)
GeneratorWrapper< T > m_generator
Definition: catch.hpp:3735
auto empty() const noexcept -> bool
Definition: catch.hpp:591
#define CATCH_ERROR(msg)
Definition: catch.hpp:3492
GeneratorException(const char *msg)
Definition: catch.hpp:3513
AutoReg(ITestInvoker *invoker, SourceLineInfo const &lineInfo, StringRef const &classOrMethod, NameAndTags const &nameAndTags) noexcept
not_this_one begin(...)
GeneratorWrapper< T > range(T const &start, T const &end)
Definition: catch.hpp:4147
std::string tagsAsString() const
unsigned long DWORD
Definition: integer.h:33
std::vector< TestCase > filterTests(std::vector< TestCase > const &testCases, TestSpec const &testSpec, IConfig const &config)
AssertionReaction m_reaction
Definition: catch.hpp:2175
TestCase withName(std::string const &_newName) const
std::uniform_real_distribution< Float > m_dist
Definition: catch.hpp:4046
AssertionInfo m_assertionInfo
Definition: catch.hpp:2174
Approx(T const &value)
Definition: catch.hpp:2766
std::string description
Definition: catch.hpp:2496
void handleUnexpectedInflightException()
Floating::WithinAbsMatcher WithinAbs(double target, double margin)
auto currentData() const noexcept -> char const *
Approx & scale(T const &newScale)
Definition: catch.hpp:2825
void populate(GeneratorWrapper< T > &&generator)
Definition: catch.hpp:3602
ArgT const & m_arg
Definition: catch.hpp:3373
void free(void *ptr)
static FRESULT sync(FATFS *fs)
Definition: ff.c:769
static std::string convert(R C::*p)
Definition: catch.hpp:1474
std::size_t failed
Definition: catch.hpp:2462
StringRef m_matcherString
Definition: catch.hpp:3375
BinaryExpr(bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs)
Definition: catch.hpp:1881
void cleanUp()
auto makeTestInvoker(void(*testAsFunction)()) noexcept -> ITestInvoker *
std::ostream & cout()
AssertionHandler(StringRef const &macroName, SourceLineInfo const &lineInfo, StringRef capturedExpression, ResultDisposition::Flags resultDisposition)
StringRef capturedExpression
Definition: catch.hpp:1110
bool shouldSuppressFailure(int flags)
virtual ~IRegistryHub()
std::shared_ptr< IReporterFactory > IReporterFactoryPtr
Definition: catch.hpp:2629
StdString::EndsWithMatcher EndsWith(std::string const &str, CaseSensitive::Choice caseSensitivity=CaseSensitive::Yes)
std::string describe() const override
Definition: catch.hpp:3107
unsigned long ULONG
Definition: integer.h:32
UnorderedEqualsMatcher(std::vector< T > const &target)
Definition: catch.hpp:3302
virtual bool allowThrows() const =0
bool isOk(ResultWas::OfType resultType)
ResultWas::OfType type
Definition: catch.hpp:2232
virtual void registerTranslator(const IExceptionTranslator *translator)=0
XMLRPCPP_DECL void setVerbosity(int level)
ReusableStringStream m_stream
Definition: catch.hpp:2249
bool operator<(MessageInfo const &other) const
SourceLineInfo lineInfo
Definition: catch.hpp:4205
GeneratorWrapper< T > m_generator
Definition: catch.hpp:3869
StringRef macroName
Definition: catch.hpp:2229
TestCaseInfo const & getTestCaseInfo() const
bool operator<(SourceLineInfo const &other) const noexcept
void handleExceptionThrownAsExpected()
Totals operator-(Totals const &other) const
std::unique_ptr< IGenerator< T > > m_generator
Definition: catch.hpp:3575
Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff)
ROSCPP_DECL bool get(const std::string &key, std::string &s)
virtual std::string translateActiveException() const =0
auto needsMoreIterations() -> bool
NameAndTags(StringRef const &name_=StringRef(), StringRef const &tags_=StringRef()) noexcept
std::string className
Definition: catch.hpp:4201
std::string m_label
Definition: catch.hpp:2876
std::map< ClassName, impl::AbstractMetaObjectBase *> FactoryMap
bool allPassed() const
void captureValues(size_t index, T const &value)
Definition: catch.hpp:2288
std::string trim(std::string const &str)
bool endsWith(std::string const &s, std::string const &suffix)
#define CATCH_INTERNAL_LINEINFO
Definition: catch.hpp:458
bool allOk() const
static std::string convert(char const *str)
Definition: catch.hpp:1386
StringRef macroName
Definition: catch.hpp:1108
std::string describe() const override
Definition: catch.hpp:3333
std::string toLower(std::string const &s)
void captureValues(size_t index, T const &value, Ts const &... values)
Definition: catch.hpp:2293
ROSCPP_DECL bool ok()
char const * file
Definition: catch.hpp:434
std::string translateActiveException()
#define CATCH_CATCH_ALL
Definition: catch.hpp:370
virtual void benchmarkStarting(BenchmarkInfo const &info)=0
Vector::EqualsMatcher< T > Equals(std::vector< T > const &comparator)
Definition: catch.hpp:3356
virtual void streamReconstructedExpression(std::ostream &os) const =0
Info
std::string describe() const override
Definition: catch.hpp:3294
Counts operator-(Counts const &other) const
bool operator==(const TiXmlString &a, const TiXmlString &b)
Definition: tinystr.h:255
std::enable_if< !std::is_enum< T >::value &&!std::is_base_of< std::exception, T >::value, std::string >::type convertUnstreamable(T const &)
Definition: catch.hpp:1256
virtual ITestCaseRegistry const & getTestCaseRegistry() const =0
void handleExpr(ExprLhs< T > const &expr)
Definition: catch.hpp:2192
bool match(ArgT const &arg) const override
Definition: catch.hpp:3003
std::string name
Definition: catch.hpp:2495
bool operator<(TestCase const &other) const
std::size_t total() const
auto numberOfCharacters() const noexcept -> size_type
IContext & getCurrentContext()
Definition: catch.hpp:3955
StringRef(StringRef &&other) noexcept
Definition: catch.hpp:548
bool match(ArgT const &arg) const override
Definition: catch.hpp:2967
auto operator+=(std::string &lhs, StringRef const &sr) -> std::string &
auto generate(SourceLineInfo const &lineInfo, L const &generatorExpression) -> decltype(std::declval< decltype(generatorExpression())>().get())
Definition: catch.hpp:3673
StringRef m_op
Definition: catch.hpp:1872
GeneratorWrapper< T > repeat(size_t repeats, GeneratorWrapper< T > &&generator)
Definition: catch.hpp:3821
RegistrarForTagAliases(char const *alias, char const *tag, SourceLineInfo const &lineInfo)
RangeGenerator(T const &start, T const &end, T const &step)
Definition: catch.hpp:4115
BenchmarkLooper(StringRef name)
Definition: catch.hpp:2583
USBInterfaceDescriptor data
MessageBuilder(StringRef const &macroName, SourceLineInfo const &lineInfo, ResultWas::OfType type)
std::ostream & clog()
IResultCapture & m_resultCapture
Definition: catch.hpp:2177
void throw_exception(std::exception const &e)
static unsigned int globalCount
Definition: catch.hpp:2238
void invoke() const
StringRef() noexcept
Definition: catch.hpp:539
auto getElapsedNanoseconds() const -> uint64_t
virtual void registerListener(IReporterFactoryPtr const &factory)=0
void streamReconstructedExpression(std::ostream &os) const override
Definition: catch.hpp:3384
std::string translate(ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd) const override
Definition: catch.hpp:2696
auto getElapsedMicroseconds() const -> uint64_t
#define false
Definition: compiler.h:424
SourceLineInfo lineInfo
Definition: catch.hpp:1109
MapGenerator(F2 &&function, GeneratorWrapper< U > &&generator)
Definition: catch.hpp:3834
bool operator==(TestCase const &other) const
const std::string unprintableString
void * malloc(size_t size)
#define EOF
Definition: ff.h:241
NMI_API sint8 close(SOCKET sock)
Definition: socket.c:879
static std::enable_if<::Catch::Detail::IsStreamInsertable< Fake >::value, std::string >::type convert(const Fake &value)
Definition: catch.hpp:1293
bool operator>=(const TiXmlString &a, const TiXmlString &b)
Definition: tinystr.h:268
virtual void handleIncomplete(AssertionInfo const &info)=0
MatcherT m_matcher
Definition: catch.hpp:3374
std::string rangeToString(std::vector< bool, Allocator > const &v)
Definition: catch.hpp:1682
auto isBinaryExpression() const -> bool
Definition: catch.hpp:1849
unsigned char bool
Boolean.
Definition: compiler.h:243
auto isOwned() const noexcept -> bool
MessageInfo(StringRef const &_macroName, SourceLineInfo const &_lineInfo, ResultWas::OfType _type)
bool okToFail() const
Generators(Gs... moreGenerators)
Definition: catch.hpp:3620
char const * m_start
Definition: catch.hpp:529
Section(SectionInfo const &info)
bool operator!=(const TiXmlString &a, const TiXmlString &b)
Definition: tinystr.h:265
virtual IReporterRegistry const & getReporterRegistry() const =0
std::vector< MatcherBase< ArgT > const * > m_matchers
Definition: catch.hpp:2995
bool isHidden() const
virtual IResultCapture * getResultCapture()=0
auto acquireGeneratorTracker(SourceLineInfo const &lineInfo) -> IGeneratorTracker &
MatchAllOf< T > operator&&(MatcherBase const &other) const
size_type m_size
Definition: catch.hpp:530
FilterGenerator(P &&pred, GeneratorWrapper< T > &&generator)
Definition: catch.hpp:3739
virtual unsigned int rngSeed() const =0
parser
MessageInfo m_info
Definition: catch.hpp:2273
Totals delta(Totals const &prevTotals) const
virtual ~IRunner()
auto makeMatchExpr(ArgT const &arg, MatcherT const &matcher, StringRef const &matcherString) -> MatchExpr< ArgT, MatcherT >
Definition: catch.hpp:3399
RandomIntegerGenerator(Integer a, Integer b)
Definition: catch.hpp:4072
std::size_t passed
Definition: catch.hpp:2461
StdString::StartsWithMatcher StartsWith(std::string const &str, CaseSensitive::Choice caseSensitivity=CaseSensitive::Yes)
std::enable_if< std::is_enum< T >::value, std::string >::type convertUnstreamable(T const &value)
Definition: catch.hpp:1269
std::size_t line
Definition: catch.hpp:435
Approx & margin(T const &newMargin)
Definition: catch.hpp:2818
std::string convertUnknownEnumToString(E e)
Definition: catch.hpp:1323
std::ostream & cerr()
std::string describe() const override
Definition: catch.hpp:2974
RepeatGenerator(size_t repeats, GeneratorWrapper< T > &&generator)
Definition: catch.hpp:3780
MatchNotOf< T > operator!() const
Definition: catch.hpp:3022
std::string describe() const override
Definition: catch.hpp:3240
void convert(const A &a, B &b)
std::function< bool(T const &)> m_predicate
Definition: catch.hpp:3094
virtual void sectionEnded(SectionEndInfo const &endInfo)=0
void handleExceptionMatchExpr(AssertionHandler &handler, std::string const &str, StringRef const &matcherString)
int errno
MatcherBase< ArgT > const & m_underlyingMatcher
Definition: catch.hpp:3010
bool match(std::vector< T > const &v) const override
Definition: catch.hpp:3252
std::vector< T > const & m_comparator
Definition: catch.hpp:3297
static IMutableContext * currentContext
Definition: catch.hpp:3942
virtual IExceptionTranslatorRegistry const & getExceptionTranslatorRegistry() const =0
StringRef name
Definition: catch.hpp:836
auto size() const noexcept -> size_type
Definition: catch.hpp:594
IMutableContext & getCurrentMutableContext()
Definition: catch.hpp:3948
bool m_sectionIncluded
Definition: catch.hpp:2548
void swap(StringRef &other) noexcept
void streamReconstructedExpression(std::ostream &os) const override
Definition: catch.hpp:1875
bool contains(InputIterator first, InputIterator last, T const &item)
Definition: catch.hpp:3216
IRegistryHub const & getRegistryHub()
Vector::UnorderedEqualsMatcher< T > UnorderedEquals(std::vector< T > const &target)
Definition: catch.hpp:3361
std::size_t size_type
Definition: catch.hpp:524
Generic::PredicateMatcher< T > Predicate(std::function< bool(T const &)> const &predicate, std::string const &description="")
Definition: catch.hpp:3119
Timer m_timer
Definition: catch.hpp:2549
static FRESULT validate(FATFS *fs, WORD id)
Definition: ff.c:2180
void handleUnexpectedExceptionNotThrown()
bool operator<=(const TiXmlString &a, const TiXmlString &b)
Definition: tinystr.h:267
MatchAnyOf< T > operator||(MatcherBase const &other) const
Definition: catch.hpp:3018
std::string description
Definition: catch.hpp:4202
auto compareEqual(LhsT const &lhs, RhsT const &rhs) -> bool
Definition: catch.hpp:1962
void captureValue(size_t index, std::string const &value)
SourceLineInfo lineInfo
Definition: catch.hpp:2497
std::shared_ptr< IConfig const > IConfigPtr
Definition: catch.hpp:3923
MatchNotOf(MatcherBase< ArgT > const &underlyingMatcher)
Definition: catch.hpp:3001
virtual void sectionEndedEarly(SectionEndInfo const &endInfo)=0
ITransientExpression const * m_transientExpression
Definition: catch.hpp:2156
std::string message
Definition: catch.hpp:2230
std::string describe() const override
Definition: catch.hpp:3007
virtual ~IContext()
std::string describe() const override
Definition: catch.hpp:2941
bool match(std::vector< T > const &v) const override
Definition: catch.hpp:3282
MatchExpr(ArgT const &arg, MatcherT const &matcher, StringRef const &matcherString)
Definition: catch.hpp:3377
typename append< TypeList< Container< Elems... > >, typename rewrap< Container, Elements... >::type >::type type
Definition: catch.hpp:793
auto substr(size_type start, size_type size) const noexcept -> StringRef
virtual void setConfig(IConfigPtr const &config)=0
static void createContext()
std::string rangeToString(Range const &range)
Definition: catch.hpp:1676
void invoke() const override
Definition: catch.hpp:821
bool equalityComparisonImpl(double other) const
auto makeStream(StringRef const &filename) -> IStream const *
static std::string convert(unsigned char const *str)
Definition: catch.hpp:1398
auto allowThrows() const -> bool
TestCaseInfo(std::string const &_name, std::string const &_className, std::string const &_description, std::vector< std::string > const &_tags, SourceLineInfo const &_lineInfo)
virtual ITagAliasRegistry const & getTagAliasRegistry() const =0
~StringRef() noexcept
Definition: catch.hpp:568
#define CATCH_CATCH_ANON(type)
Definition: catch.hpp:371
pluralise(std::size_t count, std::string const &label)
auto get() -> std::ostream &
Definition: catch.hpp:1164
std::vector< MessageInfo > m_messages
Definition: catch.hpp:2278
GeneratorWrapper< T > take(size_t target, GeneratorWrapper< T > &&generator)
Definition: catch.hpp:3729
TakeGenerator(size_t target, GeneratorWrapper< T > &&generator)
Definition: catch.hpp:3703
bool startsWith(std::string const &s, std::string const &prefix)
bool throws() const
RangeGenerator(T const &start, T const &end)
Definition: catch.hpp:4126
bool operator==(MessageInfo const &other) const
Vector::ContainsElementMatcher< T > VectorContains(T const &comparator)
Definition: catch.hpp:3351
auto getElapsedMilliseconds() const -> unsigned int


inertial_sense_ros
Author(s):
autogenerated on Sat Sep 19 2020 03:19:04