All Classes Namespaces Functions Variables Enumerations Properties Pages
catch.hpp
1 /*
2  * Catch v2.5.0
3  * Generated: 2018-11-26 20:46:12.165372
4  * ----------------------------------------------------------
5  * This file has been merged from multiple headers. Please don't edit it directly
6  * Copyright (c) 2018 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 5
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  // GCC likes to warn on REQUIREs, and we cannot suppress them
40  // locally because g++'s support for _Pragma is lacking in older,
41  // still supported, versions
42 # pragma GCC diagnostic ignored "-Wparentheses"
43 # pragma GCC diagnostic push
44 # pragma GCC diagnostic ignored "-Wunused-variable"
45 # pragma GCC diagnostic ignored "-Wpadded"
46 #endif
47 // end catch_suppress_warnings.h
48 #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
49 # define CATCH_IMPL
50 # define CATCH_CONFIG_ALL_PARTS
51 #endif
52 
53 // In the impl file, we want to have access to all parts of the headers
54 // Can also be used to sanely support PCHs
55 #if defined(CATCH_CONFIG_ALL_PARTS)
56 # define CATCH_CONFIG_EXTERNAL_INTERFACES
57 # if defined(CATCH_CONFIG_DISABLE_MATCHERS)
58 # undef CATCH_CONFIG_DISABLE_MATCHERS
59 # endif
60 # if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
61 # define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
62 # endif
63 #endif
64 
65 #if !defined(CATCH_CONFIG_IMPL_ONLY)
66 // start catch_platform.h
67 
68 #ifdef __APPLE__
69 # include <TargetConditionals.h>
70 # if TARGET_OS_OSX == 1
71 # define CATCH_PLATFORM_MAC
72 # elif TARGET_OS_IPHONE == 1
73 # define CATCH_PLATFORM_IPHONE
74 # endif
75 
76 #elif defined(linux) || defined(__linux) || defined(__linux__)
77 # define CATCH_PLATFORM_LINUX
78 
79 #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
80 # define CATCH_PLATFORM_WINDOWS
81 #endif
82 
83 // end catch_platform.h
84 
85 #ifdef CATCH_IMPL
86 # ifndef CLARA_CONFIG_MAIN
87 # define CLARA_CONFIG_MAIN_NOT_DEFINED
88 # define CLARA_CONFIG_MAIN
89 # endif
90 #endif
91 
92 // start catch_user_interfaces.h
93 
94 namespace Catch {
95  unsigned int rngSeed();
96 }
97 
98 // end catch_user_interfaces.h
99 // start catch_tag_alias_autoregistrar.h
100 
101 // start catch_common.h
102 
103 // start catch_compiler_capabilities.h
104 
105 // Detect a number of compiler features - by compiler
106 // The following features are defined:
107 //
108 // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
109 // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
110 // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
111 // CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
112 // ****************
113 // Note to maintainers: if new toggles are added please document them
114 // in configuration.md, too
115 // ****************
116 
117 // In general each macro has a _NO_<feature name> form
118 // (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
119 // Many features, at point of detection, define an _INTERNAL_ macro, so they
120 // can be combined, en-mass, with the _NO_ forms later.
121 
122 #ifdef __cplusplus
123 
124 # if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
125 # define CATCH_CPP14_OR_GREATER
126 # endif
127 
128 # if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
129 # define CATCH_CPP17_OR_GREATER
130 # endif
131 
132 #endif
133 
134 #if defined(CATCH_CPP17_OR_GREATER)
135 # define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
136 #endif
137 
138 #ifdef __clang__
139 
140 # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
141  _Pragma( "clang diagnostic push" ) \
142  _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
143  _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
144 # define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
145  _Pragma( "clang diagnostic pop" )
146 
147 # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
148  _Pragma( "clang diagnostic push" ) \
149  _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
150 # define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
151  _Pragma( "clang diagnostic pop" )
152 
153 # define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
154  _Pragma( "clang diagnostic push" ) \
155  _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
156 # define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS \
157  _Pragma( "clang diagnostic pop" )
158 
159 #endif // __clang__
160 
162 // Assume that non-Windows platforms support posix signals by default
163 #if !defined(CATCH_PLATFORM_WINDOWS)
164  #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
165 #endif
166 
168 // We know some environments not to support full POSIX signals
169 #if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
170  #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
171 #endif
172 
173 #ifdef __OS400__
174 # define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
175 # define CATCH_CONFIG_COLOUR_NONE
176 #endif
177 
179 // Android somehow still does not support std::to_string
180 #if defined(__ANDROID__)
181 # define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
182 #endif
183 
185 // Not all Windows environments support SEH properly
186 #if defined(__MINGW32__)
187 # define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
188 #endif
189 
191 // PS4
192 #if defined(__ORBIS__)
193 # define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
194 #endif
195 
197 // Cygwin
198 #ifdef __CYGWIN__
199 
200 // Required for some versions of Cygwin to declare gettimeofday
201 // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
202 # define _BSD_SOURCE
203 // some versions of cygwin (most) do not support std::to_string. Use the libstd check.
204 // https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
205 # if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
206  && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
207 
208 # define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
209 
210 # endif
211 #endif // __CYGWIN__
212 
214 // Visual C++
215 #ifdef _MSC_VER
216 
217 # if _MSC_VER >= 1900 // Visual Studio 2015 or newer
218 # define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
219 # endif
220 
221 // Universal Windows platform does not support SEH
222 // Or console colours (or console at all...)
223 # if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
224 # define CATCH_CONFIG_COLOUR_NONE
225 # else
226 # define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
227 # endif
228 
229 // MSVC traditional preprocessor needs some workaround for __VA_ARGS__
230 // _MSVC_TRADITIONAL == 0 means new conformant preprocessor
231 // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
232 # if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
233 # define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
234 # endif
235 
236 #endif // _MSC_VER
237 
239 // Check if we are compiled with -fno-exceptions or equivalent
240 #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
241 # define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
242 #endif
243 
245 // DJGPP
246 #ifdef __DJGPP__
247 # define CATCH_INTERNAL_CONFIG_NO_WCHAR
248 #endif // __DJGPP__
249 
251 // Embarcadero C++Build
252 #if defined(__BORLANDC__)
253  #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN
254 #endif
255 
257 
258 // Use of __COUNTER__ is suppressed during code analysis in
259 // CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
260 // handled by it.
261 // Otherwise all supported compilers support COUNTER macro,
262 // but user still might want to turn it off
263 #if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
264  #define CATCH_INTERNAL_CONFIG_COUNTER
265 #endif
266 
268 // Check if string_view is available and usable
269 // The check is split apart to work around v140 (VS2015) preprocessor issue...
270 #if defined(__has_include)
271 #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
272 # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
273 #endif
274 #endif
275 
277 // Check if variant is available and usable
278 #if defined(__has_include)
279 # if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
280 # if defined(__clang__) && (__clang_major__ < 8)
281  // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
282  // fix should be in clang 8, workaround in libstdc++ 8.2
283 # include <ciso646>
284 # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
285 # define CATCH_CONFIG_NO_CPP17_VARIANT
286 # else
287 # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
288 # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
289 # endif // defined(__clang__) && (__clang_major__ < 8)
290 # endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
291 #endif // __has_include
292 
293 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
294 # define CATCH_CONFIG_COUNTER
295 #endif
296 #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)
297 # define CATCH_CONFIG_WINDOWS_SEH
298 #endif
299 // This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
300 #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)
301 # define CATCH_CONFIG_POSIX_SIGNALS
302 #endif
303 // This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.
304 #if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
305 # define CATCH_CONFIG_WCHAR
306 #endif
307 
308 #if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
309 # define CATCH_CONFIG_CPP11_TO_STRING
310 #endif
311 
312 #if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
313 # define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
314 #endif
315 
316 #if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
317 # define CATCH_CONFIG_CPP17_STRING_VIEW
318 #endif
319 
320 #if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
321 # define CATCH_CONFIG_CPP17_VARIANT
322 #endif
323 
324 #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
325 # define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
326 #endif
327 
328 #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)
329 # define CATCH_CONFIG_NEW_CAPTURE
330 #endif
331 
332 #if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
333 # define CATCH_CONFIG_DISABLE_EXCEPTIONS
334 #endif
335 
336 #if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN)
337 # define CATCH_CONFIG_POLYFILL_ISNAN
338 #endif
339 
340 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
341 # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
342 # define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
343 #endif
344 #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
345 # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
346 # define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
347 #endif
348 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
349 # define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
350 # define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
351 #endif
352 
353 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
354 #define CATCH_TRY if ((true))
355 #define CATCH_CATCH_ALL if ((false))
356 #define CATCH_CATCH_ANON(type) if ((false))
357 #else
358 #define CATCH_TRY try
359 #define CATCH_CATCH_ALL catch (...)
360 #define CATCH_CATCH_ANON(type) catch (type)
361 #endif
362 
363 #if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)
364 #define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
365 #endif
366 
367 // end catch_compiler_capabilities.h
368 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
369 #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
370 #ifdef CATCH_CONFIG_COUNTER
371 # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
372 #else
373 # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
374 #endif
375 
376 #include <iosfwd>
377 #include <string>
378 #include <cstdint>
379 
380 // We need a dummy global operator<< so we can bring it into Catch namespace later
382 std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
383 
384 namespace Catch {
385 
386  struct CaseSensitive { enum Choice {
387  Yes,
388  No
389  }; };
390 
391  class NonCopyable {
392  NonCopyable( NonCopyable const& ) = delete;
393  NonCopyable( NonCopyable && ) = delete;
394  NonCopyable& operator = ( NonCopyable const& ) = delete;
395  NonCopyable& operator = ( NonCopyable && ) = delete;
396 
397  protected:
398  NonCopyable();
399  virtual ~NonCopyable();
400  };
401 
402  struct SourceLineInfo {
403 
404  SourceLineInfo() = delete;
405  SourceLineInfo( char const* _file, std::size_t _line ) noexcept
406  : file( _file ),
407  line( _line )
408  {}
409 
410  SourceLineInfo( SourceLineInfo const& other ) = default;
411  SourceLineInfo( SourceLineInfo && ) = default;
412  SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
413  SourceLineInfo& operator = ( SourceLineInfo && ) = default;
414 
415  bool empty() const noexcept;
416  bool operator == ( SourceLineInfo const& other ) const noexcept;
417  bool operator < ( SourceLineInfo const& other ) const noexcept;
418 
419  char const* file;
420  std::size_t line;
421  };
422 
423  std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
424 
425  // Bring in operator<< from global namespace into Catch namespace
426  // This is necessary because the overload of operator<< above makes
427  // lookup stop at namespace Catch
428  using ::operator<<;
429 
430  // Use this in variadic streaming macros to allow
431  // >> +StreamEndStop
432  // as well as
433  // >> stuff +StreamEndStop
434  struct StreamEndStop {
435  std::string operator+() const;
436  };
437  template<typename T>
438  T const& operator + ( T const& value, StreamEndStop ) {
439  return value;
440  }
441 }
442 
443 #define CATCH_INTERNAL_LINEINFO \
444  ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
445 
446 // end catch_common.h
447 namespace Catch {
448 
450  RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
451  };
452 
453 } // end namespace Catch
454 
455 #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
456  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
457  namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
458  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
459 
460 // end catch_tag_alias_autoregistrar.h
461 // start catch_test_registry.h
462 
463 // start catch_interfaces_testcase.h
464 
465 #include <vector>
466 #include <memory>
467 
468 namespace Catch {
469 
470  class TestSpec;
471 
472  struct ITestInvoker {
473  virtual void invoke () const = 0;
474  virtual ~ITestInvoker();
475  };
476 
477  using ITestCasePtr = std::shared_ptr<ITestInvoker>;
478 
479  class TestCase;
480  struct IConfig;
481 
483  virtual ~ITestCaseRegistry();
484  virtual std::vector<TestCase> const& getAllTests() const = 0;
485  virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
486  };
487 
488  bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
489  std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
490  std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
491 
492 }
493 
494 // end catch_interfaces_testcase.h
495 // start catch_stringref.h
496 
497 #include <cstddef>
498 #include <string>
499 #include <iosfwd>
500 
501 namespace Catch {
502 
503  class StringData;
504 
512  class StringRef {
513  public:
514  using size_type = std::size_t;
515 
516  private:
517  friend struct StringRefTestAccess;
518 
519  char const* m_start;
520  size_type m_size;
521 
522  char* m_data = nullptr;
523 
524  void takeOwnership();
525 
526  static constexpr char const* const s_empty = "";
527 
528  public: // construction/ assignment
529  StringRef() noexcept
530  : StringRef( s_empty, 0 )
531  {}
532 
533  StringRef( StringRef const& other ) noexcept
534  : m_start( other.m_start ),
535  m_size( other.m_size )
536  {}
537 
538  StringRef( StringRef&& other ) noexcept
539  : m_start( other.m_start ),
540  m_size( other.m_size ),
541  m_data( other.m_data )
542  {
543  other.m_data = nullptr;
544  }
545 
546  StringRef( char const* rawChars ) noexcept;
547 
548  StringRef( char const* rawChars, size_type size ) noexcept
549  : m_start( rawChars ),
550  m_size( size )
551  {}
552 
553  StringRef( std::string const& stdString ) noexcept
554  : m_start( stdString.c_str() ),
555  m_size( stdString.size() )
556  {}
557 
558  ~StringRef() noexcept {
559  delete[] m_data;
560  }
561 
562  auto operator = ( StringRef const &other ) noexcept -> StringRef& {
563  delete[] m_data;
564  m_data = nullptr;
565  m_start = other.m_start;
566  m_size = other.m_size;
567  return *this;
568  }
569 
570  operator std::string() const;
571 
572  void swap( StringRef& other ) noexcept;
573 
574  public: // operators
575  auto operator == ( StringRef const& other ) const noexcept -> bool;
576  auto operator != ( StringRef const& other ) const noexcept -> bool;
577 
578  auto operator[] ( size_type index ) const noexcept -> char;
579 
580  public: // named queries
581  auto empty() const noexcept -> bool {
582  return m_size == 0;
583  }
584  auto size() const noexcept -> size_type {
585  return m_size;
586  }
587 
588  auto numberOfCharacters() const noexcept -> size_type;
589  auto c_str() const -> char const*;
590 
591  public: // substrings and searches
592  auto substr( size_type start, size_type size ) const noexcept -> StringRef;
593 
594  // Returns the current start pointer.
595  // Note that the pointer can change when if the StringRef is a substring
596  auto currentData() const noexcept -> char const*;
597 
598  private: // ownership queries - may not be consistent between calls
599  auto isOwned() const noexcept -> bool;
600  auto isSubstring() const noexcept -> bool;
601  };
602 
603  auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string;
604  auto operator + ( StringRef const& lhs, char const* rhs ) -> std::string;
605  auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string;
606 
607  auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
608  auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
609 
610  inline auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
611  return StringRef( rawChars, size );
612  }
613 
614 } // namespace Catch
615 
616 inline auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
617  return Catch::StringRef( rawChars, size );
618 }
619 
620 // end catch_stringref.h
621 // start catch_type_traits.hpp
622 
623 
624 namespace Catch{
625 
626 #ifdef CATCH_CPP17_OR_GREATER
627  template <typename...>
628  inline constexpr auto is_unique = std::true_type{};
629 
630  template <typename T, typename... Rest>
631  inline constexpr auto is_unique<T, Rest...> = std::bool_constant<
632  (!std::is_same_v<T, Rest> && ...) && is_unique<Rest...>
633  >{};
634 #else
635 
636 template <typename...>
637 struct is_unique : std::true_type{};
638 
639 template <typename T0, typename T1, typename... Rest>
640 struct is_unique<T0, T1, Rest...> : std::integral_constant
641 <bool,
642  !std::is_same<T0, T1>::value
643  && is_unique<T0, Rest...>::value
644  && is_unique<T1, Rest...>::value
645 >{};
646 
647 #endif
648 }
649 
650 // end catch_type_traits.hpp
651 // start catch_preprocessor.hpp
652 
653 
654 #define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__
655 #define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))
656 #define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))
657 #define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__)))
658 #define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__)))
659 #define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__)))
660 
661 #ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
662 #define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__
663 // MSVC needs more evaluations
664 #define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__)))
665 #define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__))
666 #else
667 #define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__)
668 #endif
669 
670 #define CATCH_REC_END(...)
671 #define CATCH_REC_OUT
672 
673 #define CATCH_EMPTY()
674 #define CATCH_DEFER(id) id CATCH_EMPTY()
675 
676 #define CATCH_REC_GET_END2() 0, CATCH_REC_END
677 #define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2
678 #define CATCH_REC_GET_END(...) CATCH_REC_GET_END1
679 #define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT
680 #define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0)
681 #define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next)
682 
683 #define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
684 #define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ )
685 #define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
686 
687 #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__ )
688 #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__ )
689 #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__ )
690 
691 // Applies the function macro `f` to each of the remaining parameters, inserts commas between the results,
692 // and passes userdata as the first parameter to each invocation,
693 // e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c)
694 #define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
695 
696 #define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
697 
698 #define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
699 #define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__
700 #define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
701 #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
702 
703 #define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)
704 
705 #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name, __VA_ARGS__)
706 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
707 #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name,...) Name " - " #__VA_ARGS__
708 #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME(Name,...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
709 #else
710 // MSVC is adding extra space and needs more calls to properly remove ()
711 #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name,...) Name " -" #__VA_ARGS__
712 #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME1(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, __VA_ARGS__)
713 #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME1(Name, INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
714 #endif
715 
716 // end catch_preprocessor.hpp
717 namespace Catch {
718 
719 template<typename C>
721  void (C::*m_testAsMethod)();
722 public:
723  TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}
724 
725  void invoke() const override {
726  C obj;
727  (obj.*m_testAsMethod)();
728  }
729 };
730 
731 auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;
732 
733 template<typename C>
734 auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {
735  return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod );
736 }
737 
738 struct NameAndTags {
739  NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;
740  StringRef name;
741  StringRef tags;
742 };
743 
745  AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;
746  ~AutoReg();
747 };
748 
749 } // end namespace Catch
750 
751 #if defined(CATCH_CONFIG_DISABLE)
752  #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
753  static void TestName()
754  #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
755  namespace{ \
756  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
757  void test(); \
758  }; \
759  } \
760  void TestName::test()
761  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION( TestName, ... ) \
762  template<typename TestType> \
763  static void TestName()
764  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
765  namespace{ \
766  template<typename TestType> \
767  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
768  void test(); \
769  }; \
770  } \
771  template<typename TestType> \
772  void TestName::test()
773 #endif
774 
776  #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
777  static void TestName(); \
778  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
779  namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
780  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
781  static void TestName()
782  #define INTERNAL_CATCH_TESTCASE( ... ) \
783  INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
784 
786  #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
787  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
788  namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
789  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
790 
792  #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
793  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
794  namespace{ \
795  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
796  void test(); \
797  }; \
798  Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
799  } \
800  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
801  void TestName::test()
802  #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
803  INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
804 
806  #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
807  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
808  Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
809  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
810 
812  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, ... )\
813  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
814  template<typename TestType> \
815  static void TestFunc();\
816  namespace {\
817  template<typename...Types> \
818  struct TestName{\
819  template<typename...Ts> \
820  TestName(Ts...names){\
821  CATCH_INTERNAL_CHECK_UNIQUE_TYPES(CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)) \
822  using expander = int[];\
823  (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ names, Tags } ), 0)... };/* NOLINT */ \
824  }\
825  };\
826  INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestName, Name, __VA_ARGS__) \
827  }\
828  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
829  template<typename TestType> \
830  static void TestFunc()
831 
832 #if defined(CATCH_CPP17_OR_GREATER)
833 #define CATCH_INTERNAL_CHECK_UNIQUE_TYPES(...) static_assert(Catch::is_unique<__VA_ARGS__>,"Duplicate type detected in declaration of template test case");
834 #else
835 #define CATCH_INTERNAL_CHECK_UNIQUE_TYPES(...) static_assert(Catch::is_unique<__VA_ARGS__>::value,"Duplicate type detected in declaration of template test case");
836 #endif
837 
838 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
839  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
840  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__ )
841 #else
842  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
843  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__ ) )
844 #endif
845 
846  #define INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestName, Name, ...)\
847  static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
848  TestName<CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)>(CATCH_REC_LIST_UD(INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME,Name, __VA_ARGS__));\
849  return 0;\
850  }();
851 
852  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, ... ) \
853  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
854  namespace{ \
855  template<typename TestType> \
856  struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
857  void test();\
858  };\
859  template<typename...Types> \
860  struct TestNameClass{\
861  template<typename...Ts> \
862  TestNameClass(Ts...names){\
863  CATCH_INTERNAL_CHECK_UNIQUE_TYPES(CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)) \
864  using expander = int[];\
865  (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ names, Tags } ), 0)... };/* NOLINT */ \
866  }\
867  };\
868  INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestNameClass, Name, __VA_ARGS__)\
869  }\
870  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS\
871  template<typename TestType> \
872  void TestName<TestType>::test()
873 
874 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
875  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
876  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__ )
877 #else
878  #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
879  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__ ) )
880 #endif
881 
882 // end catch_test_registry.h
883 // start catch_capture.hpp
884 
885 // start catch_assertionhandler.h
886 
887 // start catch_assertioninfo.h
888 
889 // start catch_result_type.h
890 
891 namespace Catch {
892 
893  // ResultWas::OfType enum
894  struct ResultWas { enum OfType {
895  Unknown = -1,
896  Ok = 0,
897  Info = 1,
898  Warning = 2,
899 
900  FailureBit = 0x10,
901 
902  ExpressionFailed = FailureBit | 1,
903  ExplicitFailure = FailureBit | 2,
904 
905  Exception = 0x100 | FailureBit,
906 
907  ThrewException = Exception | 1,
908  DidntThrowException = Exception | 2,
909 
910  FatalErrorCondition = 0x200 | FailureBit
911 
912  }; };
913 
914  bool isOk( ResultWas::OfType resultType );
915  bool isJustInfo( int flags );
916 
917  // ResultDisposition::Flags enum
918  struct ResultDisposition { enum Flags {
919  Normal = 0x01,
920 
921  ContinueOnFailure = 0x02, // Failures fail test, but execution continues
922  FalseTest = 0x04, // Prefix expression with !
923  SuppressFail = 0x08 // Failures are reported but do not fail the test
924  }; };
925 
926  ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs );
927 
928  bool shouldContinueOnFailure( int flags );
929  inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
930  bool shouldSuppressFailure( int flags );
931 
932 } // end namespace Catch
933 
934 // end catch_result_type.h
935 namespace Catch {
936 
938  {
939  StringRef macroName;
940  SourceLineInfo lineInfo;
941  StringRef capturedExpression;
942  ResultDisposition::Flags resultDisposition;
943 
944  // We want to delete this constructor but a compiler bug in 4.8 means
945  // the struct is then treated as non-aggregate
946  //AssertionInfo() = delete;
947  };
948 
949 } // end namespace Catch
950 
951 // end catch_assertioninfo.h
952 // start catch_decomposer.h
953 
954 // start catch_tostring.h
955 
956 #include <vector>
957 #include <cstddef>
958 #include <type_traits>
959 #include <string>
960 // start catch_stream.h
961 
962 #include <iosfwd>
963 #include <cstddef>
964 #include <ostream>
965 
966 namespace Catch {
967 
968  std::ostream& cout();
969  std::ostream& cerr();
970  std::ostream& clog();
971 
972  class StringRef;
973 
974  struct IStream {
975  virtual ~IStream();
976  virtual std::ostream& stream() const = 0;
977  };
978 
979  auto makeStream( StringRef const &filename ) -> IStream const*;
980 
982  std::size_t m_index;
983  std::ostream* m_oss;
984  public:
987 
988  auto str() const -> std::string;
989 
990  template<typename T>
991  auto operator << ( T const& value ) -> ReusableStringStream& {
992  *m_oss << value;
993  return *this;
994  }
995  auto get() -> std::ostream& { return *m_oss; }
996  };
997 }
998 
999 // end catch_stream.h
1000 
1001 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1002 #include <string_view>
1003 #endif
1004 
1005 #ifdef __OBJC__
1006 // start catch_objc_arc.hpp
1007 
1008 #import <Foundation/Foundation.h>
1009 
1010 #ifdef __has_feature
1011 #define CATCH_ARC_ENABLED __has_feature(objc_arc)
1012 #else
1013 #define CATCH_ARC_ENABLED 0
1014 #endif
1015 
1016 void arcSafeRelease( NSObject* obj );
1017 id performOptionalSelector( id obj, SEL sel );
1018 
1019 #if !CATCH_ARC_ENABLED
1020 inline void arcSafeRelease( NSObject* obj ) {
1021  [obj release];
1022 }
1023 inline id performOptionalSelector( id obj, SEL sel ) {
1024  if( [obj respondsToSelector: sel] )
1025  return [obj performSelector: sel];
1026  return nil;
1027 }
1028 #define CATCH_UNSAFE_UNRETAINED
1029 #define CATCH_ARC_STRONG
1030 #else
1031 inline void arcSafeRelease( NSObject* ){}
1032 inline id performOptionalSelector( id obj, SEL sel ) {
1033 #ifdef __clang__
1034 #pragma clang diagnostic push
1035 #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
1036 #endif
1037  if( [obj respondsToSelector: sel] )
1038  return [obj performSelector: sel];
1039 #ifdef __clang__
1040 #pragma clang diagnostic pop
1041 #endif
1042  return nil;
1043 }
1044 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
1045 #define CATCH_ARC_STRONG __strong
1046 #endif
1047 
1048 // end catch_objc_arc.hpp
1049 #endif
1050 
1051 #ifdef _MSC_VER
1052 #pragma warning(push)
1053 #pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
1054 #endif
1055 
1056 namespace Catch {
1057  namespace Detail {
1058 
1059  extern const std::string unprintableString;
1060 
1061  std::string rawMemoryToString( const void *object, std::size_t size );
1062 
1063  template<typename T>
1064  std::string rawMemoryToString( const T& object ) {
1065  return rawMemoryToString( &object, sizeof(object) );
1066  }
1067 
1068  template<typename T>
1070  template<typename SS, typename TT>
1071  static auto test(int)
1072  -> decltype(std::declval<SS&>() << std::declval<TT>(), std::true_type());
1073 
1074  template<typename, typename>
1075  static auto test(...)->std::false_type;
1076 
1077  public:
1078  static const bool value = decltype(test<std::ostream, const T&>(0))::value;
1079  };
1080 
1081  template<typename E>
1082  std::string convertUnknownEnumToString( E e );
1083 
1084  template<typename T>
1085  typename std::enable_if<
1086  !std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value,
1087  std::string>::type convertUnstreamable( T const& ) {
1088  return Detail::unprintableString;
1089  }
1090  template<typename T>
1091  typename std::enable_if<
1092  !std::is_enum<T>::value && std::is_base_of<std::exception, T>::value,
1093  std::string>::type convertUnstreamable(T const& ex) {
1094  return ex.what();
1095  }
1096 
1097  template<typename T>
1098  typename std::enable_if<
1099  std::is_enum<T>::value
1100  , std::string>::type convertUnstreamable( T const& value ) {
1101  return convertUnknownEnumToString( value );
1102  }
1103 
1104 #if defined(_MANAGED)
1105  template<typename T>
1107  std::string clrReferenceToString( T^ ref ) {
1108  if (ref == nullptr)
1109  return std::string("null");
1110  auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
1111  cli::pin_ptr<System::Byte> p = &bytes[0];
1112  return std::string(reinterpret_cast<char const *>(p), bytes->Length);
1113  }
1114 #endif
1115 
1116  } // namespace Detail
1117 
1118  // If we decide for C++14, change these to enable_if_ts
1119  template <typename T, typename = void>
1120  struct StringMaker {
1121  template <typename Fake = T>
1122  static
1123  typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
1124  convert(const Fake& value) {
1126  // NB: call using the function-like syntax to avoid ambiguity with
1127  // user-defined templated operator<< under clang.
1128  rss.operator<<(value);
1129  return rss.str();
1130  }
1131 
1132  template <typename Fake = T>
1133  static
1134  typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
1135  convert( const Fake& value ) {
1136 #if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
1137  return Detail::convertUnstreamable(value);
1138 #else
1139  return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
1140 #endif
1141  }
1142  };
1143 
1144  namespace Detail {
1145 
1146  // This function dispatches all stringification requests inside of Catch.
1147  // Should be preferably called fully qualified, like ::Catch::Detail::stringify
1148  template <typename T>
1149  std::string stringify(const T& e) {
1150  return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);
1151  }
1152 
1153  template<typename E>
1154  std::string convertUnknownEnumToString( E e ) {
1155  return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));
1156  }
1157 
1158 #if defined(_MANAGED)
1159  template <typename T>
1160  std::string stringify( T^ e ) {
1161  return ::Catch::StringMaker<T^>::convert(e);
1162  }
1163 #endif
1164 
1165  } // namespace Detail
1166 
1167  // Some predefined specializations
1168 
1169  template<>
1170  struct StringMaker<std::string> {
1171  static std::string convert(const std::string& str);
1172  };
1173 
1174 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1175  template<>
1176  struct StringMaker<std::string_view> {
1177  static std::string convert(std::string_view str);
1178  };
1179 #endif
1180 
1181  template<>
1182  struct StringMaker<char const *> {
1183  static std::string convert(char const * str);
1184  };
1185  template<>
1186  struct StringMaker<char *> {
1187  static std::string convert(char * str);
1188  };
1189 
1190 #ifdef CATCH_CONFIG_WCHAR
1191  template<>
1192  struct StringMaker<std::wstring> {
1193  static std::string convert(const std::wstring& wstr);
1194  };
1195 
1196 # ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1197  template<>
1198  struct StringMaker<std::wstring_view> {
1199  static std::string convert(std::wstring_view str);
1200  };
1201 # endif
1202 
1203  template<>
1204  struct StringMaker<wchar_t const *> {
1205  static std::string convert(wchar_t const * str);
1206  };
1207  template<>
1208  struct StringMaker<wchar_t *> {
1209  static std::string convert(wchar_t * str);
1210  };
1211 #endif
1212 
1213  // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
1214  // while keeping string semantics?
1215  template<int SZ>
1216  struct StringMaker<char[SZ]> {
1217  static std::string convert(char const* str) {
1218  return ::Catch::Detail::stringify(std::string{ str });
1219  }
1220  };
1221  template<int SZ>
1222  struct StringMaker<signed char[SZ]> {
1223  static std::string convert(signed char const* str) {
1224  return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
1225  }
1226  };
1227  template<int SZ>
1228  struct StringMaker<unsigned char[SZ]> {
1229  static std::string convert(unsigned char const* str) {
1230  return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
1231  }
1232  };
1233 
1234  template<>
1235  struct StringMaker<int> {
1236  static std::string convert(int value);
1237  };
1238  template<>
1239  struct StringMaker<long> {
1240  static std::string convert(long value);
1241  };
1242  template<>
1243  struct StringMaker<long long> {
1244  static std::string convert(long long value);
1245  };
1246  template<>
1247  struct StringMaker<unsigned int> {
1248  static std::string convert(unsigned int value);
1249  };
1250  template<>
1251  struct StringMaker<unsigned long> {
1252  static std::string convert(unsigned long value);
1253  };
1254  template<>
1255  struct StringMaker<unsigned long long> {
1256  static std::string convert(unsigned long long value);
1257  };
1258 
1259  template<>
1260  struct StringMaker<bool> {
1261  static std::string convert(bool b);
1262  };
1263 
1264  template<>
1265  struct StringMaker<char> {
1266  static std::string convert(char c);
1267  };
1268  template<>
1269  struct StringMaker<signed char> {
1270  static std::string convert(signed char c);
1271  };
1272  template<>
1273  struct StringMaker<unsigned char> {
1274  static std::string convert(unsigned char c);
1275  };
1276 
1277  template<>
1278  struct StringMaker<std::nullptr_t> {
1279  static std::string convert(std::nullptr_t);
1280  };
1281 
1282  template<>
1283  struct StringMaker<float> {
1284  static std::string convert(float value);
1285  };
1286  template<>
1287  struct StringMaker<double> {
1288  static std::string convert(double value);
1289  };
1290 
1291  template <typename T>
1292  struct StringMaker<T*> {
1293  template <typename U>
1294  static std::string convert(U* p) {
1295  if (p) {
1296  return ::Catch::Detail::rawMemoryToString(p);
1297  } else {
1298  return "nullptr";
1299  }
1300  }
1301  };
1302 
1303  template <typename R, typename C>
1304  struct StringMaker<R C::*> {
1305  static std::string convert(R C::* p) {
1306  if (p) {
1307  return ::Catch::Detail::rawMemoryToString(p);
1308  } else {
1309  return "nullptr";
1310  }
1311  }
1312  };
1313 
1314 #if defined(_MANAGED)
1315  template <typename T>
1316  struct StringMaker<T^> {
1317  static std::string convert( T^ ref ) {
1318  return ::Catch::Detail::clrReferenceToString(ref);
1319  }
1320  };
1321 #endif
1322 
1323  namespace Detail {
1324  template<typename InputIterator>
1325  std::string rangeToString(InputIterator first, InputIterator last) {
1326  ReusableStringStream rss;
1327  rss << "{ ";
1328  if (first != last) {
1329  rss << ::Catch::Detail::stringify(*first);
1330  for (++first; first != last; ++first)
1331  rss << ", " << ::Catch::Detail::stringify(*first);
1332  }
1333  rss << " }";
1334  return rss.str();
1335  }
1336  }
1337 
1338 #ifdef __OBJC__
1339  template<>
1340  struct StringMaker<NSString*> {
1341  static std::string convert(NSString * nsstring) {
1342  if (!nsstring)
1343  return "nil";
1344  return std::string("@") + [nsstring UTF8String];
1345  }
1346  };
1347  template<>
1348  struct StringMaker<NSObject*> {
1349  static std::string convert(NSObject* nsObject) {
1350  return ::Catch::Detail::stringify([nsObject description]);
1351  }
1352 
1353  };
1354  namespace Detail {
1355  inline std::string stringify( NSString* nsstring ) {
1356  return StringMaker<NSString*>::convert( nsstring );
1357  }
1358 
1359  } // namespace Detail
1360 #endif // __OBJC__
1361 
1362 } // namespace Catch
1363 
1365 // Separate std-lib types stringification, so it can be selectively enabled
1366 // This means that we do not bring in
1367 
1368 #if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
1369 # define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
1370 # define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
1371 # define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
1372 # define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
1373 #endif
1374 
1375 // Separate std::pair specialization
1376 #if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
1377 #include <utility>
1378 namespace Catch {
1379  template<typename T1, typename T2>
1380  struct StringMaker<std::pair<T1, T2> > {
1381  static std::string convert(const std::pair<T1, T2>& pair) {
1382  ReusableStringStream rss;
1383  rss << "{ "
1384  << ::Catch::Detail::stringify(pair.first)
1385  << ", "
1386  << ::Catch::Detail::stringify(pair.second)
1387  << " }";
1388  return rss.str();
1389  }
1390  };
1391 }
1392 #endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
1393 
1394 // Separate std::tuple specialization
1395 #if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
1396 #include <tuple>
1397 namespace Catch {
1398  namespace Detail {
1399  template<
1400  typename Tuple,
1401  std::size_t N = 0,
1402  bool = (N < std::tuple_size<Tuple>::value)
1403  >
1404  struct TupleElementPrinter {
1405  static void print(const Tuple& tuple, std::ostream& os) {
1406  os << (N ? ", " : " ")
1407  << ::Catch::Detail::stringify(std::get<N>(tuple));
1408  TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
1409  }
1410  };
1411 
1412  template<
1413  typename Tuple,
1414  std::size_t N
1415  >
1416  struct TupleElementPrinter<Tuple, N, false> {
1417  static void print(const Tuple&, std::ostream&) {}
1418  };
1419 
1420  }
1421 
1422  template<typename ...Types>
1423  struct StringMaker<std::tuple<Types...>> {
1424  static std::string convert(const std::tuple<Types...>& tuple) {
1425  ReusableStringStream rss;
1426  rss << '{';
1427  Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
1428  rss << " }";
1429  return rss.str();
1430  }
1431  };
1432 }
1433 #endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
1434 
1435 #if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
1436 #include <variant>
1437 namespace Catch {
1438  template<>
1439  struct StringMaker<std::monostate> {
1440  static std::string convert(const std::monostate&) {
1441  return "{ }";
1442  }
1443  };
1444 
1445  template<typename... Elements>
1446  struct StringMaker<std::variant<Elements...>> {
1447  static std::string convert(const std::variant<Elements...>& variant) {
1448  if (variant.valueless_by_exception()) {
1449  return "{valueless variant}";
1450  } else {
1451  return std::visit(
1452  [](const auto& value) {
1453  return ::Catch::Detail::stringify(value);
1454  },
1455  variant
1456  );
1457  }
1458  }
1459  };
1460 }
1461 #endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
1462 
1463 namespace Catch {
1464  struct not_this_one {}; // Tag type for detecting which begin/ end are being selected
1465 
1466  // Import begin/ end from std here so they are considered alongside the fallback (...) overloads in this namespace
1467  using std::begin;
1468  using std::end;
1469 
1470  not_this_one begin( ... );
1471  not_this_one end( ... );
1472 
1473  template <typename T>
1474  struct is_range {
1475  static const bool value =
1476  !std::is_same<decltype(begin(std::declval<T>())), not_this_one>::value &&
1477  !std::is_same<decltype(end(std::declval<T>())), not_this_one>::value;
1478  };
1479 
1480 #if defined(_MANAGED) // Managed types are never ranges
1481  template <typename T>
1482  struct is_range<T^> {
1483  static const bool value = false;
1484  };
1485 #endif
1486 
1487  template<typename Range>
1488  std::string rangeToString( Range const& range ) {
1489  return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
1490  }
1491 
1492  // Handle vector<bool> specially
1493  template<typename Allocator>
1494  std::string rangeToString( std::vector<bool, Allocator> const& v ) {
1495  ReusableStringStream rss;
1496  rss << "{ ";
1497  bool first = true;
1498  for( bool b : v ) {
1499  if( first )
1500  first = false;
1501  else
1502  rss << ", ";
1503  rss << ::Catch::Detail::stringify( b );
1504  }
1505  rss << " }";
1506  return rss.str();
1507  }
1508 
1509  template<typename R>
1510  struct StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {
1511  static std::string convert( R const& range ) {
1512  return rangeToString( range );
1513  }
1514  };
1515 
1516  template <typename T, int SZ>
1517  struct StringMaker<T[SZ]> {
1518  static std::string convert(T const(&arr)[SZ]) {
1519  return rangeToString(arr);
1520  }
1521  };
1522 
1523 } // namespace Catch
1524 
1525 // Separate std::chrono::duration specialization
1526 #if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
1527 #include <ctime>
1528 #include <ratio>
1529 #include <chrono>
1530 
1531 namespace Catch {
1532 
1533 template <class Ratio>
1534 struct ratio_string {
1535  static std::string symbol();
1536 };
1537 
1538 template <class Ratio>
1539 std::string ratio_string<Ratio>::symbol() {
1541  rss << '[' << Ratio::num << '/'
1542  << Ratio::den << ']';
1543  return rss.str();
1544 }
1545 template <>
1546 struct ratio_string<std::atto> {
1547  static std::string symbol();
1548 };
1549 template <>
1550 struct ratio_string<std::femto> {
1551  static std::string symbol();
1552 };
1553 template <>
1554 struct ratio_string<std::pico> {
1555  static std::string symbol();
1556 };
1557 template <>
1558 struct ratio_string<std::nano> {
1559  static std::string symbol();
1560 };
1561 template <>
1562 struct ratio_string<std::micro> {
1563  static std::string symbol();
1564 };
1565 template <>
1566 struct ratio_string<std::milli> {
1567  static std::string symbol();
1568 };
1569 
1571  // std::chrono::duration specializations
1572  template<typename Value, typename Ratio>
1573  struct StringMaker<std::chrono::duration<Value, Ratio>> {
1574  static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
1575  ReusableStringStream rss;
1576  rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
1577  return rss.str();
1578  }
1579  };
1580  template<typename Value>
1581  struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
1582  static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
1583  ReusableStringStream rss;
1584  rss << duration.count() << " s";
1585  return rss.str();
1586  }
1587  };
1588  template<typename Value>
1589  struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
1590  static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
1591  ReusableStringStream rss;
1592  rss << duration.count() << " m";
1593  return rss.str();
1594  }
1595  };
1596  template<typename Value>
1597  struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
1598  static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
1599  ReusableStringStream rss;
1600  rss << duration.count() << " h";
1601  return rss.str();
1602  }
1603  };
1604 
1606  // std::chrono::time_point specialization
1607  // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
1608  template<typename Clock, typename Duration>
1609  struct StringMaker<std::chrono::time_point<Clock, Duration>> {
1610  static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {
1611  return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
1612  }
1613  };
1614  // std::chrono::time_point<system_clock> specialization
1615  template<typename Duration>
1616  struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
1617  static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
1618  auto converted = std::chrono::system_clock::to_time_t(time_point);
1619 
1620 #ifdef _MSC_VER
1621  std::tm timeInfo = {};
1622  gmtime_s(&timeInfo, &converted);
1623 #else
1624  std::tm* timeInfo = std::gmtime(&converted);
1625 #endif
1626 
1627  auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
1628  char timeStamp[timeStampSize];
1629  const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
1630 
1631 #ifdef _MSC_VER
1632  std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
1633 #else
1634  std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
1635 #endif
1636  return std::string(timeStamp);
1637  }
1638  };
1639 }
1640 #endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
1641 
1642 #ifdef _MSC_VER
1643 #pragma warning(pop)
1644 #endif
1645 
1646 // end catch_tostring.h
1647 #include <iosfwd>
1648 
1649 #ifdef _MSC_VER
1650 #pragma warning(push)
1651 #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
1652 #pragma warning(disable:4018) // more "signed/unsigned mismatch"
1653 #pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
1654 #pragma warning(disable:4180) // qualifier applied to function type has no meaning
1655 #endif
1656 
1657 namespace Catch {
1658 
1660  auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
1661  auto getResult() const -> bool { return m_result; }
1662  virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
1663 
1664  ITransientExpression( bool isBinaryExpression, bool result )
1665  : m_isBinaryExpression( isBinaryExpression ),
1666  m_result( result )
1667  {}
1668 
1669  // We don't actually need a virtual destructor, but many static analysers
1670  // complain if it's not here :-(
1671  virtual ~ITransientExpression();
1672 
1673  bool m_isBinaryExpression;
1674  bool m_result;
1675 
1676  };
1677 
1678  void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
1679 
1680  template<typename LhsT, typename RhsT>
1682  LhsT m_lhs;
1683  StringRef m_op;
1684  RhsT m_rhs;
1685 
1686  void streamReconstructedExpression( std::ostream &os ) const override {
1687  formatReconstructedExpression
1688  ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
1689  }
1690 
1691  public:
1692  BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
1693  : ITransientExpression{ true, comparisonResult },
1694  m_lhs( lhs ),
1695  m_op( op ),
1696  m_rhs( rhs )
1697  {}
1698  };
1699 
1700  template<typename LhsT>
1702  LhsT m_lhs;
1703 
1704  void streamReconstructedExpression( std::ostream &os ) const override {
1705  os << Catch::Detail::stringify( m_lhs );
1706  }
1707 
1708  public:
1709  explicit UnaryExpr( LhsT lhs )
1710  : ITransientExpression{ false, lhs ? true : false },
1711  m_lhs( lhs )
1712  {}
1713  };
1714 
1715  // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
1716  template<typename LhsT, typename RhsT>
1717  auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }
1718  template<typename T>
1719  auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
1720  template<typename T>
1721  auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
1722  template<typename T>
1723  auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
1724  template<typename T>
1725  auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
1726 
1727  template<typename LhsT, typename RhsT>
1728  auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }
1729  template<typename T>
1730  auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
1731  template<typename T>
1732  auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
1733  template<typename T>
1734  auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
1735  template<typename T>
1736  auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
1737 
1738  template<typename LhsT>
1739  class ExprLhs {
1740  LhsT m_lhs;
1741  public:
1742  explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
1743 
1744  template<typename RhsT>
1745  auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
1746  return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs };
1747  }
1748  auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
1749  return { m_lhs == rhs, m_lhs, "==", rhs };
1750  }
1751 
1752  template<typename RhsT>
1753  auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
1754  return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs };
1755  }
1756  auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
1757  return { m_lhs != rhs, m_lhs, "!=", rhs };
1758  }
1759 
1760  template<typename RhsT>
1761  auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
1762  return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs };
1763  }
1764  template<typename RhsT>
1765  auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
1766  return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs };
1767  }
1768  template<typename RhsT>
1769  auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
1770  return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs };
1771  }
1772  template<typename RhsT>
1773  auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
1774  return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs };
1775  }
1776 
1777  auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
1778  return UnaryExpr<LhsT>{ m_lhs };
1779  }
1780  };
1781 
1782  void handleExpression( ITransientExpression const& expr );
1783 
1784  template<typename T>
1785  void handleExpression( ExprLhs<T> const& expr ) {
1786  handleExpression( expr.makeUnaryExpr() );
1787  }
1788 
1789  struct Decomposer {
1790  template<typename T>
1791  auto operator <= ( T const& lhs ) -> ExprLhs<T const&> {
1792  return ExprLhs<T const&>{ lhs };
1793  }
1794 
1795  auto operator <=( bool value ) -> ExprLhs<bool> {
1796  return ExprLhs<bool>{ value };
1797  }
1798  };
1799 
1800 } // end namespace Catch
1801 
1802 #ifdef _MSC_VER
1803 #pragma warning(pop)
1804 #endif
1805 
1806 // end catch_decomposer.h
1807 // start catch_interfaces_capture.h
1808 
1809 #include <string>
1810 
1811 namespace Catch {
1812 
1813  class AssertionResult;
1814  struct AssertionInfo;
1815  struct SectionInfo;
1816  struct SectionEndInfo;
1817  struct MessageInfo;
1818  struct Counts;
1819  struct BenchmarkInfo;
1820  struct BenchmarkStats;
1821  struct AssertionReaction;
1822  struct SourceLineInfo;
1823 
1824  struct ITransientExpression;
1825  struct IGeneratorTracker;
1826 
1828 
1829  virtual ~IResultCapture();
1830 
1831  virtual bool sectionStarted( SectionInfo const& sectionInfo,
1832  Counts& assertions ) = 0;
1833  virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
1834  virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
1835 
1836  virtual auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
1837 
1838  virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
1839  virtual void benchmarkEnded( BenchmarkStats const& stats ) = 0;
1840 
1841  virtual void pushScopedMessage( MessageInfo const& message ) = 0;
1842  virtual void popScopedMessage( MessageInfo const& message ) = 0;
1843 
1844  virtual void handleFatalErrorCondition( StringRef message ) = 0;
1845 
1846  virtual void handleExpr
1847  ( AssertionInfo const& info,
1848  ITransientExpression const& expr,
1849  AssertionReaction& reaction ) = 0;
1850  virtual void handleMessage
1851  ( AssertionInfo const& info,
1852  ResultWas::OfType resultType,
1853  StringRef const& message,
1854  AssertionReaction& reaction ) = 0;
1855  virtual void handleUnexpectedExceptionNotThrown
1856  ( AssertionInfo const& info,
1857  AssertionReaction& reaction ) = 0;
1858  virtual void handleUnexpectedInflightException
1859  ( AssertionInfo const& info,
1860  std::string const& message,
1861  AssertionReaction& reaction ) = 0;
1862  virtual void handleIncomplete
1863  ( AssertionInfo const& info ) = 0;
1864  virtual void handleNonExpr
1865  ( AssertionInfo const &info,
1866  ResultWas::OfType resultType,
1867  AssertionReaction &reaction ) = 0;
1868 
1869  virtual bool lastAssertionPassed() = 0;
1870  virtual void assertionPassed() = 0;
1871 
1872  // Deprecated, do not use:
1873  virtual std::string getCurrentTestName() const = 0;
1874  virtual const AssertionResult* getLastResult() const = 0;
1875  virtual void exceptionEarlyReported() = 0;
1876  };
1877 
1878  IResultCapture& getResultCapture();
1879 }
1880 
1881 // end catch_interfaces_capture.h
1882 namespace Catch {
1883 
1885  struct AssertionResultData;
1886  struct IResultCapture;
1887  class RunContext;
1888 
1890  friend class AssertionHandler;
1891  friend struct AssertionStats;
1892  friend class RunContext;
1893 
1894  ITransientExpression const* m_transientExpression = nullptr;
1895  bool m_isNegated;
1896  public:
1897  LazyExpression( bool isNegated );
1898  LazyExpression( LazyExpression const& other );
1899  LazyExpression& operator = ( LazyExpression const& ) = delete;
1900 
1901  explicit operator bool() const;
1902 
1903  friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&;
1904  };
1905 
1907  bool shouldDebugBreak = false;
1908  bool shouldThrow = false;
1909  };
1910 
1912  AssertionInfo m_assertionInfo;
1913  AssertionReaction m_reaction;
1914  bool m_completed = false;
1915  IResultCapture& m_resultCapture;
1916 
1917  public:
1919  ( StringRef const& macroName,
1920  SourceLineInfo const& lineInfo,
1921  StringRef capturedExpression,
1922  ResultDisposition::Flags resultDisposition );
1923  ~AssertionHandler() {
1924  if ( !m_completed ) {
1925  m_resultCapture.handleIncomplete( m_assertionInfo );
1926  }
1927  }
1928 
1929  template<typename T>
1930  void handleExpr( ExprLhs<T> const& expr ) {
1931  handleExpr( expr.makeUnaryExpr() );
1932  }
1933  void handleExpr( ITransientExpression const& expr );
1934 
1935  void handleMessage(ResultWas::OfType resultType, StringRef const& message);
1936 
1937  void handleExceptionThrownAsExpected();
1938  void handleUnexpectedExceptionNotThrown();
1939  void handleExceptionNotThrownAsExpected();
1940  void handleThrowingCallSkipped();
1941  void handleUnexpectedInflightException();
1942 
1943  void complete();
1944  void setCompleted();
1945 
1946  // query
1947  auto allowThrows() const -> bool;
1948  };
1949 
1950  void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString );
1951 
1952 } // namespace Catch
1953 
1954 // end catch_assertionhandler.h
1955 // start catch_message.h
1956 
1957 #include <string>
1958 #include <vector>
1959 
1960 namespace Catch {
1961 
1962  struct MessageInfo {
1963  MessageInfo( StringRef const& _macroName,
1964  SourceLineInfo const& _lineInfo,
1965  ResultWas::OfType _type );
1966 
1967  StringRef macroName;
1968  std::string message;
1969  SourceLineInfo lineInfo;
1970  ResultWas::OfType type;
1971  unsigned int sequence;
1972 
1973  bool operator == ( MessageInfo const& other ) const;
1974  bool operator < ( MessageInfo const& other ) const;
1975  private:
1976  static unsigned int globalCount;
1977  };
1978 
1979  struct MessageStream {
1980 
1981  template<typename T>
1982  MessageStream& operator << ( T const& value ) {
1983  m_stream << value;
1984  return *this;
1985  }
1986 
1987  ReusableStringStream m_stream;
1988  };
1989 
1991  MessageBuilder( StringRef const& macroName,
1992  SourceLineInfo const& lineInfo,
1993  ResultWas::OfType type );
1994 
1995  template<typename T>
1996  MessageBuilder& operator << ( T const& value ) {
1997  m_stream << value;
1998  return *this;
1999  }
2000 
2001  MessageInfo m_info;
2002  };
2003 
2005  public:
2006  explicit ScopedMessage( MessageBuilder const& builder );
2007  ~ScopedMessage();
2008 
2009  MessageInfo m_info;
2010  };
2011 
2012  class Capturer {
2013  std::vector<MessageInfo> m_messages;
2014  IResultCapture& m_resultCapture = getResultCapture();
2015  size_t m_captured = 0;
2016  public:
2017  Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
2018  ~Capturer();
2019 
2020  void captureValue( size_t index, std::string const& value );
2021 
2022  template<typename T>
2023  void captureValues( size_t index, T const& value ) {
2024  captureValue( index, Catch::Detail::stringify( value ) );
2025  }
2026 
2027  template<typename T, typename... Ts>
2028  void captureValues( size_t index, T const& value, Ts const&... values ) {
2029  captureValue( index, Catch::Detail::stringify(value) );
2030  captureValues( index+1, values... );
2031  }
2032  };
2033 
2034 } // end namespace Catch
2035 
2036 // end catch_message.h
2037 #if !defined(CATCH_CONFIG_DISABLE)
2038 
2039 #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
2040  #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
2041 #else
2042  #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
2043 #endif
2044 
2045 #if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
2046 
2048 // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
2049 // macros.
2050 #define INTERNAL_CATCH_TRY
2051 #define INTERNAL_CATCH_CATCH( capturer )
2052 
2053 #else // CATCH_CONFIG_FAST_COMPILE
2054 
2055 #define INTERNAL_CATCH_TRY try
2056 #define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); }
2057 
2058 #endif
2059 
2060 #define INTERNAL_CATCH_REACT( handler ) handler.complete();
2061 
2063 #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
2064  do { \
2065  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
2066  INTERNAL_CATCH_TRY { \
2067  CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
2068  catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
2069  CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
2070  } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
2071  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2072  } 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
2073  // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
2074 
2076 #define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
2077  INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
2078  if( Catch::getResultCapture().lastAssertionPassed() )
2079 
2081 #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
2082  INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
2083  if( !Catch::getResultCapture().lastAssertionPassed() )
2084 
2086 #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
2087  do { \
2088  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
2089  try { \
2090  static_cast<void>(__VA_ARGS__); \
2091  catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
2092  } \
2093  catch( ... ) { \
2094  catchAssertionHandler.handleUnexpectedInflightException(); \
2095  } \
2096  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2097  } while( false )
2098 
2100 #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
2101  do { \
2102  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
2103  if( catchAssertionHandler.allowThrows() ) \
2104  try { \
2105  static_cast<void>(__VA_ARGS__); \
2106  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
2107  } \
2108  catch( ... ) { \
2109  catchAssertionHandler.handleExceptionThrownAsExpected(); \
2110  } \
2111  else \
2112  catchAssertionHandler.handleThrowingCallSkipped(); \
2113  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2114  } while( false )
2115 
2117 #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
2118  do { \
2119  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
2120  if( catchAssertionHandler.allowThrows() ) \
2121  try { \
2122  static_cast<void>(expr); \
2123  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
2124  } \
2125  catch( exceptionType const& ) { \
2126  catchAssertionHandler.handleExceptionThrownAsExpected(); \
2127  } \
2128  catch( ... ) { \
2129  catchAssertionHandler.handleUnexpectedInflightException(); \
2130  } \
2131  else \
2132  catchAssertionHandler.handleThrowingCallSkipped(); \
2133  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2134  } while( false )
2135 
2137 #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
2138  do { \
2139  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
2140  catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
2141  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2142  } while( false )
2143 
2145 #define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
2146  auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \
2147  varName.captureValues( 0, __VA_ARGS__ )
2148 
2150 #define INTERNAL_CATCH_INFO( macroName, log ) \
2151  Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
2152 
2154 // Although this is matcher-based, it can be used with just a string
2155 #define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
2156  do { \
2157  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
2158  if( catchAssertionHandler.allowThrows() ) \
2159  try { \
2160  static_cast<void>(__VA_ARGS__); \
2161  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
2162  } \
2163  catch( ... ) { \
2164  Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \
2165  } \
2166  else \
2167  catchAssertionHandler.handleThrowingCallSkipped(); \
2168  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2169  } while( false )
2170 
2171 #endif // CATCH_CONFIG_DISABLE
2172 
2173 // end catch_capture.hpp
2174 // start catch_section.h
2175 
2176 // start catch_section_info.h
2177 
2178 // start catch_totals.h
2179 
2180 #include <cstddef>
2181 
2182 namespace Catch {
2183 
2184  struct Counts {
2185  Counts operator - ( Counts const& other ) const;
2186  Counts& operator += ( Counts const& other );
2187 
2188  std::size_t total() const;
2189  bool allPassed() const;
2190  bool allOk() const;
2191 
2192  std::size_t passed = 0;
2193  std::size_t failed = 0;
2194  std::size_t failedButOk = 0;
2195  };
2196 
2197  struct Totals {
2198 
2199  Totals operator - ( Totals const& other ) const;
2200  Totals& operator += ( Totals const& other );
2201 
2202  Totals delta( Totals const& prevTotals ) const;
2203 
2204  int error = 0;
2205  Counts assertions;
2206  Counts testCases;
2207  };
2208 }
2209 
2210 // end catch_totals.h
2211 #include <string>
2212 
2213 namespace Catch {
2214 
2215  struct SectionInfo {
2216  SectionInfo
2217  ( SourceLineInfo const& _lineInfo,
2218  std::string const& _name );
2219 
2220  // Deprecated
2221  SectionInfo
2222  ( SourceLineInfo const& _lineInfo,
2223  std::string const& _name,
2224  std::string const& ) : SectionInfo( _lineInfo, _name ) {}
2225 
2226  std::string name;
2227  std::string description; // !Deprecated: this will always be empty
2228  SourceLineInfo lineInfo;
2229  };
2230 
2232  SectionInfo sectionInfo;
2233  Counts prevAssertions;
2234  double durationInSeconds;
2235  };
2236 
2237 } // end namespace Catch
2238 
2239 // end catch_section_info.h
2240 // start catch_timer.h
2241 
2242 #include <cstdint>
2243 
2244 namespace Catch {
2245 
2246  auto getCurrentNanosecondsSinceEpoch() -> uint64_t;
2247  auto getEstimatedClockResolution() -> uint64_t;
2248 
2249  class Timer {
2250  uint64_t m_nanoseconds = 0;
2251  public:
2252  void start();
2253  auto getElapsedNanoseconds() const -> uint64_t;
2254  auto getElapsedMicroseconds() const -> uint64_t;
2255  auto getElapsedMilliseconds() const -> unsigned int;
2256  auto getElapsedSeconds() const -> double;
2257  };
2258 
2259 } // namespace Catch
2260 
2261 // end catch_timer.h
2262 #include <string>
2263 
2264 namespace Catch {
2265 
2267  public:
2268  Section( SectionInfo const& info );
2269  ~Section();
2270 
2271  // This indicates whether the section should be executed or not
2272  explicit operator bool() const;
2273 
2274  private:
2275  SectionInfo m_info;
2276 
2277  std::string m_name;
2278  Counts m_assertions;
2279  bool m_sectionIncluded;
2280  Timer m_timer;
2281  };
2282 
2283 } // end namespace Catch
2284 
2285 #define INTERNAL_CATCH_SECTION( ... ) \
2286  CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
2287  if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
2288  CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
2289 
2290 #define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
2291  CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
2292  if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \
2293  CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
2294 
2295 // end catch_section.h
2296 // start catch_benchmark.h
2297 
2298 #include <cstdint>
2299 #include <string>
2300 
2301 namespace Catch {
2302 
2304 
2305  std::string m_name;
2306  std::size_t m_count = 0;
2307  std::size_t m_iterationsToRun = 1;
2308  uint64_t m_resolution;
2309  Timer m_timer;
2310 
2311  static auto getResolution() -> uint64_t;
2312  public:
2313  // Keep most of this inline as it's on the code path that is being timed
2314  BenchmarkLooper( StringRef name )
2315  : m_name( name ),
2316  m_resolution( getResolution() )
2317  {
2318  reportStart();
2319  m_timer.start();
2320  }
2321 
2322  explicit operator bool() {
2323  if( m_count < m_iterationsToRun )
2324  return true;
2325  return needsMoreIterations();
2326  }
2327 
2328  void increment() {
2329  ++m_count;
2330  }
2331 
2332  void reportStart();
2333  auto needsMoreIterations() -> bool;
2334  };
2335 
2336 } // end namespace Catch
2337 
2338 #define BENCHMARK( name ) \
2339  for( Catch::BenchmarkLooper looper( name ); looper; looper.increment() )
2340 
2341 // end catch_benchmark.h
2342 // start catch_interfaces_exception.h
2343 
2344 // start catch_interfaces_registry_hub.h
2345 
2346 #include <string>
2347 #include <memory>
2348 
2349 namespace Catch {
2350 
2351  class TestCase;
2352  struct ITestCaseRegistry;
2353  struct IExceptionTranslatorRegistry;
2354  struct IExceptionTranslator;
2355  struct IReporterRegistry;
2356  struct IReporterFactory;
2357  struct ITagAliasRegistry;
2358  class StartupExceptionRegistry;
2359 
2360  using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
2361 
2362  struct IRegistryHub {
2363  virtual ~IRegistryHub();
2364 
2365  virtual IReporterRegistry const& getReporterRegistry() const = 0;
2366  virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
2367  virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
2368 
2369  virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0;
2370 
2371  virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
2372  };
2373 
2375  virtual ~IMutableRegistryHub();
2376  virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0;
2377  virtual void registerListener( IReporterFactoryPtr const& factory ) = 0;
2378  virtual void registerTest( TestCase const& testInfo ) = 0;
2379  virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
2380  virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
2381  virtual void registerStartupException() noexcept = 0;
2382  };
2383 
2384  IRegistryHub const& getRegistryHub();
2385  IMutableRegistryHub& getMutableRegistryHub();
2386  void cleanUp();
2387  std::string translateActiveException();
2388 
2389 }
2390 
2391 // end catch_interfaces_registry_hub.h
2392 #if defined(CATCH_CONFIG_DISABLE)
2393  #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \
2394  static std::string translatorName( signature )
2395 #endif
2396 
2397 #include <exception>
2398 #include <string>
2399 #include <vector>
2400 
2401 namespace Catch {
2402  using exceptionTranslateFunction = std::string(*)();
2403 
2404  struct IExceptionTranslator;
2405  using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;
2406 
2408  virtual ~IExceptionTranslator();
2409  virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
2410  };
2411 
2413  virtual ~IExceptionTranslatorRegistry();
2414 
2415  virtual std::string translateActiveException() const = 0;
2416  };
2417 
2419  template<typename T>
2421  public:
2422 
2423  ExceptionTranslator( std::string(*translateFunction)( T& ) )
2424  : m_translateFunction( translateFunction )
2425  {}
2426 
2427  std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override {
2428  try {
2429  if( it == itEnd )
2430  std::rethrow_exception(std::current_exception());
2431  else
2432  return (*it)->translate( it+1, itEnd );
2433  }
2434  catch( T& ex ) {
2435  return m_translateFunction( ex );
2436  }
2437  }
2438 
2439  protected:
2440  std::string(*m_translateFunction)( T& );
2441  };
2442 
2443  public:
2444  template<typename T>
2445  ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
2446  getMutableRegistryHub().registerTranslator
2447  ( new ExceptionTranslator<T>( translateFunction ) );
2448  }
2449  };
2450 }
2451 
2453 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
2454  static std::string translatorName( signature ); \
2455  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
2456  namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \
2457  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
2458  static std::string translatorName( signature )
2459 
2460 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
2461 
2462 // end catch_interfaces_exception.h
2463 // start catch_approx.h
2464 
2465 #include <type_traits>
2466 
2467 namespace Catch {
2468 namespace Detail {
2469 
2470  class Approx {
2471  private:
2472  bool equalityComparisonImpl(double other) const;
2473  // Validates the new margin (margin >= 0)
2474  // out-of-line to avoid including stdexcept in the header
2475  void setMargin(double margin);
2476  // Validates the new epsilon (0 < epsilon < 1)
2477  // out-of-line to avoid including stdexcept in the header
2478  void setEpsilon(double epsilon);
2479 
2480  public:
2481  explicit Approx ( double value );
2482 
2483  static Approx custom();
2484 
2485  Approx operator-() const;
2486 
2487  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
2488  Approx operator()( T const& value ) {
2489  Approx approx( static_cast<double>(value) );
2490  approx.m_epsilon = m_epsilon;
2491  approx.m_margin = m_margin;
2492  approx.m_scale = m_scale;
2493  return approx;
2494  }
2495 
2496  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
2497  explicit Approx( T const& value ): Approx(static_cast<double>(value))
2498  {}
2499 
2500  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
2501  friend bool operator == ( const T& lhs, Approx const& rhs ) {
2502  auto lhs_v = static_cast<double>(lhs);
2503  return rhs.equalityComparisonImpl(lhs_v);
2504  }
2505 
2506  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
2507  friend bool operator == ( Approx const& lhs, const T& rhs ) {
2508  return operator==( rhs, lhs );
2509  }
2510 
2511  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
2512  friend bool operator != ( T const& lhs, Approx const& rhs ) {
2513  return !operator==( lhs, rhs );
2514  }
2515 
2516  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
2517  friend bool operator != ( Approx const& lhs, T const& rhs ) {
2518  return !operator==( rhs, lhs );
2519  }
2520 
2521  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
2522  friend bool operator <= ( T const& lhs, Approx const& rhs ) {
2523  return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;
2524  }
2525 
2526  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
2527  friend bool operator <= ( Approx const& lhs, T const& rhs ) {
2528  return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
2529  }
2530 
2531  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
2532  friend bool operator >= ( T const& lhs, Approx const& rhs ) {
2533  return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;
2534  }
2535 
2536  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
2537  friend bool operator >= ( Approx const& lhs, T const& rhs ) {
2538  return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
2539  }
2540 
2541  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
2542  Approx& epsilon( T const& newEpsilon ) {
2543  double epsilonAsDouble = static_cast<double>(newEpsilon);
2544  setEpsilon(epsilonAsDouble);
2545  return *this;
2546  }
2547 
2548  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
2549  Approx& margin( T const& newMargin ) {
2550  double marginAsDouble = static_cast<double>(newMargin);
2551  setMargin(marginAsDouble);
2552  return *this;
2553  }
2554 
2555  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
2556  Approx& scale( T const& newScale ) {
2557  m_scale = static_cast<double>(newScale);
2558  return *this;
2559  }
2560 
2561  std::string toString() const;
2562 
2563  private:
2564  double m_epsilon;
2565  double m_margin;
2566  double m_scale;
2567  double m_value;
2568  };
2569 } // end namespace Detail
2570 
2571 namespace literals {
2572  Detail::Approx operator "" _a(long double val);
2573  Detail::Approx operator "" _a(unsigned long long val);
2574 } // end namespace literals
2575 
2576 template<>
2577 struct StringMaker<Catch::Detail::Approx> {
2578  static std::string convert(Catch::Detail::Approx const& value);
2579 };
2580 
2581 } // end namespace Catch
2582 
2583 // end catch_approx.h
2584 // start catch_string_manip.h
2585 
2586 #include <string>
2587 #include <iosfwd>
2588 
2589 namespace Catch {
2590 
2591  bool startsWith( std::string const& s, std::string const& prefix );
2592  bool startsWith( std::string const& s, char prefix );
2593  bool endsWith( std::string const& s, std::string const& suffix );
2594  bool endsWith( std::string const& s, char suffix );
2595  bool contains( std::string const& s, std::string const& infix );
2596  void toLowerInPlace( std::string& s );
2597  std::string toLower( std::string const& s );
2598  std::string trim( std::string const& str );
2599  bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
2600 
2601  struct pluralise {
2602  pluralise( std::size_t count, std::string const& label );
2603 
2604  friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
2605 
2606  std::size_t m_count;
2607  std::string m_label;
2608  };
2609 }
2610 
2611 // end catch_string_manip.h
2612 #ifndef CATCH_CONFIG_DISABLE_MATCHERS
2613 // start catch_capture_matchers.h
2614 
2615 // start catch_matchers.h
2616 
2617 #include <string>
2618 #include <vector>
2619 
2620 namespace Catch {
2621 namespace Matchers {
2622  namespace Impl {
2623 
2624  template<typename ArgT> struct MatchAllOf;
2625  template<typename ArgT> struct MatchAnyOf;
2626  template<typename ArgT> struct MatchNotOf;
2627 
2629  public:
2630  MatcherUntypedBase() = default;
2631  MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
2632  MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete;
2633  std::string toString() const;
2634 
2635  protected:
2636  virtual ~MatcherUntypedBase();
2637  virtual std::string describe() const = 0;
2638  mutable std::string m_cachedToString;
2639  };
2640 
2641 #ifdef __clang__
2642 # pragma clang diagnostic push
2643 # pragma clang diagnostic ignored "-Wnon-virtual-dtor"
2644 #endif
2645 
2646  template<typename ObjectT>
2647  struct MatcherMethod {
2648  virtual bool match( ObjectT const& arg ) const = 0;
2649  };
2650 
2651 #ifdef __clang__
2652 # pragma clang diagnostic pop
2653 #endif
2654 
2655  template<typename T>
2657 
2658  MatchAllOf<T> operator && ( MatcherBase const& other ) const;
2659  MatchAnyOf<T> operator || ( MatcherBase const& other ) const;
2660  MatchNotOf<T> operator ! () const;
2661  };
2662 
2663  template<typename ArgT>
2664  struct MatchAllOf : MatcherBase<ArgT> {
2665  bool match( ArgT const& arg ) const override {
2666  for( auto matcher : m_matchers ) {
2667  if (!matcher->match(arg))
2668  return false;
2669  }
2670  return true;
2671  }
2672  std::string describe() const override {
2673  std::string description;
2674  description.reserve( 4 + m_matchers.size()*32 );
2675  description += "( ";
2676  bool first = true;
2677  for( auto matcher : m_matchers ) {
2678  if( first )
2679  first = false;
2680  else
2681  description += " and ";
2682  description += matcher->toString();
2683  }
2684  description += " )";
2685  return description;
2686  }
2687 
2688  MatchAllOf<ArgT>& operator && ( MatcherBase<ArgT> const& other ) {
2689  m_matchers.push_back( &other );
2690  return *this;
2691  }
2692 
2693  std::vector<MatcherBase<ArgT> const*> m_matchers;
2694  };
2695  template<typename ArgT>
2696  struct MatchAnyOf : MatcherBase<ArgT> {
2697 
2698  bool match( ArgT const& arg ) const override {
2699  for( auto matcher : m_matchers ) {
2700  if (matcher->match(arg))
2701  return true;
2702  }
2703  return false;
2704  }
2705  std::string describe() const override {
2706  std::string description;
2707  description.reserve( 4 + m_matchers.size()*32 );
2708  description += "( ";
2709  bool first = true;
2710  for( auto matcher : m_matchers ) {
2711  if( first )
2712  first = false;
2713  else
2714  description += " or ";
2715  description += matcher->toString();
2716  }
2717  description += " )";
2718  return description;
2719  }
2720 
2721  MatchAnyOf<ArgT>& operator || ( MatcherBase<ArgT> const& other ) {
2722  m_matchers.push_back( &other );
2723  return *this;
2724  }
2725 
2726  std::vector<MatcherBase<ArgT> const*> m_matchers;
2727  };
2728 
2729  template<typename ArgT>
2730  struct MatchNotOf : MatcherBase<ArgT> {
2731 
2732  MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
2733 
2734  bool match( ArgT const& arg ) const override {
2735  return !m_underlyingMatcher.match( arg );
2736  }
2737 
2738  std::string describe() const override {
2739  return "not " + m_underlyingMatcher.toString();
2740  }
2741  MatcherBase<ArgT> const& m_underlyingMatcher;
2742  };
2743 
2744  template<typename T>
2745  MatchAllOf<T> MatcherBase<T>::operator && ( MatcherBase const& other ) const {
2746  return MatchAllOf<T>() && *this && other;
2747  }
2748  template<typename T>
2749  MatchAnyOf<T> MatcherBase<T>::operator || ( MatcherBase const& other ) const {
2750  return MatchAnyOf<T>() || *this || other;
2751  }
2752  template<typename T>
2753  MatchNotOf<T> MatcherBase<T>::operator ! () const {
2754  return MatchNotOf<T>( *this );
2755  }
2756 
2757  } // namespace Impl
2758 
2759 } // namespace Matchers
2760 
2761 using namespace Matchers;
2762 using Matchers::Impl::MatcherBase;
2763 
2764 } // namespace Catch
2765 
2766 // end catch_matchers.h
2767 // start catch_matchers_floating.h
2768 
2769 #include <type_traits>
2770 #include <cmath>
2771 
2772 namespace Catch {
2773 namespace Matchers {
2774 
2775  namespace Floating {
2776 
2777  enum class FloatingPointKind : uint8_t;
2778 
2779  struct WithinAbsMatcher : MatcherBase<double> {
2780  WithinAbsMatcher(double target, double margin);
2781  bool match(double const& matchee) const override;
2782  std::string describe() const override;
2783  private:
2784  double m_target;
2785  double m_margin;
2786  };
2787 
2788  struct WithinUlpsMatcher : MatcherBase<double> {
2789  WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType);
2790  bool match(double const& matchee) const override;
2791  std::string describe() const override;
2792  private:
2793  double m_target;
2794  int m_ulps;
2795  FloatingPointKind m_type;
2796  };
2797 
2798  } // namespace Floating
2799 
2800  // The following functions create the actual matcher objects.
2801  // This allows the types to be inferred
2802  Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff);
2803  Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff);
2804  Floating::WithinAbsMatcher WithinAbs(double target, double margin);
2805 
2806 } // namespace Matchers
2807 } // namespace Catch
2808 
2809 // end catch_matchers_floating.h
2810 // start catch_matchers_generic.hpp
2811 
2812 #include <functional>
2813 #include <string>
2814 
2815 namespace Catch {
2816 namespace Matchers {
2817 namespace Generic {
2818 
2819 namespace Detail {
2820  std::string finalizeDescription(const std::string& desc);
2821 }
2822 
2823 template <typename T>
2824 class PredicateMatcher : public MatcherBase<T> {
2825  std::function<bool(T const&)> m_predicate;
2826  std::string m_description;
2827 public:
2828 
2829  PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr)
2830  :m_predicate(std::move(elem)),
2831  m_description(Detail::finalizeDescription(descr))
2832  {}
2833 
2834  bool match( T const& item ) const override {
2835  return m_predicate(item);
2836  }
2837 
2838  std::string describe() const override {
2839  return m_description;
2840  }
2841 };
2842 
2843 } // namespace Generic
2844 
2845  // The following functions create the actual matcher objects.
2846  // The user has to explicitly specify type to the function, because
2847  // infering std::function<bool(T const&)> is hard (but possible) and
2848  // requires a lot of TMP.
2849  template<typename T>
2850  Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") {
2851  return Generic::PredicateMatcher<T>(predicate, description);
2852  }
2853 
2854 } // namespace Matchers
2855 } // namespace Catch
2856 
2857 // end catch_matchers_generic.hpp
2858 // start catch_matchers_string.h
2859 
2860 #include <string>
2861 
2862 namespace Catch {
2863 namespace Matchers {
2864 
2865  namespace StdString {
2866 
2868  {
2869  CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );
2870  std::string adjustString( std::string const& str ) const;
2871  std::string caseSensitivitySuffix() const;
2872 
2873  CaseSensitive::Choice m_caseSensitivity;
2874  std::string m_str;
2875  };
2876 
2877  struct StringMatcherBase : MatcherBase<std::string> {
2878  StringMatcherBase( std::string const& operation, CasedString const& comparator );
2879  std::string describe() const override;
2880 
2881  CasedString m_comparator;
2882  std::string m_operation;
2883  };
2884 
2886  EqualsMatcher( CasedString const& comparator );
2887  bool match( std::string const& source ) const override;
2888  };
2890  ContainsMatcher( CasedString const& comparator );
2891  bool match( std::string const& source ) const override;
2892  };
2894  StartsWithMatcher( CasedString const& comparator );
2895  bool match( std::string const& source ) const override;
2896  };
2898  EndsWithMatcher( CasedString const& comparator );
2899  bool match( std::string const& source ) const override;
2900  };
2901 
2902  struct RegexMatcher : MatcherBase<std::string> {
2903  RegexMatcher( std::string regex, CaseSensitive::Choice caseSensitivity );
2904  bool match( std::string const& matchee ) const override;
2905  std::string describe() const override;
2906 
2907  private:
2908  std::string m_regex;
2909  CaseSensitive::Choice m_caseSensitivity;
2910  };
2911 
2912  } // namespace StdString
2913 
2914  // The following functions create the actual matcher objects.
2915  // This allows the types to be inferred
2916 
2917  StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
2918  StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
2919  StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
2920  StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
2921  StdString::RegexMatcher Matches( std::string const& regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
2922 
2923 } // namespace Matchers
2924 } // namespace Catch
2925 
2926 // end catch_matchers_string.h
2927 // start catch_matchers_vector.h
2928 
2929 #include <algorithm>
2930 
2931 namespace Catch {
2932 namespace Matchers {
2933 
2934  namespace Vector {
2935  namespace Detail {
2936  template <typename InputIterator, typename T>
2937  size_t count(InputIterator first, InputIterator last, T const& item) {
2938  size_t cnt = 0;
2939  for (; first != last; ++first) {
2940  if (*first == item) {
2941  ++cnt;
2942  }
2943  }
2944  return cnt;
2945  }
2946  template <typename InputIterator, typename T>
2947  bool contains(InputIterator first, InputIterator last, T const& item) {
2948  for (; first != last; ++first) {
2949  if (*first == item) {
2950  return true;
2951  }
2952  }
2953  return false;
2954  }
2955  }
2956 
2957  template<typename T>
2958  struct ContainsElementMatcher : MatcherBase<std::vector<T>> {
2959 
2960  ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
2961 
2962  bool match(std::vector<T> const &v) const override {
2963  for (auto const& el : v) {
2964  if (el == m_comparator) {
2965  return true;
2966  }
2967  }
2968  return false;
2969  }
2970 
2971  std::string describe() const override {
2972  return "Contains: " + ::Catch::Detail::stringify( m_comparator );
2973  }
2974 
2975  T const& m_comparator;
2976  };
2977 
2978  template<typename T>
2979  struct ContainsMatcher : MatcherBase<std::vector<T>> {
2980 
2981  ContainsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
2982 
2983  bool match(std::vector<T> const &v) const override {
2984  // !TBD: see note in EqualsMatcher
2985  if (m_comparator.size() > v.size())
2986  return false;
2987  for (auto const& comparator : m_comparator) {
2988  auto present = false;
2989  for (const auto& el : v) {
2990  if (el == comparator) {
2991  present = true;
2992  break;
2993  }
2994  }
2995  if (!present) {
2996  return false;
2997  }
2998  }
2999  return true;
3000  }
3001  std::string describe() const override {
3002  return "Contains: " + ::Catch::Detail::stringify( m_comparator );
3003  }
3004 
3005  std::vector<T> const& m_comparator;
3006  };
3007 
3008  template<typename T>
3009  struct EqualsMatcher : MatcherBase<std::vector<T>> {
3010 
3011  EqualsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
3012 
3013  bool match(std::vector<T> const &v) const override {
3014  // !TBD: This currently works if all elements can be compared using !=
3015  // - a more general approach would be via a compare template that defaults
3016  // to using !=. but could be specialised for, e.g. std::vector<T> etc
3017  // - then just call that directly
3018  if (m_comparator.size() != v.size())
3019  return false;
3020  for (std::size_t i = 0; i < v.size(); ++i)
3021  if (m_comparator[i] != v[i])
3022  return false;
3023  return true;
3024  }
3025  std::string describe() const override {
3026  return "Equals: " + ::Catch::Detail::stringify( m_comparator );
3027  }
3028  std::vector<T> const& m_comparator;
3029  };
3030 
3031  template<typename T>
3032  struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>> {
3033  UnorderedEqualsMatcher(std::vector<T> const& target) : m_target(target) {}
3034  bool match(std::vector<T> const& vec) const override {
3035  // Note: This is a reimplementation of std::is_permutation,
3036  // because I don't want to include <algorithm> inside the common path
3037  if (m_target.size() != vec.size()) {
3038  return false;
3039  }
3040  auto lfirst = m_target.begin(), llast = m_target.end();
3041  auto rfirst = vec.begin(), rlast = vec.end();
3042  // Cut common prefix to optimize checking of permuted parts
3043  while (lfirst != llast && *lfirst == *rfirst) {
3044  ++lfirst; ++rfirst;
3045  }
3046  if (lfirst == llast) {
3047  return true;
3048  }
3049 
3050  for (auto mid = lfirst; mid != llast; ++mid) {
3051  // Skip already counted items
3052  if (Detail::contains(lfirst, mid, *mid)) {
3053  continue;
3054  }
3055  size_t num_vec = Detail::count(rfirst, rlast, *mid);
3056  if (num_vec == 0 || Detail::count(lfirst, llast, *mid) != num_vec) {
3057  return false;
3058  }
3059  }
3060 
3061  return true;
3062  }
3063 
3064  std::string describe() const override {
3065  return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
3066  }
3067  private:
3068  std::vector<T> const& m_target;
3069  };
3070 
3071  } // namespace Vector
3072 
3073  // The following functions create the actual matcher objects.
3074  // This allows the types to be inferred
3075 
3076  template<typename T>
3077  Vector::ContainsMatcher<T> Contains( std::vector<T> const& comparator ) {
3078  return Vector::ContainsMatcher<T>( comparator );
3079  }
3080 
3081  template<typename T>
3082  Vector::ContainsElementMatcher<T> VectorContains( T const& comparator ) {
3083  return Vector::ContainsElementMatcher<T>( comparator );
3084  }
3085 
3086  template<typename T>
3087  Vector::EqualsMatcher<T> Equals( std::vector<T> const& comparator ) {
3088  return Vector::EqualsMatcher<T>( comparator );
3089  }
3090 
3091  template<typename T>
3092  Vector::UnorderedEqualsMatcher<T> UnorderedEquals(std::vector<T> const& target) {
3093  return Vector::UnorderedEqualsMatcher<T>(target);
3094  }
3095 
3096 } // namespace Matchers
3097 } // namespace Catch
3098 
3099 // end catch_matchers_vector.h
3100 namespace Catch {
3101 
3102  template<typename ArgT, typename MatcherT>
3104  ArgT const& m_arg;
3105  MatcherT m_matcher;
3106  StringRef m_matcherString;
3107  public:
3108  MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString )
3109  : ITransientExpression{ true, matcher.match( arg ) },
3110  m_arg( arg ),
3111  m_matcher( matcher ),
3112  m_matcherString( matcherString )
3113  {}
3114 
3115  void streamReconstructedExpression( std::ostream &os ) const override {
3116  auto matcherAsString = m_matcher.toString();
3117  os << Catch::Detail::stringify( m_arg ) << ' ';
3118  if( matcherAsString == Detail::unprintableString )
3119  os << m_matcherString;
3120  else
3121  os << matcherAsString;
3122  }
3123  };
3124 
3126 
3127  void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString );
3128 
3129  template<typename ArgT, typename MatcherT>
3130  auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString ) -> MatchExpr<ArgT, MatcherT> {
3131  return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );
3132  }
3133 
3134 } // namespace Catch
3135 
3137 #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
3138  do { \
3139  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
3140  INTERNAL_CATCH_TRY { \
3141  catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \
3142  } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
3143  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
3144  } while( false )
3145 
3147 #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
3148  do { \
3149  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
3150  if( catchAssertionHandler.allowThrows() ) \
3151  try { \
3152  static_cast<void>(__VA_ARGS__ ); \
3153  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
3154  } \
3155  catch( exceptionType const& ex ) { \
3156  catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \
3157  } \
3158  catch( ... ) { \
3159  catchAssertionHandler.handleUnexpectedInflightException(); \
3160  } \
3161  else \
3162  catchAssertionHandler.handleThrowingCallSkipped(); \
3163  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
3164  } while( false )
3165 
3166 // end catch_capture_matchers.h
3167 #endif
3168 // start catch_generators.hpp
3169 
3170 // start catch_interfaces_generatortracker.h
3171 
3172 
3173 #include <memory>
3174 
3175 namespace Catch {
3176 
3177  namespace Generators {
3179  protected:
3180  size_t m_size = 0;
3181 
3182  public:
3183  GeneratorBase( size_t size ) : m_size( size ) {}
3184  virtual ~GeneratorBase();
3185  auto size() const -> size_t { return m_size; }
3186  };
3187  using GeneratorBasePtr = std::unique_ptr<GeneratorBase>;
3188 
3189  } // namespace Generators
3190 
3192  virtual ~IGeneratorTracker();
3193  virtual auto hasGenerator() const -> bool = 0;
3194  virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;
3195  virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0;
3196  virtual auto getIndex() const -> std::size_t = 0;
3197  };
3198 
3199 } // namespace Catch
3200 
3201 // end catch_interfaces_generatortracker.h
3202 // start catch_enforce.h
3203 
3204 #include <stdexcept>
3205 
3206 namespace Catch {
3207 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
3208  template <typename Ex>
3209  [[noreturn]]
3210  void throw_exception(Ex const& e) {
3211  throw e;
3212  }
3213 #else // ^^ Exceptions are enabled // Exceptions are disabled vv
3214  [[noreturn]]
3215  void throw_exception(std::exception const& e);
3216 #endif
3217 } // namespace Catch;
3218 
3219 #define CATCH_PREPARE_EXCEPTION( type, msg ) \
3220  type( ( Catch::ReusableStringStream() << msg ).str() )
3221 #define CATCH_INTERNAL_ERROR( msg ) \
3222  Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg))
3223 #define CATCH_ERROR( msg ) \
3224  Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::domain_error, msg ))
3225 #define CATCH_RUNTIME_ERROR( msg ) \
3226  Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::runtime_error, msg ))
3227 #define CATCH_ENFORCE( condition, msg ) \
3228  do{ if( !(condition) ) CATCH_ERROR( msg ); } while(false)
3229 
3230 // end catch_enforce.h
3231 #include <memory>
3232 #include <vector>
3233 #include <cassert>
3234 
3235 #include <utility>
3236 
3237 namespace Catch {
3238 namespace Generators {
3239 
3240  // !TBD move this into its own location?
3241  namespace pf{
3242  template<typename T, typename... Args>
3243  std::unique_ptr<T> make_unique( Args&&... args ) {
3244  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
3245  }
3246  }
3247 
3248  template<typename T>
3249  struct IGenerator {
3250  virtual ~IGenerator() {}
3251  virtual auto get( size_t index ) const -> T = 0;
3252  };
3253 
3254  template<typename T>
3255  class SingleValueGenerator : public IGenerator<T> {
3256  T m_value;
3257  public:
3258  SingleValueGenerator( T const& value ) : m_value( value ) {}
3259 
3260  auto get( size_t ) const -> T override {
3261  return m_value;
3262  }
3263  };
3264 
3265  template<typename T>
3266  class FixedValuesGenerator : public IGenerator<T> {
3267  std::vector<T> m_values;
3268 
3269  public:
3270  FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {}
3271 
3272  auto get( size_t index ) const -> T override {
3273  return m_values[index];
3274  }
3275  };
3276 
3277  template<typename T>
3278  class RangeGenerator : public IGenerator<T> {
3279  T const m_first;
3280  T const m_last;
3281 
3282  public:
3283  RangeGenerator( T const& first, T const& last ) : m_first( first ), m_last( last ) {
3284  assert( m_last > m_first );
3285  }
3286 
3287  auto get( size_t index ) const -> T override {
3288  // ToDo:: introduce a safe cast to catch potential overflows
3289  return static_cast<T>(m_first+index);
3290  }
3291  };
3292 
3293  template<typename T>
3295  auto get( size_t ) const -> T override {
3296  CATCH_INTERNAL_ERROR("A Null Generator is always empty");
3297  }
3298  };
3299 
3300  template<typename T>
3301  class Generator {
3302  std::unique_ptr<IGenerator<T>> m_generator;
3303  size_t m_size;
3304 
3305  public:
3306  Generator( size_t size, std::unique_ptr<IGenerator<T>> generator )
3307  : m_generator( std::move( generator ) ),
3308  m_size( size )
3309  {}
3310 
3311  auto size() const -> size_t { return m_size; }
3312  auto operator[]( size_t index ) const -> T {
3313  assert( index < m_size );
3314  return m_generator->get( index );
3315  }
3316  };
3317 
3318  std::vector<size_t> randomiseIndices( size_t selectionSize, size_t sourceSize );
3319 
3320  template<typename T>
3321  class GeneratorRandomiser : public IGenerator<T> {
3322  Generator<T> m_baseGenerator;
3323 
3324  std::vector<size_t> m_indices;
3325  public:
3326  GeneratorRandomiser( Generator<T>&& baseGenerator, size_t numberOfItems )
3327  : m_baseGenerator( std::move( baseGenerator ) ),
3328  m_indices( randomiseIndices( numberOfItems, m_baseGenerator.size() ) )
3329  {}
3330 
3331  auto get( size_t index ) const -> T override {
3332  return m_baseGenerator[m_indices[index]];
3333  }
3334  };
3335 
3336  template<typename T>
3338 
3339  template<typename T>
3340  auto all() -> Generator<T> { return RequiresASpecialisationFor<T>(); }
3341 
3342  template<>
3343  auto all<int>() -> Generator<int>;
3344 
3345  template<typename T>
3346  auto range( T const& first, T const& last ) -> Generator<T> {
3347  return Generator<T>( (last-first), pf::make_unique<RangeGenerator<T>>( first, last ) );
3348  }
3349 
3350  template<typename T>
3351  auto random( T const& first, T const& last ) -> Generator<T> {
3352  auto gen = range( first, last );
3353  auto size = gen.size();
3354 
3355  return Generator<T>( size, pf::make_unique<GeneratorRandomiser<T>>( std::move( gen ), size ) );
3356  }
3357  template<typename T>
3358  auto random( size_t size ) -> Generator<T> {
3359  return Generator<T>( size, pf::make_unique<GeneratorRandomiser<T>>( all<T>(), size ) );
3360  }
3361 
3362  template<typename T>
3363  auto values( std::initializer_list<T> values ) -> Generator<T> {
3364  return Generator<T>( values.size(), pf::make_unique<FixedValuesGenerator<T>>( values ) );
3365  }
3366  template<typename T>
3367  auto value( T const& val ) -> Generator<T> {
3368  return Generator<T>( 1, pf::make_unique<SingleValueGenerator<T>>( val ) );
3369  }
3370 
3371  template<typename T>
3372  auto as() -> Generator<T> {
3373  return Generator<T>( 0, pf::make_unique<NullGenerator<T>>() );
3374  }
3375 
3376  template<typename... Ts>
3377  auto table( std::initializer_list<std::tuple<Ts...>>&& tuples ) -> Generator<std::tuple<Ts...>> {
3378  return values<std::tuple<Ts...>>( std::forward<std::initializer_list<std::tuple<Ts...>>>( tuples ) );
3379  }
3380 
3381  template<typename T>
3383  std::vector<Generator<T>> m_generators;
3384 
3385  using type = T;
3386 
3387  Generators() : GeneratorBase( 0 ) {}
3388 
3389  void populate( T&& val ) {
3390  m_size += 1;
3391  m_generators.emplace_back( value( std::move( val ) ) );
3392  }
3393  template<typename U>
3394  void populate( U&& val ) {
3395  populate( T( std::move( val ) ) );
3396  }
3397  void populate( Generator<T>&& generator ) {
3398  m_size += generator.size();
3399  m_generators.emplace_back( std::move( generator ) );
3400  }
3401 
3402  template<typename U, typename... Gs>
3403  void populate( U&& valueOrGenerator, Gs... moreGenerators ) {
3404  populate( std::forward<U>( valueOrGenerator ) );
3405  populate( std::forward<Gs>( moreGenerators )... );
3406  }
3407 
3408  auto operator[]( size_t index ) const -> T {
3409  size_t sizes = 0;
3410  for( auto const& gen : m_generators ) {
3411  auto localIndex = index-sizes;
3412  sizes += gen.size();
3413  if( index < sizes )
3414  return gen[localIndex];
3415  }
3416  CATCH_INTERNAL_ERROR("Index '" << index << "' is out of range (" << sizes << ')');
3417  }
3418  };
3419 
3420  template<typename T, typename... Gs>
3421  auto makeGenerators( Generator<T>&& generator, Gs... moreGenerators ) -> Generators<T> {
3422  Generators<T> generators;
3423  generators.m_generators.reserve( 1+sizeof...(Gs) );
3424  generators.populate( std::move( generator ), std::forward<Gs>( moreGenerators )... );
3425  return generators;
3426  }
3427  template<typename T>
3428  auto makeGenerators( Generator<T>&& generator ) -> Generators<T> {
3429  Generators<T> generators;
3430  generators.populate( std::move( generator ) );
3431  return generators;
3432  }
3433  template<typename T, typename... Gs>
3434  auto makeGenerators( T&& val, Gs... moreGenerators ) -> Generators<T> {
3435  return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );
3436  }
3437  template<typename T, typename U, typename... Gs>
3438  auto makeGenerators( U&& val, Gs... moreGenerators ) -> Generators<T> {
3439  return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );
3440  }
3441 
3442  auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
3443 
3444  template<typename L>
3445  // Note: The type after -> is weird, because VS2015 cannot parse
3446  // the expression used in the typedef inside, when it is in
3447  // return type. Yeah, ¯\_(ツ)_/¯
3448  auto generate( SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>()[0]) {
3449  using UnderlyingType = typename decltype(generatorExpression())::type;
3450 
3451  IGeneratorTracker& tracker = acquireGeneratorTracker( lineInfo );
3452  if( !tracker.hasGenerator() )
3453  tracker.setGenerator( pf::make_unique<Generators<UnderlyingType>>( generatorExpression() ) );
3454 
3455  auto const& generator = static_cast<Generators<UnderlyingType> const&>( *tracker.getGenerator() );
3456  return generator[tracker.getIndex()];
3457  }
3458 
3459 } // namespace Generators
3460 } // namespace Catch
3461 
3462 #define GENERATE( ... ) \
3463  Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, []{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
3464 
3465 // end catch_generators.hpp
3466 
3467 // These files are included here so the single_include script doesn't put them
3468 // in the conditionally compiled sections
3469 // start catch_test_case_info.h
3470 
3471 #include <string>
3472 #include <vector>
3473 #include <memory>
3474 
3475 #ifdef __clang__
3476 #pragma clang diagnostic push
3477 #pragma clang diagnostic ignored "-Wpadded"
3478 #endif
3479 
3480 namespace Catch {
3481 
3482  struct ITestInvoker;
3483 
3484  struct TestCaseInfo {
3485  enum SpecialProperties{
3486  None = 0,
3487  IsHidden = 1 << 1,
3488  ShouldFail = 1 << 2,
3489  MayFail = 1 << 3,
3490  Throws = 1 << 4,
3491  NonPortable = 1 << 5,
3492  Benchmark = 1 << 6
3493  };
3494 
3495  TestCaseInfo( std::string const& _name,
3496  std::string const& _className,
3497  std::string const& _description,
3498  std::vector<std::string> const& _tags,
3499  SourceLineInfo const& _lineInfo );
3500 
3501  friend void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags );
3502 
3503  bool isHidden() const;
3504  bool throws() const;
3505  bool okToFail() const;
3506  bool expectedToFail() const;
3507 
3508  std::string tagsAsString() const;
3509 
3510  std::string name;
3511  std::string className;
3512  std::string description;
3513  std::vector<std::string> tags;
3514  std::vector<std::string> lcaseTags;
3515  SourceLineInfo lineInfo;
3516  SpecialProperties properties;
3517  };
3518 
3519  class TestCase : public TestCaseInfo {
3520  public:
3521 
3522  TestCase( ITestInvoker* testCase, TestCaseInfo&& info );
3523 
3524  TestCase withName( std::string const& _newName ) const;
3525 
3526  void invoke() const;
3527 
3528  TestCaseInfo const& getTestCaseInfo() const;
3529 
3530  bool operator == ( TestCase const& other ) const;
3531  bool operator < ( TestCase const& other ) const;
3532 
3533  private:
3534  std::shared_ptr<ITestInvoker> test;
3535  };
3536 
3537  TestCase makeTestCase( ITestInvoker* testCase,
3538  std::string const& className,
3539  NameAndTags const& nameAndTags,
3540  SourceLineInfo const& lineInfo );
3541 }
3542 
3543 #ifdef __clang__
3544 #pragma clang diagnostic pop
3545 #endif
3546 
3547 // end catch_test_case_info.h
3548 // start catch_interfaces_runner.h
3549 
3550 namespace Catch {
3551 
3552  struct IRunner {
3553  virtual ~IRunner();
3554  virtual bool aborting() const = 0;
3555  };
3556 }
3557 
3558 // end catch_interfaces_runner.h
3559 
3560 #ifdef __OBJC__
3561 // start catch_objc.hpp
3562 
3563 #import <objc/runtime.h>
3564 
3565 #include <string>
3566 
3567 // NB. Any general catch headers included here must be included
3568 // in catch.hpp first to make sure they are included by the single
3569 // header for non obj-usage
3570 
3572 // This protocol is really only here for (self) documenting purposes, since
3573 // all its methods are optional.
3574 @protocol OcFixture
3575 
3576 @optional
3577 
3578 -(void) setUp;
3579 -(void) tearDown;
3580 
3581 @end
3582 
3583 namespace Catch {
3584 
3585  class OcMethod : public ITestInvoker {
3586 
3587  public:
3588  OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
3589 
3590  virtual void invoke() const {
3591  id obj = [[m_cls alloc] init];
3592 
3593  performOptionalSelector( obj, @selector(setUp) );
3594  performOptionalSelector( obj, m_sel );
3595  performOptionalSelector( obj, @selector(tearDown) );
3596 
3597  arcSafeRelease( obj );
3598  }
3599  private:
3600  virtual ~OcMethod() {}
3601 
3602  Class m_cls;
3603  SEL m_sel;
3604  };
3605 
3606  namespace Detail{
3607 
3608  inline std::string getAnnotation( Class cls,
3609  std::string const& annotationName,
3610  std::string const& testCaseName ) {
3611  NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
3612  SEL sel = NSSelectorFromString( selStr );
3613  arcSafeRelease( selStr );
3614  id value = performOptionalSelector( cls, sel );
3615  if( value )
3616  return [(NSString*)value UTF8String];
3617  return "";
3618  }
3619  }
3620 
3621  inline std::size_t registerTestMethods() {
3622  std::size_t noTestMethods = 0;
3623  int noClasses = objc_getClassList( nullptr, 0 );
3624 
3625  Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
3626  objc_getClassList( classes, noClasses );
3627 
3628  for( int c = 0; c < noClasses; c++ ) {
3629  Class cls = classes[c];
3630  {
3631  u_int count;
3632  Method* methods = class_copyMethodList( cls, &count );
3633  for( u_int m = 0; m < count ; m++ ) {
3634  SEL selector = method_getName(methods[m]);
3635  std::string methodName = sel_getName(selector);
3636  if( startsWith( methodName, "Catch_TestCase_" ) ) {
3637  std::string testCaseName = methodName.substr( 15 );
3638  std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
3639  std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
3640  const char* className = class_getName( cls );
3641 
3642  getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo("",0) ) );
3643  noTestMethods++;
3644  }
3645  }
3646  free(methods);
3647  }
3648  }
3649  return noTestMethods;
3650  }
3651 
3652 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
3653 
3654  namespace Matchers {
3655  namespace Impl {
3656  namespace NSStringMatchers {
3657 
3658  struct StringHolder : MatcherBase<NSString*>{
3659  StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
3660  StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
3661  StringHolder() {
3662  arcSafeRelease( m_substr );
3663  }
3664 
3665  bool match( NSString* arg ) const override {
3666  return false;
3667  }
3668 
3669  NSString* CATCH_ARC_STRONG m_substr;
3670  };
3671 
3672  struct Equals : StringHolder {
3673  Equals( NSString* substr ) : StringHolder( substr ){}
3674 
3675  bool match( NSString* str ) const override {
3676  return (str != nil || m_substr == nil ) &&
3677  [str isEqualToString:m_substr];
3678  }
3679 
3680  std::string describe() const override {
3681  return "equals string: " + Catch::Detail::stringify( m_substr );
3682  }
3683  };
3684 
3685  struct Contains : StringHolder {
3686  Contains( NSString* substr ) : StringHolder( substr ){}
3687 
3688  bool match( NSString* str ) const {
3689  return (str != nil || m_substr == nil ) &&
3690  [str rangeOfString:m_substr].location != NSNotFound;
3691  }
3692 
3693  std::string describe() const override {
3694  return "contains string: " + Catch::Detail::stringify( m_substr );
3695  }
3696  };
3697 
3698  struct StartsWith : StringHolder {
3699  StartsWith( NSString* substr ) : StringHolder( substr ){}
3700 
3701  bool match( NSString* str ) const override {
3702  return (str != nil || m_substr == nil ) &&
3703  [str rangeOfString:m_substr].location == 0;
3704  }
3705 
3706  std::string describe() const override {
3707  return "starts with: " + Catch::Detail::stringify( m_substr );
3708  }
3709  };
3710  struct EndsWith : StringHolder {
3711  EndsWith( NSString* substr ) : StringHolder( substr ){}
3712 
3713  bool match( NSString* str ) const override {
3714  return (str != nil || m_substr == nil ) &&
3715  [str rangeOfString:m_substr].location == [str length] - [m_substr length];
3716  }
3717 
3718  std::string describe() const override {
3719  return "ends with: " + Catch::Detail::stringify( m_substr );
3720  }
3721  };
3722 
3723  } // namespace NSStringMatchers
3724  } // namespace Impl
3725 
3726  inline Impl::NSStringMatchers::Equals
3727  Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
3728 
3729  inline Impl::NSStringMatchers::Contains
3730  Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
3731 
3732  inline Impl::NSStringMatchers::StartsWith
3733  StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
3734 
3735  inline Impl::NSStringMatchers::EndsWith
3736  EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
3737 
3738  } // namespace Matchers
3739 
3740  using namespace Matchers;
3741 
3742 #endif // CATCH_CONFIG_DISABLE_MATCHERS
3743 
3744 } // namespace Catch
3745 
3747 #define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix
3748 #define OC_TEST_CASE2( name, desc, uniqueSuffix ) \
3749 +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \
3750 { \
3751 return @ name; \
3752 } \
3753 +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \
3754 { \
3755 return @ desc; \
3756 } \
3757 -(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix )
3758 
3759 #define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ )
3760 
3761 // end catch_objc.hpp
3762 #endif
3763 
3764 #ifdef CATCH_CONFIG_EXTERNAL_INTERFACES
3765 // start catch_external_interfaces.h
3766 
3767 // start catch_reporter_bases.hpp
3768 
3769 // start catch_interfaces_reporter.h
3770 
3771 // start catch_config.hpp
3772 
3773 // start catch_test_spec_parser.h
3774 
3775 #ifdef __clang__
3776 #pragma clang diagnostic push
3777 #pragma clang diagnostic ignored "-Wpadded"
3778 #endif
3779 
3780 // start catch_test_spec.h
3781 
3782 #ifdef __clang__
3783 #pragma clang diagnostic push
3784 #pragma clang diagnostic ignored "-Wpadded"
3785 #endif
3786 
3787 // start catch_wildcard_pattern.h
3788 
3789 namespace Catch
3790 {
3791  class WildcardPattern {
3792  enum WildcardPosition {
3793  NoWildcard = 0,
3794  WildcardAtStart = 1,
3795  WildcardAtEnd = 2,
3796  WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
3797  };
3798 
3799  public:
3800 
3801  WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity );
3802  virtual ~WildcardPattern() = default;
3803  virtual bool matches( std::string const& str ) const;
3804 
3805  private:
3806  std::string adjustCase( std::string const& str ) const;
3807  CaseSensitive::Choice m_caseSensitivity;
3808  WildcardPosition m_wildcard = NoWildcard;
3809  std::string m_pattern;
3810  };
3811 }
3812 
3813 // end catch_wildcard_pattern.h
3814 #include <string>
3815 #include <vector>
3816 #include <memory>
3817 
3818 namespace Catch {
3819 
3820  class TestSpec {
3821  struct Pattern {
3822  virtual ~Pattern();
3823  virtual bool matches( TestCaseInfo const& testCase ) const = 0;
3824  };
3825  using PatternPtr = std::shared_ptr<Pattern>;
3826 
3827  class NamePattern : public Pattern {
3828  public:
3829  NamePattern( std::string const& name );
3830  virtual ~NamePattern();
3831  virtual bool matches( TestCaseInfo const& testCase ) const override;
3832  private:
3833  WildcardPattern m_wildcardPattern;
3834  };
3835 
3836  class TagPattern : public Pattern {
3837  public:
3838  TagPattern( std::string const& tag );
3839  virtual ~TagPattern();
3840  virtual bool matches( TestCaseInfo const& testCase ) const override;
3841  private:
3842  std::string m_tag;
3843  };
3844 
3845  class ExcludedPattern : public Pattern {
3846  public:
3847  ExcludedPattern( PatternPtr const& underlyingPattern );
3848  virtual ~ExcludedPattern();
3849  virtual bool matches( TestCaseInfo const& testCase ) const override;
3850  private:
3851  PatternPtr m_underlyingPattern;
3852  };
3853 
3854  struct Filter {
3855  std::vector<PatternPtr> m_patterns;
3856 
3857  bool matches( TestCaseInfo const& testCase ) const;
3858  };
3859 
3860  public:
3861  bool hasFilters() const;
3862  bool matches( TestCaseInfo const& testCase ) const;
3863 
3864  private:
3865  std::vector<Filter> m_filters;
3866 
3867  friend class TestSpecParser;
3868  };
3869 }
3870 
3871 #ifdef __clang__
3872 #pragma clang diagnostic pop
3873 #endif
3874 
3875 // end catch_test_spec.h
3876 // start catch_interfaces_tag_alias_registry.h
3877 
3878 #include <string>
3879 
3880 namespace Catch {
3881 
3882  struct TagAlias;
3883 
3884  struct ITagAliasRegistry {
3885  virtual ~ITagAliasRegistry();
3886  // Nullptr if not present
3887  virtual TagAlias const* find( std::string const& alias ) const = 0;
3888  virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
3889 
3890  static ITagAliasRegistry const& get();
3891  };
3892 
3893 } // end namespace Catch
3894 
3895 // end catch_interfaces_tag_alias_registry.h
3896 namespace Catch {
3897 
3898  class TestSpecParser {
3899  enum Mode{ None, Name, QuotedName, Tag, EscapedName };
3900  Mode m_mode = None;
3901  bool m_exclusion = false;
3902  std::size_t m_start = std::string::npos, m_pos = 0;
3903  std::string m_arg;
3904  std::vector<std::size_t> m_escapeChars;
3905  TestSpec::Filter m_currentFilter;
3906  TestSpec m_testSpec;
3907  ITagAliasRegistry const* m_tagAliases = nullptr;
3908 
3909  public:
3910  TestSpecParser( ITagAliasRegistry const& tagAliases );
3911 
3912  TestSpecParser& parse( std::string const& arg );
3913  TestSpec testSpec();
3914 
3915  private:
3916  void visitChar( char c );
3917  void startNewMode( Mode mode, std::size_t start );
3918  void escape();
3919  std::string subString() const;
3920 
3921  template<typename T>
3922  void addPattern() {
3923  std::string token = subString();
3924  for( std::size_t i = 0; i < m_escapeChars.size(); ++i )
3925  token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 );
3926  m_escapeChars.clear();
3927  if( startsWith( token, "exclude:" ) ) {
3928  m_exclusion = true;
3929  token = token.substr( 8 );
3930  }
3931  if( !token.empty() ) {
3932  TestSpec::PatternPtr pattern = std::make_shared<T>( token );
3933  if( m_exclusion )
3934  pattern = std::make_shared<TestSpec::ExcludedPattern>( pattern );
3935  m_currentFilter.m_patterns.push_back( pattern );
3936  }
3937  m_exclusion = false;
3938  m_mode = None;
3939  }
3940 
3941  void addFilter();
3942  };
3943  TestSpec parseTestSpec( std::string const& arg );
3944 
3945 } // namespace Catch
3946 
3947 #ifdef __clang__
3948 #pragma clang diagnostic pop
3949 #endif
3950 
3951 // end catch_test_spec_parser.h
3952 // start catch_interfaces_config.h
3953 
3954 #include <iosfwd>
3955 #include <string>
3956 #include <vector>
3957 #include <memory>
3958 
3959 namespace Catch {
3960 
3961  enum class Verbosity {
3962  Quiet = 0,
3963  Normal,
3964  High
3965  };
3966 
3967  struct WarnAbout { enum What {
3968  Nothing = 0x00,
3969  NoAssertions = 0x01,
3970  NoTests = 0x02
3971  }; };
3972 
3973  struct ShowDurations { enum OrNot {
3974  DefaultForReporter,
3975  Always,
3976  Never
3977  }; };
3978  struct RunTests { enum InWhatOrder {
3979  InDeclarationOrder,
3980  InLexicographicalOrder,
3981  InRandomOrder
3982  }; };
3983  struct UseColour { enum YesOrNo {
3984  Auto,
3985  Yes,
3986  No
3987  }; };
3988  struct WaitForKeypress { enum When {
3989  Never,
3990  BeforeStart = 1,
3991  BeforeExit = 2,
3992  BeforeStartAndExit = BeforeStart | BeforeExit
3993  }; };
3994 
3995  class TestSpec;
3996 
3997  struct IConfig : NonCopyable {
3998 
3999  virtual ~IConfig();
4000 
4001  virtual bool allowThrows() const = 0;
4002  virtual std::ostream& stream() const = 0;
4003  virtual std::string name() const = 0;
4004  virtual bool includeSuccessfulResults() const = 0;
4005  virtual bool shouldDebugBreak() const = 0;
4006  virtual bool warnAboutMissingAssertions() const = 0;
4007  virtual bool warnAboutNoTests() const = 0;
4008  virtual int abortAfter() const = 0;
4009  virtual bool showInvisibles() const = 0;
4010  virtual ShowDurations::OrNot showDurations() const = 0;
4011  virtual TestSpec const& testSpec() const = 0;
4012  virtual bool hasTestFilters() const = 0;
4013  virtual RunTests::InWhatOrder runOrder() const = 0;
4014  virtual unsigned int rngSeed() const = 0;
4015  virtual int benchmarkResolutionMultiple() const = 0;
4016  virtual UseColour::YesOrNo useColour() const = 0;
4017  virtual std::vector<std::string> const& getSectionsToRun() const = 0;
4018  virtual Verbosity verbosity() const = 0;
4019  };
4020 
4021  using IConfigPtr = std::shared_ptr<IConfig const>;
4022 }
4023 
4024 // end catch_interfaces_config.h
4025 // Libstdc++ doesn't like incomplete classes for unique_ptr
4026 
4027 #include <memory>
4028 #include <vector>
4029 #include <string>
4030 
4031 #ifndef CATCH_CONFIG_CONSOLE_WIDTH
4032 #define CATCH_CONFIG_CONSOLE_WIDTH 80
4033 #endif
4034 
4035 namespace Catch {
4036 
4037  struct IStream;
4038 
4039  struct ConfigData {
4040  bool listTests = false;
4041  bool listTags = false;
4042  bool listReporters = false;
4043  bool listTestNamesOnly = false;
4044 
4045  bool showSuccessfulTests = false;
4046  bool shouldDebugBreak = false;
4047  bool noThrow = false;
4048  bool showHelp = false;
4049  bool showInvisibles = false;
4050  bool filenamesAsTags = false;
4051  bool libIdentify = false;
4052 
4053  int abortAfter = -1;
4054  unsigned int rngSeed = 0;
4055  int benchmarkResolutionMultiple = 100;
4056 
4057  Verbosity verbosity = Verbosity::Normal;
4058  WarnAbout::What warnings = WarnAbout::Nothing;
4059  ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;
4060  RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;
4061  UseColour::YesOrNo useColour = UseColour::Auto;
4062  WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
4063 
4064  std::string outputFilename;
4065  std::string name;
4066  std::string processName;
4067 #ifndef CATCH_CONFIG_DEFAULT_REPORTER
4068 #define CATCH_CONFIG_DEFAULT_REPORTER "console"
4069 #endif
4070  std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER;
4071 #undef CATCH_CONFIG_DEFAULT_REPORTER
4072 
4073  std::vector<std::string> testsOrTags;
4074  std::vector<std::string> sectionsToRun;
4075  };
4076 
4077  class Config : public IConfig {
4078  public:
4079 
4080  Config() = default;
4081  Config( ConfigData const& data );
4082  virtual ~Config() = default;
4083 
4084  std::string const& getFilename() const;
4085 
4086  bool listTests() const;
4087  bool listTestNamesOnly() const;
4088  bool listTags() const;
4089  bool listReporters() const;
4090 
4091  std::string getProcessName() const;
4092  std::string const& getReporterName() const;
4093 
4094  std::vector<std::string> const& getTestsOrTags() const;
4095  std::vector<std::string> const& getSectionsToRun() const override;
4096 
4097  virtual TestSpec const& testSpec() const override;
4098  bool hasTestFilters() const override;
4099 
4100  bool showHelp() const;
4101 
4102  // IConfig interface
4103  bool allowThrows() const override;
4104  std::ostream& stream() const override;
4105  std::string name() const override;
4106  bool includeSuccessfulResults() const override;
4107  bool warnAboutMissingAssertions() const override;
4108  bool warnAboutNoTests() const override;
4109  ShowDurations::OrNot showDurations() const override;
4110  RunTests::InWhatOrder runOrder() const override;
4111  unsigned int rngSeed() const override;
4112  int benchmarkResolutionMultiple() const override;
4113  UseColour::YesOrNo useColour() const override;
4114  bool shouldDebugBreak() const override;
4115  int abortAfter() const override;
4116  bool showInvisibles() const override;
4117  Verbosity verbosity() const override;
4118 
4119  private:
4120 
4121  IStream const* openStream();
4122  ConfigData m_data;
4123 
4124  std::unique_ptr<IStream const> m_stream;
4125  TestSpec m_testSpec;
4126  bool m_hasTestFilters = false;
4127  };
4128 
4129 } // end namespace Catch
4130 
4131 // end catch_config.hpp
4132 // start catch_assertionresult.h
4133 
4134 #include <string>
4135 
4136 namespace Catch {
4137 
4138  struct AssertionResultData
4139  {
4140  AssertionResultData() = delete;
4141 
4142  AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression );
4143 
4144  std::string message;
4145  mutable std::string reconstructedExpression;
4146  LazyExpression lazyExpression;
4147  ResultWas::OfType resultType;
4148 
4149  std::string reconstructExpression() const;
4150  };
4151 
4152  class AssertionResult {
4153  public:
4154  AssertionResult() = delete;
4155  AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
4156 
4157  bool isOk() const;
4158  bool succeeded() const;
4159  ResultWas::OfType getResultType() const;
4160  bool hasExpression() const;
4161  bool hasMessage() const;
4162  std::string getExpression() const;
4163  std::string getExpressionInMacro() const;
4164  bool hasExpandedExpression() const;
4165  std::string getExpandedExpression() const;
4166  std::string getMessage() const;
4167  SourceLineInfo getSourceInfo() const;
4168  StringRef getTestMacroName() const;
4169 
4170  //protected:
4171  AssertionInfo m_info;
4172  AssertionResultData m_resultData;
4173  };
4174 
4175 } // end namespace Catch
4176 
4177 // end catch_assertionresult.h
4178 // start catch_option.hpp
4179 
4180 namespace Catch {
4181 
4182  // An optional type
4183  template<typename T>
4184  class Option {
4185  public:
4186  Option() : nullableValue( nullptr ) {}
4187  Option( T const& _value )
4188  : nullableValue( new( storage ) T( _value ) )
4189  {}
4190  Option( Option const& _other )
4191  : nullableValue( _other ? new( storage ) T( *_other ) : nullptr )
4192  {}
4193 
4194  ~Option() {
4195  reset();
4196  }
4197 
4198  Option& operator= ( Option const& _other ) {
4199  if( &_other != this ) {
4200  reset();
4201  if( _other )
4202  nullableValue = new( storage ) T( *_other );
4203  }
4204  return *this;
4205  }
4206  Option& operator = ( T const& _value ) {
4207  reset();
4208  nullableValue = new( storage ) T( _value );
4209  return *this;
4210  }
4211 
4212  void reset() {
4213  if( nullableValue )
4214  nullableValue->~T();
4215  nullableValue = nullptr;
4216  }
4217 
4218  T& operator*() { return *nullableValue; }
4219  T const& operator*() const { return *nullableValue; }
4220  T* operator->() { return nullableValue; }
4221  const T* operator->() const { return nullableValue; }
4222 
4223  T valueOr( T const& defaultValue ) const {
4224  return nullableValue ? *nullableValue : defaultValue;
4225  }
4226 
4227  bool some() const { return nullableValue != nullptr; }
4228  bool none() const { return nullableValue == nullptr; }
4229 
4230  bool operator !() const { return nullableValue == nullptr; }
4231  explicit operator bool() const {
4232  return some();
4233  }
4234 
4235  private:
4236  T *nullableValue;
4237  alignas(alignof(T)) char storage[sizeof(T)];
4238  };
4239 
4240 } // end namespace Catch
4241 
4242 // end catch_option.hpp
4243 #include <string>
4244 #include <iosfwd>
4245 #include <map>
4246 #include <set>
4247 #include <memory>
4248 
4249 namespace Catch {
4250 
4251  struct ReporterConfig {
4252  explicit ReporterConfig( IConfigPtr const& _fullConfig );
4253 
4254  ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream );
4255 
4256  std::ostream& stream() const;
4257  IConfigPtr fullConfig() const;
4258 
4259  private:
4260  std::ostream* m_stream;
4261  IConfigPtr m_fullConfig;
4262  };
4263 
4264  struct ReporterPreferences {
4265  bool shouldRedirectStdOut = false;
4266  bool shouldReportAllAssertions = false;
4267  };
4268 
4269  template<typename T>
4270  struct LazyStat : Option<T> {
4271  LazyStat& operator=( T const& _value ) {
4272  Option<T>::operator=( _value );
4273  used = false;
4274  return *this;
4275  }
4276  void reset() {
4277  Option<T>::reset();
4278  used = false;
4279  }
4280  bool used = false;
4281  };
4282 
4283  struct TestRunInfo {
4284  TestRunInfo( std::string const& _name );
4285  std::string name;
4286  };
4287  struct GroupInfo {
4288  GroupInfo( std::string const& _name,
4289  std::size_t _groupIndex,
4290  std::size_t _groupsCount );
4291 
4292  std::string name;
4293  std::size_t groupIndex;
4294  std::size_t groupsCounts;
4295  };
4296 
4297  struct AssertionStats {
4298  AssertionStats( AssertionResult const& _assertionResult,
4299  std::vector<MessageInfo> const& _infoMessages,
4300  Totals const& _totals );
4301 
4302  AssertionStats( AssertionStats const& ) = default;
4303  AssertionStats( AssertionStats && ) = default;
4304  AssertionStats& operator = ( AssertionStats const& ) = default;
4305  AssertionStats& operator = ( AssertionStats && ) = default;
4306  virtual ~AssertionStats();
4307 
4308  AssertionResult assertionResult;
4309  std::vector<MessageInfo> infoMessages;
4310  Totals totals;
4311  };
4312 
4313  struct SectionStats {
4314  SectionStats( SectionInfo const& _sectionInfo,
4315  Counts const& _assertions,
4316  double _durationInSeconds,
4317  bool _missingAssertions );
4318  SectionStats( SectionStats const& ) = default;
4319  SectionStats( SectionStats && ) = default;
4320  SectionStats& operator = ( SectionStats const& ) = default;
4321  SectionStats& operator = ( SectionStats && ) = default;
4322  virtual ~SectionStats();
4323 
4324  SectionInfo sectionInfo;
4325  Counts assertions;
4326  double durationInSeconds;
4327  bool missingAssertions;
4328  };
4329 
4330  struct TestCaseStats {
4331  TestCaseStats( TestCaseInfo const& _testInfo,
4332  Totals const& _totals,
4333  std::string const& _stdOut,
4334  std::string const& _stdErr,
4335  bool _aborting );
4336 
4337  TestCaseStats( TestCaseStats const& ) = default;
4338  TestCaseStats( TestCaseStats && ) = default;
4339  TestCaseStats& operator = ( TestCaseStats const& ) = default;
4340  TestCaseStats& operator = ( TestCaseStats && ) = default;
4341  virtual ~TestCaseStats();
4342 
4343  TestCaseInfo testInfo;
4344  Totals totals;
4345  std::string stdOut;
4346  std::string stdErr;
4347  bool aborting;
4348  };
4349 
4350  struct TestGroupStats {
4351  TestGroupStats( GroupInfo const& _groupInfo,
4352  Totals const& _totals,
4353  bool _aborting );
4354  TestGroupStats( GroupInfo const& _groupInfo );
4355 
4356  TestGroupStats( TestGroupStats const& ) = default;
4357  TestGroupStats( TestGroupStats && ) = default;
4358  TestGroupStats& operator = ( TestGroupStats const& ) = default;
4359  TestGroupStats& operator = ( TestGroupStats && ) = default;
4360  virtual ~TestGroupStats();
4361 
4362  GroupInfo groupInfo;
4363  Totals totals;
4364  bool aborting;
4365  };
4366 
4367  struct TestRunStats {
4368  TestRunStats( TestRunInfo const& _runInfo,
4369  Totals const& _totals,
4370  bool _aborting );
4371 
4372  TestRunStats( TestRunStats const& ) = default;
4373  TestRunStats( TestRunStats && ) = default;
4374  TestRunStats& operator = ( TestRunStats const& ) = default;
4375  TestRunStats& operator = ( TestRunStats && ) = default;
4376  virtual ~TestRunStats();
4377 
4378  TestRunInfo runInfo;
4379  Totals totals;
4380  bool aborting;
4381  };
4382 
4383  struct BenchmarkInfo {
4384  std::string name;
4385  };
4386  struct BenchmarkStats {
4387  BenchmarkInfo info;
4388  std::size_t iterations;
4389  uint64_t elapsedTimeInNanoseconds;
4390  };
4391 
4392  struct IStreamingReporter {
4393  virtual ~IStreamingReporter() = default;
4394 
4395  // Implementing class must also provide the following static methods:
4396  // static std::string getDescription();
4397  // static std::set<Verbosity> getSupportedVerbosities()
4398 
4399  virtual ReporterPreferences getPreferences() const = 0;
4400 
4401  virtual void noMatchingTestCases( std::string const& spec ) = 0;
4402 
4403  virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
4404  virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
4405 
4406  virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
4407  virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
4408 
4409  // *** experimental ***
4410  virtual void benchmarkStarting( BenchmarkInfo const& ) {}
4411 
4412  virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
4413 
4414  // The return value indicates if the messages buffer should be cleared:
4415  virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
4416 
4417  // *** experimental ***
4418  virtual void benchmarkEnded( BenchmarkStats const& ) {}
4419 
4420  virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
4421  virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
4422  virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
4423  virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
4424 
4425  virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
4426 
4427  // Default empty implementation provided
4428  virtual void fatalErrorEncountered( StringRef name );
4429 
4430  virtual bool isMulti() const;
4431  };
4432  using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>;
4433 
4434  struct IReporterFactory {
4435  virtual ~IReporterFactory();
4436  virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0;
4437  virtual std::string getDescription() const = 0;
4438  };
4439  using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
4440 
4441  struct IReporterRegistry {
4442  using FactoryMap = std::map<std::string, IReporterFactoryPtr>;
4443  using Listeners = std::vector<IReporterFactoryPtr>;
4444 
4445  virtual ~IReporterRegistry();
4446  virtual IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const = 0;
4447  virtual FactoryMap const& getFactories() const = 0;
4448  virtual Listeners const& getListeners() const = 0;
4449  };
4450 
4451 } // end namespace Catch
4452 
4453 // end catch_interfaces_reporter.h
4454 #include <algorithm>
4455 #include <cstring>
4456 #include <cfloat>
4457 #include <cstdio>
4458 #include <cassert>
4459 #include <memory>
4460 #include <ostream>
4461 
4462 namespace Catch {
4463  void prepareExpandedExpression(AssertionResult& result);
4464 
4465  // Returns double formatted as %.3f (format expected on output)
4466  std::string getFormattedDuration( double duration );
4467 
4468  template<typename DerivedT>
4469  struct StreamingReporterBase : IStreamingReporter {
4470 
4471  StreamingReporterBase( ReporterConfig const& _config )
4472  : m_config( _config.fullConfig() ),
4473  stream( _config.stream() )
4474  {
4475  m_reporterPrefs.shouldRedirectStdOut = false;
4476  if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
4477  CATCH_ERROR( "Verbosity level not supported by this reporter" );
4478  }
4479 
4480  ReporterPreferences getPreferences() const override {
4481  return m_reporterPrefs;
4482  }
4483 
4484  static std::set<Verbosity> getSupportedVerbosities() {
4485  return { Verbosity::Normal };
4486  }
4487 
4488  ~StreamingReporterBase() override = default;
4489 
4490  void noMatchingTestCases(std::string const&) override {}
4491 
4492  void testRunStarting(TestRunInfo const& _testRunInfo) override {
4493  currentTestRunInfo = _testRunInfo;
4494  }
4495  void testGroupStarting(GroupInfo const& _groupInfo) override {
4496  currentGroupInfo = _groupInfo;
4497  }
4498 
4499  void testCaseStarting(TestCaseInfo const& _testInfo) override {
4500  currentTestCaseInfo = _testInfo;
4501  }
4502  void sectionStarting(SectionInfo const& _sectionInfo) override {
4503  m_sectionStack.push_back(_sectionInfo);
4504  }
4505 
4506  void sectionEnded(SectionStats const& /* _sectionStats */) override {
4507  m_sectionStack.pop_back();
4508  }
4509  void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {
4510  currentTestCaseInfo.reset();
4511  }
4512  void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override {
4513  currentGroupInfo.reset();
4514  }
4515  void testRunEnded(TestRunStats const& /* _testRunStats */) override {
4516  currentTestCaseInfo.reset();
4517  currentGroupInfo.reset();
4518  currentTestRunInfo.reset();
4519  }
4520 
4521  void skipTest(TestCaseInfo const&) override {
4522  // Don't do anything with this by default.
4523  // It can optionally be overridden in the derived class.
4524  }
4525 
4526  IConfigPtr m_config;
4527  std::ostream& stream;
4528 
4529  LazyStat<TestRunInfo> currentTestRunInfo;
4530  LazyStat<GroupInfo> currentGroupInfo;
4531  LazyStat<TestCaseInfo> currentTestCaseInfo;
4532 
4533  std::vector<SectionInfo> m_sectionStack;
4534  ReporterPreferences m_reporterPrefs;
4535  };
4536 
4537  template<typename DerivedT>
4538  struct CumulativeReporterBase : IStreamingReporter {
4539  template<typename T, typename ChildNodeT>
4540  struct Node {
4541  explicit Node( T const& _value ) : value( _value ) {}
4542  virtual ~Node() {}
4543 
4544  using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;
4545  T value;
4546  ChildNodes children;
4547  };
4548  struct SectionNode {
4549  explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}
4550  virtual ~SectionNode() = default;
4551 
4552  bool operator == (SectionNode const& other) const {
4553  return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
4554  }
4555  bool operator == (std::shared_ptr<SectionNode> const& other) const {
4556  return operator==(*other);
4557  }
4558 
4559  SectionStats stats;
4560  using ChildSections = std::vector<std::shared_ptr<SectionNode>>;
4561  using Assertions = std::vector<AssertionStats>;
4562  ChildSections childSections;
4563  Assertions assertions;
4564  std::string stdOut;
4565  std::string stdErr;
4566  };
4567 
4568  struct BySectionInfo {
4569  BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
4570  BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
4571  bool operator() (std::shared_ptr<SectionNode> const& node) const {
4572  return ((node->stats.sectionInfo.name == m_other.name) &&
4573  (node->stats.sectionInfo.lineInfo == m_other.lineInfo));
4574  }
4575  void operator=(BySectionInfo const&) = delete;
4576 
4577  private:
4578  SectionInfo const& m_other;
4579  };
4580 
4581  using TestCaseNode = Node<TestCaseStats, SectionNode>;
4582  using TestGroupNode = Node<TestGroupStats, TestCaseNode>;
4583  using TestRunNode = Node<TestRunStats, TestGroupNode>;
4584 
4585  CumulativeReporterBase( ReporterConfig const& _config )
4586  : m_config( _config.fullConfig() ),
4587  stream( _config.stream() )
4588  {
4589  m_reporterPrefs.shouldRedirectStdOut = false;
4590  if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
4591  CATCH_ERROR( "Verbosity level not supported by this reporter" );
4592  }
4593  ~CumulativeReporterBase() override = default;
4594 
4595  ReporterPreferences getPreferences() const override {
4596  return m_reporterPrefs;
4597  }
4598 
4599  static std::set<Verbosity> getSupportedVerbosities() {
4600  return { Verbosity::Normal };
4601  }
4602 
4603  void testRunStarting( TestRunInfo const& ) override {}
4604  void testGroupStarting( GroupInfo const& ) override {}
4605 
4606  void testCaseStarting( TestCaseInfo const& ) override {}
4607 
4608  void sectionStarting( SectionInfo const& sectionInfo ) override {
4609  SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
4610  std::shared_ptr<SectionNode> node;
4611  if( m_sectionStack.empty() ) {
4612  if( !m_rootSection )
4613  m_rootSection = std::make_shared<SectionNode>( incompleteStats );
4614  node = m_rootSection;
4615  }
4616  else {
4617  SectionNode& parentNode = *m_sectionStack.back();
4618  auto it =
4619  std::find_if( parentNode.childSections.begin(),
4620  parentNode.childSections.end(),
4621  BySectionInfo( sectionInfo ) );
4622  if( it == parentNode.childSections.end() ) {
4623  node = std::make_shared<SectionNode>( incompleteStats );
4624  parentNode.childSections.push_back( node );
4625  }
4626  else
4627  node = *it;
4628  }
4629  m_sectionStack.push_back( node );
4630  m_deepestSection = std::move(node);
4631  }
4632 
4633  void assertionStarting(AssertionInfo const&) override {}
4634 
4635  bool assertionEnded(AssertionStats const& assertionStats) override {
4636  assert(!m_sectionStack.empty());
4637  // AssertionResult holds a pointer to a temporary DecomposedExpression,
4638  // which getExpandedExpression() calls to build the expression string.
4639  // Our section stack copy of the assertionResult will likely outlive the
4640  // temporary, so it must be expanded or discarded now to avoid calling
4641  // a destroyed object later.
4642  prepareExpandedExpression(const_cast<AssertionResult&>( assertionStats.assertionResult ) );
4643  SectionNode& sectionNode = *m_sectionStack.back();
4644  sectionNode.assertions.push_back(assertionStats);
4645  return true;
4646  }
4647  void sectionEnded(SectionStats const& sectionStats) override {
4648  assert(!m_sectionStack.empty());
4649  SectionNode& node = *m_sectionStack.back();
4650  node.stats = sectionStats;
4651  m_sectionStack.pop_back();
4652  }
4653  void testCaseEnded(TestCaseStats const& testCaseStats) override {
4654  auto node = std::make_shared<TestCaseNode>(testCaseStats);
4655  assert(m_sectionStack.size() == 0);
4656  node->children.push_back(m_rootSection);
4657  m_testCases.push_back(node);
4658  m_rootSection.reset();
4659 
4660  assert(m_deepestSection);
4661  m_deepestSection->stdOut = testCaseStats.stdOut;
4662  m_deepestSection->stdErr = testCaseStats.stdErr;
4663  }
4664  void testGroupEnded(TestGroupStats const& testGroupStats) override {
4665  auto node = std::make_shared<TestGroupNode>(testGroupStats);
4666  node->children.swap(m_testCases);
4667  m_testGroups.push_back(node);
4668  }
4669  void testRunEnded(TestRunStats const& testRunStats) override {
4670  auto node = std::make_shared<TestRunNode>(testRunStats);
4671  node->children.swap(m_testGroups);
4672  m_testRuns.push_back(node);
4673  testRunEndedCumulative();
4674  }
4675  virtual void testRunEndedCumulative() = 0;
4676 
4677  void skipTest(TestCaseInfo const&) override {}
4678 
4679  IConfigPtr m_config;
4680  std::ostream& stream;
4681  std::vector<AssertionStats> m_assertions;
4682  std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;
4683  std::vector<std::shared_ptr<TestCaseNode>> m_testCases;
4684  std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;
4685 
4686  std::vector<std::shared_ptr<TestRunNode>> m_testRuns;
4687 
4688  std::shared_ptr<SectionNode> m_rootSection;
4689  std::shared_ptr<SectionNode> m_deepestSection;
4690  std::vector<std::shared_ptr<SectionNode>> m_sectionStack;
4691  ReporterPreferences m_reporterPrefs;
4692  };
4693 
4694  template<char C>
4695  char const* getLineOfChars() {
4696  static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
4697  if( !*line ) {
4698  std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
4699  line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
4700  }
4701  return line;
4702  }
4703 
4704  struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> {
4705  TestEventListenerBase( ReporterConfig const& _config );
4706 
4707  static std::set<Verbosity> getSupportedVerbosities();
4708 
4709  void assertionStarting(AssertionInfo const&) override;
4710  bool assertionEnded(AssertionStats const&) override;
4711  };
4712 
4713 } // end namespace Catch
4714 
4715 // end catch_reporter_bases.hpp
4716 // start catch_console_colour.h
4717 
4718 namespace Catch {
4719 
4720  struct Colour {
4721  enum Code {
4722  None = 0,
4723 
4724  White,
4725  Red,
4726  Green,
4727  Blue,
4728  Cyan,
4729  Yellow,
4730  Grey,
4731 
4732  Bright = 0x10,
4733 
4734  BrightRed = Bright | Red,
4735  BrightGreen = Bright | Green,
4736  LightGrey = Bright | Grey,
4737  BrightWhite = Bright | White,
4738  BrightYellow = Bright | Yellow,
4739 
4740  // By intention
4741  FileName = LightGrey,
4742  Warning = BrightYellow,
4743  ResultError = BrightRed,
4744  ResultSuccess = BrightGreen,
4745  ResultExpectedFailure = Warning,
4746 
4747  Error = BrightRed,
4748  Success = Green,
4749 
4750  OriginalExpression = Cyan,
4751  ReconstructedExpression = BrightYellow,
4752 
4753  SecondaryText = LightGrey,
4754  Headers = White
4755  };
4756 
4757  // Use constructed object for RAII guard
4758  Colour( Code _colourCode );
4759  Colour( Colour&& other ) noexcept;
4760  Colour& operator=( Colour&& other ) noexcept;
4761  ~Colour();
4762 
4763  // Use static method for one-shot changes
4764  static void use( Code _colourCode );
4765 
4766  private:
4767  bool m_moved = false;
4768  };
4769 
4770  std::ostream& operator << ( std::ostream& os, Colour const& );
4771 
4772 } // end namespace Catch
4773 
4774 // end catch_console_colour.h
4775 // start catch_reporter_registrars.hpp
4776 
4777 
4778 namespace Catch {
4779 
4780  template<typename T>
4781  class ReporterRegistrar {
4782 
4783  class ReporterFactory : public IReporterFactory {
4784 
4785  virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override {
4786  return std::unique_ptr<T>( new T( config ) );
4787  }
4788 
4789  virtual std::string getDescription() const override {
4790  return T::getDescription();
4791  }
4792  };
4793 
4794  public:
4795 
4796  explicit ReporterRegistrar( std::string const& name ) {
4797  getMutableRegistryHub().registerReporter( name, std::make_shared<ReporterFactory>() );
4798  }
4799  };
4800 
4801  template<typename T>
4802  class ListenerRegistrar {
4803 
4804  class ListenerFactory : public IReporterFactory {
4805 
4806  virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override {
4807  return std::unique_ptr<T>( new T( config ) );
4808  }
4809  virtual std::string getDescription() const override {
4810  return std::string();
4811  }
4812  };
4813 
4814  public:
4815 
4816  ListenerRegistrar() {
4817  getMutableRegistryHub().registerListener( std::make_shared<ListenerFactory>() );
4818  }
4819  };
4820 }
4821 
4822 #if !defined(CATCH_CONFIG_DISABLE)
4823 
4824 #define CATCH_REGISTER_REPORTER( name, reporterType ) \
4825  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
4826  namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \
4827  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
4828 
4829 #define CATCH_REGISTER_LISTENER( listenerType ) \
4830  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
4831  namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \
4832  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
4833 #else // CATCH_CONFIG_DISABLE
4834 
4835 #define CATCH_REGISTER_REPORTER(name, reporterType)
4836 #define CATCH_REGISTER_LISTENER(listenerType)
4837 
4838 #endif // CATCH_CONFIG_DISABLE
4839 
4840 // end catch_reporter_registrars.hpp
4841 // Allow users to base their work off existing reporters
4842 // start catch_reporter_compact.h
4843 
4844 namespace Catch {
4845 
4846  struct CompactReporter : StreamingReporterBase<CompactReporter> {
4847 
4848  using StreamingReporterBase::StreamingReporterBase;
4849 
4850  ~CompactReporter() override;
4851 
4852  static std::string getDescription();
4853 
4854  ReporterPreferences getPreferences() const override;
4855 
4856  void noMatchingTestCases(std::string const& spec) override;
4857 
4858  void assertionStarting(AssertionInfo const&) override;
4859 
4860  bool assertionEnded(AssertionStats const& _assertionStats) override;
4861 
4862  void sectionEnded(SectionStats const& _sectionStats) override;
4863 
4864  void testRunEnded(TestRunStats const& _testRunStats) override;
4865 
4866  };
4867 
4868 } // end namespace Catch
4869 
4870 // end catch_reporter_compact.h
4871 // start catch_reporter_console.h
4872 
4873 #if defined(_MSC_VER)
4874 #pragma warning(push)
4875 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
4876  // Note that 4062 (not all labels are handled
4877  // and default is missing) is enabled
4878 #endif
4879 
4880 namespace Catch {
4881  // Fwd decls
4882  struct SummaryColumn;
4883  class TablePrinter;
4884 
4885  struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> {
4886  std::unique_ptr<TablePrinter> m_tablePrinter;
4887 
4888  ConsoleReporter(ReporterConfig const& config);
4889  ~ConsoleReporter() override;
4890  static std::string getDescription();
4891 
4892  void noMatchingTestCases(std::string const& spec) override;
4893 
4894  void assertionStarting(AssertionInfo const&) override;
4895 
4896  bool assertionEnded(AssertionStats const& _assertionStats) override;
4897 
4898  void sectionStarting(SectionInfo const& _sectionInfo) override;
4899  void sectionEnded(SectionStats const& _sectionStats) override;
4900 
4901  void benchmarkStarting(BenchmarkInfo const& info) override;
4902  void benchmarkEnded(BenchmarkStats const& stats) override;
4903 
4904  void testCaseEnded(TestCaseStats const& _testCaseStats) override;
4905  void testGroupEnded(TestGroupStats const& _testGroupStats) override;
4906  void testRunEnded(TestRunStats const& _testRunStats) override;
4907 
4908  private:
4909 
4910  void lazyPrint();
4911 
4912  void lazyPrintWithoutClosingBenchmarkTable();
4913  void lazyPrintRunInfo();
4914  void lazyPrintGroupInfo();
4915  void printTestCaseAndSectionHeader();
4916 
4917  void printClosedHeader(std::string const& _name);
4918  void printOpenHeader(std::string const& _name);
4919 
4920  // if string has a : in first line will set indent to follow it on
4921  // subsequent lines
4922  void printHeaderString(std::string const& _string, std::size_t indent = 0);
4923 
4924  void printTotals(Totals const& totals);
4925  void printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row);
4926 
4927  void printTotalsDivider(Totals const& totals);
4928  void printSummaryDivider();
4929 
4930  private:
4931  bool m_headerPrinted = false;
4932  };
4933 
4934 } // end namespace Catch
4935 
4936 #if defined(_MSC_VER)
4937 #pragma warning(pop)
4938 #endif
4939 
4940 // end catch_reporter_console.h
4941 // start catch_reporter_junit.h
4942 
4943 // start catch_xmlwriter.h
4944 
4945 #include <vector>
4946 
4947 namespace Catch {
4948 
4949  class XmlEncode {
4950  public:
4951  enum ForWhat { ForTextNodes, ForAttributes };
4952 
4953  XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes );
4954 
4955  void encodeTo( std::ostream& os ) const;
4956 
4957  friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );
4958 
4959  private:
4960  std::string m_str;
4961  ForWhat m_forWhat;
4962  };
4963 
4964  class XmlWriter {
4965  public:
4966 
4967  class ScopedElement {
4968  public:
4969  ScopedElement( XmlWriter* writer );
4970 
4971  ScopedElement( ScopedElement&& other ) noexcept;
4972  ScopedElement& operator=( ScopedElement&& other ) noexcept;
4973 
4974  ~ScopedElement();
4975 
4976  ScopedElement& writeText( std::string const& text, bool indent = true );
4977 
4978  template<typename T>
4979  ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
4980  m_writer->writeAttribute( name, attribute );
4981  return *this;
4982  }
4983 
4984  private:
4985  mutable XmlWriter* m_writer = nullptr;
4986  };
4987 
4988  XmlWriter( std::ostream& os = Catch::cout() );
4989  ~XmlWriter();
4990 
4991  XmlWriter( XmlWriter const& ) = delete;
4992  XmlWriter& operator=( XmlWriter const& ) = delete;
4993 
4994  XmlWriter& startElement( std::string const& name );
4995 
4996  ScopedElement scopedElement( std::string const& name );
4997 
4998  XmlWriter& endElement();
4999 
5000  XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );
5001 
5002  XmlWriter& writeAttribute( std::string const& name, bool attribute );
5003 
5004  template<typename T>
5005  XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
5006  ReusableStringStream rss;
5007  rss << attribute;
5008  return writeAttribute( name, rss.str() );
5009  }
5010 
5011  XmlWriter& writeText( std::string const& text, bool indent = true );
5012 
5013  XmlWriter& writeComment( std::string const& text );
5014 
5015  void writeStylesheetRef( std::string const& url );
5016 
5017  XmlWriter& writeBlankLine();
5018 
5019  void ensureTagClosed();
5020 
5021  private:
5022 
5023  void writeDeclaration();
5024 
5025  void newlineIfNecessary();
5026 
5027  bool m_tagIsOpen = false;
5028  bool m_needsNewline = false;
5029  std::vector<std::string> m_tags;
5030  std::string m_indent;
5031  std::ostream& m_os;
5032  };
5033 
5034 }
5035 
5036 // end catch_xmlwriter.h
5037 namespace Catch {
5038 
5039  class JunitReporter : public CumulativeReporterBase<JunitReporter> {
5040  public:
5041  JunitReporter(ReporterConfig const& _config);
5042 
5043  ~JunitReporter() override;
5044 
5045  static std::string getDescription();
5046 
5047  void noMatchingTestCases(std::string const& /*spec*/) override;
5048 
5049  void testRunStarting(TestRunInfo const& runInfo) override;
5050 
5051  void testGroupStarting(GroupInfo const& groupInfo) override;
5052 
5053  void testCaseStarting(TestCaseInfo const& testCaseInfo) override;
5054  bool assertionEnded(AssertionStats const& assertionStats) override;
5055 
5056  void testCaseEnded(TestCaseStats const& testCaseStats) override;
5057 
5058  void testGroupEnded(TestGroupStats const& testGroupStats) override;
5059 
5060  void testRunEndedCumulative() override;
5061 
5062  void writeGroup(TestGroupNode const& groupNode, double suiteTime);
5063 
5064  void writeTestCase(TestCaseNode const& testCaseNode);
5065 
5066  void writeSection(std::string const& className,
5067  std::string const& rootName,
5068  SectionNode const& sectionNode);
5069 
5070  void writeAssertions(SectionNode const& sectionNode);
5071  void writeAssertion(AssertionStats const& stats);
5072 
5073  XmlWriter xml;
5074  Timer suiteTimer;
5075  std::string stdOutForSuite;
5076  std::string stdErrForSuite;
5077  unsigned int unexpectedExceptions = 0;
5078  bool m_okToFail = false;
5079  };
5080 
5081 } // end namespace Catch
5082 
5083 // end catch_reporter_junit.h
5084 // start catch_reporter_xml.h
5085 
5086 namespace Catch {
5087  class XmlReporter : public StreamingReporterBase<XmlReporter> {
5088  public:
5089  XmlReporter(ReporterConfig const& _config);
5090 
5091  ~XmlReporter() override;
5092 
5093  static std::string getDescription();
5094 
5095  virtual std::string getStylesheetRef() const;
5096 
5097  void writeSourceInfo(SourceLineInfo const& sourceInfo);
5098 
5099  public: // StreamingReporterBase
5100 
5101  void noMatchingTestCases(std::string const& s) override;
5102 
5103  void testRunStarting(TestRunInfo const& testInfo) override;
5104 
5105  void testGroupStarting(GroupInfo const& groupInfo) override;
5106 
5107  void testCaseStarting(TestCaseInfo const& testInfo) override;
5108 
5109  void sectionStarting(SectionInfo const& sectionInfo) override;
5110 
5111  void assertionStarting(AssertionInfo const&) override;
5112 
5113  bool assertionEnded(AssertionStats const& assertionStats) override;
5114 
5115  void sectionEnded(SectionStats const& sectionStats) override;
5116 
5117  void testCaseEnded(TestCaseStats const& testCaseStats) override;
5118 
5119  void testGroupEnded(TestGroupStats const& testGroupStats) override;
5120 
5121  void testRunEnded(TestRunStats const& testRunStats) override;
5122 
5123  private:
5124  Timer m_testCaseTimer;
5125  XmlWriter m_xml;
5126  int m_sectionDepth = 0;
5127  };
5128 
5129 } // end namespace Catch
5130 
5131 // end catch_reporter_xml.h
5132 
5133 // end catch_external_interfaces.h
5134 #endif
5135 
5136 #endif // ! CATCH_CONFIG_IMPL_ONLY
5137 
5138 #ifdef CATCH_IMPL
5139 // start catch_impl.hpp
5140 
5141 #ifdef __clang__
5142 #pragma clang diagnostic push
5143 #pragma clang diagnostic ignored "-Wweak-vtables"
5144 #endif
5145 
5146 // Keep these here for external reporters
5147 // start catch_test_case_tracker.h
5148 
5149 #include <string>
5150 #include <vector>
5151 #include <memory>
5152 
5153 namespace Catch {
5154 namespace TestCaseTracking {
5155 
5156  struct NameAndLocation {
5157  std::string name;
5158  SourceLineInfo location;
5159 
5160  NameAndLocation( std::string const& _name, SourceLineInfo const& _location );
5161  };
5162 
5163  struct ITracker;
5164 
5165  using ITrackerPtr = std::shared_ptr<ITracker>;
5166 
5167  struct ITracker {
5168  virtual ~ITracker();
5169 
5170  // static queries
5171  virtual NameAndLocation const& nameAndLocation() const = 0;
5172 
5173  // dynamic queries
5174  virtual bool isComplete() const = 0; // Successfully completed or failed
5175  virtual bool isSuccessfullyCompleted() const = 0;
5176  virtual bool isOpen() const = 0; // Started but not complete
5177  virtual bool hasChildren() const = 0;
5178 
5179  virtual ITracker& parent() = 0;
5180 
5181  // actions
5182  virtual void close() = 0; // Successfully complete
5183  virtual void fail() = 0;
5184  virtual void markAsNeedingAnotherRun() = 0;
5185 
5186  virtual void addChild( ITrackerPtr const& child ) = 0;
5187  virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0;
5188  virtual void openChild() = 0;
5189 
5190  // Debug/ checking
5191  virtual bool isSectionTracker() const = 0;
5192  virtual bool isIndexTracker() const = 0;
5193  };
5194 
5195  class TrackerContext {
5196 
5197  enum RunState {
5198  NotStarted,
5199  Executing,
5200  CompletedCycle
5201  };
5202 
5203  ITrackerPtr m_rootTracker;
5204  ITracker* m_currentTracker = nullptr;
5205  RunState m_runState = NotStarted;
5206 
5207  public:
5208 
5209  static TrackerContext& instance();
5210 
5211  ITracker& startRun();
5212  void endRun();
5213 
5214  void startCycle();
5215  void completeCycle();
5216 
5217  bool completedCycle() const;
5218  ITracker& currentTracker();
5219  void setCurrentTracker( ITracker* tracker );
5220  };
5221 
5222  class TrackerBase : public ITracker {
5223  protected:
5224  enum CycleState {
5225  NotStarted,
5226  Executing,
5227  ExecutingChildren,
5228  NeedsAnotherRun,
5229  CompletedSuccessfully,
5230  Failed
5231  };
5232 
5233  using Children = std::vector<ITrackerPtr>;
5234  NameAndLocation m_nameAndLocation;
5235  TrackerContext& m_ctx;
5236  ITracker* m_parent;
5237  Children m_children;
5238  CycleState m_runState = NotStarted;
5239 
5240  public:
5241  TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
5242 
5243  NameAndLocation const& nameAndLocation() const override;
5244  bool isComplete() const override;
5245  bool isSuccessfullyCompleted() const override;
5246  bool isOpen() const override;
5247  bool hasChildren() const override;
5248 
5249  void addChild( ITrackerPtr const& child ) override;
5250 
5251  ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override;
5252  ITracker& parent() override;
5253 
5254  void openChild() override;
5255 
5256  bool isSectionTracker() const override;
5257  bool isIndexTracker() const override;
5258 
5259  void open();
5260 
5261  void close() override;
5262  void fail() override;
5263  void markAsNeedingAnotherRun() override;
5264 
5265  private:
5266  void moveToParent();
5267  void moveToThis();
5268  };
5269 
5270  class SectionTracker : public TrackerBase {
5271  std::vector<std::string> m_filters;
5272  public:
5273  SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
5274 
5275  bool isSectionTracker() const override;
5276 
5277  static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation );
5278 
5279  void tryOpen();
5280 
5281  void addInitialFilters( std::vector<std::string> const& filters );
5282  void addNextFilters( std::vector<std::string> const& filters );
5283  };
5284 
5285  class IndexTracker : public TrackerBase {
5286  int m_size;
5287  int m_index = -1;
5288  public:
5289  IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size );
5290 
5291  bool isIndexTracker() const override;
5292  void close() override;
5293 
5294  static IndexTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size );
5295 
5296  int index() const;
5297 
5298  void moveNext();
5299  };
5300 
5301 } // namespace TestCaseTracking
5302 
5303 using TestCaseTracking::ITracker;
5304 using TestCaseTracking::TrackerContext;
5305 using TestCaseTracking::SectionTracker;
5306 using TestCaseTracking::IndexTracker;
5307 
5308 } // namespace Catch
5309 
5310 // end catch_test_case_tracker.h
5311 
5312 // start catch_leak_detector.h
5313 
5314 namespace Catch {
5315 
5316  struct LeakDetector {
5317  LeakDetector();
5318  ~LeakDetector();
5319  };
5320 
5321 }
5322 // end catch_leak_detector.h
5323 // Cpp files will be included in the single-header file here
5324 // start catch_approx.cpp
5325 
5326 #include <cmath>
5327 #include <limits>
5328 
5329 namespace {
5330 
5331 // Performs equivalent check of std::fabs(lhs - rhs) <= margin
5332 // But without the subtraction to allow for INFINITY in comparison
5333 bool marginComparison(double lhs, double rhs, double margin) {
5334  return (lhs + margin >= rhs) && (rhs + margin >= lhs);
5335 }
5336 
5337 }
5338 
5339 namespace Catch {
5340 namespace Detail {
5341 
5342  Approx::Approx ( double value )
5343  : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
5344  m_margin( 0.0 ),
5345  m_scale( 0.0 ),
5346  m_value( value )
5347  {}
5348 
5349  Approx Approx::custom() {
5350  return Approx( 0 );
5351  }
5352 
5353  Approx Approx::operator-() const {
5354  auto temp(*this);
5355  temp.m_value = -temp.m_value;
5356  return temp;
5357  }
5358 
5359  std::string Approx::toString() const {
5360  ReusableStringStream rss;
5361  rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
5362  return rss.str();
5363  }
5364 
5365  bool Approx::equalityComparisonImpl(const double other) const {
5366  // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
5367  // Thanks to Richard Harris for his help refining the scaled margin value
5368  return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
5369  }
5370 
5371  void Approx::setMargin(double margin) {
5372  CATCH_ENFORCE(margin >= 0,
5373  "Invalid Approx::margin: " << margin << '.'
5374  << " Approx::Margin has to be non-negative.");
5375  m_margin = margin;
5376  }
5377 
5378  void Approx::setEpsilon(double epsilon) {
5379  CATCH_ENFORCE(epsilon >= 0 && epsilon <= 1.0,
5380  "Invalid Approx::epsilon: " << epsilon << '.'
5381  << " Approx::epsilon has to be in [0, 1]");
5382  m_epsilon = epsilon;
5383  }
5384 
5385 } // end namespace Detail
5386 
5387 namespace literals {
5388  Detail::Approx operator "" _a(long double val) {
5389  return Detail::Approx(val);
5390  }
5391  Detail::Approx operator "" _a(unsigned long long val) {
5392  return Detail::Approx(val);
5393  }
5394 } // end namespace literals
5395 
5396 std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
5397  return value.toString();
5398 }
5399 
5400 } // end namespace Catch
5401 // end catch_approx.cpp
5402 // start catch_assertionhandler.cpp
5403 
5404 // start catch_context.h
5405 
5406 #include <memory>
5407 
5408 namespace Catch {
5409 
5410  struct IResultCapture;
5411  struct IRunner;
5412  struct IConfig;
5413  struct IMutableContext;
5414 
5415  using IConfigPtr = std::shared_ptr<IConfig const>;
5416 
5417  struct IContext
5418  {
5419  virtual ~IContext();
5420 
5421  virtual IResultCapture* getResultCapture() = 0;
5422  virtual IRunner* getRunner() = 0;
5423  virtual IConfigPtr const& getConfig() const = 0;
5424  };
5425 
5426  struct IMutableContext : IContext
5427  {
5428  virtual ~IMutableContext();
5429  virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
5430  virtual void setRunner( IRunner* runner ) = 0;
5431  virtual void setConfig( IConfigPtr const& config ) = 0;
5432 
5433  private:
5434  static IMutableContext *currentContext;
5435  friend IMutableContext& getCurrentMutableContext();
5436  friend void cleanUpContext();
5437  static void createContext();
5438  };
5439 
5440  inline IMutableContext& getCurrentMutableContext()
5441  {
5442  if( !IMutableContext::currentContext )
5443  IMutableContext::createContext();
5444  return *IMutableContext::currentContext;
5445  }
5446 
5447  inline IContext& getCurrentContext()
5448  {
5449  return getCurrentMutableContext();
5450  }
5451 
5452  void cleanUpContext();
5453 }
5454 
5455 // end catch_context.h
5456 // start catch_debugger.h
5457 
5458 namespace Catch {
5459  bool isDebuggerActive();
5460 }
5461 
5462 #ifdef CATCH_PLATFORM_MAC
5463 
5464  #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
5465 
5466 #elif defined(CATCH_PLATFORM_LINUX)
5467  // If we can use inline assembler, do it because this allows us to break
5468  // directly at the location of the failing check instead of breaking inside
5469  // raise() called from it, i.e. one stack frame below.
5470  #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
5471  #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
5472  #else // Fall back to the generic way.
5473  #include <signal.h>
5474 
5475  #define CATCH_TRAP() raise(SIGTRAP)
5476  #endif
5477 #elif defined(_MSC_VER)
5478  #define CATCH_TRAP() __debugbreak()
5479 #elif defined(__MINGW32__)
5480  extern "C" __declspec(dllimport) void __stdcall DebugBreak();
5481  #define CATCH_TRAP() DebugBreak()
5482 #endif
5483 
5484 #ifdef CATCH_TRAP
5485  #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); }
5486 #else
5487  namespace Catch {
5488  inline void doNothing() {}
5489  }
5490  #define CATCH_BREAK_INTO_DEBUGGER() Catch::doNothing()
5491 #endif
5492 
5493 // end catch_debugger.h
5494 // start catch_run_context.h
5495 
5496 // start catch_fatal_condition.h
5497 
5498 // start catch_windows_h_proxy.h
5499 
5500 
5501 #if defined(CATCH_PLATFORM_WINDOWS)
5502 
5503 #if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
5504 # define CATCH_DEFINED_NOMINMAX
5505 # define NOMINMAX
5506 #endif
5507 #if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
5508 # define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
5509 # define WIN32_LEAN_AND_MEAN
5510 #endif
5511 
5512 #ifdef __AFXDLL
5513 #include <AfxWin.h>
5514 #else
5515 #include <windows.h>
5516 #endif
5517 
5518 #ifdef CATCH_DEFINED_NOMINMAX
5519 # undef NOMINMAX
5520 #endif
5521 #ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
5522 # undef WIN32_LEAN_AND_MEAN
5523 #endif
5524 
5525 #endif // defined(CATCH_PLATFORM_WINDOWS)
5526 
5527 // end catch_windows_h_proxy.h
5528 #if defined( CATCH_CONFIG_WINDOWS_SEH )
5529 
5530 namespace Catch {
5531 
5532  struct FatalConditionHandler {
5533 
5534  static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
5535  FatalConditionHandler();
5536  static void reset();
5537  ~FatalConditionHandler();
5538 
5539  private:
5540  static bool isSet;
5541  static ULONG guaranteeSize;
5542  static PVOID exceptionHandlerHandle;
5543  };
5544 
5545 } // namespace Catch
5546 
5547 #elif defined ( CATCH_CONFIG_POSIX_SIGNALS )
5548 
5549 #include <signal.h>
5550 
5551 namespace Catch {
5552 
5553  struct FatalConditionHandler {
5554 
5555  static bool isSet;
5556  static struct sigaction oldSigActions[];
5557  static stack_t oldSigStack;
5558  static char altStackMem[];
5559 
5560  static void handleSignal( int sig );
5561 
5562  FatalConditionHandler();
5563  ~FatalConditionHandler();
5564  static void reset();
5565  };
5566 
5567 } // namespace Catch
5568 
5569 #else
5570 
5571 namespace Catch {
5572  struct FatalConditionHandler {
5573  void reset();
5574  };
5575 }
5576 
5577 #endif
5578 
5579 // end catch_fatal_condition.h
5580 #include <string>
5581 
5582 namespace Catch {
5583 
5584  struct IMutableContext;
5585 
5587 
5588  class RunContext : public IResultCapture, public IRunner {
5589 
5590  public:
5591  RunContext( RunContext const& ) = delete;
5592  RunContext& operator =( RunContext const& ) = delete;
5593 
5594  explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr&& reporter );
5595 
5596  ~RunContext() override;
5597 
5598  void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount );
5599  void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount );
5600 
5601  Totals runTest(TestCase const& testCase);
5602 
5603  IConfigPtr config() const;
5604  IStreamingReporter& reporter() const;
5605 
5606  public: // IResultCapture
5607 
5608  // Assertion handlers
5609  void handleExpr
5610  ( AssertionInfo const& info,
5611  ITransientExpression const& expr,
5612  AssertionReaction& reaction ) override;
5613  void handleMessage
5614  ( AssertionInfo const& info,
5615  ResultWas::OfType resultType,
5616  StringRef const& message,
5617  AssertionReaction& reaction ) override;
5618  void handleUnexpectedExceptionNotThrown
5619  ( AssertionInfo const& info,
5620  AssertionReaction& reaction ) override;
5621  void handleUnexpectedInflightException
5622  ( AssertionInfo const& info,
5623  std::string const& message,
5624  AssertionReaction& reaction ) override;
5625  void handleIncomplete
5626  ( AssertionInfo const& info ) override;
5627  void handleNonExpr
5628  ( AssertionInfo const &info,
5629  ResultWas::OfType resultType,
5630  AssertionReaction &reaction ) override;
5631 
5632  bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override;
5633 
5634  void sectionEnded( SectionEndInfo const& endInfo ) override;
5635  void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
5636 
5637  auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
5638 
5639  void benchmarkStarting( BenchmarkInfo const& info ) override;
5640  void benchmarkEnded( BenchmarkStats const& stats ) override;
5641 
5642  void pushScopedMessage( MessageInfo const& message ) override;
5643  void popScopedMessage( MessageInfo const& message ) override;
5644 
5645  std::string getCurrentTestName() const override;
5646 
5647  const AssertionResult* getLastResult() const override;
5648 
5649  void exceptionEarlyReported() override;
5650 
5651  void handleFatalErrorCondition( StringRef message ) override;
5652 
5653  bool lastAssertionPassed() override;
5654 
5655  void assertionPassed() override;
5656 
5657  public:
5658  // !TBD We need to do this another way!
5659  bool aborting() const final;
5660 
5661  private:
5662 
5663  void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr );
5664  void invokeActiveTestCase();
5665 
5666  void resetAssertionInfo();
5667  bool testForMissingAssertions( Counts& assertions );
5668 
5669  void assertionEnded( AssertionResult const& result );
5670  void reportExpr
5671  ( AssertionInfo const &info,
5672  ResultWas::OfType resultType,
5673  ITransientExpression const *expr,
5674  bool negated );
5675 
5676  void populateReaction( AssertionReaction& reaction );
5677 
5678  private:
5679 
5680  void handleUnfinishedSections();
5681 
5682  TestRunInfo m_runInfo;
5683  IMutableContext& m_context;
5684  TestCase const* m_activeTestCase = nullptr;
5685  ITracker* m_testCaseTracker;
5686  Option<AssertionResult> m_lastResult;
5687 
5688  IConfigPtr m_config;
5689  Totals m_totals;
5690  IStreamingReporterPtr m_reporter;
5691  std::vector<MessageInfo> m_messages;
5692  AssertionInfo m_lastAssertionInfo;
5693  std::vector<SectionEndInfo> m_unfinishedSections;
5694  std::vector<ITracker*> m_activeSections;
5695  TrackerContext m_trackerContext;
5696  bool m_lastAssertionPassed = false;
5697  bool m_shouldReportUnexpected = true;
5698  bool m_includeSuccessfulResults;
5699  };
5700 
5701 } // end namespace Catch
5702 
5703 // end catch_run_context.h
5704 namespace Catch {
5705 
5706  namespace {
5707  auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
5708  expr.streamReconstructedExpression( os );
5709  return os;
5710  }
5711  }
5712 
5713  LazyExpression::LazyExpression( bool isNegated )
5714  : m_isNegated( isNegated )
5715  {}
5716 
5717  LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {}
5718 
5719  LazyExpression::operator bool() const {
5720  return m_transientExpression != nullptr;
5721  }
5722 
5723  auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& {
5724  if( lazyExpr.m_isNegated )
5725  os << "!";
5726 
5727  if( lazyExpr ) {
5728  if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() )
5729  os << "(" << *lazyExpr.m_transientExpression << ")";
5730  else
5731  os << *lazyExpr.m_transientExpression;
5732  }
5733  else {
5734  os << "{** error - unchecked empty expression requested **}";
5735  }
5736  return os;
5737  }
5738 
5739  AssertionHandler::AssertionHandler
5740  ( StringRef const& macroName,
5741  SourceLineInfo const& lineInfo,
5742  StringRef capturedExpression,
5743  ResultDisposition::Flags resultDisposition )
5744  : m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },
5745  m_resultCapture( getResultCapture() )
5746  {}
5747 
5748  void AssertionHandler::handleExpr( ITransientExpression const& expr ) {
5749  m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );
5750  }
5751  void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) {
5752  m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction );
5753  }
5754 
5755  auto AssertionHandler::allowThrows() const -> bool {
5756  return getCurrentContext().getConfig()->allowThrows();
5757  }
5758 
5759  void AssertionHandler::complete() {
5760  setCompleted();
5761  if( m_reaction.shouldDebugBreak ) {
5762 
5763  // If you find your debugger stopping you here then go one level up on the
5764  // call-stack for the code that caused it (typically a failed assertion)
5765 
5766  // (To go back to the test and change execution, jump over the throw, next)
5767  CATCH_BREAK_INTO_DEBUGGER();
5768  }
5769  if (m_reaction.shouldThrow) {
5770 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
5772 #else
5773  CATCH_ERROR( "Test failure requires aborting test!" );
5774 #endif
5775  }
5776  }
5777  void AssertionHandler::setCompleted() {
5778  m_completed = true;
5779  }
5780 
5781  void AssertionHandler::handleUnexpectedInflightException() {
5782  m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction );
5783  }
5784 
5785  void AssertionHandler::handleExceptionThrownAsExpected() {
5786  m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
5787  }
5788  void AssertionHandler::handleExceptionNotThrownAsExpected() {
5789  m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
5790  }
5791 
5792  void AssertionHandler::handleUnexpectedExceptionNotThrown() {
5793  m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction );
5794  }
5795 
5796  void AssertionHandler::handleThrowingCallSkipped() {
5797  m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
5798  }
5799 
5800  // This is the overload that takes a string and infers the Equals matcher from it
5801  // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
5802  void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString ) {
5803  handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );
5804  }
5805 
5806 } // namespace Catch
5807 // end catch_assertionhandler.cpp
5808 // start catch_assertionresult.cpp
5809 
5810 namespace Catch {
5811  AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression):
5812  lazyExpression(_lazyExpression),
5813  resultType(_resultType) {}
5814 
5815  std::string AssertionResultData::reconstructExpression() const {
5816 
5817  if( reconstructedExpression.empty() ) {
5818  if( lazyExpression ) {
5819  ReusableStringStream rss;
5820  rss << lazyExpression;
5821  reconstructedExpression = rss.str();
5822  }
5823  }
5824  return reconstructedExpression;
5825  }
5826 
5827  AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
5828  : m_info( info ),
5829  m_resultData( data )
5830  {}
5831 
5832  // Result was a success
5833  bool AssertionResult::succeeded() const {
5834  return Catch::isOk( m_resultData.resultType );
5835  }
5836 
5837  // Result was a success, or failure is suppressed
5838  bool AssertionResult::isOk() const {
5839  return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
5840  }
5841 
5842  ResultWas::OfType AssertionResult::getResultType() const {
5843  return m_resultData.resultType;
5844  }
5845 
5846  bool AssertionResult::hasExpression() const {
5847  return m_info.capturedExpression[0] != 0;
5848  }
5849 
5850  bool AssertionResult::hasMessage() const {
5851  return !m_resultData.message.empty();
5852  }
5853 
5854  std::string AssertionResult::getExpression() const {
5855  if( isFalseTest( m_info.resultDisposition ) )
5856  return "!(" + m_info.capturedExpression + ")";
5857  else
5858  return m_info.capturedExpression;
5859  }
5860 
5861  std::string AssertionResult::getExpressionInMacro() const {
5862  std::string expr;
5863  if( m_info.macroName[0] == 0 )
5864  expr = m_info.capturedExpression;
5865  else {
5866  expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
5867  expr += m_info.macroName;
5868  expr += "( ";
5869  expr += m_info.capturedExpression;
5870  expr += " )";
5871  }
5872  return expr;
5873  }
5874 
5875  bool AssertionResult::hasExpandedExpression() const {
5876  return hasExpression() && getExpandedExpression() != getExpression();
5877  }
5878 
5879  std::string AssertionResult::getExpandedExpression() const {
5880  std::string expr = m_resultData.reconstructExpression();
5881  return expr.empty()
5882  ? getExpression()
5883  : expr;
5884  }
5885 
5886  std::string AssertionResult::getMessage() const {
5887  return m_resultData.message;
5888  }
5889  SourceLineInfo AssertionResult::getSourceInfo() const {
5890  return m_info.lineInfo;
5891  }
5892 
5893  StringRef AssertionResult::getTestMacroName() const {
5894  return m_info.macroName;
5895  }
5896 
5897 } // end namespace Catch
5898 // end catch_assertionresult.cpp
5899 // start catch_benchmark.cpp
5900 
5901 namespace Catch {
5902 
5903  auto BenchmarkLooper::getResolution() -> uint64_t {
5904  return getEstimatedClockResolution() * getCurrentContext().getConfig()->benchmarkResolutionMultiple();
5905  }
5906 
5907  void BenchmarkLooper::reportStart() {
5908  getResultCapture().benchmarkStarting( { m_name } );
5909  }
5910  auto BenchmarkLooper::needsMoreIterations() -> bool {
5911  auto elapsed = m_timer.getElapsedNanoseconds();
5912 
5913  // Exponentially increasing iterations until we're confident in our timer resolution
5914  if( elapsed < m_resolution ) {
5915  m_iterationsToRun *= 10;
5916  return true;
5917  }
5918 
5919  getResultCapture().benchmarkEnded( { { m_name }, m_count, elapsed } );
5920  return false;
5921  }
5922 
5923 } // end namespace Catch
5924 // end catch_benchmark.cpp
5925 // start catch_capture_matchers.cpp
5926 
5927 namespace Catch {
5928 
5929  using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
5930 
5931  // This is the general overload that takes a any string matcher
5932  // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
5933  // the Equals matcher (so the header does not mention matchers)
5934  void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString ) {
5935  std::string exceptionMessage = Catch::translateActiveException();
5936  MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );
5937  handler.handleExpr( expr );
5938  }
5939 
5940 } // namespace Catch
5941 // end catch_capture_matchers.cpp
5942 // start catch_commandline.cpp
5943 
5944 // start catch_commandline.h
5945 
5946 // start catch_clara.h
5947 
5948 // Use Catch's value for console width (store Clara's off to the side, if present)
5949 #ifdef CLARA_CONFIG_CONSOLE_WIDTH
5950 #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
5951 #undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
5952 #endif
5953 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1
5954 
5955 #ifdef __clang__
5956 #pragma clang diagnostic push
5957 #pragma clang diagnostic ignored "-Wweak-vtables"
5958 #pragma clang diagnostic ignored "-Wexit-time-destructors"
5959 #pragma clang diagnostic ignored "-Wshadow"
5960 #endif
5961 
5962 // start clara.hpp
5963 // Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
5964 //
5965 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5966 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5967 //
5968 // See https://github.com/philsquared/Clara for more details
5969 
5970 // Clara v1.1.5
5971 
5972 
5973 #ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
5974 #define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80
5975 #endif
5976 
5977 #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
5978 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH
5979 #endif
5980 
5981 #ifndef CLARA_CONFIG_OPTIONAL_TYPE
5982 #ifdef __has_include
5983 #if __has_include(<optional>) && __cplusplus >= 201703L
5984 #include <optional>
5985 #define CLARA_CONFIG_OPTIONAL_TYPE std::optional
5986 #endif
5987 #endif
5988 #endif
5989 
5990 // ----------- #included from clara_textflow.hpp -----------
5991 
5992 // TextFlowCpp
5993 //
5994 // A single-header library for wrapping and laying out basic text, by Phil Nash
5995 //
5996 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5997 // file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5998 //
5999 // This project is hosted at https://github.com/philsquared/textflowcpp
6000 
6001 
6002 #include <cassert>
6003 #include <ostream>
6004 #include <sstream>
6005 #include <vector>
6006 
6007 #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
6008 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80
6009 #endif
6010 
6011 namespace Catch {
6012 namespace clara {
6013 namespace TextFlow {
6014 
6015 inline auto isWhitespace(char c) -> bool {
6016  static std::string chars = " \t\n\r";
6017  return chars.find(c) != std::string::npos;
6018 }
6019 inline auto isBreakableBefore(char c) -> bool {
6020  static std::string chars = "[({<|";
6021  return chars.find(c) != std::string::npos;
6022 }
6023 inline auto isBreakableAfter(char c) -> bool {
6024  static std::string chars = "])}>.,:;*+-=&/\\";
6025  return chars.find(c) != std::string::npos;
6026 }
6027 
6028 class Columns;
6029 
6030 class Column {
6031  std::vector<std::string> m_strings;
6032  size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
6033  size_t m_indent = 0;
6034  size_t m_initialIndent = std::string::npos;
6035 
6036 public:
6037  class iterator {
6038  friend Column;
6039 
6040  Column const& m_column;
6041  size_t m_stringIndex = 0;
6042  size_t m_pos = 0;
6043 
6044  size_t m_len = 0;
6045  size_t m_end = 0;
6046  bool m_suffix = false;
6047 
6048  iterator(Column const& column, size_t stringIndex)
6049  : m_column(column),
6050  m_stringIndex(stringIndex) {}
6051 
6052  auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
6053 
6054  auto isBoundary(size_t at) const -> bool {
6055  assert(at > 0);
6056  assert(at <= line().size());
6057 
6058  return at == line().size() ||
6059  (isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) ||
6060  isBreakableBefore(line()[at]) ||
6061  isBreakableAfter(line()[at - 1]);
6062  }
6063 
6064  void calcLength() {
6065  assert(m_stringIndex < m_column.m_strings.size());
6066 
6067  m_suffix = false;
6068  auto width = m_column.m_width - indent();
6069  m_end = m_pos;
6070  while (m_end < line().size() && line()[m_end] != '\n')
6071  ++m_end;
6072 
6073  if (m_end < m_pos + width) {
6074  m_len = m_end - m_pos;
6075  } else {
6076  size_t len = width;
6077  while (len > 0 && !isBoundary(m_pos + len))
6078  --len;
6079  while (len > 0 && isWhitespace(line()[m_pos + len - 1]))
6080  --len;
6081 
6082  if (len > 0) {
6083  m_len = len;
6084  } else {
6085  m_suffix = true;
6086  m_len = width - 1;
6087  }
6088  }
6089  }
6090 
6091  auto indent() const -> size_t {
6092  auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
6093  return initial == std::string::npos ? m_column.m_indent : initial;
6094  }
6095 
6096  auto addIndentAndSuffix(std::string const &plain) const -> std::string {
6097  return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain);
6098  }
6099 
6100  public:
6101  using difference_type = std::ptrdiff_t;
6102  using value_type = std::string;
6103  using pointer = value_type * ;
6104  using reference = value_type & ;
6105  using iterator_category = std::forward_iterator_tag;
6106 
6107  explicit iterator(Column const& column) : m_column(column) {
6108  assert(m_column.m_width > m_column.m_indent);
6109  assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent);
6110  calcLength();
6111  if (m_len == 0)
6112  m_stringIndex++; // Empty string
6113  }
6114 
6115  auto operator *() const -> std::string {
6116  assert(m_stringIndex < m_column.m_strings.size());
6117  assert(m_pos <= m_end);
6118  return addIndentAndSuffix(line().substr(m_pos, m_len));
6119  }
6120 
6121  auto operator ++() -> iterator& {
6122  m_pos += m_len;
6123  if (m_pos < line().size() && line()[m_pos] == '\n')
6124  m_pos += 1;
6125  else
6126  while (m_pos < line().size() && isWhitespace(line()[m_pos]))
6127  ++m_pos;
6128 
6129  if (m_pos == line().size()) {
6130  m_pos = 0;
6131  ++m_stringIndex;
6132  }
6133  if (m_stringIndex < m_column.m_strings.size())
6134  calcLength();
6135  return *this;
6136  }
6137  auto operator ++(int) -> iterator {
6138  iterator prev(*this);
6139  operator++();
6140  return prev;
6141  }
6142 
6143  auto operator ==(iterator const& other) const -> bool {
6144  return
6145  m_pos == other.m_pos &&
6146  m_stringIndex == other.m_stringIndex &&
6147  &m_column == &other.m_column;
6148  }
6149  auto operator !=(iterator const& other) const -> bool {
6150  return !operator==(other);
6151  }
6152  };
6153  using const_iterator = iterator;
6154 
6155  explicit Column(std::string const& text) { m_strings.push_back(text); }
6156 
6157  auto width(size_t newWidth) -> Column& {
6158  assert(newWidth > 0);
6159  m_width = newWidth;
6160  return *this;
6161  }
6162  auto indent(size_t newIndent) -> Column& {
6163  m_indent = newIndent;
6164  return *this;
6165  }
6166  auto initialIndent(size_t newIndent) -> Column& {
6167  m_initialIndent = newIndent;
6168  return *this;
6169  }
6170 
6171  auto width() const -> size_t { return m_width; }
6172  auto begin() const -> iterator { return iterator(*this); }
6173  auto end() const -> iterator { return { *this, m_strings.size() }; }
6174 
6175  inline friend std::ostream& operator << (std::ostream& os, Column const& col) {
6176  bool first = true;
6177  for (auto line : col) {
6178  if (first)
6179  first = false;
6180  else
6181  os << "\n";
6182  os << line;
6183  }
6184  return os;
6185  }
6186 
6187  auto operator + (Column const& other)->Columns;
6188 
6189  auto toString() const -> std::string {
6190  std::ostringstream oss;
6191  oss << *this;
6192  return oss.str();
6193  }
6194 };
6195 
6196 class Spacer : public Column {
6197 
6198 public:
6199  explicit Spacer(size_t spaceWidth) : Column("") {
6200  width(spaceWidth);
6201  }
6202 };
6203 
6204 class Columns {
6205  std::vector<Column> m_columns;
6206 
6207 public:
6208 
6209  class iterator {
6210  friend Columns;
6211  struct EndTag {};
6212 
6213  std::vector<Column> const& m_columns;
6214  std::vector<Column::iterator> m_iterators;
6215  size_t m_activeIterators;
6216 
6217  iterator(Columns const& columns, EndTag)
6218  : m_columns(columns.m_columns),
6219  m_activeIterators(0) {
6220  m_iterators.reserve(m_columns.size());
6221 
6222  for (auto const& col : m_columns)
6223  m_iterators.push_back(col.end());
6224  }
6225 
6226  public:
6227  using difference_type = std::ptrdiff_t;
6228  using value_type = std::string;
6229  using pointer = value_type * ;
6230  using reference = value_type & ;
6231  using iterator_category = std::forward_iterator_tag;
6232 
6233  explicit iterator(Columns const& columns)
6234  : m_columns(columns.m_columns),
6235  m_activeIterators(m_columns.size()) {
6236  m_iterators.reserve(m_columns.size());
6237 
6238  for (auto const& col : m_columns)
6239  m_iterators.push_back(col.begin());
6240  }
6241 
6242  auto operator ==(iterator const& other) const -> bool {
6243  return m_iterators == other.m_iterators;
6244  }
6245  auto operator !=(iterator const& other) const -> bool {
6246  return m_iterators != other.m_iterators;
6247  }
6248  auto operator *() const -> std::string {
6249  std::string row, padding;
6250 
6251  for (size_t i = 0; i < m_columns.size(); ++i) {
6252  auto width = m_columns[i].width();
6253  if (m_iterators[i] != m_columns[i].end()) {
6254  std::string col = *m_iterators[i];
6255  row += padding + col;
6256  if (col.size() < width)
6257  padding = std::string(width - col.size(), ' ');
6258  else
6259  padding = "";
6260  } else {
6261  padding += std::string(width, ' ');
6262  }
6263  }
6264  return row;
6265  }
6266  auto operator ++() -> iterator& {
6267  for (size_t i = 0; i < m_columns.size(); ++i) {
6268  if (m_iterators[i] != m_columns[i].end())
6269  ++m_iterators[i];
6270  }
6271  return *this;
6272  }
6273  auto operator ++(int) -> iterator {
6274  iterator prev(*this);
6275  operator++();
6276  return prev;
6277  }
6278  };
6279  using const_iterator = iterator;
6280 
6281  auto begin() const -> iterator { return iterator(*this); }
6282  auto end() const -> iterator { return { *this, iterator::EndTag() }; }
6283 
6284  auto operator += (Column const& col) -> Columns& {
6285  m_columns.push_back(col);
6286  return *this;
6287  }
6288  auto operator + (Column const& col) -> Columns {
6289  Columns combined = *this;
6290  combined += col;
6291  return combined;
6292  }
6293 
6294  inline friend std::ostream& operator << (std::ostream& os, Columns const& cols) {
6295 
6296  bool first = true;
6297  for (auto line : cols) {
6298  if (first)
6299  first = false;
6300  else
6301  os << "\n";
6302  os << line;
6303  }
6304  return os;
6305  }
6306 
6307  auto toString() const -> std::string {
6308  std::ostringstream oss;
6309  oss << *this;
6310  return oss.str();
6311  }
6312 };
6313 
6314 inline auto Column::operator + (Column const& other) -> Columns {
6315  Columns cols;
6316  cols += *this;
6317  cols += other;
6318  return cols;
6319 }
6320 }
6321 
6322 }
6323 }
6324 
6325 // ----------- end of #include from clara_textflow.hpp -----------
6326 // ........... back in clara.hpp
6327 
6328 #include <string>
6329 #include <memory>
6330 #include <set>
6331 #include <algorithm>
6332 
6333 #if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) )
6334 #define CATCH_PLATFORM_WINDOWS
6335 #endif
6336 
6337 namespace Catch { namespace clara {
6338 namespace detail {
6339 
6340  // Traits for extracting arg and return type of lambdas (for single argument lambdas)
6341  template<typename L>
6342  struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {};
6343 
6344  template<typename ClassT, typename ReturnT, typename... Args>
6345  struct UnaryLambdaTraits<ReturnT( ClassT::* )( Args... ) const> {
6346  static const bool isValid = false;
6347  };
6348 
6349  template<typename ClassT, typename ReturnT, typename ArgT>
6350  struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
6351  static const bool isValid = true;
6352  using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;
6353  using ReturnType = ReturnT;
6354  };
6355 
6356  class TokenStream;
6357 
6358  // Transport for raw args (copied from main args, or supplied via init list for testing)
6359  class Args {
6360  friend TokenStream;
6361  std::string m_exeName;
6362  std::vector<std::string> m_args;
6363 
6364  public:
6365  Args( int argc, char const* const* argv )
6366  : m_exeName(argv[0]),
6367  m_args(argv + 1, argv + argc) {}
6368 
6369  Args( std::initializer_list<std::string> args )
6370  : m_exeName( *args.begin() ),
6371  m_args( args.begin()+1, args.end() )
6372  {}
6373 
6374  auto exeName() const -> std::string {
6375  return m_exeName;
6376  }
6377  };
6378 
6379  // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string
6380  // may encode an option + its argument if the : or = form is used
6381  enum class TokenType {
6382  Option, Argument
6383  };
6384  struct Token {
6385  TokenType type;
6386  std::string token;
6387  };
6388 
6389  inline auto isOptPrefix( char c ) -> bool {
6390  return c == '-'
6391 #ifdef CATCH_PLATFORM_WINDOWS
6392  || c == '/'
6393 #endif
6394  ;
6395  }
6396 
6397  // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
6398  class TokenStream {
6399  using Iterator = std::vector<std::string>::const_iterator;
6400  Iterator it;
6401  Iterator itEnd;
6402  std::vector<Token> m_tokenBuffer;
6403 
6404  void loadBuffer() {
6405  m_tokenBuffer.resize( 0 );
6406 
6407  // Skip any empty strings
6408  while( it != itEnd && it->empty() )
6409  ++it;
6410 
6411  if( it != itEnd ) {
6412  auto const &next = *it;
6413  if( isOptPrefix( next[0] ) ) {
6414  auto delimiterPos = next.find_first_of( " :=" );
6415  if( delimiterPos != std::string::npos ) {
6416  m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
6417  m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } );
6418  } else {
6419  if( next[1] != '-' && next.size() > 2 ) {
6420  std::string opt = "- ";
6421  for( size_t i = 1; i < next.size(); ++i ) {
6422  opt[1] = next[i];
6423  m_tokenBuffer.push_back( { TokenType::Option, opt } );
6424  }
6425  } else {
6426  m_tokenBuffer.push_back( { TokenType::Option, next } );
6427  }
6428  }
6429  } else {
6430  m_tokenBuffer.push_back( { TokenType::Argument, next } );
6431  }
6432  }
6433  }
6434 
6435  public:
6436  explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {}
6437 
6438  TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) {
6439  loadBuffer();
6440  }
6441 
6442  explicit operator bool() const {
6443  return !m_tokenBuffer.empty() || it != itEnd;
6444  }
6445 
6446  auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); }
6447 
6448  auto operator*() const -> Token {
6449  assert( !m_tokenBuffer.empty() );
6450  return m_tokenBuffer.front();
6451  }
6452 
6453  auto operator->() const -> Token const * {
6454  assert( !m_tokenBuffer.empty() );
6455  return &m_tokenBuffer.front();
6456  }
6457 
6458  auto operator++() -> TokenStream & {
6459  if( m_tokenBuffer.size() >= 2 ) {
6460  m_tokenBuffer.erase( m_tokenBuffer.begin() );
6461  } else {
6462  if( it != itEnd )
6463  ++it;
6464  loadBuffer();
6465  }
6466  return *this;
6467  }
6468  };
6469 
6470  class ResultBase {
6471  public:
6472  enum Type {
6473  Ok, LogicError, RuntimeError
6474  };
6475 
6476  protected:
6477  ResultBase( Type type ) : m_type( type ) {}
6478  virtual ~ResultBase() = default;
6479 
6480  virtual void enforceOk() const = 0;
6481 
6482  Type m_type;
6483  };
6484 
6485  template<typename T>
6486  class ResultValueBase : public ResultBase {
6487  public:
6488  auto value() const -> T const & {
6489  enforceOk();
6490  return m_value;
6491  }
6492 
6493  protected:
6494  ResultValueBase( Type type ) : ResultBase( type ) {}
6495 
6496  ResultValueBase( ResultValueBase const &other ) : ResultBase( other ) {
6497  if( m_type == ResultBase::Ok )
6498  new( &m_value ) T( other.m_value );
6499  }
6500 
6501  ResultValueBase( Type, T const &value ) : ResultBase( Ok ) {
6502  new( &m_value ) T( value );
6503  }
6504 
6505  auto operator=( ResultValueBase const &other ) -> ResultValueBase & {
6506  if( m_type == ResultBase::Ok )
6507  m_value.~T();
6508  ResultBase::operator=(other);
6509  if( m_type == ResultBase::Ok )
6510  new( &m_value ) T( other.m_value );
6511  return *this;
6512  }
6513 
6514  ~ResultValueBase() override {
6515  if( m_type == Ok )
6516  m_value.~T();
6517  }
6518 
6519  union {
6520  T m_value;
6521  };
6522  };
6523 
6524  template<>
6525  class ResultValueBase<void> : public ResultBase {
6526  protected:
6527  using ResultBase::ResultBase;
6528  };
6529 
6530  template<typename T = void>
6531  class BasicResult : public ResultValueBase<T> {
6532  public:
6533  template<typename U>
6534  explicit BasicResult( BasicResult<U> const &other )
6535  : ResultValueBase<T>( other.type() ),
6536  m_errorMessage( other.errorMessage() )
6537  {
6538  assert( type() != ResultBase::Ok );
6539  }
6540 
6541  template<typename U>
6542  static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; }
6543  static auto ok() -> BasicResult { return { ResultBase::Ok }; }
6544  static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; }
6545  static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; }
6546 
6547  explicit operator bool() const { return m_type == ResultBase::Ok; }
6548  auto type() const -> ResultBase::Type { return m_type; }
6549  auto errorMessage() const -> std::string { return m_errorMessage; }
6550 
6551  protected:
6552  void enforceOk() const override {
6553 
6554  // Errors shouldn't reach this point, but if they do
6555  // the actual error message will be in m_errorMessage
6556  assert( m_type != ResultBase::LogicError );
6557  assert( m_type != ResultBase::RuntimeError );
6558  if( m_type != ResultBase::Ok )
6559  std::abort();
6560  }
6561 
6562  std::string m_errorMessage; // Only populated if resultType is an error
6563 
6564  BasicResult( ResultBase::Type type, std::string const &message )
6565  : ResultValueBase<T>(type),
6566  m_errorMessage(message)
6567  {
6568  assert( m_type != ResultBase::Ok );
6569  }
6570 
6571  using ResultValueBase<T>::ResultValueBase;
6572  using ResultBase::m_type;
6573  };
6574 
6575  enum class ParseResultType {
6576  Matched, NoMatch, ShortCircuitAll, ShortCircuitSame
6577  };
6578 
6579  class ParseState {
6580  public:
6581 
6582  ParseState( ParseResultType type, TokenStream const &remainingTokens )
6583  : m_type(type),
6584  m_remainingTokens( remainingTokens )
6585  {}
6586 
6587  auto type() const -> ParseResultType { return m_type; }
6588  auto remainingTokens() const -> TokenStream { return m_remainingTokens; }
6589 
6590  private:
6591  ParseResultType m_type;
6592  TokenStream m_remainingTokens;
6593  };
6594 
6595  using Result = BasicResult<void>;
6596  using ParserResult = BasicResult<ParseResultType>;
6597  using InternalParseResult = BasicResult<ParseState>;
6598 
6599  struct HelpColumns {
6600  std::string left;
6601  std::string right;
6602  };
6603 
6604  template<typename T>
6605  inline auto convertInto( std::string const &source, T& target ) -> ParserResult {
6606  std::stringstream ss;
6607  ss << source;
6608  ss >> target;
6609  if( ss.fail() )
6610  return ParserResult::runtimeError( "Unable to convert '" + source + "' to destination type" );
6611  else
6612  return ParserResult::ok( ParseResultType::Matched );
6613  }
6614  inline auto convertInto( std::string const &source, std::string& target ) -> ParserResult {
6615  target = source;
6616  return ParserResult::ok( ParseResultType::Matched );
6617  }
6618  inline auto convertInto( std::string const &source, bool &target ) -> ParserResult {
6619  std::string srcLC = source;
6620  std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast<char>( ::tolower(c) ); } );
6621  if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
6622  target = true;
6623  else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
6624  target = false;
6625  else
6626  return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" );
6627  return ParserResult::ok( ParseResultType::Matched );
6628  }
6629 #ifdef CLARA_CONFIG_OPTIONAL_TYPE
6630  template<typename T>
6631  inline auto convertInto( std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target ) -> ParserResult {
6632  T temp;
6633  auto result = convertInto( source, temp );
6634  if( result )
6635  target = std::move(temp);
6636  return result;
6637  }
6638 #endif // CLARA_CONFIG_OPTIONAL_TYPE
6639 
6640  struct NonCopyable {
6641  NonCopyable() = default;
6642  NonCopyable( NonCopyable const & ) = delete;
6643  NonCopyable( NonCopyable && ) = delete;
6644  NonCopyable &operator=( NonCopyable const & ) = delete;
6645  NonCopyable &operator=( NonCopyable && ) = delete;
6646  };
6647 
6648  struct BoundRef : NonCopyable {
6649  virtual ~BoundRef() = default;
6650  virtual auto isContainer() const -> bool { return false; }
6651  virtual auto isFlag() const -> bool { return false; }
6652  };
6653  struct BoundValueRefBase : BoundRef {
6654  virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
6655  };
6656  struct BoundFlagRefBase : BoundRef {
6657  virtual auto setFlag( bool flag ) -> ParserResult = 0;
6658  virtual auto isFlag() const -> bool { return true; }
6659  };
6660 
6661  template<typename T>
6662  struct BoundValueRef : BoundValueRefBase {
6663  T &m_ref;
6664 
6665  explicit BoundValueRef( T &ref ) : m_ref( ref ) {}
6666 
6667  auto setValue( std::string const &arg ) -> ParserResult override {
6668  return convertInto( arg, m_ref );
6669  }
6670  };
6671 
6672  template<typename T>
6673  struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
6674  std::vector<T> &m_ref;
6675 
6676  explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {}
6677 
6678  auto isContainer() const -> bool override { return true; }
6679 
6680  auto setValue( std::string const &arg ) -> ParserResult override {
6681  T temp;
6682  auto result = convertInto( arg, temp );
6683  if( result )
6684  m_ref.push_back( temp );
6685  return result;
6686  }
6687  };
6688 
6689  struct BoundFlagRef : BoundFlagRefBase {
6690  bool &m_ref;
6691 
6692  explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {}
6693 
6694  auto setFlag( bool flag ) -> ParserResult override {
6695  m_ref = flag;
6696  return ParserResult::ok( ParseResultType::Matched );
6697  }
6698  };
6699 
6700  template<typename ReturnType>
6701  struct LambdaInvoker {
6702  static_assert( std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult" );
6703 
6704  template<typename L, typename ArgType>
6705  static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
6706  return lambda( arg );
6707  }
6708  };
6709 
6710  template<>
6711  struct LambdaInvoker<void> {
6712  template<typename L, typename ArgType>
6713  static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
6714  lambda( arg );
6715  return ParserResult::ok( ParseResultType::Matched );
6716  }
6717  };
6718 
6719  template<typename ArgType, typename L>
6720  inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
6721  ArgType temp{};
6722  auto result = convertInto( arg, temp );
6723  return !result
6724  ? result
6725  : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
6726  }
6727 
6728  template<typename L>
6729  struct BoundLambda : BoundValueRefBase {
6730  L m_lambda;
6731 
6732  static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
6733  explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {}
6734 
6735  auto setValue( std::string const &arg ) -> ParserResult override {
6736  return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>( m_lambda, arg );
6737  }
6738  };
6739 
6740  template<typename L>
6741  struct BoundFlagLambda : BoundFlagRefBase {
6742  L m_lambda;
6743 
6744  static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
6745  static_assert( std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, "flags must be boolean" );
6746 
6747  explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {}
6748 
6749  auto setFlag( bool flag ) -> ParserResult override {
6750  return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( m_lambda, flag );
6751  }
6752  };
6753 
6754  enum class Optionality { Optional, Required };
6755 
6756  struct Parser;
6757 
6758  class ParserBase {
6759  public:
6760  virtual ~ParserBase() = default;
6761  virtual auto validate() const -> Result { return Result::ok(); }
6762  virtual auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult = 0;
6763  virtual auto cardinality() const -> size_t { return 1; }
6764 
6765  auto parse( Args const &args ) const -> InternalParseResult {
6766  return parse( args.exeName(), TokenStream( args ) );
6767  }
6768  };
6769 
6770  template<typename DerivedT>
6771  class ComposableParserImpl : public ParserBase {
6772  public:
6773  template<typename T>
6774  auto operator|( T const &other ) const -> Parser;
6775 
6776  template<typename T>
6777  auto operator+( T const &other ) const -> Parser;
6778  };
6779 
6780  // Common code and state for Args and Opts
6781  template<typename DerivedT>
6782  class ParserRefImpl : public ComposableParserImpl<DerivedT> {
6783  protected:
6784  Optionality m_optionality = Optionality::Optional;
6785  std::shared_ptr<BoundRef> m_ref;
6786  std::string m_hint;
6787  std::string m_description;
6788 
6789  explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {}
6790 
6791  public:
6792  template<typename T>
6793  ParserRefImpl( T &ref, std::string const &hint )
6794  : m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
6795  m_hint( hint )
6796  {}
6797 
6798  template<typename LambdaT>
6799  ParserRefImpl( LambdaT const &ref, std::string const &hint )
6800  : m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),
6801  m_hint(hint)
6802  {}
6803 
6804  auto operator()( std::string const &description ) -> DerivedT & {
6805  m_description = description;
6806  return static_cast<DerivedT &>( *this );
6807  }
6808 
6809  auto optional() -> DerivedT & {
6810  m_optionality = Optionality::Optional;
6811  return static_cast<DerivedT &>( *this );
6812  };
6813 
6814  auto required() -> DerivedT & {
6815  m_optionality = Optionality::Required;
6816  return static_cast<DerivedT &>( *this );
6817  };
6818 
6819  auto isOptional() const -> bool {
6820  return m_optionality == Optionality::Optional;
6821  }
6822 
6823  auto cardinality() const -> size_t override {
6824  if( m_ref->isContainer() )
6825  return 0;
6826  else
6827  return 1;
6828  }
6829 
6830  auto hint() const -> std::string { return m_hint; }
6831  };
6832 
6833  class ExeName : public ComposableParserImpl<ExeName> {
6834  std::shared_ptr<std::string> m_name;
6835  std::shared_ptr<BoundValueRefBase> m_ref;
6836 
6837  template<typename LambdaT>
6838  static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {
6839  return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
6840  }
6841 
6842  public:
6843  ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
6844 
6845  explicit ExeName( std::string &ref ) : ExeName() {
6846  m_ref = std::make_shared<BoundValueRef<std::string>>( ref );
6847  }
6848 
6849  template<typename LambdaT>
6850  explicit ExeName( LambdaT const& lambda ) : ExeName() {
6851  m_ref = std::make_shared<BoundLambda<LambdaT>>( lambda );
6852  }
6853 
6854  // The exe name is not parsed out of the normal tokens, but is handled specially
6855  auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
6856  return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
6857  }
6858 
6859  auto name() const -> std::string { return *m_name; }
6860  auto set( std::string const& newName ) -> ParserResult {
6861 
6862  auto lastSlash = newName.find_last_of( "\\/" );
6863  auto filename = ( lastSlash == std::string::npos )
6864  ? newName
6865  : newName.substr( lastSlash+1 );
6866 
6867  *m_name = filename;
6868  if( m_ref )
6869  return m_ref->setValue( filename );
6870  else
6871  return ParserResult::ok( ParseResultType::Matched );
6872  }
6873  };
6874 
6875  class Arg : public ParserRefImpl<Arg> {
6876  public:
6877  using ParserRefImpl::ParserRefImpl;
6878 
6879  auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override {
6880  auto validationResult = validate();
6881  if( !validationResult )
6882  return InternalParseResult( validationResult );
6883 
6884  auto remainingTokens = tokens;
6885  auto const &token = *remainingTokens;
6886  if( token.type != TokenType::Argument )
6887  return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
6888 
6889  assert( !m_ref->isFlag() );
6890  auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
6891 
6892  auto result = valueRef->setValue( remainingTokens->token );
6893  if( !result )
6894  return InternalParseResult( result );
6895  else
6896  return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
6897  }
6898  };
6899 
6900  inline auto normaliseOpt( std::string const &optName ) -> std::string {
6901 #ifdef CATCH_PLATFORM_WINDOWS
6902  if( optName[0] == '/' )
6903  return "-" + optName.substr( 1 );
6904  else
6905 #endif
6906  return optName;
6907  }
6908 
6909  class Opt : public ParserRefImpl<Opt> {
6910  protected:
6911  std::vector<std::string> m_optNames;
6912 
6913  public:
6914  template<typename LambdaT>
6915  explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared<BoundFlagLambda<LambdaT>>( ref ) ) {}
6916 
6917  explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared<BoundFlagRef>( ref ) ) {}
6918 
6919  template<typename LambdaT>
6920  Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
6921 
6922  template<typename T>
6923  Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
6924 
6925  auto operator[]( std::string const &optName ) -> Opt & {
6926  m_optNames.push_back( optName );
6927  return *this;
6928  }
6929 
6930  auto getHelpColumns() const -> std::vector<HelpColumns> {
6931  std::ostringstream oss;
6932  bool first = true;
6933  for( auto const &opt : m_optNames ) {
6934  if (first)
6935  first = false;
6936  else
6937  oss << ", ";
6938  oss << opt;
6939  }
6940  if( !m_hint.empty() )
6941  oss << " <" << m_hint << ">";
6942  return { { oss.str(), m_description } };
6943  }
6944 
6945  auto isMatch( std::string const &optToken ) const -> bool {
6946  auto normalisedToken = normaliseOpt( optToken );
6947  for( auto const &name : m_optNames ) {
6948  if( normaliseOpt( name ) == normalisedToken )
6949  return true;
6950  }
6951  return false;
6952  }
6953 
6954  using ParserBase::parse;
6955 
6956  auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
6957  auto validationResult = validate();
6958  if( !validationResult )
6959  return InternalParseResult( validationResult );
6960 
6961  auto remainingTokens = tokens;
6962  if( remainingTokens && remainingTokens->type == TokenType::Option ) {
6963  auto const &token = *remainingTokens;
6964  if( isMatch(token.token ) ) {
6965  if( m_ref->isFlag() ) {
6966  auto flagRef = static_cast<detail::BoundFlagRefBase*>( m_ref.get() );
6967  auto result = flagRef->setFlag( true );
6968  if( !result )
6969  return InternalParseResult( result );
6970  if( result.value() == ParseResultType::ShortCircuitAll )
6971  return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
6972  } else {
6973  auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
6974  ++remainingTokens;
6975  if( !remainingTokens )
6976  return InternalParseResult::runtimeError( "Expected argument following " + token.token );
6977  auto const &argToken = *remainingTokens;
6978  if( argToken.type != TokenType::Argument )
6979  return InternalParseResult::runtimeError( "Expected argument following " + token.token );
6980  auto result = valueRef->setValue( argToken.token );
6981  if( !result )
6982  return InternalParseResult( result );
6983  if( result.value() == ParseResultType::ShortCircuitAll )
6984  return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
6985  }
6986  return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
6987  }
6988  }
6989  return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
6990  }
6991 
6992  auto validate() const -> Result override {
6993  if( m_optNames.empty() )
6994  return Result::logicError( "No options supplied to Opt" );
6995  for( auto const &name : m_optNames ) {
6996  if( name.empty() )
6997  return Result::logicError( "Option name cannot be empty" );
6998 #ifdef CATCH_PLATFORM_WINDOWS
6999  if( name[0] != '-' && name[0] != '/' )
7000  return Result::logicError( "Option name must begin with '-' or '/'" );
7001 #else
7002  if( name[0] != '-' )
7003  return Result::logicError( "Option name must begin with '-'" );
7004 #endif
7005  }
7006  return ParserRefImpl::validate();
7007  }
7008  };
7009 
7010  struct Help : Opt {
7011  Help( bool &showHelpFlag )
7012  : Opt([&]( bool flag ) {
7013  showHelpFlag = flag;
7014  return ParserResult::ok( ParseResultType::ShortCircuitAll );
7015  })
7016  {
7017  static_cast<Opt &>( *this )
7018  ("display usage information")
7019  ["-?"]["-h"]["--help"]
7020  .optional();
7021  }
7022  };
7023 
7024  struct Parser : ParserBase {
7025 
7026  mutable ExeName m_exeName;
7027  std::vector<Opt> m_options;
7028  std::vector<Arg> m_args;
7029 
7030  auto operator|=( ExeName const &exeName ) -> Parser & {
7031  m_exeName = exeName;
7032  return *this;
7033  }
7034 
7035  auto operator|=( Arg const &arg ) -> Parser & {
7036  m_args.push_back(arg);
7037  return *this;
7038  }
7039 
7040  auto operator|=( Opt const &opt ) -> Parser & {
7041  m_options.push_back(opt);
7042  return *this;
7043  }
7044 
7045  auto operator|=( Parser const &other ) -> Parser & {
7046  m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
7047  m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
7048  return *this;
7049  }
7050 
7051  template<typename T>
7052  auto operator|( T const &other ) const -> Parser {
7053  return Parser( *this ) |= other;
7054  }
7055 
7056  // Forward deprecated interface with '+' instead of '|'
7057  template<typename T>
7058  auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }
7059  template<typename T>
7060  auto operator+( T const &other ) const -> Parser { return operator|( other ); }
7061 
7062  auto getHelpColumns() const -> std::vector<HelpColumns> {
7063  std::vector<HelpColumns> cols;
7064  for (auto const &o : m_options) {
7065  auto childCols = o.getHelpColumns();
7066  cols.insert( cols.end(), childCols.begin(), childCols.end() );
7067  }
7068  return cols;
7069  }
7070 
7071  void writeToStream( std::ostream &os ) const {
7072  if (!m_exeName.name().empty()) {
7073  os << "usage:\n" << " " << m_exeName.name() << " ";
7074  bool required = true, first = true;
7075  for( auto const &arg : m_args ) {
7076  if (first)
7077  first = false;
7078  else
7079  os << " ";
7080  if( arg.isOptional() && required ) {
7081  os << "[";
7082  required = false;
7083  }
7084  os << "<" << arg.hint() << ">";
7085  if( arg.cardinality() == 0 )
7086  os << " ... ";
7087  }
7088  if( !required )
7089  os << "]";
7090  if( !m_options.empty() )
7091  os << " options";
7092  os << "\n\nwhere options are:" << std::endl;
7093  }
7094 
7095  auto rows = getHelpColumns();
7096  size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
7097  size_t optWidth = 0;
7098  for( auto const &cols : rows )
7099  optWidth = (std::max)(optWidth, cols.left.size() + 2);
7100 
7101  optWidth = (std::min)(optWidth, consoleWidth/2);
7102 
7103  for( auto const &cols : rows ) {
7104  auto row =
7105  TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
7106  TextFlow::Spacer(4) +
7107  TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth );
7108  os << row << std::endl;
7109  }
7110  }
7111 
7112  friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream& {
7113  parser.writeToStream( os );
7114  return os;
7115  }
7116 
7117  auto validate() const -> Result override {
7118  for( auto const &opt : m_options ) {
7119  auto result = opt.validate();
7120  if( !result )
7121  return result;
7122  }
7123  for( auto const &arg : m_args ) {
7124  auto result = arg.validate();
7125  if( !result )
7126  return result;
7127  }
7128  return Result::ok();
7129  }
7130 
7131  using ParserBase::parse;
7132 
7133  auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override {
7134 
7135  struct ParserInfo {
7136  ParserBase const* parser = nullptr;
7137  size_t count = 0;
7138  };
7139  const size_t totalParsers = m_options.size() + m_args.size();
7140  assert( totalParsers < 512 );
7141  // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do
7142  ParserInfo parseInfos[512];
7143 
7144  {
7145  size_t i = 0;
7146  for (auto const &opt : m_options) parseInfos[i++].parser = &opt;
7147  for (auto const &arg : m_args) parseInfos[i++].parser = &arg;
7148  }
7149 
7150  m_exeName.set( exeName );
7151 
7152  auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
7153  while( result.value().remainingTokens() ) {
7154  bool tokenParsed = false;
7155 
7156  for( size_t i = 0; i < totalParsers; ++i ) {
7157  auto& parseInfo = parseInfos[i];
7158  if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) {
7159  result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
7160  if (!result)
7161  return result;
7162  if (result.value().type() != ParseResultType::NoMatch) {
7163  tokenParsed = true;
7164  ++parseInfo.count;
7165  break;
7166  }
7167  }
7168  }
7169 
7170  if( result.value().type() == ParseResultType::ShortCircuitAll )
7171  return result;
7172  if( !tokenParsed )
7173  return InternalParseResult::runtimeError( "Unrecognised token: " + result.value().remainingTokens()->token );
7174  }
7175  // !TBD Check missing required options
7176  return result;
7177  }
7178  };
7179 
7180  template<typename DerivedT>
7181  template<typename T>
7182  auto ComposableParserImpl<DerivedT>::operator|( T const &other ) const -> Parser {
7183  return Parser() | static_cast<DerivedT const &>( *this ) | other;
7184  }
7185 } // namespace detail
7186 
7187 // A Combined parser
7188 using detail::Parser;
7189 
7190 // A parser for options
7191 using detail::Opt;
7192 
7193 // A parser for arguments
7194 using detail::Arg;
7195 
7196 // Wrapper for argc, argv from main()
7197 using detail::Args;
7198 
7199 // Specifies the name of the executable
7200 using detail::ExeName;
7201 
7202 // Convenience wrapper for option parser that specifies the help option
7203 using detail::Help;
7204 
7205 // enum of result types from a parse
7206 using detail::ParseResultType;
7207 
7208 // Result type for parser operation
7209 using detail::ParserResult;
7210 
7211 }} // namespace Catch::clara
7212 
7213 // end clara.hpp
7214 #ifdef __clang__
7215 #pragma clang diagnostic pop
7216 #endif
7217 
7218 // Restore Clara's value for console width, if present
7219 #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
7220 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
7221 #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
7222 #endif
7223 
7224 // end catch_clara.h
7225 namespace Catch {
7226 
7227  clara::Parser makeCommandLineParser( ConfigData& config );
7228 
7229 } // end namespace Catch
7230 
7231 // end catch_commandline.h
7232 #include <fstream>
7233 #include <ctime>
7234 
7235 namespace Catch {
7236 
7237  clara::Parser makeCommandLineParser( ConfigData& config ) {
7238 
7239  using namespace clara;
7240 
7241  auto const setWarning = [&]( std::string const& warning ) {
7242  auto warningSet = [&]() {
7243  if( warning == "NoAssertions" )
7244  return WarnAbout::NoAssertions;
7245 
7246  if ( warning == "NoTests" )
7247  return WarnAbout::NoTests;
7248 
7249  return WarnAbout::Nothing;
7250  }();
7251 
7252  if (warningSet == WarnAbout::Nothing)
7253  return ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" );
7254  config.warnings = static_cast<WarnAbout::What>( config.warnings | warningSet );
7255  return ParserResult::ok( ParseResultType::Matched );
7256  };
7257  auto const loadTestNamesFromFile = [&]( std::string const& filename ) {
7258  std::ifstream f( filename.c_str() );
7259  if( !f.is_open() )
7260  return ParserResult::runtimeError( "Unable to load input file: '" + filename + "'" );
7261 
7262  std::string line;
7263  while( std::getline( f, line ) ) {
7264  line = trim(line);
7265  if( !line.empty() && !startsWith( line, '#' ) ) {
7266  if( !startsWith( line, '"' ) )
7267  line = '"' + line + '"';
7268  config.testsOrTags.push_back( line + ',' );
7269  }
7270  }
7271  return ParserResult::ok( ParseResultType::Matched );
7272  };
7273  auto const setTestOrder = [&]( std::string const& order ) {
7274  if( startsWith( "declared", order ) )
7275  config.runOrder = RunTests::InDeclarationOrder;
7276  else if( startsWith( "lexical", order ) )
7277  config.runOrder = RunTests::InLexicographicalOrder;
7278  else if( startsWith( "random", order ) )
7279  config.runOrder = RunTests::InRandomOrder;
7280  else
7281  return clara::ParserResult::runtimeError( "Unrecognised ordering: '" + order + "'" );
7282  return ParserResult::ok( ParseResultType::Matched );
7283  };
7284  auto const setRngSeed = [&]( std::string const& seed ) {
7285  if( seed != "time" )
7286  return clara::detail::convertInto( seed, config.rngSeed );
7287  config.rngSeed = static_cast<unsigned int>( std::time(nullptr) );
7288  return ParserResult::ok( ParseResultType::Matched );
7289  };
7290  auto const setColourUsage = [&]( std::string const& useColour ) {
7291  auto mode = toLower( useColour );
7292 
7293  if( mode == "yes" )
7294  config.useColour = UseColour::Yes;
7295  else if( mode == "no" )
7296  config.useColour = UseColour::No;
7297  else if( mode == "auto" )
7298  config.useColour = UseColour::Auto;
7299  else
7300  return ParserResult::runtimeError( "colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised" );
7301  return ParserResult::ok( ParseResultType::Matched );
7302  };
7303  auto const setWaitForKeypress = [&]( std::string const& keypress ) {
7304  auto keypressLc = toLower( keypress );
7305  if( keypressLc == "start" )
7306  config.waitForKeypress = WaitForKeypress::BeforeStart;
7307  else if( keypressLc == "exit" )
7308  config.waitForKeypress = WaitForKeypress::BeforeExit;
7309  else if( keypressLc == "both" )
7310  config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
7311  else
7312  return ParserResult::runtimeError( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" );
7313  return ParserResult::ok( ParseResultType::Matched );
7314  };
7315  auto const setVerbosity = [&]( std::string const& verbosity ) {
7316  auto lcVerbosity = toLower( verbosity );
7317  if( lcVerbosity == "quiet" )
7318  config.verbosity = Verbosity::Quiet;
7319  else if( lcVerbosity == "normal" )
7320  config.verbosity = Verbosity::Normal;
7321  else if( lcVerbosity == "high" )
7322  config.verbosity = Verbosity::High;
7323  else
7324  return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" );
7325  return ParserResult::ok( ParseResultType::Matched );
7326  };
7327  auto const setReporter = [&]( std::string const& reporter ) {
7328  IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
7329 
7330  auto lcReporter = toLower( reporter );
7331  auto result = factories.find( lcReporter );
7332 
7333  if( factories.end() != result )
7334  config.reporterName = lcReporter;
7335  else
7336  return ParserResult::runtimeError( "Unrecognized reporter, '" + reporter + "'. Check available with --list-reporters" );
7337  return ParserResult::ok( ParseResultType::Matched );
7338  };
7339 
7340  auto cli
7341  = ExeName( config.processName )
7342  | Help( config.showHelp )
7343  | Opt( config.listTests )
7344  ["-l"]["--list-tests"]
7345  ( "list all/matching test cases" )
7346  | Opt( config.listTags )
7347  ["-t"]["--list-tags"]
7348  ( "list all/matching tags" )
7349  | Opt( config.showSuccessfulTests )
7350  ["-s"]["--success"]
7351  ( "include successful tests in output" )
7352  | Opt( config.shouldDebugBreak )
7353  ["-b"]["--break"]
7354  ( "break into debugger on failure" )
7355  | Opt( config.noThrow )
7356  ["-e"]["--nothrow"]
7357  ( "skip exception tests" )
7358  | Opt( config.showInvisibles )
7359  ["-i"]["--invisibles"]
7360  ( "show invisibles (tabs, newlines)" )
7361  | Opt( config.outputFilename, "filename" )
7362  ["-o"]["--out"]
7363  ( "output filename" )
7364  | Opt( setReporter, "name" )
7365  ["-r"]["--reporter"]
7366  ( "reporter to use (defaults to console)" )
7367  | Opt( config.name, "name" )
7368  ["-n"]["--name"]
7369  ( "suite name" )
7370  | Opt( [&]( bool ){ config.abortAfter = 1; } )
7371  ["-a"]["--abort"]
7372  ( "abort at first failure" )
7373  | Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" )
7374  ["-x"]["--abortx"]
7375  ( "abort after x failures" )
7376  | Opt( setWarning, "warning name" )
7377  ["-w"]["--warn"]
7378  ( "enable warnings" )
7379  | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" )
7380  ["-d"]["--durations"]
7381  ( "show test durations" )
7382  | Opt( loadTestNamesFromFile, "filename" )
7383  ["-f"]["--input-file"]
7384  ( "load test names to run from a file" )
7385  | Opt( config.filenamesAsTags )
7386  ["-#"]["--filenames-as-tags"]
7387  ( "adds a tag for the filename" )
7388  | Opt( config.sectionsToRun, "section name" )
7389  ["-c"]["--section"]
7390  ( "specify section to run" )
7391  | Opt( setVerbosity, "quiet|normal|high" )
7392  ["-v"]["--verbosity"]
7393  ( "set output verbosity" )
7394  | Opt( config.listTestNamesOnly )
7395  ["--list-test-names-only"]
7396  ( "list all/matching test cases names only" )
7397  | Opt( config.listReporters )
7398  ["--list-reporters"]
7399  ( "list all reporters" )
7400  | Opt( setTestOrder, "decl|lex|rand" )
7401  ["--order"]
7402  ( "test case order (defaults to decl)" )
7403  | Opt( setRngSeed, "'time'|number" )
7404  ["--rng-seed"]
7405  ( "set a specific seed for random numbers" )
7406  | Opt( setColourUsage, "yes|no" )
7407  ["--use-colour"]
7408  ( "should output be colourised" )
7409  | Opt( config.libIdentify )
7410  ["--libidentify"]
7411  ( "report name and version according to libidentify standard" )
7412  | Opt( setWaitForKeypress, "start|exit|both" )
7413  ["--wait-for-keypress"]
7414  ( "waits for a keypress before exiting" )
7415  | Opt( config.benchmarkResolutionMultiple, "multiplier" )
7416  ["--benchmark-resolution-multiple"]
7417  ( "multiple of clock resolution to run benchmarks" )
7418 
7419  | Arg( config.testsOrTags, "test name|pattern|tags" )
7420  ( "which test or tests to use" );
7421 
7422  return cli;
7423  }
7424 
7425 } // end namespace Catch
7426 // end catch_commandline.cpp
7427 // start catch_common.cpp
7428 
7429 #include <cstring>
7430 #include <ostream>
7431 
7432 namespace Catch {
7433 
7434  bool SourceLineInfo::empty() const noexcept {
7435  return file[0] == '\0';
7436  }
7437  bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept {
7438  return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
7439  }
7440  bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept {
7441  // We can assume that the same file will usually have the same pointer.
7442  // Thus, if the pointers are the same, there is no point in calling the strcmp
7443  return line < other.line || ( line == other.line && file != other.file && (std::strcmp(file, other.file) < 0));
7444  }
7445 
7446  std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
7447 #ifndef __GNUG__
7448  os << info.file << '(' << info.line << ')';
7449 #else
7450  os << info.file << ':' << info.line;
7451 #endif
7452  return os;
7453  }
7454 
7455  std::string StreamEndStop::operator+() const {
7456  return std::string();
7457  }
7458 
7459  NonCopyable::NonCopyable() = default;
7460  NonCopyable::~NonCopyable() = default;
7461 
7462 }
7463 // end catch_common.cpp
7464 // start catch_config.cpp
7465 
7466 namespace Catch {
7467 
7468  Config::Config( ConfigData const& data )
7469  : m_data( data ),
7470  m_stream( openStream() )
7471  {
7472  TestSpecParser parser(ITagAliasRegistry::get());
7473  if (data.testsOrTags.empty()) {
7474  parser.parse("~[.]"); // All not hidden tests
7475  }
7476  else {
7477  m_hasTestFilters = true;
7478  for( auto const& testOrTags : data.testsOrTags )
7479  parser.parse( testOrTags );
7480  }
7481  m_testSpec = parser.testSpec();
7482  }
7483 
7484  std::string const& Config::getFilename() const {
7485  return m_data.outputFilename ;
7486  }
7487 
7488  bool Config::listTests() const { return m_data.listTests; }
7489  bool Config::listTestNamesOnly() const { return m_data.listTestNamesOnly; }
7490  bool Config::listTags() const { return m_data.listTags; }
7491  bool Config::listReporters() const { return m_data.listReporters; }
7492 
7493  std::string Config::getProcessName() const { return m_data.processName; }
7494  std::string const& Config::getReporterName() const { return m_data.reporterName; }
7495 
7496  std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }
7497  std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
7498 
7499  TestSpec const& Config::testSpec() const { return m_testSpec; }
7500  bool Config::hasTestFilters() const { return m_hasTestFilters; }
7501 
7502  bool Config::showHelp() const { return m_data.showHelp; }
7503 
7504  // IConfig interface
7505  bool Config::allowThrows() const { return !m_data.noThrow; }
7506  std::ostream& Config::stream() const { return m_stream->stream(); }
7507  std::string Config::name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
7508  bool Config::includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
7509  bool Config::warnAboutMissingAssertions() const { return !!(m_data.warnings & WarnAbout::NoAssertions); }
7510  bool Config::warnAboutNoTests() const { return !!(m_data.warnings & WarnAbout::NoTests); }
7511  ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }
7512  RunTests::InWhatOrder Config::runOrder() const { return m_data.runOrder; }
7513  unsigned int Config::rngSeed() const { return m_data.rngSeed; }
7514  int Config::benchmarkResolutionMultiple() const { return m_data.benchmarkResolutionMultiple; }
7515  UseColour::YesOrNo Config::useColour() const { return m_data.useColour; }
7516  bool Config::shouldDebugBreak() const { return m_data.shouldDebugBreak; }
7517  int Config::abortAfter() const { return m_data.abortAfter; }
7518  bool Config::showInvisibles() const { return m_data.showInvisibles; }
7519  Verbosity Config::verbosity() const { return m_data.verbosity; }
7520 
7521  IStream const* Config::openStream() {
7522  return Catch::makeStream(m_data.outputFilename);
7523  }
7524 
7525 } // end namespace Catch
7526 // end catch_config.cpp
7527 // start catch_console_colour.cpp
7528 
7529 #if defined(__clang__)
7530 # pragma clang diagnostic push
7531 # pragma clang diagnostic ignored "-Wexit-time-destructors"
7532 #endif
7533 
7534 // start catch_errno_guard.h
7535 
7536 namespace Catch {
7537 
7538  class ErrnoGuard {
7539  public:
7540  ErrnoGuard();
7541  ~ErrnoGuard();
7542  private:
7543  int m_oldErrno;
7544  };
7545 
7546 }
7547 
7548 // end catch_errno_guard.h
7549 #include <sstream>
7550 
7551 namespace Catch {
7552  namespace {
7553 
7554  struct IColourImpl {
7555  virtual ~IColourImpl() = default;
7556  virtual void use( Colour::Code _colourCode ) = 0;
7557  };
7558 
7559  struct NoColourImpl : IColourImpl {
7560  void use( Colour::Code ) {}
7561 
7562  static IColourImpl* instance() {
7563  static NoColourImpl s_instance;
7564  return &s_instance;
7565  }
7566  };
7567 
7568  } // anon namespace
7569 } // namespace Catch
7570 
7571 #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
7572 # ifdef CATCH_PLATFORM_WINDOWS
7573 # define CATCH_CONFIG_COLOUR_WINDOWS
7574 # else
7575 # define CATCH_CONFIG_COLOUR_ANSI
7576 # endif
7577 #endif
7578 
7579 #if defined ( CATCH_CONFIG_COLOUR_WINDOWS )
7580 
7581 namespace Catch {
7582 namespace {
7583 
7584  class Win32ColourImpl : public IColourImpl {
7585  public:
7586  Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
7587  {
7588  CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
7589  GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
7590  originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
7591  originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
7592  }
7593 
7594  virtual void use( Colour::Code _colourCode ) override {
7595  switch( _colourCode ) {
7596  case Colour::None: return setTextAttribute( originalForegroundAttributes );
7597  case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
7598  case Colour::Red: return setTextAttribute( FOREGROUND_RED );
7599  case Colour::Green: return setTextAttribute( FOREGROUND_GREEN );
7600  case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE );
7601  case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
7602  case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
7603  case Colour::Grey: return setTextAttribute( 0 );
7604 
7605  case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY );
7606  case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
7607  case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
7608  case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
7609  case Colour::BrightYellow: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN );
7610 
7611  case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
7612 
7613  default:
7614  CATCH_ERROR( "Unknown colour requested" );
7615  }
7616  }
7617 
7618  private:
7619  void setTextAttribute( WORD _textAttribute ) {
7620  SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
7621  }
7622  HANDLE stdoutHandle;
7623  WORD originalForegroundAttributes;
7624  WORD originalBackgroundAttributes;
7625  };
7626 
7627  IColourImpl* platformColourInstance() {
7628  static Win32ColourImpl s_instance;
7629 
7630  IConfigPtr config = getCurrentContext().getConfig();
7631  UseColour::YesOrNo colourMode = config
7632  ? config->useColour()
7633  : UseColour::Auto;
7634  if( colourMode == UseColour::Auto )
7635  colourMode = UseColour::Yes;
7636  return colourMode == UseColour::Yes
7637  ? &s_instance
7638  : NoColourImpl::instance();
7639  }
7640 
7641 } // end anon namespace
7642 } // end namespace Catch
7643 
7644 #elif defined( CATCH_CONFIG_COLOUR_ANSI )
7645 
7646 #include <unistd.h>
7647 
7648 namespace Catch {
7649 namespace {
7650 
7651  // use POSIX/ ANSI console terminal codes
7652  // Thanks to Adam Strzelecki for original contribution
7653  // (http://github.com/nanoant)
7654  // https://github.com/philsquared/Catch/pull/131
7655  class PosixColourImpl : public IColourImpl {
7656  public:
7657  virtual void use( Colour::Code _colourCode ) override {
7658  switch( _colourCode ) {
7659  case Colour::None:
7660  case Colour::White: return setColour( "[0m" );
7661  case Colour::Red: return setColour( "[0;31m" );
7662  case Colour::Green: return setColour( "[0;32m" );
7663  case Colour::Blue: return setColour( "[0;34m" );
7664  case Colour::Cyan: return setColour( "[0;36m" );
7665  case Colour::Yellow: return setColour( "[0;33m" );
7666  case Colour::Grey: return setColour( "[1;30m" );
7667 
7668  case Colour::LightGrey: return setColour( "[0;37m" );
7669  case Colour::BrightRed: return setColour( "[1;31m" );
7670  case Colour::BrightGreen: return setColour( "[1;32m" );
7671  case Colour::BrightWhite: return setColour( "[1;37m" );
7672  case Colour::BrightYellow: return setColour( "[1;33m" );
7673 
7674  case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
7675  default: CATCH_INTERNAL_ERROR( "Unknown colour requested" );
7676  }
7677  }
7678  static IColourImpl* instance() {
7679  static PosixColourImpl s_instance;
7680  return &s_instance;
7681  }
7682 
7683  private:
7684  void setColour( const char* _escapeCode ) {
7685  Catch::cout() << '\033' << _escapeCode;
7686  }
7687  };
7688 
7689  bool useColourOnPlatform() {
7690  return
7691 #ifdef CATCH_PLATFORM_MAC
7692  !isDebuggerActive() &&
7693 #endif
7694 #if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
7695  isatty(STDOUT_FILENO)
7696 #else
7697  false
7698 #endif
7699  ;
7700  }
7701  IColourImpl* platformColourInstance() {
7702  ErrnoGuard guard;
7703  IConfigPtr config = getCurrentContext().getConfig();
7704  UseColour::YesOrNo colourMode = config
7705  ? config->useColour()
7706  : UseColour::Auto;
7707  if( colourMode == UseColour::Auto )
7708  colourMode = useColourOnPlatform()
7709  ? UseColour::Yes
7710  : UseColour::No;
7711  return colourMode == UseColour::Yes
7712  ? PosixColourImpl::instance()
7713  : NoColourImpl::instance();
7714  }
7715 
7716 } // end anon namespace
7717 } // end namespace Catch
7718 
7719 #else // not Windows or ANSI
7720 
7721 namespace Catch {
7722 
7723  static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
7724 
7725 } // end namespace Catch
7726 
7727 #endif // Windows/ ANSI/ None
7728 
7729 namespace Catch {
7730 
7731  Colour::Colour( Code _colourCode ) { use( _colourCode ); }
7732  Colour::Colour( Colour&& rhs ) noexcept {
7733  m_moved = rhs.m_moved;
7734  rhs.m_moved = true;
7735  }
7736  Colour& Colour::operator=( Colour&& rhs ) noexcept {
7737  m_moved = rhs.m_moved;
7738  rhs.m_moved = true;
7739  return *this;
7740  }
7741 
7742  Colour::~Colour(){ if( !m_moved ) use( None ); }
7743 
7744  void Colour::use( Code _colourCode ) {
7745  static IColourImpl* impl = platformColourInstance();
7746  impl->use( _colourCode );
7747  }
7748 
7749  std::ostream& operator << ( std::ostream& os, Colour const& ) {
7750  return os;
7751  }
7752 
7753 } // end namespace Catch
7754 
7755 #if defined(__clang__)
7756 # pragma clang diagnostic pop
7757 #endif
7758 
7759 // end catch_console_colour.cpp
7760 // start catch_context.cpp
7761 
7762 namespace Catch {
7763 
7764  class Context : public IMutableContext, NonCopyable {
7765 
7766  public: // IContext
7767  virtual IResultCapture* getResultCapture() override {
7768  return m_resultCapture;
7769  }
7770  virtual IRunner* getRunner() override {
7771  return m_runner;
7772  }
7773 
7774  virtual IConfigPtr const& getConfig() const override {
7775  return m_config;
7776  }
7777 
7778  virtual ~Context() override;
7779 
7780  public: // IMutableContext
7781  virtual void setResultCapture( IResultCapture* resultCapture ) override {
7782  m_resultCapture = resultCapture;
7783  }
7784  virtual void setRunner( IRunner* runner ) override {
7785  m_runner = runner;
7786  }
7787  virtual void setConfig( IConfigPtr const& config ) override {
7788  m_config = config;
7789  }
7790 
7791  friend IMutableContext& getCurrentMutableContext();
7792 
7793  private:
7794  IConfigPtr m_config;
7795  IRunner* m_runner = nullptr;
7796  IResultCapture* m_resultCapture = nullptr;
7797  };
7798 
7799  IMutableContext *IMutableContext::currentContext = nullptr;
7800 
7801  void IMutableContext::createContext()
7802  {
7803  currentContext = new Context();
7804  }
7805 
7806  void cleanUpContext() {
7807  delete IMutableContext::currentContext;
7808  IMutableContext::currentContext = nullptr;
7809  }
7810  IContext::~IContext() = default;
7811  IMutableContext::~IMutableContext() = default;
7812  Context::~Context() = default;
7813 }
7814 // end catch_context.cpp
7815 // start catch_debug_console.cpp
7816 
7817 // start catch_debug_console.h
7818 
7819 #include <string>
7820 
7821 namespace Catch {
7822  void writeToDebugConsole( std::string const& text );
7823 }
7824 
7825 // end catch_debug_console.h
7826 #ifdef CATCH_PLATFORM_WINDOWS
7827 
7828  namespace Catch {
7829  void writeToDebugConsole( std::string const& text ) {
7830  ::OutputDebugStringA( text.c_str() );
7831  }
7832  }
7833 
7834 #else
7835 
7836  namespace Catch {
7837  void writeToDebugConsole( std::string const& text ) {
7838  // !TBD: Need a version for Mac/ XCode and other IDEs
7839  Catch::cout() << text;
7840  }
7841  }
7842 
7843 #endif // Platform
7844 // end catch_debug_console.cpp
7845 // start catch_debugger.cpp
7846 
7847 #ifdef CATCH_PLATFORM_MAC
7848 
7849 # include <assert.h>
7850 # include <stdbool.h>
7851 # include <sys/types.h>
7852 # include <unistd.h>
7853 # include <sys/sysctl.h>
7854 # include <cstddef>
7855 # include <ostream>
7856 
7857 namespace Catch {
7858 
7859  // The following function is taken directly from the following technical note:
7860  // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
7861 
7862  // Returns true if the current process is being debugged (either
7863  // running under the debugger or has a debugger attached post facto).
7864  bool isDebuggerActive(){
7865 
7866  int mib[4];
7867  struct kinfo_proc info;
7868  std::size_t size;
7869 
7870  // Initialize the flags so that, if sysctl fails for some bizarre
7871  // reason, we get a predictable result.
7872 
7873  info.kp_proc.p_flag = 0;
7874 
7875  // Initialize mib, which tells sysctl the info we want, in this case
7876  // we're looking for information about a specific process ID.
7877 
7878  mib[0] = CTL_KERN;
7879  mib[1] = KERN_PROC;
7880  mib[2] = KERN_PROC_PID;
7881  mib[3] = getpid();
7882 
7883  // Call sysctl.
7884 
7885  size = sizeof(info);
7886  if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) {
7887  Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
7888  return false;
7889  }
7890 
7891  // We're being debugged if the P_TRACED flag is set.
7892 
7893  return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
7894  }
7895  } // namespace Catch
7896 
7897 #elif defined(CATCH_PLATFORM_LINUX)
7898  #include <fstream>
7899  #include <string>
7900 
7901  namespace Catch{
7902  // The standard POSIX way of detecting a debugger is to attempt to
7903  // ptrace() the process, but this needs to be done from a child and not
7904  // this process itself to still allow attaching to this process later
7905  // if wanted, so is rather heavy. Under Linux we have the PID of the
7906  // "debugger" (which doesn't need to be gdb, of course, it could also
7907  // be strace, for example) in /proc/$PID/status, so just get it from
7908  // there instead.
7909  bool isDebuggerActive(){
7910  // Libstdc++ has a bug, where std::ifstream sets errno to 0
7911  // This way our users can properly assert over errno values
7912  ErrnoGuard guard;
7913  std::ifstream in("/proc/self/status");
7914  for( std::string line; std::getline(in, line); ) {
7915  static const int PREFIX_LEN = 11;
7916  if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
7917  // We're traced if the PID is not 0 and no other PID starts
7918  // with 0 digit, so it's enough to check for just a single
7919  // character.
7920  return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
7921  }
7922  }
7923 
7924  return false;
7925  }
7926  } // namespace Catch
7927 #elif defined(_MSC_VER)
7928  extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
7929  namespace Catch {
7930  bool isDebuggerActive() {
7931  return IsDebuggerPresent() != 0;
7932  }
7933  }
7934 #elif defined(__MINGW32__)
7935  extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
7936  namespace Catch {
7937  bool isDebuggerActive() {
7938  return IsDebuggerPresent() != 0;
7939  }
7940  }
7941 #else
7942  namespace Catch {
7943  bool isDebuggerActive() { return false; }
7944  }
7945 #endif // Platform
7946 // end catch_debugger.cpp
7947 // start catch_decomposer.cpp
7948 
7949 namespace Catch {
7950 
7951  ITransientExpression::~ITransientExpression() = default;
7952 
7953  void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {
7954  if( lhs.size() + rhs.size() < 40 &&
7955  lhs.find('\n') == std::string::npos &&
7956  rhs.find('\n') == std::string::npos )
7957  os << lhs << " " << op << " " << rhs;
7958  else
7959  os << lhs << "\n" << op << "\n" << rhs;
7960  }
7961 }
7962 // end catch_decomposer.cpp
7963 // start catch_enforce.cpp
7964 
7965 namespace Catch {
7966 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)
7967  [[noreturn]]
7968  void throw_exception(std::exception const& e) {
7969  Catch::cerr() << "Catch will terminate because it needed to throw an exception.\n"
7970  << "The message was: " << e.what() << '\n';
7971  std::terminate();
7972  }
7973 #endif
7974 } // namespace Catch;
7975 // end catch_enforce.cpp
7976 // start catch_errno_guard.cpp
7977 
7978 #include <cerrno>
7979 
7980 namespace Catch {
7981  ErrnoGuard::ErrnoGuard():m_oldErrno(errno){}
7982  ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }
7983 }
7984 // end catch_errno_guard.cpp
7985 // start catch_exception_translator_registry.cpp
7986 
7987 // start catch_exception_translator_registry.h
7988 
7989 #include <vector>
7990 #include <string>
7991 #include <memory>
7992 
7993 namespace Catch {
7994 
7995  class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
7996  public:
7997  ~ExceptionTranslatorRegistry();
7998  virtual void registerTranslator( const IExceptionTranslator* translator );
7999  virtual std::string translateActiveException() const override;
8000  std::string tryTranslators() const;
8001 
8002  private:
8003  std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators;
8004  };
8005 }
8006 
8007 // end catch_exception_translator_registry.h
8008 #ifdef __OBJC__
8009 #import "Foundation/Foundation.h"
8010 #endif
8011 
8012 namespace Catch {
8013 
8014  ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {
8015  }
8016 
8017  void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) {
8018  m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );
8019  }
8020 
8021 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
8022  std::string ExceptionTranslatorRegistry::translateActiveException() const {
8023  try {
8024 #ifdef __OBJC__
8025  // In Objective-C try objective-c exceptions first
8026  @try {
8027  return tryTranslators();
8028  }
8029  @catch (NSException *exception) {
8030  return Catch::Detail::stringify( [exception description] );
8031  }
8032 #else
8033  // Compiling a mixed mode project with MSVC means that CLR
8034  // exceptions will be caught in (...) as well. However, these
8035  // do not fill-in std::current_exception and thus lead to crash
8036  // when attempting rethrow.
8037  // /EHa switch also causes structured exceptions to be caught
8038  // here, but they fill-in current_exception properly, so
8039  // at worst the output should be a little weird, instead of
8040  // causing a crash.
8041  if (std::current_exception() == nullptr) {
8042  return "Non C++ exception. Possibly a CLR exception.";
8043  }
8044  return tryTranslators();
8045 #endif
8046  }
8047  catch( TestFailureException& ) {
8048  std::rethrow_exception(std::current_exception());
8049  }
8050  catch( std::exception& ex ) {
8051  return ex.what();
8052  }
8053  catch( std::string& msg ) {
8054  return msg;
8055  }
8056  catch( const char* msg ) {
8057  return msg;
8058  }
8059  catch(...) {
8060  return "Unknown exception";
8061  }
8062  }
8063 
8064 #else // ^^ Exceptions are enabled // Exceptions are disabled vv
8065  std::string ExceptionTranslatorRegistry::translateActiveException() const {
8066  CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
8067  }
8068 #endif
8069 
8070  std::string ExceptionTranslatorRegistry::tryTranslators() const {
8071  if( m_translators.empty() )
8072  std::rethrow_exception(std::current_exception());
8073  else
8074  return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );
8075  }
8076 }
8077 // end catch_exception_translator_registry.cpp
8078 // start catch_fatal_condition.cpp
8079 
8080 #if defined(__GNUC__)
8081 # pragma GCC diagnostic push
8082 # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
8083 #endif
8084 
8085 #if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )
8086 
8087 namespace {
8088  // Report the error condition
8089  void reportFatal( char const * const message ) {
8090  Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
8091  }
8092 }
8093 
8094 #endif // signals/SEH handling
8095 
8096 #if defined( CATCH_CONFIG_WINDOWS_SEH )
8097 
8098 namespace Catch {
8099  struct SignalDefs { DWORD id; const char* name; };
8100 
8101  // There is no 1-1 mapping between signals and windows exceptions.
8102  // Windows can easily distinguish between SO and SigSegV,
8103  // but SigInt, SigTerm, etc are handled differently.
8104  static SignalDefs signalDefs[] = {
8105  { EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal" },
8106  { EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" },
8107  { EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" },
8108  { EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" },
8109  };
8110 
8111  LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
8112  for (auto const& def : signalDefs) {
8113  if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
8114  reportFatal(def.name);
8115  }
8116  }
8117  // If its not an exception we care about, pass it along.
8118  // This stops us from eating debugger breaks etc.
8119  return EXCEPTION_CONTINUE_SEARCH;
8120  }
8121 
8122  FatalConditionHandler::FatalConditionHandler() {
8123  isSet = true;
8124  // 32k seems enough for Catch to handle stack overflow,
8125  // but the value was found experimentally, so there is no strong guarantee
8126  guaranteeSize = 32 * 1024;
8127  exceptionHandlerHandle = nullptr;
8128  // Register as first handler in current chain
8129  exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
8130  // Pass in guarantee size to be filled
8131  SetThreadStackGuarantee(&guaranteeSize);
8132  }
8133 
8134  void FatalConditionHandler::reset() {
8135  if (isSet) {
8136  RemoveVectoredExceptionHandler(exceptionHandlerHandle);
8137  SetThreadStackGuarantee(&guaranteeSize);
8138  exceptionHandlerHandle = nullptr;
8139  isSet = false;
8140  }
8141  }
8142 
8143  FatalConditionHandler::~FatalConditionHandler() {
8144  reset();
8145  }
8146 
8147 bool FatalConditionHandler::isSet = false;
8148 ULONG FatalConditionHandler::guaranteeSize = 0;
8149 PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;
8150 
8151 } // namespace Catch
8152 
8153 #elif defined( CATCH_CONFIG_POSIX_SIGNALS )
8154 
8155 namespace Catch {
8156 
8157  struct SignalDefs {
8158  int id;
8159  const char* name;
8160  };
8161 
8162  // 32kb for the alternate stack seems to be sufficient. However, this value
8163  // is experimentally determined, so that's not guaranteed.
8164  constexpr static std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
8165 
8166  static SignalDefs signalDefs[] = {
8167  { SIGINT, "SIGINT - Terminal interrupt signal" },
8168  { SIGILL, "SIGILL - Illegal instruction signal" },
8169  { SIGFPE, "SIGFPE - Floating point error signal" },
8170  { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
8171  { SIGTERM, "SIGTERM - Termination request signal" },
8172  { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
8173  };
8174 
8175  void FatalConditionHandler::handleSignal( int sig ) {
8176  char const * name = "<unknown signal>";
8177  for (auto const& def : signalDefs) {
8178  if (sig == def.id) {
8179  name = def.name;
8180  break;
8181  }
8182  }
8183  reset();
8184  reportFatal(name);
8185  raise( sig );
8186  }
8187 
8188  FatalConditionHandler::FatalConditionHandler() {
8189  isSet = true;
8190  stack_t sigStack;
8191  sigStack.ss_sp = altStackMem;
8192  sigStack.ss_size = sigStackSize;
8193  sigStack.ss_flags = 0;
8194  sigaltstack(&sigStack, &oldSigStack);
8195  struct sigaction sa = { };
8196 
8197  sa.sa_handler = handleSignal;
8198  sa.sa_flags = SA_ONSTACK;
8199  for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {
8200  sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
8201  }
8202  }
8203 
8204  FatalConditionHandler::~FatalConditionHandler() {
8205  reset();
8206  }
8207 
8208  void FatalConditionHandler::reset() {
8209  if( isSet ) {
8210  // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
8211  for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
8212  sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
8213  }
8214  // Return the old stack
8215  sigaltstack(&oldSigStack, nullptr);
8216  isSet = false;
8217  }
8218  }
8219 
8220  bool FatalConditionHandler::isSet = false;
8221  struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
8222  stack_t FatalConditionHandler::oldSigStack = {};
8223  char FatalConditionHandler::altStackMem[sigStackSize] = {};
8224 
8225 } // namespace Catch
8226 
8227 #else
8228 
8229 namespace Catch {
8230  void FatalConditionHandler::reset() {}
8231 }
8232 
8233 #endif // signals/SEH handling
8234 
8235 #if defined(__GNUC__)
8236 # pragma GCC diagnostic pop
8237 #endif
8238 // end catch_fatal_condition.cpp
8239 // start catch_generators.cpp
8240 
8241 // start catch_random_number_generator.h
8242 
8243 #include <algorithm>
8244 #include <random>
8245 
8246 namespace Catch {
8247 
8248  struct IConfig;
8249 
8250  std::mt19937& rng();
8251  void seedRng( IConfig const& config );
8252  unsigned int rngSeed();
8253 
8254 }
8255 
8256 // end catch_random_number_generator.h
8257 #include <limits>
8258 #include <set>
8259 
8260 namespace Catch {
8261 
8262 IGeneratorTracker::~IGeneratorTracker() {}
8263 
8264 namespace Generators {
8265 
8266  GeneratorBase::~GeneratorBase() {}
8267 
8268  std::vector<size_t> randomiseIndices( size_t selectionSize, size_t sourceSize ) {
8269 
8270  assert( selectionSize <= sourceSize );
8271  std::vector<size_t> indices;
8272  indices.reserve( selectionSize );
8273  std::uniform_int_distribution<size_t> uid( 0, sourceSize-1 );
8274 
8275  std::set<size_t> seen;
8276  // !TBD: improve this algorithm
8277  while( indices.size() < selectionSize ) {
8278  auto index = uid( rng() );
8279  if( seen.insert( index ).second )
8280  indices.push_back( index );
8281  }
8282  return indices;
8283  }
8284 
8285  auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
8286  return getResultCapture().acquireGeneratorTracker( lineInfo );
8287  }
8288 
8289  template<>
8290  auto all<int>() -> Generator<int> {
8291  return range( std::numeric_limits<int>::min(), std::numeric_limits<int>::max() );
8292  }
8293 
8294 } // namespace Generators
8295 } // namespace Catch
8296 // end catch_generators.cpp
8297 // start catch_interfaces_capture.cpp
8298 
8299 namespace Catch {
8300  IResultCapture::~IResultCapture() = default;
8301 }
8302 // end catch_interfaces_capture.cpp
8303 // start catch_interfaces_config.cpp
8304 
8305 namespace Catch {
8306  IConfig::~IConfig() = default;
8307 }
8308 // end catch_interfaces_config.cpp
8309 // start catch_interfaces_exception.cpp
8310 
8311 namespace Catch {
8312  IExceptionTranslator::~IExceptionTranslator() = default;
8313  IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default;
8314 }
8315 // end catch_interfaces_exception.cpp
8316 // start catch_interfaces_registry_hub.cpp
8317 
8318 namespace Catch {
8319  IRegistryHub::~IRegistryHub() = default;
8320  IMutableRegistryHub::~IMutableRegistryHub() = default;
8321 }
8322 // end catch_interfaces_registry_hub.cpp
8323 // start catch_interfaces_reporter.cpp
8324 
8325 // start catch_reporter_listening.h
8326 
8327 namespace Catch {
8328 
8329  class ListeningReporter : public IStreamingReporter {
8330  using Reporters = std::vector<IStreamingReporterPtr>;
8331  Reporters m_listeners;
8332  IStreamingReporterPtr m_reporter = nullptr;
8333  ReporterPreferences m_preferences;
8334 
8335  public:
8336  ListeningReporter();
8337 
8338  void addListener( IStreamingReporterPtr&& listener );
8339  void addReporter( IStreamingReporterPtr&& reporter );
8340 
8341  public: // IStreamingReporter
8342 
8343  ReporterPreferences getPreferences() const override;
8344 
8345  void noMatchingTestCases( std::string const& spec ) override;
8346 
8347  static std::set<Verbosity> getSupportedVerbosities();
8348 
8349  void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;
8350  void benchmarkEnded( BenchmarkStats const& benchmarkStats ) override;
8351 
8352  void testRunStarting( TestRunInfo const& testRunInfo ) override;
8353  void testGroupStarting( GroupInfo const& groupInfo ) override;
8354  void testCaseStarting( TestCaseInfo const& testInfo ) override;
8355  void sectionStarting( SectionInfo const& sectionInfo ) override;
8356  void assertionStarting( AssertionInfo const& assertionInfo ) override;
8357 
8358  // The return value indicates if the messages buffer should be cleared:
8359  bool assertionEnded( AssertionStats const& assertionStats ) override;
8360  void sectionEnded( SectionStats const& sectionStats ) override;
8361  void testCaseEnded( TestCaseStats const& testCaseStats ) override;
8362  void testGroupEnded( TestGroupStats const& testGroupStats ) override;
8363  void testRunEnded( TestRunStats const& testRunStats ) override;
8364 
8365  void skipTest( TestCaseInfo const& testInfo ) override;
8366  bool isMulti() const override;
8367 
8368  };
8369 
8370 } // end namespace Catch
8371 
8372 // end catch_reporter_listening.h
8373 namespace Catch {
8374 
8375  ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig )
8376  : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
8377 
8378  ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream )
8379  : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
8380 
8381  std::ostream& ReporterConfig::stream() const { return *m_stream; }
8382  IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; }
8383 
8384  TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {}
8385 
8386  GroupInfo::GroupInfo( std::string const& _name,
8387  std::size_t _groupIndex,
8388  std::size_t _groupsCount )
8389  : name( _name ),
8390  groupIndex( _groupIndex ),
8391  groupsCounts( _groupsCount )
8392  {}
8393 
8394  AssertionStats::AssertionStats( AssertionResult const& _assertionResult,
8395  std::vector<MessageInfo> const& _infoMessages,
8396  Totals const& _totals )
8397  : assertionResult( _assertionResult ),
8398  infoMessages( _infoMessages ),
8399  totals( _totals )
8400  {
8401  assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;
8402 
8403  if( assertionResult.hasMessage() ) {
8404  // Copy message into messages list.
8405  // !TBD This should have been done earlier, somewhere
8406  MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
8407  builder << assertionResult.getMessage();
8408  builder.m_info.message = builder.m_stream.str();
8409 
8410  infoMessages.push_back( builder.m_info );
8411  }
8412  }
8413 
8414  AssertionStats::~AssertionStats() = default;
8415 
8416  SectionStats::SectionStats( SectionInfo const& _sectionInfo,
8417  Counts const& _assertions,
8418  double _durationInSeconds,
8419  bool _missingAssertions )
8420  : sectionInfo( _sectionInfo ),
8421  assertions( _assertions ),
8422  durationInSeconds( _durationInSeconds ),
8423  missingAssertions( _missingAssertions )
8424  {}
8425 
8426  SectionStats::~SectionStats() = default;
8427 
8428  TestCaseStats::TestCaseStats( TestCaseInfo const& _testInfo,
8429  Totals const& _totals,
8430  std::string const& _stdOut,
8431  std::string const& _stdErr,
8432  bool _aborting )
8433  : testInfo( _testInfo ),
8434  totals( _totals ),
8435  stdOut( _stdOut ),
8436  stdErr( _stdErr ),
8437  aborting( _aborting )
8438  {}
8439 
8440  TestCaseStats::~TestCaseStats() = default;
8441 
8442  TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo,
8443  Totals const& _totals,
8444  bool _aborting )
8445  : groupInfo( _groupInfo ),
8446  totals( _totals ),
8447  aborting( _aborting )
8448  {}
8449 
8450  TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo )
8451  : groupInfo( _groupInfo ),
8452  aborting( false )
8453  {}
8454 
8455  TestGroupStats::~TestGroupStats() = default;
8456 
8457  TestRunStats::TestRunStats( TestRunInfo const& _runInfo,
8458  Totals const& _totals,
8459  bool _aborting )
8460  : runInfo( _runInfo ),
8461  totals( _totals ),
8462  aborting( _aborting )
8463  {}
8464 
8465  TestRunStats::~TestRunStats() = default;
8466 
8467  void IStreamingReporter::fatalErrorEncountered( StringRef ) {}
8468  bool IStreamingReporter::isMulti() const { return false; }
8469 
8470  IReporterFactory::~IReporterFactory() = default;
8471  IReporterRegistry::~IReporterRegistry() = default;
8472 
8473 } // end namespace Catch
8474 // end catch_interfaces_reporter.cpp
8475 // start catch_interfaces_runner.cpp
8476 
8477 namespace Catch {
8478  IRunner::~IRunner() = default;
8479 }
8480 // end catch_interfaces_runner.cpp
8481 // start catch_interfaces_testcase.cpp
8482 
8483 namespace Catch {
8484  ITestInvoker::~ITestInvoker() = default;
8485  ITestCaseRegistry::~ITestCaseRegistry() = default;
8486 }
8487 // end catch_interfaces_testcase.cpp
8488 // start catch_leak_detector.cpp
8489 
8490 #ifdef CATCH_CONFIG_WINDOWS_CRTDBG
8491 #include <crtdbg.h>
8492 
8493 namespace Catch {
8494 
8495  LeakDetector::LeakDetector() {
8496  int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
8497  flag |= _CRTDBG_LEAK_CHECK_DF;
8498  flag |= _CRTDBG_ALLOC_MEM_DF;
8499  _CrtSetDbgFlag(flag);
8500  _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
8501  _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
8502  // Change this to leaking allocation's number to break there
8503  _CrtSetBreakAlloc(-1);
8504  }
8505 }
8506 
8507 #else
8508 
8509  Catch::LeakDetector::LeakDetector() {}
8510 
8511 #endif
8512 
8513 Catch::LeakDetector::~LeakDetector() {
8514  Catch::cleanUp();
8515 }
8516 // end catch_leak_detector.cpp
8517 // start catch_list.cpp
8518 
8519 // start catch_list.h
8520 
8521 #include <set>
8522 
8523 namespace Catch {
8524 
8525  std::size_t listTests( Config const& config );
8526 
8527  std::size_t listTestsNamesOnly( Config const& config );
8528 
8529  struct TagInfo {
8530  void add( std::string const& spelling );
8531  std::string all() const;
8532 
8533  std::set<std::string> spellings;
8534  std::size_t count = 0;
8535  };
8536 
8537  std::size_t listTags( Config const& config );
8538 
8539  std::size_t listReporters();
8540 
8541  Option<std::size_t> list( Config const& config );
8542 
8543 } // end namespace Catch
8544 
8545 // end catch_list.h
8546 // start catch_text.h
8547 
8548 namespace Catch {
8549  using namespace clara::TextFlow;
8550 }
8551 
8552 // end catch_text.h
8553 #include <limits>
8554 #include <algorithm>
8555 #include <iomanip>
8556 
8557 namespace Catch {
8558 
8559  std::size_t listTests( Config const& config ) {
8560  TestSpec testSpec = config.testSpec();
8561  if( config.hasTestFilters() )
8562  Catch::cout() << "Matching test cases:\n";
8563  else {
8564  Catch::cout() << "All available test cases:\n";
8565  }
8566 
8567  auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
8568  for( auto const& testCaseInfo : matchedTestCases ) {
8569  Colour::Code colour = testCaseInfo.isHidden()
8570  ? Colour::SecondaryText
8571  : Colour::None;
8572  Colour colourGuard( colour );
8573 
8574  Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << "\n";
8575  if( config.verbosity() >= Verbosity::High ) {
8576  Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl;
8577  std::string description = testCaseInfo.description;
8578  if( description.empty() )
8579  description = "(NO DESCRIPTION)";
8580  Catch::cout() << Column( description ).indent(4) << std::endl;
8581  }
8582  if( !testCaseInfo.tags.empty() )
8583  Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << "\n";
8584  }
8585 
8586  if( !config.hasTestFilters() )
8587  Catch::cout() << pluralise( matchedTestCases.size(), "test case" ) << '\n' << std::endl;
8588  else
8589  Catch::cout() << pluralise( matchedTestCases.size(), "matching test case" ) << '\n' << std::endl;
8590  return matchedTestCases.size();
8591  }
8592 
8593  std::size_t listTestsNamesOnly( Config const& config ) {
8594  TestSpec testSpec = config.testSpec();
8595  std::size_t matchedTests = 0;
8596  std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
8597  for( auto const& testCaseInfo : matchedTestCases ) {
8598  matchedTests++;
8599  if( startsWith( testCaseInfo.name, '#' ) )
8600  Catch::cout() << '"' << testCaseInfo.name << '"';
8601  else
8602  Catch::cout() << testCaseInfo.name;
8603  if ( config.verbosity() >= Verbosity::High )
8604  Catch::cout() << "\t@" << testCaseInfo.lineInfo;
8605  Catch::cout() << std::endl;
8606  }
8607  return matchedTests;
8608  }
8609 
8610  void TagInfo::add( std::string const& spelling ) {
8611  ++count;
8612  spellings.insert( spelling );
8613  }
8614 
8615  std::string TagInfo::all() const {
8616  std::string out;
8617  for( auto const& spelling : spellings )
8618  out += "[" + spelling + "]";
8619  return out;
8620  }
8621 
8622  std::size_t listTags( Config const& config ) {
8623  TestSpec testSpec = config.testSpec();
8624  if( config.hasTestFilters() )
8625  Catch::cout() << "Tags for matching test cases:\n";
8626  else {
8627  Catch::cout() << "All available tags:\n";
8628  }
8629 
8630  std::map<std::string, TagInfo> tagCounts;
8631 
8632  std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
8633  for( auto const& testCase : matchedTestCases ) {
8634  for( auto const& tagName : testCase.getTestCaseInfo().tags ) {
8635  std::string lcaseTagName = toLower( tagName );
8636  auto countIt = tagCounts.find( lcaseTagName );
8637  if( countIt == tagCounts.end() )
8638  countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
8639  countIt->second.add( tagName );
8640  }
8641  }
8642 
8643  for( auto const& tagCount : tagCounts ) {
8644  ReusableStringStream rss;
8645  rss << " " << std::setw(2) << tagCount.second.count << " ";
8646  auto str = rss.str();
8647  auto wrapper = Column( tagCount.second.all() )
8648  .initialIndent( 0 )
8649  .indent( str.size() )
8650  .width( CATCH_CONFIG_CONSOLE_WIDTH-10 );
8651  Catch::cout() << str << wrapper << '\n';
8652  }
8653  Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl;
8654  return tagCounts.size();
8655  }
8656 
8657  std::size_t listReporters() {
8658  Catch::cout() << "Available reporters:\n";
8659  IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
8660  std::size_t maxNameLen = 0;
8661  for( auto const& factoryKvp : factories )
8662  maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() );
8663 
8664  for( auto const& factoryKvp : factories ) {
8665  Catch::cout()
8666  << Column( factoryKvp.first + ":" )
8667  .indent(2)
8668  .width( 5+maxNameLen )
8669  + Column( factoryKvp.second->getDescription() )
8670  .initialIndent(0)
8671  .indent(2)
8672  .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 )
8673  << "\n";
8674  }
8675  Catch::cout() << std::endl;
8676  return factories.size();
8677  }
8678 
8679  Option<std::size_t> list( Config const& config ) {
8680  Option<std::size_t> listedCount;
8681  if( config.listTests() )
8682  listedCount = listedCount.valueOr(0) + listTests( config );
8683  if( config.listTestNamesOnly() )
8684  listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
8685  if( config.listTags() )
8686  listedCount = listedCount.valueOr(0) + listTags( config );
8687  if( config.listReporters() )
8688  listedCount = listedCount.valueOr(0) + listReporters();
8689  return listedCount;
8690  }
8691 
8692 } // end namespace Catch
8693 // end catch_list.cpp
8694 // start catch_matchers.cpp
8695 
8696 namespace Catch {
8697 namespace Matchers {
8698  namespace Impl {
8699 
8700  std::string MatcherUntypedBase::toString() const {
8701  if( m_cachedToString.empty() )
8702  m_cachedToString = describe();
8703  return m_cachedToString;
8704  }
8705 
8706  MatcherUntypedBase::~MatcherUntypedBase() = default;
8707 
8708  } // namespace Impl
8709 } // namespace Matchers
8710 
8711 using namespace Matchers;
8712 using Matchers::Impl::MatcherBase;
8713 
8714 } // namespace Catch
8715 // end catch_matchers.cpp
8716 // start catch_matchers_floating.cpp
8717 
8718 // start catch_polyfills.hpp
8719 
8720 namespace Catch {
8721  bool isnan(float f);
8722  bool isnan(double d);
8723 }
8724 
8725 // end catch_polyfills.hpp
8726 // start catch_to_string.hpp
8727 
8728 #include <string>
8729 
8730 namespace Catch {
8731  template <typename T>
8732  std::string to_string(T const& t) {
8733 #if defined(CATCH_CONFIG_CPP11_TO_STRING)
8734  return std::to_string(t);
8735 #else
8736  ReusableStringStream rss;
8737  rss << t;
8738  return rss.str();
8739 #endif
8740  }
8741 } // end namespace Catch
8742 
8743 // end catch_to_string.hpp
8744 #include <cstdlib>
8745 #include <cstdint>
8746 #include <cstring>
8747 
8748 namespace Catch {
8749 namespace Matchers {
8750 namespace Floating {
8751 enum class FloatingPointKind : uint8_t {
8752  Float,
8753  Double
8754 };
8755 }
8756 }
8757 }
8758 
8759 namespace {
8760 
8761 template <typename T>
8762 struct Converter;
8763 
8764 template <>
8765 struct Converter<float> {
8766  static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
8767  Converter(float f) {
8768  std::memcpy(&i, &f, sizeof(f));
8769  }
8770  int32_t i;
8771 };
8772 
8773 template <>
8774 struct Converter<double> {
8775  static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
8776  Converter(double d) {
8777  std::memcpy(&i, &d, sizeof(d));
8778  }
8779  int64_t i;
8780 };
8781 
8782 template <typename T>
8783 auto convert(T t) -> Converter<T> {
8784  return Converter<T>(t);
8785 }
8786 
8787 template <typename FP>
8788 bool almostEqualUlps(FP lhs, FP rhs, int maxUlpDiff) {
8789  // Comparison with NaN should always be false.
8790  // This way we can rule it out before getting into the ugly details
8791  if (Catch::isnan(lhs) || Catch::isnan(rhs)) {
8792  return false;
8793  }
8794 
8795  auto lc = convert(lhs);
8796  auto rc = convert(rhs);
8797 
8798  if ((lc.i < 0) != (rc.i < 0)) {
8799  // Potentially we can have +0 and -0
8800  return lhs == rhs;
8801  }
8802 
8803  auto ulpDiff = std::abs(lc.i - rc.i);
8804  return ulpDiff <= maxUlpDiff;
8805 }
8806 
8807 }
8808 
8809 namespace Catch {
8810 namespace Matchers {
8811 namespace Floating {
8812  WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
8813  :m_target{ target }, m_margin{ margin } {
8814  CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.'
8815  << " Margin has to be non-negative.");
8816  }
8817 
8818  // Performs equivalent check of std::fabs(lhs - rhs) <= margin
8819  // But without the subtraction to allow for INFINITY in comparison
8820  bool WithinAbsMatcher::match(double const& matchee) const {
8821  return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);
8822  }
8823 
8824  std::string WithinAbsMatcher::describe() const {
8825  return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target);
8826  }
8827 
8828  WithinUlpsMatcher::WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType)
8829  :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
8830  CATCH_ENFORCE(ulps >= 0, "Invalid ULP setting: " << ulps << '.'
8831  << " ULPs have to be non-negative.");
8832  }
8833 
8834 #if defined(__clang__)
8835 #pragma clang diagnostic push
8836 // Clang <3.5 reports on the default branch in the switch below
8837 #pragma clang diagnostic ignored "-Wunreachable-code"
8838 #endif
8839 
8840  bool WithinUlpsMatcher::match(double const& matchee) const {
8841  switch (m_type) {
8842  case FloatingPointKind::Float:
8843  return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps);
8844  case FloatingPointKind::Double:
8845  return almostEqualUlps<double>(matchee, m_target, m_ulps);
8846  default:
8847  CATCH_INTERNAL_ERROR( "Unknown FloatingPointKind value" );
8848  }
8849  }
8850 
8851 #if defined(__clang__)
8852 #pragma clang diagnostic pop
8853 #endif
8854 
8855  std::string WithinUlpsMatcher::describe() const {
8856  return "is within " + Catch::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : "");
8857  }
8858 
8859 }// namespace Floating
8860 
8861 Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff) {
8862  return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
8863 }
8864 
8865 Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff) {
8866  return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
8867 }
8868 
8869 Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
8870  return Floating::WithinAbsMatcher(target, margin);
8871 }
8872 
8873 } // namespace Matchers
8874 } // namespace Catch
8875 
8876 // end catch_matchers_floating.cpp
8877 // start catch_matchers_generic.cpp
8878 
8879 std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) {
8880  if (desc.empty()) {
8881  return "matches undescribed predicate";
8882  } else {
8883  return "matches predicate: \"" + desc + '"';
8884  }
8885 }
8886 // end catch_matchers_generic.cpp
8887 // start catch_matchers_string.cpp
8888 
8889 #include <regex>
8890 
8891 namespace Catch {
8892 namespace Matchers {
8893 
8894  namespace StdString {
8895 
8896  CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
8897  : m_caseSensitivity( caseSensitivity ),
8898  m_str( adjustString( str ) )
8899  {}
8900  std::string CasedString::adjustString( std::string const& str ) const {
8901  return m_caseSensitivity == CaseSensitive::No
8902  ? toLower( str )
8903  : str;
8904  }
8905  std::string CasedString::caseSensitivitySuffix() const {
8906  return m_caseSensitivity == CaseSensitive::No
8907  ? " (case insensitive)"
8908  : std::string();
8909  }
8910 
8911  StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )
8912  : m_comparator( comparator ),
8913  m_operation( operation ) {
8914  }
8915 
8916  std::string StringMatcherBase::describe() const {
8917  std::string description;
8918  description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +
8919  m_comparator.caseSensitivitySuffix().size());
8920  description += m_operation;
8921  description += ": \"";
8922  description += m_comparator.m_str;
8923  description += "\"";
8924  description += m_comparator.caseSensitivitySuffix();
8925  return description;
8926  }
8927 
8928  EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {}
8929 
8930  bool EqualsMatcher::match( std::string const& source ) const {
8931  return m_comparator.adjustString( source ) == m_comparator.m_str;
8932  }
8933 
8934  ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {}
8935 
8936  bool ContainsMatcher::match( std::string const& source ) const {
8937  return contains( m_comparator.adjustString( source ), m_comparator.m_str );
8938  }
8939 
8940  StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {}
8941 
8942  bool StartsWithMatcher::match( std::string const& source ) const {
8943  return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );
8944  }
8945 
8946  EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {}
8947 
8948  bool EndsWithMatcher::match( std::string const& source ) const {
8949  return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );
8950  }
8951 
8952  RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity): m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {}
8953 
8954  bool RegexMatcher::match(std::string const& matchee) const {
8955  auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway
8956  if (m_caseSensitivity == CaseSensitive::Choice::No) {
8957  flags |= std::regex::icase;
8958  }
8959  auto reg = std::regex(m_regex, flags);
8960  return std::regex_match(matchee, reg);
8961  }
8962 
8963  std::string RegexMatcher::describe() const {
8964  return "matches " + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? " case sensitively" : " case insensitively");
8965  }
8966 
8967  } // namespace StdString
8968 
8969  StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
8970  return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );
8971  }
8972  StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
8973  return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );
8974  }
8975  StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
8976  return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );
8977  }
8978  StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
8979  return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );
8980  }
8981 
8982  StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity) {
8983  return StdString::RegexMatcher(regex, caseSensitivity);
8984  }
8985 
8986 } // namespace Matchers
8987 } // namespace Catch
8988 // end catch_matchers_string.cpp
8989 // start catch_message.cpp
8990 
8991 // start catch_uncaught_exceptions.h
8992 
8993 namespace Catch {
8994  bool uncaught_exceptions();
8995 } // end namespace Catch
8996 
8997 // end catch_uncaught_exceptions.h
8998 #include <cassert>
8999 #include <stack>
9000 
9001 namespace Catch {
9002 
9003  MessageInfo::MessageInfo( StringRef const& _macroName,
9004  SourceLineInfo const& _lineInfo,
9005  ResultWas::OfType _type )
9006  : macroName( _macroName ),
9007  lineInfo( _lineInfo ),
9008  type( _type ),
9009  sequence( ++globalCount )
9010  {}
9011 
9012  bool MessageInfo::operator==( MessageInfo const& other ) const {
9013  return sequence == other.sequence;
9014  }
9015 
9016  bool MessageInfo::operator<( MessageInfo const& other ) const {
9017  return sequence < other.sequence;
9018  }
9019 
9020  // This may need protecting if threading support is added
9021  unsigned int MessageInfo::globalCount = 0;
9022 
9024 
9025  Catch::MessageBuilder::MessageBuilder( StringRef const& macroName,
9026  SourceLineInfo const& lineInfo,
9027  ResultWas::OfType type )
9028  :m_info(macroName, lineInfo, type) {}
9029 
9031 
9032  ScopedMessage::ScopedMessage( MessageBuilder const& builder )
9033  : m_info( builder.m_info )
9034  {
9035  m_info.message = builder.m_stream.str();
9036  getResultCapture().pushScopedMessage( m_info );
9037  }
9038 
9039  ScopedMessage::~ScopedMessage() {
9040  if ( !uncaught_exceptions() ){
9041  getResultCapture().popScopedMessage(m_info);
9042  }
9043  }
9044 
9045  Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {
9046  auto trimmed = [&] (size_t start, size_t end) {
9047  while (names[start] == ',' || isspace(names[start])) {
9048  ++start;
9049  }
9050  while (names[end] == ',' || isspace(names[end])) {
9051  --end;
9052  }
9053  return names.substr(start, end - start + 1);
9054  };
9055 
9056  size_t start = 0;
9057  std::stack<char> openings;
9058  for (size_t pos = 0; pos < names.size(); ++pos) {
9059  char c = names[pos];
9060  switch (c) {
9061  case '[':
9062  case '{':
9063  case '(':
9064  // It is basically impossible to disambiguate between
9065  // comparison and start of template args in this context
9066 // case '<':
9067  openings.push(c);
9068  break;
9069  case ']':
9070  case '}':
9071  case ')':
9072 // case '>':
9073  openings.pop();
9074  break;
9075  case ',':
9076  if (start != pos && openings.size() == 0) {
9077  m_messages.emplace_back(macroName, lineInfo, resultType);
9078  m_messages.back().message = trimmed(start, pos);
9079  m_messages.back().message += " := ";
9080  start = pos;
9081  }
9082  }
9083  }
9084  assert(openings.size() == 0 && "Mismatched openings");
9085  m_messages.emplace_back(macroName, lineInfo, resultType);
9086  m_messages.back().message = trimmed(start, names.size() - 1);
9087  m_messages.back().message += " := ";
9088  }
9089  Capturer::~Capturer() {
9090  if ( !uncaught_exceptions() ){
9091  assert( m_captured == m_messages.size() );
9092  for( size_t i = 0; i < m_captured; ++i )
9093  m_resultCapture.popScopedMessage( m_messages[i] );
9094  }
9095  }
9096 
9097  void Capturer::captureValue( size_t index, std::string const& value ) {
9098  assert( index < m_messages.size() );
9099  m_messages[index].message += value;
9100  m_resultCapture.pushScopedMessage( m_messages[index] );
9101  m_captured++;
9102  }
9103 
9104 } // end namespace Catch
9105 // end catch_message.cpp
9106 // start catch_output_redirect.cpp
9107 
9108 // start catch_output_redirect.h
9109 #ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
9110 #define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
9111 
9112 #include <cstdio>
9113 #include <iosfwd>
9114 #include <string>
9115 
9116 namespace Catch {
9117 
9118  class RedirectedStream {
9119  std::ostream& m_originalStream;
9120  std::ostream& m_redirectionStream;
9121  std::streambuf* m_prevBuf;
9122 
9123  public:
9124  RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream );
9125  ~RedirectedStream();
9126  };
9127 
9128  class RedirectedStdOut {
9129  ReusableStringStream m_rss;
9130  RedirectedStream m_cout;
9131  public:
9132  RedirectedStdOut();
9133  auto str() const -> std::string;
9134  };
9135 
9136  // StdErr has two constituent streams in C++, std::cerr and std::clog
9137  // This means that we need to redirect 2 streams into 1 to keep proper
9138  // order of writes
9139  class RedirectedStdErr {
9140  ReusableStringStream m_rss;
9141  RedirectedStream m_cerr;
9142  RedirectedStream m_clog;
9143  public:
9144  RedirectedStdErr();
9145  auto str() const -> std::string;
9146  };
9147 
9148 #if defined(CATCH_CONFIG_NEW_CAPTURE)
9149 
9150  // Windows's implementation of std::tmpfile is terrible (it tries
9151  // to create a file inside system folder, thus requiring elevated
9152  // privileges for the binary), so we have to use tmpnam(_s) and
9153  // create the file ourselves there.
9154  class TempFile {
9155  public:
9156  TempFile(TempFile const&) = delete;
9157  TempFile& operator=(TempFile const&) = delete;
9158  TempFile(TempFile&&) = delete;
9159  TempFile& operator=(TempFile&&) = delete;
9160 
9161  TempFile();
9162  ~TempFile();
9163 
9164  std::FILE* getFile();
9165  std::string getContents();
9166 
9167  private:
9168  std::FILE* m_file = nullptr;
9169  #if defined(_MSC_VER)
9170  char m_buffer[L_tmpnam] = { 0 };
9171  #endif
9172  };
9173 
9174  class OutputRedirect {
9175  public:
9176  OutputRedirect(OutputRedirect const&) = delete;
9177  OutputRedirect& operator=(OutputRedirect const&) = delete;
9178  OutputRedirect(OutputRedirect&&) = delete;
9179  OutputRedirect& operator=(OutputRedirect&&) = delete;
9180 
9181  OutputRedirect(std::string& stdout_dest, std::string& stderr_dest);
9182  ~OutputRedirect();
9183 
9184  private:
9185  int m_originalStdout = -1;
9186  int m_originalStderr = -1;
9187  TempFile m_stdoutFile;
9188  TempFile m_stderrFile;
9189  std::string& m_stdoutDest;
9190  std::string& m_stderrDest;
9191  };
9192 
9193 #endif
9194 
9195 } // end namespace Catch
9196 
9197 #endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
9198 // end catch_output_redirect.h
9199 #include <cstdio>
9200 #include <cstring>
9201 #include <fstream>
9202 #include <sstream>
9203 #include <stdexcept>
9204 
9205 #if defined(CATCH_CONFIG_NEW_CAPTURE)
9206  #if defined(_MSC_VER)
9207  #include <io.h> //_dup and _dup2
9208  #define dup _dup
9209  #define dup2 _dup2
9210  #define fileno _fileno
9211  #else
9212  #include <unistd.h> // dup and dup2
9213  #endif
9214 #endif
9215 
9216 namespace Catch {
9217 
9218  RedirectedStream::RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream )
9219  : m_originalStream( originalStream ),
9220  m_redirectionStream( redirectionStream ),
9221  m_prevBuf( m_originalStream.rdbuf() )
9222  {
9223  m_originalStream.rdbuf( m_redirectionStream.rdbuf() );
9224  }
9225 
9226  RedirectedStream::~RedirectedStream() {
9227  m_originalStream.rdbuf( m_prevBuf );
9228  }
9229 
9230  RedirectedStdOut::RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {}
9231  auto RedirectedStdOut::str() const -> std::string { return m_rss.str(); }
9232 
9233  RedirectedStdErr::RedirectedStdErr()
9234  : m_cerr( Catch::cerr(), m_rss.get() ),
9235  m_clog( Catch::clog(), m_rss.get() )
9236  {}
9237  auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }
9238 
9239 #if defined(CATCH_CONFIG_NEW_CAPTURE)
9240 
9241 #if defined(_MSC_VER)
9242  TempFile::TempFile() {
9243  if (tmpnam_s(m_buffer)) {
9244  CATCH_RUNTIME_ERROR("Could not get a temp filename");
9245  }
9246  if (fopen_s(&m_file, m_buffer, "w")) {
9247  char buffer[100];
9248  if (strerror_s(buffer, errno)) {
9249  CATCH_RUNTIME_ERROR("Could not translate errno to a string");
9250  }
9251  CATCH_RUNTIME_ERROR("Coul dnot open the temp file: '" << m_buffer << "' because: " << buffer);
9252  }
9253  }
9254 #else
9255  TempFile::TempFile() {
9256  m_file = std::tmpfile();
9257  if (!m_file) {
9258  CATCH_RUNTIME_ERROR("Could not create a temp file.");
9259  }
9260  }
9261 
9262 #endif
9263 
9264  TempFile::~TempFile() {
9265  // TBD: What to do about errors here?
9266  std::fclose(m_file);
9267  // We manually create the file on Windows only, on Linux
9268  // it will be autodeleted
9269 #if defined(_MSC_VER)
9270  std::remove(m_buffer);
9271 #endif
9272  }
9273 
9274  FILE* TempFile::getFile() {
9275  return m_file;
9276  }
9277 
9278  std::string TempFile::getContents() {
9279  std::stringstream sstr;
9280  char buffer[100] = {};
9281  std::rewind(m_file);
9282  while (std::fgets(buffer, sizeof(buffer), m_file)) {
9283  sstr << buffer;
9284  }
9285  return sstr.str();
9286  }
9287 
9288  OutputRedirect::OutputRedirect(std::string& stdout_dest, std::string& stderr_dest) :
9289  m_originalStdout(dup(1)),
9290  m_originalStderr(dup(2)),
9291  m_stdoutDest(stdout_dest),
9292  m_stderrDest(stderr_dest) {
9293  dup2(fileno(m_stdoutFile.getFile()), 1);
9294  dup2(fileno(m_stderrFile.getFile()), 2);
9295  }
9296 
9297  OutputRedirect::~OutputRedirect() {
9298  Catch::cout() << std::flush;
9299  fflush(stdout);
9300  // Since we support overriding these streams, we flush cerr
9301  // even though std::cerr is unbuffered
9302  Catch::cerr() << std::flush;
9303  Catch::clog() << std::flush;
9304  fflush(stderr);
9305 
9306  dup2(m_originalStdout, 1);
9307  dup2(m_originalStderr, 2);
9308 
9309  m_stdoutDest += m_stdoutFile.getContents();
9310  m_stderrDest += m_stderrFile.getContents();
9311  }
9312 
9313 #endif // CATCH_CONFIG_NEW_CAPTURE
9314 
9315 } // namespace Catch
9316 
9317 #if defined(CATCH_CONFIG_NEW_CAPTURE)
9318  #if defined(_MSC_VER)
9319  #undef dup
9320  #undef dup2
9321  #undef fileno
9322  #endif
9323 #endif
9324 // end catch_output_redirect.cpp
9325 // start catch_polyfills.cpp
9326 
9327 #include <cmath>
9328 
9329 namespace Catch {
9330 
9331 #if !defined(CATCH_CONFIG_POLYFILL_ISNAN)
9332  bool isnan(float f) {
9333  return std::isnan(f);
9334  }
9335  bool isnan(double d) {
9336  return std::isnan(d);
9337  }
9338 #else
9339  // For now we only use this for embarcadero
9340  bool isnan(float f) {
9341  return std::_isnan(f);
9342  }
9343  bool isnan(double d) {
9344  return std::_isnan(d);
9345  }
9346 #endif
9347 
9348 } // end namespace Catch
9349 // end catch_polyfills.cpp
9350 // start catch_random_number_generator.cpp
9351 
9352 namespace Catch {
9353 
9354  std::mt19937& rng() {
9355  static std::mt19937 s_rng;
9356  return s_rng;
9357  }
9358 
9359  void seedRng( IConfig const& config ) {
9360  if( config.rngSeed() != 0 ) {
9361  std::srand( config.rngSeed() );
9362  rng().seed( config.rngSeed() );
9363  }
9364  }
9365 
9366  unsigned int rngSeed() {
9367  return getCurrentContext().getConfig()->rngSeed();
9368  }
9369 }
9370 // end catch_random_number_generator.cpp
9371 // start catch_registry_hub.cpp
9372 
9373 // start catch_test_case_registry_impl.h
9374 
9375 #include <vector>
9376 #include <set>
9377 #include <algorithm>
9378 #include <ios>
9379 
9380 namespace Catch {
9381 
9382  class TestCase;
9383  struct IConfig;
9384 
9385  std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases );
9386  bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
9387 
9388  void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions );
9389 
9390  std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
9391  std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
9392 
9393  class TestRegistry : public ITestCaseRegistry {
9394  public:
9395  virtual ~TestRegistry() = default;
9396 
9397  virtual void registerTest( TestCase const& testCase );
9398 
9399  std::vector<TestCase> const& getAllTests() const override;
9400  std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const override;
9401 
9402  private:
9403  std::vector<TestCase> m_functions;
9404  mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;
9405  mutable std::vector<TestCase> m_sortedFunctions;
9406  std::size_t m_unnamedCount = 0;
9407  std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
9408  };
9409 
9411 
9412  class TestInvokerAsFunction : public ITestInvoker {
9413  void(*m_testAsFunction)();
9414  public:
9415  TestInvokerAsFunction( void(*testAsFunction)() ) noexcept;
9416 
9417  void invoke() const override;
9418  };
9419 
9420  std::string extractClassName( StringRef const& classOrQualifiedMethodName );
9421 
9423 
9424 } // end namespace Catch
9425 
9426 // end catch_test_case_registry_impl.h
9427 // start catch_reporter_registry.h
9428 
9429 #include <map>
9430 
9431 namespace Catch {
9432 
9433  class ReporterRegistry : public IReporterRegistry {
9434 
9435  public:
9436 
9437  ~ReporterRegistry() override;
9438 
9439  IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const override;
9440 
9441  void registerReporter( std::string const& name, IReporterFactoryPtr const& factory );
9442  void registerListener( IReporterFactoryPtr const& factory );
9443 
9444  FactoryMap const& getFactories() const override;
9445  Listeners const& getListeners() const override;
9446 
9447  private:
9448  FactoryMap m_factories;
9449  Listeners m_listeners;
9450  };
9451 }
9452 
9453 // end catch_reporter_registry.h
9454 // start catch_tag_alias_registry.h
9455 
9456 // start catch_tag_alias.h
9457 
9458 #include <string>
9459 
9460 namespace Catch {
9461 
9462  struct TagAlias {
9463  TagAlias(std::string const& _tag, SourceLineInfo _lineInfo);
9464 
9465  std::string tag;
9466  SourceLineInfo lineInfo;
9467  };
9468 
9469 } // end namespace Catch
9470 
9471 // end catch_tag_alias.h
9472 #include <map>
9473 
9474 namespace Catch {
9475 
9476  class TagAliasRegistry : public ITagAliasRegistry {
9477  public:
9478  ~TagAliasRegistry() override;
9479  TagAlias const* find( std::string const& alias ) const override;
9480  std::string expandAliases( std::string const& unexpandedTestSpec ) const override;
9481  void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
9482 
9483  private:
9484  std::map<std::string, TagAlias> m_registry;
9485  };
9486 
9487 } // end namespace Catch
9488 
9489 // end catch_tag_alias_registry.h
9490 // start catch_startup_exception_registry.h
9491 
9492 #include <vector>
9493 #include <exception>
9494 
9495 namespace Catch {
9496 
9497  class StartupExceptionRegistry {
9498  public:
9499  void add(std::exception_ptr const& exception) noexcept;
9500  std::vector<std::exception_ptr> const& getExceptions() const noexcept;
9501  private:
9502  std::vector<std::exception_ptr> m_exceptions;
9503  };
9504 
9505 } // end namespace Catch
9506 
9507 // end catch_startup_exception_registry.h
9508 // start catch_singletons.hpp
9509 
9510 namespace Catch {
9511 
9512  struct ISingleton {
9513  virtual ~ISingleton();
9514  };
9515 
9516  void addSingleton( ISingleton* singleton );
9517  void cleanupSingletons();
9518 
9519  template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>
9520  class Singleton : SingletonImplT, public ISingleton {
9521 
9522  static auto getInternal() -> Singleton* {
9523  static Singleton* s_instance = nullptr;
9524  if( !s_instance ) {
9525  s_instance = new Singleton;
9526  addSingleton( s_instance );
9527  }
9528  return s_instance;
9529  }
9530 
9531  public:
9532  static auto get() -> InterfaceT const& {
9533  return *getInternal();
9534  }
9535  static auto getMutable() -> MutableInterfaceT& {
9536  return *getInternal();
9537  }
9538  };
9539 
9540 } // namespace Catch
9541 
9542 // end catch_singletons.hpp
9543 namespace Catch {
9544 
9545  namespace {
9546 
9547  class RegistryHub : public IRegistryHub, public IMutableRegistryHub,
9548  private NonCopyable {
9549 
9550  public: // IRegistryHub
9551  RegistryHub() = default;
9552  IReporterRegistry const& getReporterRegistry() const override {
9553  return m_reporterRegistry;
9554  }
9555  ITestCaseRegistry const& getTestCaseRegistry() const override {
9556  return m_testCaseRegistry;
9557  }
9558  IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override {
9559  return m_exceptionTranslatorRegistry;
9560  }
9561  ITagAliasRegistry const& getTagAliasRegistry() const override {
9562  return m_tagAliasRegistry;
9563  }
9564  StartupExceptionRegistry const& getStartupExceptionRegistry() const override {
9565  return m_exceptionRegistry;
9566  }
9567 
9568  public: // IMutableRegistryHub
9569  void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) override {
9570  m_reporterRegistry.registerReporter( name, factory );
9571  }
9572  void registerListener( IReporterFactoryPtr const& factory ) override {
9573  m_reporterRegistry.registerListener( factory );
9574  }
9575  void registerTest( TestCase const& testInfo ) override {
9576  m_testCaseRegistry.registerTest( testInfo );
9577  }
9578  void registerTranslator( const IExceptionTranslator* translator ) override {
9579  m_exceptionTranslatorRegistry.registerTranslator( translator );
9580  }
9581  void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override {
9582  m_tagAliasRegistry.add( alias, tag, lineInfo );
9583  }
9584  void registerStartupException() noexcept override {
9585  m_exceptionRegistry.add(std::current_exception());
9586  }
9587 
9588  private:
9589  TestRegistry m_testCaseRegistry;
9590  ReporterRegistry m_reporterRegistry;
9591  ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
9592  TagAliasRegistry m_tagAliasRegistry;
9593  StartupExceptionRegistry m_exceptionRegistry;
9594  };
9595  }
9596 
9597  using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>;
9598 
9599  IRegistryHub const& getRegistryHub() {
9600  return RegistryHubSingleton::get();
9601  }
9602  IMutableRegistryHub& getMutableRegistryHub() {
9603  return RegistryHubSingleton::getMutable();
9604  }
9605  void cleanUp() {
9606  cleanupSingletons();
9607  cleanUpContext();
9608  }
9609  std::string translateActiveException() {
9610  return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
9611  }
9612 
9613 } // end namespace Catch
9614 // end catch_registry_hub.cpp
9615 // start catch_reporter_registry.cpp
9616 
9617 namespace Catch {
9618 
9619  ReporterRegistry::~ReporterRegistry() = default;
9620 
9621  IStreamingReporterPtr ReporterRegistry::create( std::string const& name, IConfigPtr const& config ) const {
9622  auto it = m_factories.find( name );
9623  if( it == m_factories.end() )
9624  return nullptr;
9625  return it->second->create( ReporterConfig( config ) );
9626  }
9627 
9628  void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) {
9629  m_factories.emplace(name, factory);
9630  }
9631  void ReporterRegistry::registerListener( IReporterFactoryPtr const& factory ) {
9632  m_listeners.push_back( factory );
9633  }
9634 
9635  IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const {
9636  return m_factories;
9637  }
9638  IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const {
9639  return m_listeners;
9640  }
9641 
9642 }
9643 // end catch_reporter_registry.cpp
9644 // start catch_result_type.cpp
9645 
9646 namespace Catch {
9647 
9648  bool isOk( ResultWas::OfType resultType ) {
9649  return ( resultType & ResultWas::FailureBit ) == 0;
9650  }
9651  bool isJustInfo( int flags ) {
9652  return flags == ResultWas::Info;
9653  }
9654 
9655  ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
9656  return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
9657  }
9658 
9659  bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
9660  bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
9661 
9662 } // end namespace Catch
9663 // end catch_result_type.cpp
9664 // start catch_run_context.cpp
9665 
9666 #include <cassert>
9667 #include <algorithm>
9668 #include <sstream>
9669 
9670 namespace Catch {
9671 
9672  namespace Generators {
9673  struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {
9674  size_t m_index = static_cast<size_t>( -1 );
9675  GeneratorBasePtr m_generator;
9676 
9677  GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
9678  : TrackerBase( nameAndLocation, ctx, parent )
9679  {}
9680  ~GeneratorTracker();
9681 
9682  static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {
9683  std::shared_ptr<GeneratorTracker> tracker;
9684 
9685  ITracker& currentTracker = ctx.currentTracker();
9686  if( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
9687  assert( childTracker );
9688  assert( childTracker->isIndexTracker() );
9689  tracker = std::static_pointer_cast<GeneratorTracker>( childTracker );
9690  }
9691  else {
9692  tracker = std::make_shared<GeneratorTracker>( nameAndLocation, ctx, &currentTracker );
9693  currentTracker.addChild( tracker );
9694  }
9695 
9696  if( !ctx.completedCycle() && !tracker->isComplete() ) {
9697  if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
9698  tracker->moveNext();
9699  tracker->open();
9700  }
9701 
9702  return *tracker;
9703  }
9704 
9705  void moveNext() {
9706  m_index++;
9707  m_children.clear();
9708  }
9709 
9710  // TrackerBase interface
9711  bool isIndexTracker() const override { return true; }
9712  auto hasGenerator() const -> bool override {
9713  return !!m_generator;
9714  }
9715  void close() override {
9716  TrackerBase::close();
9717  if( m_runState == CompletedSuccessfully && m_index < m_generator->size()-1 )
9718  m_runState = Executing;
9719  }
9720 
9721  // IGeneratorTracker interface
9722  auto getGenerator() const -> GeneratorBasePtr const& override {
9723  return m_generator;
9724  }
9725  void setGenerator( GeneratorBasePtr&& generator ) override {
9726  m_generator = std::move( generator );
9727  }
9728  auto getIndex() const -> size_t override {
9729  return m_index;
9730  }
9731  };
9732  GeneratorTracker::~GeneratorTracker() {}
9733  }
9734 
9735  RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
9736  : m_runInfo(_config->name()),
9737  m_context(getCurrentMutableContext()),
9738  m_config(_config),
9739  m_reporter(std::move(reporter)),
9740  m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
9741  m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )
9742  {
9743  m_context.setRunner(this);
9744  m_context.setConfig(m_config);
9745  m_context.setResultCapture(this);
9746  m_reporter->testRunStarting(m_runInfo);
9747  }
9748 
9749  RunContext::~RunContext() {
9750  m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
9751  }
9752 
9753  void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) {
9754  m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));
9755  }
9756 
9757  void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) {
9758  m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));
9759  }
9760 
9761  Totals RunContext::runTest(TestCase const& testCase) {
9762  Totals prevTotals = m_totals;
9763 
9764  std::string redirectedCout;
9765  std::string redirectedCerr;
9766 
9767  auto const& testInfo = testCase.getTestCaseInfo();
9768 
9769  m_reporter->testCaseStarting(testInfo);
9770 
9771  m_activeTestCase = &testCase;
9772 
9773  ITracker& rootTracker = m_trackerContext.startRun();
9774  assert(rootTracker.isSectionTracker());
9775  static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun());
9776  do {
9777  m_trackerContext.startCycle();
9778  m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));
9779  runCurrentTest(redirectedCout, redirectedCerr);
9780  } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());
9781 
9782  Totals deltaTotals = m_totals.delta(prevTotals);
9783  if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) {
9784  deltaTotals.assertions.failed++;
9785  deltaTotals.testCases.passed--;
9786  deltaTotals.testCases.failed++;
9787  }
9788  m_totals.testCases += deltaTotals.testCases;
9789  m_reporter->testCaseEnded(TestCaseStats(testInfo,
9790  deltaTotals,
9791  redirectedCout,
9792  redirectedCerr,
9793  aborting()));
9794 
9795  m_activeTestCase = nullptr;
9796  m_testCaseTracker = nullptr;
9797 
9798  return deltaTotals;
9799  }
9800 
9801  IConfigPtr RunContext::config() const {
9802  return m_config;
9803  }
9804 
9805  IStreamingReporter& RunContext::reporter() const {
9806  return *m_reporter;
9807  }
9808 
9809  void RunContext::assertionEnded(AssertionResult const & result) {
9810  if (result.getResultType() == ResultWas::Ok) {
9811  m_totals.assertions.passed++;
9812  m_lastAssertionPassed = true;
9813  } else if (!result.isOk()) {
9814  m_lastAssertionPassed = false;
9815  if( m_activeTestCase->getTestCaseInfo().okToFail() )
9816  m_totals.assertions.failedButOk++;
9817  else
9818  m_totals.assertions.failed++;
9819  }
9820  else {
9821  m_lastAssertionPassed = true;
9822  }
9823 
9824  // We have no use for the return value (whether messages should be cleared), because messages were made scoped
9825  // and should be let to clear themselves out.
9826  static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
9827 
9828  // Reset working state
9829  resetAssertionInfo();
9830  m_lastResult = result;
9831  }
9832  void RunContext::resetAssertionInfo() {
9833  m_lastAssertionInfo.macroName = StringRef();
9834  m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
9835  }
9836 
9837  bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) {
9838  ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));
9839  if (!sectionTracker.isOpen())
9840  return false;
9841  m_activeSections.push_back(&sectionTracker);
9842 
9843  m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
9844 
9845  m_reporter->sectionStarting(sectionInfo);
9846 
9847  assertions = m_totals.assertions;
9848 
9849  return true;
9850  }
9851  auto RunContext::acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
9852  using namespace Generators;
9853  GeneratorTracker& tracker = GeneratorTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( "generator", lineInfo ) );
9854  assert( tracker.isOpen() );
9855  m_lastAssertionInfo.lineInfo = lineInfo;
9856  return tracker;
9857  }
9858 
9859  bool RunContext::testForMissingAssertions(Counts& assertions) {
9860  if (assertions.total() != 0)
9861  return false;
9862  if (!m_config->warnAboutMissingAssertions())
9863  return false;
9864  if (m_trackerContext.currentTracker().hasChildren())
9865  return false;
9866  m_totals.assertions.failed++;
9867  assertions.failed++;
9868  return true;
9869  }
9870 
9871  void RunContext::sectionEnded(SectionEndInfo const & endInfo) {
9872  Counts assertions = m_totals.assertions - endInfo.prevAssertions;
9873  bool missingAssertions = testForMissingAssertions(assertions);
9874 
9875  if (!m_activeSections.empty()) {
9876  m_activeSections.back()->close();
9877  m_activeSections.pop_back();
9878  }
9879 
9880  m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
9881  m_messages.clear();
9882  }
9883 
9884  void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {
9885  if (m_unfinishedSections.empty())
9886  m_activeSections.back()->fail();
9887  else
9888  m_activeSections.back()->close();
9889  m_activeSections.pop_back();
9890 
9891  m_unfinishedSections.push_back(endInfo);
9892  }
9893  void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {
9894  m_reporter->benchmarkStarting( info );
9895  }
9896  void RunContext::benchmarkEnded( BenchmarkStats const& stats ) {
9897  m_reporter->benchmarkEnded( stats );
9898  }
9899 
9900  void RunContext::pushScopedMessage(MessageInfo const & message) {
9901  m_messages.push_back(message);
9902  }
9903 
9904  void RunContext::popScopedMessage(MessageInfo const & message) {
9905  m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
9906  }
9907 
9908  std::string RunContext::getCurrentTestName() const {
9909  return m_activeTestCase
9910  ? m_activeTestCase->getTestCaseInfo().name
9911  : std::string();
9912  }
9913 
9914  const AssertionResult * RunContext::getLastResult() const {
9915  return &(*m_lastResult);
9916  }
9917 
9918  void RunContext::exceptionEarlyReported() {
9919  m_shouldReportUnexpected = false;
9920  }
9921 
9922  void RunContext::handleFatalErrorCondition( StringRef message ) {
9923  // First notify reporter that bad things happened
9924  m_reporter->fatalErrorEncountered(message);
9925 
9926  // Don't rebuild the result -- the stringification itself can cause more fatal errors
9927  // Instead, fake a result data.
9928  AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );
9929  tempResult.message = message;
9930  AssertionResult result(m_lastAssertionInfo, tempResult);
9931 
9932  assertionEnded(result);
9933 
9934  handleUnfinishedSections();
9935 
9936  // Recreate section for test case (as we will lose the one that was in scope)
9937  auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
9938  SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
9939 
9940  Counts assertions;
9941  assertions.failed = 1;
9942  SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);
9943  m_reporter->sectionEnded(testCaseSectionStats);
9944 
9945  auto const& testInfo = m_activeTestCase->getTestCaseInfo();
9946 
9947  Totals deltaTotals;
9948  deltaTotals.testCases.failed = 1;
9949  deltaTotals.assertions.failed = 1;
9950  m_reporter->testCaseEnded(TestCaseStats(testInfo,
9951  deltaTotals,
9952  std::string(),
9953  std::string(),
9954  false));
9955  m_totals.testCases.failed++;
9956  testGroupEnded(std::string(), m_totals, 1, 1);
9957  m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
9958  }
9959 
9960  bool RunContext::lastAssertionPassed() {
9961  return m_lastAssertionPassed;
9962  }
9963 
9964  void RunContext::assertionPassed() {
9965  m_lastAssertionPassed = true;
9966  ++m_totals.assertions.passed;
9967  resetAssertionInfo();
9968  }
9969 
9970  bool RunContext::aborting() const {
9971  return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter());
9972  }
9973 
9974  void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
9975  auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
9976  SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
9977  m_reporter->sectionStarting(testCaseSection);
9978  Counts prevAssertions = m_totals.assertions;
9979  double duration = 0;
9980  m_shouldReportUnexpected = true;
9981  m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal };
9982 
9983  seedRng(*m_config);
9984 
9985  Timer timer;
9986  CATCH_TRY {
9987  if (m_reporter->getPreferences().shouldRedirectStdOut) {
9988 #if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
9989  RedirectedStdOut redirectedStdOut;
9990  RedirectedStdErr redirectedStdErr;
9991 
9992  timer.start();
9993  invokeActiveTestCase();
9994  redirectedCout += redirectedStdOut.str();
9995  redirectedCerr += redirectedStdErr.str();
9996 #else
9997  OutputRedirect r(redirectedCout, redirectedCerr);
9998  timer.start();
9999  invokeActiveTestCase();
10000 #endif
10001  } else {
10002  timer.start();
10003  invokeActiveTestCase();
10004  }
10005  duration = timer.getElapsedSeconds();
10006  } CATCH_CATCH_ANON (TestFailureException&) {
10007  // This just means the test was aborted due to failure
10008  } CATCH_CATCH_ALL {
10009  // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
10010  // are reported without translation at the point of origin.
10011  if( m_shouldReportUnexpected ) {
10012  AssertionReaction dummyReaction;
10013  handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction );
10014  }
10015  }
10016  Counts assertions = m_totals.assertions - prevAssertions;
10017  bool missingAssertions = testForMissingAssertions(assertions);
10018 
10019  m_testCaseTracker->close();
10020  handleUnfinishedSections();
10021  m_messages.clear();
10022 
10023  SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
10024  m_reporter->sectionEnded(testCaseSectionStats);
10025  }
10026 
10027  void RunContext::invokeActiveTestCase() {
10028  FatalConditionHandler fatalConditionHandler; // Handle signals
10029  m_activeTestCase->invoke();
10030  fatalConditionHandler.reset();
10031  }
10032 
10033  void RunContext::handleUnfinishedSections() {
10034  // If sections ended prematurely due to an exception we stored their
10035  // infos here so we can tear them down outside the unwind process.
10036  for (auto it = m_unfinishedSections.rbegin(),
10037  itEnd = m_unfinishedSections.rend();
10038  it != itEnd;
10039  ++it)
10040  sectionEnded(*it);
10041  m_unfinishedSections.clear();
10042  }
10043 
10044  void RunContext::handleExpr(
10045  AssertionInfo const& info,
10046  ITransientExpression const& expr,
10047  AssertionReaction& reaction
10048  ) {
10049  m_reporter->assertionStarting( info );
10050 
10051  bool negated = isFalseTest( info.resultDisposition );
10052  bool result = expr.getResult() != negated;
10053 
10054  if( result ) {
10055  if (!m_includeSuccessfulResults) {
10056  assertionPassed();
10057  }
10058  else {
10059  reportExpr(info, ResultWas::Ok, &expr, negated);
10060  }
10061  }
10062  else {
10063  reportExpr(info, ResultWas::ExpressionFailed, &expr, negated );
10064  populateReaction( reaction );
10065  }
10066  }
10067  void RunContext::reportExpr(
10068  AssertionInfo const &info,
10069  ResultWas::OfType resultType,
10070  ITransientExpression const *expr,
10071  bool negated ) {
10072 
10073  m_lastAssertionInfo = info;
10074  AssertionResultData data( resultType, LazyExpression( negated ) );
10075 
10076  AssertionResult assertionResult{ info, data };
10077  assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;
10078 
10079  assertionEnded( assertionResult );
10080  }
10081 
10082  void RunContext::handleMessage(
10083  AssertionInfo const& info,
10084  ResultWas::OfType resultType,
10085  StringRef const& message,
10086  AssertionReaction& reaction
10087  ) {
10088  m_reporter->assertionStarting( info );
10089 
10090  m_lastAssertionInfo = info;
10091 
10092  AssertionResultData data( resultType, LazyExpression( false ) );
10093  data.message = message;
10094  AssertionResult assertionResult{ m_lastAssertionInfo, data };
10095  assertionEnded( assertionResult );
10096  if( !assertionResult.isOk() )
10097  populateReaction( reaction );
10098  }
10099  void RunContext::handleUnexpectedExceptionNotThrown(
10100  AssertionInfo const& info,
10101  AssertionReaction& reaction
10102  ) {
10103  handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction);
10104  }
10105 
10106  void RunContext::handleUnexpectedInflightException(
10107  AssertionInfo const& info,
10108  std::string const& message,
10109  AssertionReaction& reaction
10110  ) {
10111  m_lastAssertionInfo = info;
10112 
10113  AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
10114  data.message = message;
10115  AssertionResult assertionResult{ info, data };
10116  assertionEnded( assertionResult );
10117  populateReaction( reaction );
10118  }
10119 
10120  void RunContext::populateReaction( AssertionReaction& reaction ) {
10121  reaction.shouldDebugBreak = m_config->shouldDebugBreak();
10122  reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal);
10123  }
10124 
10125  void RunContext::handleIncomplete(
10126  AssertionInfo const& info
10127  ) {
10128  m_lastAssertionInfo = info;
10129 
10130  AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
10131  data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
10132  AssertionResult assertionResult{ info, data };
10133  assertionEnded( assertionResult );
10134  }
10135  void RunContext::handleNonExpr(
10136  AssertionInfo const &info,
10137  ResultWas::OfType resultType,
10138  AssertionReaction &reaction
10139  ) {
10140  m_lastAssertionInfo = info;
10141 
10142  AssertionResultData data( resultType, LazyExpression( false ) );
10143  AssertionResult assertionResult{ info, data };
10144  assertionEnded( assertionResult );
10145 
10146  if( !assertionResult.isOk() )
10147  populateReaction( reaction );
10148  }
10149 
10150  IResultCapture& getResultCapture() {
10151  if (auto* capture = getCurrentContext().getResultCapture())
10152  return *capture;
10153  else
10154  CATCH_INTERNAL_ERROR("No result capture instance");
10155  }
10156 }
10157 // end catch_run_context.cpp
10158 // start catch_section.cpp
10159 
10160 namespace Catch {
10161 
10162  Section::Section( SectionInfo const& info )
10163  : m_info( info ),
10164  m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
10165  {
10166  m_timer.start();
10167  }
10168 
10169  Section::~Section() {
10170  if( m_sectionIncluded ) {
10171  SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };
10172  if( uncaught_exceptions() )
10173  getResultCapture().sectionEndedEarly( endInfo );
10174  else
10175  getResultCapture().sectionEnded( endInfo );
10176  }
10177  }
10178 
10179  // This indicates whether the section should be executed or not
10180  Section::operator bool() const {
10181  return m_sectionIncluded;
10182  }
10183 
10184 } // end namespace Catch
10185 // end catch_section.cpp
10186 // start catch_section_info.cpp
10187 
10188 namespace Catch {
10189 
10190  SectionInfo::SectionInfo
10191  ( SourceLineInfo const& _lineInfo,
10192  std::string const& _name )
10193  : name( _name ),
10194  lineInfo( _lineInfo )
10195  {}
10196 
10197 } // end namespace Catch
10198 // end catch_section_info.cpp
10199 // start catch_session.cpp
10200 
10201 // start catch_session.h
10202 
10203 #include <memory>
10204 
10205 namespace Catch {
10206 
10207  class Session : NonCopyable {
10208  public:
10209 
10210  Session();
10211  ~Session() override;
10212 
10213  void showHelp() const;
10214  void libIdentify();
10215 
10216  int applyCommandLine( int argc, char const * const * argv );
10217  #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
10218  int applyCommandLine( int argc, wchar_t const * const * argv );
10219  #endif
10220 
10221  void useConfigData( ConfigData const& configData );
10222 
10223  template<typename CharT>
10224  int run(int argc, CharT const * const argv[]) {
10225  if (m_startupExceptions)
10226  return 1;
10227  int returnCode = applyCommandLine(argc, argv);
10228  if (returnCode == 0)
10229  returnCode = run();
10230  return returnCode;
10231  }
10232 
10233  int run();
10234 
10235  clara::Parser const& cli() const;
10236  void cli( clara::Parser const& newParser );
10237  ConfigData& configData();
10238  Config& config();
10239  private:
10240  int runInternal();
10241 
10242  clara::Parser m_cli;
10243  ConfigData m_configData;
10244  std::shared_ptr<Config> m_config;
10245  bool m_startupExceptions = false;
10246  };
10247 
10248 } // end namespace Catch
10249 
10250 // end catch_session.h
10251 // start catch_version.h
10252 
10253 #include <iosfwd>
10254 
10255 namespace Catch {
10256 
10257  // Versioning information
10258  struct Version {
10259  Version( Version const& ) = delete;
10260  Version& operator=( Version const& ) = delete;
10261  Version( unsigned int _majorVersion,
10262  unsigned int _minorVersion,
10263  unsigned int _patchNumber,
10264  char const * const _branchName,
10265  unsigned int _buildNumber );
10266 
10267  unsigned int const majorVersion;
10268  unsigned int const minorVersion;
10269  unsigned int const patchNumber;
10270 
10271  // buildNumber is only used if branchName is not null
10272  char const * const branchName;
10273  unsigned int const buildNumber;
10274 
10275  friend std::ostream& operator << ( std::ostream& os, Version const& version );
10276  };
10277 
10278  Version const& libraryVersion();
10279 }
10280 
10281 // end catch_version.h
10282 #include <cstdlib>
10283 #include <iomanip>
10284 
10285 namespace Catch {
10286 
10287  namespace {
10288  const int MaxExitCode = 255;
10289 
10290  IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) {
10291  auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config);
10292  CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'");
10293 
10294  return reporter;
10295  }
10296 
10297  IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) {
10298  if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) {
10299  return createReporter(config->getReporterName(), config);
10300  }
10301 
10302  auto multi = std::unique_ptr<ListeningReporter>(new ListeningReporter);
10303 
10304  auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();
10305  for (auto const& listener : listeners) {
10306  multi->addListener(listener->create(Catch::ReporterConfig(config)));
10307  }
10308  multi->addReporter(createReporter(config->getReporterName(), config));
10309  return std::move(multi);
10310  }
10311 
10312  Catch::Totals runTests(std::shared_ptr<Config> const& config) {
10313  auto reporter = makeReporter(config);
10314 
10315  RunContext context(config, std::move(reporter));
10316 
10317  Totals totals;
10318 
10319  context.testGroupStarting(config->name(), 1, 1);
10320 
10321  TestSpec testSpec = config->testSpec();
10322 
10323  auto const& allTestCases = getAllTestCasesSorted(*config);
10324  for (auto const& testCase : allTestCases) {
10325  if (!context.aborting() && matchTest(testCase, testSpec, *config))
10326  totals += context.runTest(testCase);
10327  else
10328  context.reporter().skipTest(testCase);
10329  }
10330 
10331  if (config->warnAboutNoTests() && totals.testCases.total() == 0) {
10332  ReusableStringStream testConfig;
10333 
10334  bool first = true;
10335  for (const auto& input : config->getTestsOrTags()) {
10336  if (!first) { testConfig << ' '; }
10337  first = false;
10338  testConfig << input;
10339  }
10340 
10341  context.reporter().noMatchingTestCases(testConfig.str());
10342  totals.error = -1;
10343  }
10344 
10345  context.testGroupEnded(config->name(), totals, 1, 1);
10346  return totals;
10347  }
10348 
10349  void applyFilenamesAsTags(Catch::IConfig const& config) {
10350  auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));
10351  for (auto& testCase : tests) {
10352  auto tags = testCase.tags;
10353 
10354  std::string filename = testCase.lineInfo.file;
10355  auto lastSlash = filename.find_last_of("\\/");
10356  if (lastSlash != std::string::npos) {
10357  filename.erase(0, lastSlash);
10358  filename[0] = '#';
10359  }
10360 
10361  auto lastDot = filename.find_last_of('.');
10362  if (lastDot != std::string::npos) {
10363  filename.erase(lastDot);
10364  }
10365 
10366  tags.push_back(std::move(filename));
10367  setTags(testCase, tags);
10368  }
10369  }
10370 
10371  } // anon namespace
10372 
10373  Session::Session() {
10374  static bool alreadyInstantiated = false;
10375  if( alreadyInstantiated ) {
10376  CATCH_TRY { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
10377  CATCH_CATCH_ALL { getMutableRegistryHub().registerStartupException(); }
10378  }
10379 
10380  // There cannot be exceptions at startup in no-exception mode.
10381 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
10382  const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
10383  if ( !exceptions.empty() ) {
10384  m_startupExceptions = true;
10385  Colour colourGuard( Colour::Red );
10386  Catch::cerr() << "Errors occurred during startup!" << '\n';
10387  // iterate over all exceptions and notify user
10388  for ( const auto& ex_ptr : exceptions ) {
10389  try {
10390  std::rethrow_exception(ex_ptr);
10391  } catch ( std::exception const& ex ) {
10392  Catch::cerr() << Column( ex.what() ).indent(2) << '\n';
10393  }
10394  }
10395  }
10396 #endif
10397 
10398  alreadyInstantiated = true;
10399  m_cli = makeCommandLineParser( m_configData );
10400  }
10401  Session::~Session() {
10402  Catch::cleanUp();
10403  }
10404 
10405  void Session::showHelp() const {
10406  Catch::cout()
10407  << "\nCatch v" << libraryVersion() << "\n"
10408  << m_cli << std::endl
10409  << "For more detailed usage please see the project docs\n" << std::endl;
10410  }
10411  void Session::libIdentify() {
10412  Catch::cout()
10413  << std::left << std::setw(16) << "description: " << "A Catch test executable\n"
10414  << std::left << std::setw(16) << "category: " << "testframework\n"
10415  << std::left << std::setw(16) << "framework: " << "Catch Test\n"
10416  << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
10417  }
10418 
10419  int Session::applyCommandLine( int argc, char const * const * argv ) {
10420  if( m_startupExceptions )
10421  return 1;
10422 
10423  auto result = m_cli.parse( clara::Args( argc, argv ) );
10424  if( !result ) {
10425  Catch::cerr()
10426  << Colour( Colour::Red )
10427  << "\nError(s) in input:\n"
10428  << Column( result.errorMessage() ).indent( 2 )
10429  << "\n\n";
10430  Catch::cerr() << "Run with -? for usage\n" << std::endl;
10431  return MaxExitCode;
10432  }
10433 
10434  if( m_configData.showHelp )
10435  showHelp();
10436  if( m_configData.libIdentify )
10437  libIdentify();
10438  m_config.reset();
10439  return 0;
10440  }
10441 
10442 #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
10443  int Session::applyCommandLine( int argc, wchar_t const * const * argv ) {
10444 
10445  char **utf8Argv = new char *[ argc ];
10446 
10447  for ( int i = 0; i < argc; ++i ) {
10448  int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL );
10449 
10450  utf8Argv[ i ] = new char[ bufSize ];
10451 
10452  WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL );
10453  }
10454 
10455  int returnCode = applyCommandLine( argc, utf8Argv );
10456 
10457  for ( int i = 0; i < argc; ++i )
10458  delete [] utf8Argv[ i ];
10459 
10460  delete [] utf8Argv;
10461 
10462  return returnCode;
10463  }
10464 #endif
10465 
10466  void Session::useConfigData( ConfigData const& configData ) {
10467  m_configData = configData;
10468  m_config.reset();
10469  }
10470 
10471  int Session::run() {
10472  if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {
10473  Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
10474  static_cast<void>(std::getchar());
10475  }
10476  int exitCode = runInternal();
10477  if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {
10478  Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
10479  static_cast<void>(std::getchar());
10480  }
10481  return exitCode;
10482  }
10483 
10484  clara::Parser const& Session::cli() const {
10485  return m_cli;
10486  }
10487  void Session::cli( clara::Parser const& newParser ) {
10488  m_cli = newParser;
10489  }
10490  ConfigData& Session::configData() {
10491  return m_configData;
10492  }
10493  Config& Session::config() {
10494  if( !m_config )
10495  m_config = std::make_shared<Config>( m_configData );
10496  return *m_config;
10497  }
10498 
10499  int Session::runInternal() {
10500  if( m_startupExceptions )
10501  return 1;
10502 
10503  if (m_configData.showHelp || m_configData.libIdentify) {
10504  return 0;
10505  }
10506 
10507  CATCH_TRY {
10508  config(); // Force config to be constructed
10509 
10510  seedRng( *m_config );
10511 
10512  if( m_configData.filenamesAsTags )
10513  applyFilenamesAsTags( *m_config );
10514 
10515  // Handle list request
10516  if( Option<std::size_t> listed = list( config() ) )
10517  return static_cast<int>( *listed );
10518 
10519  auto totals = runTests( m_config );
10520  // Note that on unices only the lower 8 bits are usually used, clamping
10521  // the return value to 255 prevents false negative when some multiple
10522  // of 256 tests has failed
10523  return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed)));
10524  }
10525 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
10526  catch( std::exception& ex ) {
10527  Catch::cerr() << ex.what() << std::endl;
10528  return MaxExitCode;
10529  }
10530 #endif
10531  }
10532 
10533 } // end namespace Catch
10534 // end catch_session.cpp
10535 // start catch_singletons.cpp
10536 
10537 #include <vector>
10538 
10539 namespace Catch {
10540 
10541  namespace {
10542  static auto getSingletons() -> std::vector<ISingleton*>*& {
10543  static std::vector<ISingleton*>* g_singletons = nullptr;
10544  if( !g_singletons )
10545  g_singletons = new std::vector<ISingleton*>();
10546  return g_singletons;
10547  }
10548  }
10549 
10550  ISingleton::~ISingleton() {}
10551 
10552  void addSingleton(ISingleton* singleton ) {
10553  getSingletons()->push_back( singleton );
10554  }
10555  void cleanupSingletons() {
10556  auto& singletons = getSingletons();
10557  for( auto singleton : *singletons )
10558  delete singleton;
10559  delete singletons;
10560  singletons = nullptr;
10561  }
10562 
10563 } // namespace Catch
10564 // end catch_singletons.cpp
10565 // start catch_startup_exception_registry.cpp
10566 
10567 namespace Catch {
10568 void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
10569  CATCH_TRY {
10570  m_exceptions.push_back(exception);
10571  } CATCH_CATCH_ALL {
10572  // If we run out of memory during start-up there's really not a lot more we can do about it
10573  std::terminate();
10574  }
10575  }
10576 
10577  std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept {
10578  return m_exceptions;
10579  }
10580 
10581 } // end namespace Catch
10582 // end catch_startup_exception_registry.cpp
10583 // start catch_stream.cpp
10584 
10585 #include <cstdio>
10586 #include <iostream>
10587 #include <fstream>
10588 #include <sstream>
10589 #include <vector>
10590 #include <memory>
10591 
10592 namespace Catch {
10593 
10594  Catch::IStream::~IStream() = default;
10595 
10596  namespace detail { namespace {
10597  template<typename WriterF, std::size_t bufferSize=256>
10598  class StreamBufImpl : public std::streambuf {
10599  char data[bufferSize];
10600  WriterF m_writer;
10601 
10602  public:
10603  StreamBufImpl() {
10604  setp( data, data + sizeof(data) );
10605  }
10606 
10607  ~StreamBufImpl() noexcept {
10608  StreamBufImpl::sync();
10609  }
10610 
10611  private:
10612  int overflow( int c ) override {
10613  sync();
10614 
10615  if( c != EOF ) {
10616  if( pbase() == epptr() )
10617  m_writer( std::string( 1, static_cast<char>( c ) ) );
10618  else
10619  sputc( static_cast<char>( c ) );
10620  }
10621  return 0;
10622  }
10623 
10624  int sync() override {
10625  if( pbase() != pptr() ) {
10626  m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
10627  setp( pbase(), epptr() );
10628  }
10629  return 0;
10630  }
10631  };
10632 
10634 
10635  struct OutputDebugWriter {
10636 
10637  void operator()( std::string const&str ) {
10638  writeToDebugConsole( str );
10639  }
10640  };
10641 
10643 
10644  class FileStream : public IStream {
10645  mutable std::ofstream m_ofs;
10646  public:
10647  FileStream( StringRef filename ) {
10648  m_ofs.open( filename.c_str() );
10649  CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << "'" );
10650  }
10651  ~FileStream() override = default;
10652  public: // IStream
10653  std::ostream& stream() const override {
10654  return m_ofs;
10655  }
10656  };
10657 
10659 
10660  class CoutStream : public IStream {
10661  mutable std::ostream m_os;
10662  public:
10663  // Store the streambuf from cout up-front because
10664  // cout may get redirected when running tests
10665  CoutStream() : m_os( Catch::cout().rdbuf() ) {}
10666  ~CoutStream() override = default;
10667 
10668  public: // IStream
10669  std::ostream& stream() const override { return m_os; }
10670  };
10671 
10673 
10674  class DebugOutStream : public IStream {
10675  std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf;
10676  mutable std::ostream m_os;
10677  public:
10678  DebugOutStream()
10679  : m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
10680  m_os( m_streamBuf.get() )
10681  {}
10682 
10683  ~DebugOutStream() override = default;
10684 
10685  public: // IStream
10686  std::ostream& stream() const override { return m_os; }
10687  };
10688 
10689  }} // namespace anon::detail
10690 
10692 
10693  auto makeStream( StringRef const &filename ) -> IStream const* {
10694  if( filename.empty() )
10695  return new detail::CoutStream();
10696  else if( filename[0] == '%' ) {
10697  if( filename == "%debug" )
10698  return new detail::DebugOutStream();
10699  else
10700  CATCH_ERROR( "Unrecognised stream: '" << filename << "'" );
10701  }
10702  else
10703  return new detail::FileStream( filename );
10704  }
10705 
10706  // This class encapsulates the idea of a pool of ostringstreams that can be reused.
10707  struct StringStreams {
10708  std::vector<std::unique_ptr<std::ostringstream>> m_streams;
10709  std::vector<std::size_t> m_unused;
10710  std::ostringstream m_referenceStream; // Used for copy state/ flags from
10711 
10712  auto add() -> std::size_t {
10713  if( m_unused.empty() ) {
10714  m_streams.push_back( std::unique_ptr<std::ostringstream>( new std::ostringstream ) );
10715  return m_streams.size()-1;
10716  }
10717  else {
10718  auto index = m_unused.back();
10719  m_unused.pop_back();
10720  return index;
10721  }
10722  }
10723 
10724  void release( std::size_t index ) {
10725  m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state
10726  m_unused.push_back(index);
10727  }
10728  };
10729 
10730  ReusableStringStream::ReusableStringStream()
10731  : m_index( Singleton<StringStreams>::getMutable().add() ),
10732  m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].get() )
10733  {}
10734 
10735  ReusableStringStream::~ReusableStringStream() {
10736  static_cast<std::ostringstream*>( m_oss )->str("");
10737  m_oss->clear();
10738  Singleton<StringStreams>::getMutable().release( m_index );
10739  }
10740 
10741  auto ReusableStringStream::str() const -> std::string {
10742  return static_cast<std::ostringstream*>( m_oss )->str();
10743  }
10744 
10746 
10747 #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
10748  std::ostream& cout() { return std::cout; }
10749  std::ostream& cerr() { return std::cerr; }
10750  std::ostream& clog() { return std::clog; }
10751 #endif
10752 }
10753 // end catch_stream.cpp
10754 // start catch_string_manip.cpp
10755 
10756 #include <algorithm>
10757 #include <ostream>
10758 #include <cstring>
10759 #include <cctype>
10760 
10761 namespace Catch {
10762 
10763  namespace {
10764  char toLowerCh(char c) {
10765  return static_cast<char>( std::tolower( c ) );
10766  }
10767  }
10768 
10769  bool startsWith( std::string const& s, std::string const& prefix ) {
10770  return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
10771  }
10772  bool startsWith( std::string const& s, char prefix ) {
10773  return !s.empty() && s[0] == prefix;
10774  }
10775  bool endsWith( std::string const& s, std::string const& suffix ) {
10776  return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
10777  }
10778  bool endsWith( std::string const& s, char suffix ) {
10779  return !s.empty() && s[s.size()-1] == suffix;
10780  }
10781  bool contains( std::string const& s, std::string const& infix ) {
10782  return s.find( infix ) != std::string::npos;
10783  }
10784  void toLowerInPlace( std::string& s ) {
10785  std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
10786  }
10787  std::string toLower( std::string const& s ) {
10788  std::string lc = s;
10789  toLowerInPlace( lc );
10790  return lc;
10791  }
10792  std::string trim( std::string const& str ) {
10793  static char const* whitespaceChars = "\n\r\t ";
10794  std::string::size_type start = str.find_first_not_of( whitespaceChars );
10795  std::string::size_type end = str.find_last_not_of( whitespaceChars );
10796 
10797  return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
10798  }
10799 
10800  bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
10801  bool replaced = false;
10802  std::size_t i = str.find( replaceThis );
10803  while( i != std::string::npos ) {
10804  replaced = true;
10805  str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
10806  if( i < str.size()-withThis.size() )
10807  i = str.find( replaceThis, i+withThis.size() );
10808  else
10809  i = std::string::npos;
10810  }
10811  return replaced;
10812  }
10813 
10814  pluralise::pluralise( std::size_t count, std::string const& label )
10815  : m_count( count ),
10816  m_label( label )
10817  {}
10818 
10819  std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
10820  os << pluraliser.m_count << ' ' << pluraliser.m_label;
10821  if( pluraliser.m_count != 1 )
10822  os << 's';
10823  return os;
10824  }
10825 
10826 }
10827 // end catch_string_manip.cpp
10828 // start catch_stringref.cpp
10829 
10830 #if defined(__clang__)
10831 # pragma clang diagnostic push
10832 # pragma clang diagnostic ignored "-Wexit-time-destructors"
10833 #endif
10834 
10835 #include <ostream>
10836 #include <cstring>
10837 #include <cstdint>
10838 
10839 namespace {
10840  const uint32_t byte_2_lead = 0xC0;
10841  const uint32_t byte_3_lead = 0xE0;
10842  const uint32_t byte_4_lead = 0xF0;
10843 }
10844 
10845 namespace Catch {
10846  StringRef::StringRef( char const* rawChars ) noexcept
10847  : StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) )
10848  {}
10849 
10850  StringRef::operator std::string() const {
10851  return std::string( m_start, m_size );
10852  }
10853 
10854  void StringRef::swap( StringRef& other ) noexcept {
10855  std::swap( m_start, other.m_start );
10856  std::swap( m_size, other.m_size );
10857  std::swap( m_data, other.m_data );
10858  }
10859 
10860  auto StringRef::c_str() const -> char const* {
10861  if( isSubstring() )
10862  const_cast<StringRef*>( this )->takeOwnership();
10863  return m_start;
10864  }
10865  auto StringRef::currentData() const noexcept -> char const* {
10866  return m_start;
10867  }
10868 
10869  auto StringRef::isOwned() const noexcept -> bool {
10870  return m_data != nullptr;
10871  }
10872  auto StringRef::isSubstring() const noexcept -> bool {
10873  return m_start[m_size] != '\0';
10874  }
10875 
10876  void StringRef::takeOwnership() {
10877  if( !isOwned() ) {
10878  m_data = new char[m_size+1];
10879  memcpy( m_data, m_start, m_size );
10880  m_data[m_size] = '\0';
10881  m_start = m_data;
10882  }
10883  }
10884  auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {
10885  if( start < m_size )
10886  return StringRef( m_start+start, size );
10887  else
10888  return StringRef();
10889  }
10890  auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool {
10891  return
10892  size() == other.size() &&
10893  (std::strncmp( m_start, other.m_start, size() ) == 0);
10894  }
10895  auto StringRef::operator != ( StringRef const& other ) const noexcept -> bool {
10896  return !operator==( other );
10897  }
10898 
10899  auto StringRef::operator[](size_type index) const noexcept -> char {
10900  return m_start[index];
10901  }
10902 
10903  auto StringRef::numberOfCharacters() const noexcept -> size_type {
10904  size_type noChars = m_size;
10905  // Make adjustments for uft encodings
10906  for( size_type i=0; i < m_size; ++i ) {
10907  char c = m_start[i];
10908  if( ( c & byte_2_lead ) == byte_2_lead ) {
10909  noChars--;
10910  if (( c & byte_3_lead ) == byte_3_lead )
10911  noChars--;
10912  if( ( c & byte_4_lead ) == byte_4_lead )
10913  noChars--;
10914  }
10915  }
10916  return noChars;
10917  }
10918 
10919  auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string {
10920  std::string str;
10921  str.reserve( lhs.size() + rhs.size() );
10922  str += lhs;
10923  str += rhs;
10924  return str;
10925  }
10926  auto operator + ( StringRef const& lhs, const char* rhs ) -> std::string {
10927  return std::string( lhs ) + std::string( rhs );
10928  }
10929  auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string {
10930  return std::string( lhs ) + std::string( rhs );
10931  }
10932 
10933  auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {
10934  return os.write(str.currentData(), str.size());
10935  }
10936 
10937  auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& {
10938  lhs.append(rhs.currentData(), rhs.size());
10939  return lhs;
10940  }
10941 
10942 } // namespace Catch
10943 
10944 #if defined(__clang__)
10945 # pragma clang diagnostic pop
10946 #endif
10947 // end catch_stringref.cpp
10948 // start catch_tag_alias.cpp
10949 
10950 namespace Catch {
10951  TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {}
10952 }
10953 // end catch_tag_alias.cpp
10954 // start catch_tag_alias_autoregistrar.cpp
10955 
10956 namespace Catch {
10957 
10958  RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {
10959  CATCH_TRY {
10960  getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
10961  } CATCH_CATCH_ALL {
10962  // Do not throw when constructing global objects, instead register the exception to be processed later
10963  getMutableRegistryHub().registerStartupException();
10964  }
10965  }
10966 
10967 }
10968 // end catch_tag_alias_autoregistrar.cpp
10969 // start catch_tag_alias_registry.cpp
10970 
10971 #include <sstream>
10972 
10973 namespace Catch {
10974 
10975  TagAliasRegistry::~TagAliasRegistry() {}
10976 
10977  TagAlias const* TagAliasRegistry::find( std::string const& alias ) const {
10978  auto it = m_registry.find( alias );
10979  if( it != m_registry.end() )
10980  return &(it->second);
10981  else
10982  return nullptr;
10983  }
10984 
10985  std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
10986  std::string expandedTestSpec = unexpandedTestSpec;
10987  for( auto const& registryKvp : m_registry ) {
10988  std::size_t pos = expandedTestSpec.find( registryKvp.first );
10989  if( pos != std::string::npos ) {
10990  expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
10991  registryKvp.second.tag +
10992  expandedTestSpec.substr( pos + registryKvp.first.size() );
10993  }
10994  }
10995  return expandedTestSpec;
10996  }
10997 
10998  void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) {
10999  CATCH_ENFORCE( startsWith(alias, "[@") && endsWith(alias, ']'),
11000  "error: tag alias, '" << alias << "' is not of the form [@alias name].\n" << lineInfo );
11001 
11002  CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,
11003  "error: tag alias, '" << alias << "' already registered.\n"
11004  << "\tFirst seen at: " << find(alias)->lineInfo << "\n"
11005  << "\tRedefined at: " << lineInfo );
11006  }
11007 
11008  ITagAliasRegistry::~ITagAliasRegistry() {}
11009 
11010  ITagAliasRegistry const& ITagAliasRegistry::get() {
11011  return getRegistryHub().getTagAliasRegistry();
11012  }
11013 
11014 } // end namespace Catch
11015 // end catch_tag_alias_registry.cpp
11016 // start catch_test_case_info.cpp
11017 
11018 #include <cctype>
11019 #include <exception>
11020 #include <algorithm>
11021 #include <sstream>
11022 
11023 namespace Catch {
11024 
11025  namespace {
11026  TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
11027  if( startsWith( tag, '.' ) ||
11028  tag == "!hide" )
11029  return TestCaseInfo::IsHidden;
11030  else if( tag == "!throws" )
11031  return TestCaseInfo::Throws;
11032  else if( tag == "!shouldfail" )
11033  return TestCaseInfo::ShouldFail;
11034  else if( tag == "!mayfail" )
11035  return TestCaseInfo::MayFail;
11036  else if( tag == "!nonportable" )
11037  return TestCaseInfo::NonPortable;
11038  else if( tag == "!benchmark" )
11039  return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden );
11040  else
11041  return TestCaseInfo::None;
11042  }
11043  bool isReservedTag( std::string const& tag ) {
11044  return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) );
11045  }
11046  void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
11047  CATCH_ENFORCE( !isReservedTag(tag),
11048  "Tag name: [" << tag << "] is not allowed.\n"
11049  << "Tag names starting with non alpha-numeric characters are reserved\n"
11050  << _lineInfo );
11051  }
11052  }
11053 
11054  TestCase makeTestCase( ITestInvoker* _testCase,
11055  std::string const& _className,
11056  NameAndTags const& nameAndTags,
11057  SourceLineInfo const& _lineInfo )
11058  {
11059  bool isHidden = false;
11060 
11061  // Parse out tags
11062  std::vector<std::string> tags;
11063  std::string desc, tag;
11064  bool inTag = false;
11065  std::string _descOrTags = nameAndTags.tags;
11066  for (char c : _descOrTags) {
11067  if( !inTag ) {
11068  if( c == '[' )
11069  inTag = true;
11070  else
11071  desc += c;
11072  }
11073  else {
11074  if( c == ']' ) {
11075  TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
11076  if( ( prop & TestCaseInfo::IsHidden ) != 0 )
11077  isHidden = true;
11078  else if( prop == TestCaseInfo::None )
11079  enforceNotReservedTag( tag, _lineInfo );
11080 
11081  tags.push_back( tag );
11082  tag.clear();
11083  inTag = false;
11084  }
11085  else
11086  tag += c;
11087  }
11088  }
11089  if( isHidden ) {
11090  tags.push_back( "." );
11091  }
11092 
11093  TestCaseInfo info( nameAndTags.name, _className, desc, tags, _lineInfo );
11094  return TestCase( _testCase, std::move(info) );
11095  }
11096 
11097  void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ) {
11098  std::sort(begin(tags), end(tags));
11099  tags.erase(std::unique(begin(tags), end(tags)), end(tags));
11100  testCaseInfo.lcaseTags.clear();
11101 
11102  for( auto const& tag : tags ) {
11103  std::string lcaseTag = toLower( tag );
11104  testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
11105  testCaseInfo.lcaseTags.push_back( lcaseTag );
11106  }
11107  testCaseInfo.tags = std::move(tags);
11108  }
11109 
11110  TestCaseInfo::TestCaseInfo( std::string const& _name,
11111  std::string const& _className,
11112  std::string const& _description,
11113  std::vector<std::string> const& _tags,
11114  SourceLineInfo const& _lineInfo )
11115  : name( _name ),
11116  className( _className ),
11117  description( _description ),
11118  lineInfo( _lineInfo ),
11119  properties( None )
11120  {
11121  setTags( *this, _tags );
11122  }
11123 
11124  bool TestCaseInfo::isHidden() const {
11125  return ( properties & IsHidden ) != 0;
11126  }
11127  bool TestCaseInfo::throws() const {
11128  return ( properties & Throws ) != 0;
11129  }
11130  bool TestCaseInfo::okToFail() const {
11131  return ( properties & (ShouldFail | MayFail ) ) != 0;
11132  }
11133  bool TestCaseInfo::expectedToFail() const {
11134  return ( properties & (ShouldFail ) ) != 0;
11135  }
11136 
11137  std::string TestCaseInfo::tagsAsString() const {
11138  std::string ret;
11139  // '[' and ']' per tag
11140  std::size_t full_size = 2 * tags.size();
11141  for (const auto& tag : tags) {
11142  full_size += tag.size();
11143  }
11144  ret.reserve(full_size);
11145  for (const auto& tag : tags) {
11146  ret.push_back('[');
11147  ret.append(tag);
11148  ret.push_back(']');
11149  }
11150 
11151  return ret;
11152  }
11153 
11154  TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( std::move(info) ), test( testCase ) {}
11155 
11156  TestCase TestCase::withName( std::string const& _newName ) const {
11157  TestCase other( *this );
11158  other.name = _newName;
11159  return other;
11160  }
11161 
11162  void TestCase::invoke() const {
11163  test->invoke();
11164  }
11165 
11166  bool TestCase::operator == ( TestCase const& other ) const {
11167  return test.get() == other.test.get() &&
11168  name == other.name &&
11169  className == other.className;
11170  }
11171 
11172  bool TestCase::operator < ( TestCase const& other ) const {
11173  return name < other.name;
11174  }
11175 
11176  TestCaseInfo const& TestCase::getTestCaseInfo() const
11177  {
11178  return *this;
11179  }
11180 
11181 } // end namespace Catch
11182 // end catch_test_case_info.cpp
11183 // start catch_test_case_registry_impl.cpp
11184 
11185 #include <sstream>
11186 
11187 namespace Catch {
11188 
11189  std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
11190 
11191  std::vector<TestCase> sorted = unsortedTestCases;
11192 
11193  switch( config.runOrder() ) {
11194  case RunTests::InLexicographicalOrder:
11195  std::sort( sorted.begin(), sorted.end() );
11196  break;
11197  case RunTests::InRandomOrder:
11198  seedRng( config );
11199  std::shuffle( sorted.begin(), sorted.end(), rng() );
11200  break;
11201  case RunTests::InDeclarationOrder:
11202  // already in declaration order
11203  break;
11204  }
11205  return sorted;
11206  }
11207  bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
11208  return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
11209  }
11210 
11211  void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
11212  std::set<TestCase> seenFunctions;
11213  for( auto const& function : functions ) {
11214  auto prev = seenFunctions.insert( function );
11215  CATCH_ENFORCE( prev.second,
11216  "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n"
11217  << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
11218  << "\tRedefined at " << function.getTestCaseInfo().lineInfo );
11219  }
11220  }
11221 
11222  std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
11223  std::vector<TestCase> filtered;
11224  filtered.reserve( testCases.size() );
11225  for( auto const& testCase : testCases )
11226  if( matchTest( testCase, testSpec, config ) )
11227  filtered.push_back( testCase );
11228  return filtered;
11229  }
11230  std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
11231  return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
11232  }
11233 
11234  void TestRegistry::registerTest( TestCase const& testCase ) {
11235  std::string name = testCase.getTestCaseInfo().name;
11236  if( name.empty() ) {
11237  ReusableStringStream rss;
11238  rss << "Anonymous test case " << ++m_unnamedCount;
11239  return registerTest( testCase.withName( rss.str() ) );
11240  }
11241  m_functions.push_back( testCase );
11242  }
11243 
11244  std::vector<TestCase> const& TestRegistry::getAllTests() const {
11245  return m_functions;
11246  }
11247  std::vector<TestCase> const& TestRegistry::getAllTestsSorted( IConfig const& config ) const {
11248  if( m_sortedFunctions.empty() )
11249  enforceNoDuplicateTestCases( m_functions );
11250 
11251  if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
11252  m_sortedFunctions = sortTests( config, m_functions );
11253  m_currentSortOrder = config.runOrder();
11254  }
11255  return m_sortedFunctions;
11256  }
11257 
11259  TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {}
11260 
11261  void TestInvokerAsFunction::invoke() const {
11262  m_testAsFunction();
11263  }
11264 
11265  std::string extractClassName( StringRef const& classOrQualifiedMethodName ) {
11266  std::string className = classOrQualifiedMethodName;
11267  if( startsWith( className, '&' ) )
11268  {
11269  std::size_t lastColons = className.rfind( "::" );
11270  std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
11271  if( penultimateColons == std::string::npos )
11272  penultimateColons = 1;
11273  className = className.substr( penultimateColons, lastColons-penultimateColons );
11274  }
11275  return className;
11276  }
11277 
11278 } // end namespace Catch
11279 // end catch_test_case_registry_impl.cpp
11280 // start catch_test_case_tracker.cpp
11281 
11282 #include <algorithm>
11283 #include <cassert>
11284 #include <stdexcept>
11285 #include <memory>
11286 #include <sstream>
11287 
11288 #if defined(__clang__)
11289 # pragma clang diagnostic push
11290 # pragma clang diagnostic ignored "-Wexit-time-destructors"
11291 #endif
11292 
11293 namespace Catch {
11294 namespace TestCaseTracking {
11295 
11296  NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location )
11297  : name( _name ),
11298  location( _location )
11299  {}
11300 
11301  ITracker::~ITracker() = default;
11302 
11303  TrackerContext& TrackerContext::instance() {
11304  static TrackerContext s_instance;
11305  return s_instance;
11306  }
11307 
11308  ITracker& TrackerContext::startRun() {
11309  m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr );
11310  m_currentTracker = nullptr;
11311  m_runState = Executing;
11312  return *m_rootTracker;
11313  }
11314 
11315  void TrackerContext::endRun() {
11316  m_rootTracker.reset();
11317  m_currentTracker = nullptr;
11318  m_runState = NotStarted;
11319  }
11320 
11321  void TrackerContext::startCycle() {
11322  m_currentTracker = m_rootTracker.get();
11323  m_runState = Executing;
11324  }
11325  void TrackerContext::completeCycle() {
11326  m_runState = CompletedCycle;
11327  }
11328 
11329  bool TrackerContext::completedCycle() const {
11330  return m_runState == CompletedCycle;
11331  }
11332  ITracker& TrackerContext::currentTracker() {
11333  return *m_currentTracker;
11334  }
11335  void TrackerContext::setCurrentTracker( ITracker* tracker ) {
11336  m_currentTracker = tracker;
11337  }
11338 
11339  TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
11340  : m_nameAndLocation( nameAndLocation ),
11341  m_ctx( ctx ),
11342  m_parent( parent )
11343  {}
11344 
11345  NameAndLocation const& TrackerBase::nameAndLocation() const {
11346  return m_nameAndLocation;
11347  }
11348  bool TrackerBase::isComplete() const {
11349  return m_runState == CompletedSuccessfully || m_runState == Failed;
11350  }
11351  bool TrackerBase::isSuccessfullyCompleted() const {
11352  return m_runState == CompletedSuccessfully;
11353  }
11354  bool TrackerBase::isOpen() const {
11355  return m_runState != NotStarted && !isComplete();
11356  }
11357  bool TrackerBase::hasChildren() const {
11358  return !m_children.empty();
11359  }
11360 
11361  void TrackerBase::addChild( ITrackerPtr const& child ) {
11362  m_children.push_back( child );
11363  }
11364 
11365  ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) {
11366  auto it = std::find_if( m_children.begin(), m_children.end(),
11367  [&nameAndLocation]( ITrackerPtr const& tracker ){
11368  return
11369  tracker->nameAndLocation().location == nameAndLocation.location &&
11370  tracker->nameAndLocation().name == nameAndLocation.name;
11371  } );
11372  return( it != m_children.end() )
11373  ? *it
11374  : nullptr;
11375  }
11376  ITracker& TrackerBase::parent() {
11377  assert( m_parent ); // Should always be non-null except for root
11378  return *m_parent;
11379  }
11380 
11381  void TrackerBase::openChild() {
11382  if( m_runState != ExecutingChildren ) {
11383  m_runState = ExecutingChildren;
11384  if( m_parent )
11385  m_parent->openChild();
11386  }
11387  }
11388 
11389  bool TrackerBase::isSectionTracker() const { return false; }
11390  bool TrackerBase::isIndexTracker() const { return false; }
11391 
11392  void TrackerBase::open() {
11393  m_runState = Executing;
11394  moveToThis();
11395  if( m_parent )
11396  m_parent->openChild();
11397  }
11398 
11399  void TrackerBase::close() {
11400 
11401  // Close any still open children (e.g. generators)
11402  while( &m_ctx.currentTracker() != this )
11403  m_ctx.currentTracker().close();
11404 
11405  switch( m_runState ) {
11406  case NeedsAnotherRun:
11407  break;
11408 
11409  case Executing:
11410  m_runState = CompletedSuccessfully;
11411  break;
11412  case ExecutingChildren:
11413  if( m_children.empty() || m_children.back()->isComplete() )
11414  m_runState = CompletedSuccessfully;
11415  break;
11416 
11417  case NotStarted:
11418  case CompletedSuccessfully:
11419  case Failed:
11420  CATCH_INTERNAL_ERROR( "Illogical state: " << m_runState );
11421 
11422  default:
11423  CATCH_INTERNAL_ERROR( "Unknown state: " << m_runState );
11424  }
11425  moveToParent();
11426  m_ctx.completeCycle();
11427  }
11428  void TrackerBase::fail() {
11429  m_runState = Failed;
11430  if( m_parent )
11431  m_parent->markAsNeedingAnotherRun();
11432  moveToParent();
11433  m_ctx.completeCycle();
11434  }
11435  void TrackerBase::markAsNeedingAnotherRun() {
11436  m_runState = NeedsAnotherRun;
11437  }
11438 
11439  void TrackerBase::moveToParent() {
11440  assert( m_parent );
11441  m_ctx.setCurrentTracker( m_parent );
11442  }
11443  void TrackerBase::moveToThis() {
11444  m_ctx.setCurrentTracker( this );
11445  }
11446 
11447  SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
11448  : TrackerBase( nameAndLocation, ctx, parent )
11449  {
11450  if( parent ) {
11451  while( !parent->isSectionTracker() )
11452  parent = &parent->parent();
11453 
11454  SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );
11455  addNextFilters( parentSection.m_filters );
11456  }
11457  }
11458 
11459  bool SectionTracker::isSectionTracker() const { return true; }
11460 
11461  SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {
11462  std::shared_ptr<SectionTracker> section;
11463 
11464  ITracker& currentTracker = ctx.currentTracker();
11465  if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
11466  assert( childTracker );
11467  assert( childTracker->isSectionTracker() );
11468  section = std::static_pointer_cast<SectionTracker>( childTracker );
11469  }
11470  else {
11471  section = std::make_shared<SectionTracker>( nameAndLocation, ctx, &currentTracker );
11472  currentTracker.addChild( section );
11473  }
11474  if( !ctx.completedCycle() )
11475  section->tryOpen();
11476  return *section;
11477  }
11478 
11479  void SectionTracker::tryOpen() {
11480  if( !isComplete() && (m_filters.empty() || m_filters[0].empty() || m_filters[0] == m_nameAndLocation.name ) )
11481  open();
11482  }
11483 
11484  void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) {
11485  if( !filters.empty() ) {
11486  m_filters.push_back(""); // Root - should never be consulted
11487  m_filters.push_back(""); // Test Case - not a section filter
11488  m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
11489  }
11490  }
11491  void SectionTracker::addNextFilters( std::vector<std::string> const& filters ) {
11492  if( filters.size() > 1 )
11493  m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() );
11494  }
11495 
11496  IndexTracker::IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size )
11497  : TrackerBase( nameAndLocation, ctx, parent ),
11498  m_size( size )
11499  {}
11500 
11501  bool IndexTracker::isIndexTracker() const { return true; }
11502 
11503  IndexTracker& IndexTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size ) {
11504  std::shared_ptr<IndexTracker> tracker;
11505 
11506  ITracker& currentTracker = ctx.currentTracker();
11507  if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
11508  assert( childTracker );
11509  assert( childTracker->isIndexTracker() );
11510  tracker = std::static_pointer_cast<IndexTracker>( childTracker );
11511  }
11512  else {
11513  tracker = std::make_shared<IndexTracker>( nameAndLocation, ctx, &currentTracker, size );
11514  currentTracker.addChild( tracker );
11515  }
11516 
11517  if( !ctx.completedCycle() && !tracker->isComplete() ) {
11518  if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
11519  tracker->moveNext();
11520  tracker->open();
11521  }
11522 
11523  return *tracker;
11524  }
11525 
11526  int IndexTracker::index() const { return m_index; }
11527 
11528  void IndexTracker::moveNext() {
11529  m_index++;
11530  m_children.clear();
11531  }
11532 
11533  void IndexTracker::close() {
11534  TrackerBase::close();
11535  if( m_runState == CompletedSuccessfully && m_index < m_size-1 )
11536  m_runState = Executing;
11537  }
11538 
11539 } // namespace TestCaseTracking
11540 
11541 using TestCaseTracking::ITracker;
11542 using TestCaseTracking::TrackerContext;
11543 using TestCaseTracking::SectionTracker;
11544 using TestCaseTracking::IndexTracker;
11545 
11546 } // namespace Catch
11547 
11548 #if defined(__clang__)
11549 # pragma clang diagnostic pop
11550 #endif
11551 // end catch_test_case_tracker.cpp
11552 // start catch_test_registry.cpp
11553 
11554 namespace Catch {
11555 
11556  auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker* {
11557  return new(std::nothrow) TestInvokerAsFunction( testAsFunction );
11558  }
11559 
11560  NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {}
11561 
11562  AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept {
11563  CATCH_TRY {
11564  getMutableRegistryHub()
11565  .registerTest(
11566  makeTestCase(
11567  invoker,
11568  extractClassName( classOrMethod ),
11569  nameAndTags,
11570  lineInfo));
11571  } CATCH_CATCH_ALL {
11572  // Do not throw when constructing global objects, instead register the exception to be processed later
11573  getMutableRegistryHub().registerStartupException();
11574  }
11575  }
11576 
11577  AutoReg::~AutoReg() = default;
11578 }
11579 // end catch_test_registry.cpp
11580 // start catch_test_spec.cpp
11581 
11582 #include <algorithm>
11583 #include <string>
11584 #include <vector>
11585 #include <memory>
11586 
11587 namespace Catch {
11588 
11589  TestSpec::Pattern::~Pattern() = default;
11590  TestSpec::NamePattern::~NamePattern() = default;
11591  TestSpec::TagPattern::~TagPattern() = default;
11592  TestSpec::ExcludedPattern::~ExcludedPattern() = default;
11593 
11594  TestSpec::NamePattern::NamePattern( std::string const& name )
11595  : m_wildcardPattern( toLower( name ), CaseSensitive::No )
11596  {}
11597  bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const {
11598  return m_wildcardPattern.matches( toLower( testCase.name ) );
11599  }
11600 
11601  TestSpec::TagPattern::TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
11602  bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const {
11603  return std::find(begin(testCase.lcaseTags),
11604  end(testCase.lcaseTags),
11605  m_tag) != end(testCase.lcaseTags);
11606  }
11607 
11608  TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
11609  bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
11610 
11611  bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const {
11612  // All patterns in a filter must match for the filter to be a match
11613  for( auto const& pattern : m_patterns ) {
11614  if( !pattern->matches( testCase ) )
11615  return false;
11616  }
11617  return true;
11618  }
11619 
11620  bool TestSpec::hasFilters() const {
11621  return !m_filters.empty();
11622  }
11623  bool TestSpec::matches( TestCaseInfo const& testCase ) const {
11624  // A TestSpec matches if any filter matches
11625  for( auto const& filter : m_filters )
11626  if( filter.matches( testCase ) )
11627  return true;
11628  return false;
11629  }
11630 }
11631 // end catch_test_spec.cpp
11632 // start catch_test_spec_parser.cpp
11633 
11634 namespace Catch {
11635 
11636  TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
11637 
11638  TestSpecParser& TestSpecParser::parse( std::string const& arg ) {
11639  m_mode = None;
11640  m_exclusion = false;
11641  m_start = std::string::npos;
11642  m_arg = m_tagAliases->expandAliases( arg );
11643  m_escapeChars.clear();
11644  for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
11645  visitChar( m_arg[m_pos] );
11646  if( m_mode == Name )
11647  addPattern<TestSpec::NamePattern>();
11648  return *this;
11649  }
11650  TestSpec TestSpecParser::testSpec() {
11651  addFilter();
11652  return m_testSpec;
11653  }
11654 
11655  void TestSpecParser::visitChar( char c ) {
11656  if( m_mode == None ) {
11657  switch( c ) {
11658  case ' ': return;
11659  case '~': m_exclusion = true; return;
11660  case '[': return startNewMode( Tag, ++m_pos );
11661  case '"': return startNewMode( QuotedName, ++m_pos );
11662  case '\\': return escape();
11663  default: startNewMode( Name, m_pos ); break;
11664  }
11665  }
11666  if( m_mode == Name ) {
11667  if( c == ',' ) {
11668  addPattern<TestSpec::NamePattern>();
11669  addFilter();
11670  }
11671  else if( c == '[' ) {
11672  if( subString() == "exclude:" )
11673  m_exclusion = true;
11674  else
11675  addPattern<TestSpec::NamePattern>();
11676  startNewMode( Tag, ++m_pos );
11677  }
11678  else if( c == '\\' )
11679  escape();
11680  }
11681  else if( m_mode == EscapedName )
11682  m_mode = Name;
11683  else if( m_mode == QuotedName && c == '"' )
11684  addPattern<TestSpec::NamePattern>();
11685  else if( m_mode == Tag && c == ']' )
11686  addPattern<TestSpec::TagPattern>();
11687  }
11688  void TestSpecParser::startNewMode( Mode mode, std::size_t start ) {
11689  m_mode = mode;
11690  m_start = start;
11691  }
11692  void TestSpecParser::escape() {
11693  if( m_mode == None )
11694  m_start = m_pos;
11695  m_mode = EscapedName;
11696  m_escapeChars.push_back( m_pos );
11697  }
11698  std::string TestSpecParser::subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
11699 
11700  void TestSpecParser::addFilter() {
11701  if( !m_currentFilter.m_patterns.empty() ) {
11702  m_testSpec.m_filters.push_back( m_currentFilter );
11703  m_currentFilter = TestSpec::Filter();
11704  }
11705  }
11706 
11707  TestSpec parseTestSpec( std::string const& arg ) {
11708  return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
11709  }
11710 
11711 } // namespace Catch
11712 // end catch_test_spec_parser.cpp
11713 // start catch_timer.cpp
11714 
11715 #include <chrono>
11716 
11717 static const uint64_t nanosecondsInSecond = 1000000000;
11718 
11719 namespace Catch {
11720 
11721  auto getCurrentNanosecondsSinceEpoch() -> uint64_t {
11722  return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
11723  }
11724 
11725  namespace {
11726  auto estimateClockResolution() -> uint64_t {
11727  uint64_t sum = 0;
11728  static const uint64_t iterations = 1000000;
11729 
11730  auto startTime = getCurrentNanosecondsSinceEpoch();
11731 
11732  for( std::size_t i = 0; i < iterations; ++i ) {
11733 
11734  uint64_t ticks;
11735  uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
11736  do {
11737  ticks = getCurrentNanosecondsSinceEpoch();
11738  } while( ticks == baseTicks );
11739 
11740  auto delta = ticks - baseTicks;
11741  sum += delta;
11742 
11743  // If we have been calibrating for over 3 seconds -- the clock
11744  // is terrible and we should move on.
11745  // TBD: How to signal that the measured resolution is probably wrong?
11746  if (ticks > startTime + 3 * nanosecondsInSecond) {
11747  return sum / i;
11748  }
11749  }
11750 
11751  // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
11752  // - and potentially do more iterations if there's a high variance.
11753  return sum/iterations;
11754  }
11755  }
11756  auto getEstimatedClockResolution() -> uint64_t {
11757  static auto s_resolution = estimateClockResolution();
11758  return s_resolution;
11759  }
11760 
11761  void Timer::start() {
11762  m_nanoseconds = getCurrentNanosecondsSinceEpoch();
11763  }
11764  auto Timer::getElapsedNanoseconds() const -> uint64_t {
11765  return getCurrentNanosecondsSinceEpoch() - m_nanoseconds;
11766  }
11767  auto Timer::getElapsedMicroseconds() const -> uint64_t {
11768  return getElapsedNanoseconds()/1000;
11769  }
11770  auto Timer::getElapsedMilliseconds() const -> unsigned int {
11771  return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
11772  }
11773  auto Timer::getElapsedSeconds() const -> double {
11774  return getElapsedMicroseconds()/1000000.0;
11775  }
11776 
11777 } // namespace Catch
11778 // end catch_timer.cpp
11779 // start catch_tostring.cpp
11780 
11781 #if defined(__clang__)
11782 # pragma clang diagnostic push
11783 # pragma clang diagnostic ignored "-Wexit-time-destructors"
11784 # pragma clang diagnostic ignored "-Wglobal-constructors"
11785 #endif
11786 
11787 // Enable specific decls locally
11788 #if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
11789 #define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
11790 #endif
11791 
11792 #include <cmath>
11793 #include <iomanip>
11794 
11795 namespace Catch {
11796 
11797 namespace Detail {
11798 
11799  const std::string unprintableString = "{?}";
11800 
11801  namespace {
11802  const int hexThreshold = 255;
11803 
11804  struct Endianness {
11805  enum Arch { Big, Little };
11806 
11807  static Arch which() {
11808  union _{
11809  int asInt;
11810  char asChar[sizeof (int)];
11811  } u;
11812 
11813  u.asInt = 1;
11814  return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
11815  }
11816  };
11817  }
11818 
11819  std::string rawMemoryToString( const void *object, std::size_t size ) {
11820  // Reverse order for little endian architectures
11821  int i = 0, end = static_cast<int>( size ), inc = 1;
11822  if( Endianness::which() == Endianness::Little ) {
11823  i = end-1;
11824  end = inc = -1;
11825  }
11826 
11827  unsigned char const *bytes = static_cast<unsigned char const *>(object);
11828  ReusableStringStream rss;
11829  rss << "0x" << std::setfill('0') << std::hex;
11830  for( ; i != end; i += inc )
11831  rss << std::setw(2) << static_cast<unsigned>(bytes[i]);
11832  return rss.str();
11833  }
11834 }
11835 
11836 template<typename T>
11837 std::string fpToString( T value, int precision ) {
11838  if (Catch::isnan(value)) {
11839  return "nan";
11840  }
11841 
11842  ReusableStringStream rss;
11843  rss << std::setprecision( precision )
11844  << std::fixed
11845  << value;
11846  std::string d = rss.str();
11847  std::size_t i = d.find_last_not_of( '0' );
11848  if( i != std::string::npos && i != d.size()-1 ) {
11849  if( d[i] == '.' )
11850  i++;
11851  d = d.substr( 0, i+1 );
11852  }
11853  return d;
11854 }
11855 
11857 //
11858 // Out-of-line defs for full specialization of StringMaker
11859 //
11861 
11862 std::string StringMaker<std::string>::convert(const std::string& str) {
11863  if (!getCurrentContext().getConfig()->showInvisibles()) {
11864  return '"' + str + '"';
11865  }
11866 
11867  std::string s("\"");
11868  for (char c : str) {
11869  switch (c) {
11870  case '\n':
11871  s.append("\\n");
11872  break;
11873  case '\t':
11874  s.append("\\t");
11875  break;
11876  default:
11877  s.push_back(c);
11878  break;
11879  }
11880  }
11881  s.append("\"");
11882  return s;
11883 }
11884 
11885 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
11886 std::string StringMaker<std::string_view>::convert(std::string_view str) {
11887  return ::Catch::Detail::stringify(std::string{ str });
11888 }
11889 #endif
11890 
11891 std::string StringMaker<char const*>::convert(char const* str) {
11892  if (str) {
11893  return ::Catch::Detail::stringify(std::string{ str });
11894  } else {
11895  return{ "{null string}" };
11896  }
11897 }
11898 std::string StringMaker<char*>::convert(char* str) {
11899  if (str) {
11900  return ::Catch::Detail::stringify(std::string{ str });
11901  } else {
11902  return{ "{null string}" };
11903  }
11904 }
11905 
11906 #ifdef CATCH_CONFIG_WCHAR
11907 std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
11908  std::string s;
11909  s.reserve(wstr.size());
11910  for (auto c : wstr) {
11911  s += (c <= 0xff) ? static_cast<char>(c) : '?';
11912  }
11913  return ::Catch::Detail::stringify(s);
11914 }
11915 
11916 # ifdef CATCH_CONFIG_CPP17_STRING_VIEW
11917 std::string StringMaker<std::wstring_view>::convert(std::wstring_view str) {
11918  return StringMaker<std::wstring>::convert(std::wstring(str));
11919 }
11920 # endif
11921 
11922 std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {
11923  if (str) {
11924  return ::Catch::Detail::stringify(std::wstring{ str });
11925  } else {
11926  return{ "{null string}" };
11927  }
11928 }
11929 std::string StringMaker<wchar_t *>::convert(wchar_t * str) {
11930  if (str) {
11931  return ::Catch::Detail::stringify(std::wstring{ str });
11932  } else {
11933  return{ "{null string}" };
11934  }
11935 }
11936 #endif
11937 
11938 std::string StringMaker<int>::convert(int value) {
11939  return ::Catch::Detail::stringify(static_cast<long long>(value));
11940 }
11941 std::string StringMaker<long>::convert(long value) {
11942  return ::Catch::Detail::stringify(static_cast<long long>(value));
11943 }
11944 std::string StringMaker<long long>::convert(long long value) {
11945  ReusableStringStream rss;
11946  rss << value;
11947  if (value > Detail::hexThreshold) {
11948  rss << " (0x" << std::hex << value << ')';
11949  }
11950  return rss.str();
11951 }
11952 
11953 std::string StringMaker<unsigned int>::convert(unsigned int value) {
11954  return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
11955 }
11956 std::string StringMaker<unsigned long>::convert(unsigned long value) {
11957  return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
11958 }
11959 std::string StringMaker<unsigned long long>::convert(unsigned long long value) {
11960  ReusableStringStream rss;
11961  rss << value;
11962  if (value > Detail::hexThreshold) {
11963  rss << " (0x" << std::hex << value << ')';
11964  }
11965  return rss.str();
11966 }
11967 
11968 std::string StringMaker<bool>::convert(bool b) {
11969  return b ? "true" : "false";
11970 }
11971 
11972 std::string StringMaker<signed char>::convert(signed char value) {
11973  if (value == '\r') {
11974  return "'\\r'";
11975  } else if (value == '\f') {
11976  return "'\\f'";
11977  } else if (value == '\n') {
11978  return "'\\n'";
11979  } else if (value == '\t') {
11980  return "'\\t'";
11981  } else if ('\0' <= value && value < ' ') {
11982  return ::Catch::Detail::stringify(static_cast<unsigned int>(value));
11983  } else {
11984  char chstr[] = "' '";
11985  chstr[1] = value;
11986  return chstr;
11987  }
11988 }
11989 std::string StringMaker<char>::convert(char c) {
11990  return ::Catch::Detail::stringify(static_cast<signed char>(c));
11991 }
11992 std::string StringMaker<unsigned char>::convert(unsigned char c) {
11993  return ::Catch::Detail::stringify(static_cast<char>(c));
11994 }
11995 
11996 std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) {
11997  return "nullptr";
11998 }
11999 
12000 std::string StringMaker<float>::convert(float value) {
12001  return fpToString(value, 5) + 'f';
12002 }
12003 std::string StringMaker<double>::convert(double value) {
12004  return fpToString(value, 10);
12005 }
12006 
12007 std::string ratio_string<std::atto>::symbol() { return "a"; }
12008 std::string ratio_string<std::femto>::symbol() { return "f"; }
12009 std::string ratio_string<std::pico>::symbol() { return "p"; }
12010 std::string ratio_string<std::nano>::symbol() { return "n"; }
12011 std::string ratio_string<std::micro>::symbol() { return "u"; }
12012 std::string ratio_string<std::milli>::symbol() { return "m"; }
12013 
12014 } // end namespace Catch
12015 
12016 #if defined(__clang__)
12017 # pragma clang diagnostic pop
12018 #endif
12019 
12020 // end catch_tostring.cpp
12021 // start catch_totals.cpp
12022 
12023 namespace Catch {
12024 
12025  Counts Counts::operator - ( Counts const& other ) const {
12026  Counts diff;
12027  diff.passed = passed - other.passed;
12028  diff.failed = failed - other.failed;
12029  diff.failedButOk = failedButOk - other.failedButOk;
12030  return diff;
12031  }
12032 
12033  Counts& Counts::operator += ( Counts const& other ) {
12034  passed += other.passed;
12035  failed += other.failed;
12036  failedButOk += other.failedButOk;
12037  return *this;
12038  }
12039 
12040  std::size_t Counts::total() const {
12041  return passed + failed + failedButOk;
12042  }
12043  bool Counts::allPassed() const {
12044  return failed == 0 && failedButOk == 0;
12045  }
12046  bool Counts::allOk() const {
12047  return failed == 0;
12048  }
12049 
12050  Totals Totals::operator - ( Totals const& other ) const {
12051  Totals diff;
12052  diff.assertions = assertions - other.assertions;
12053  diff.testCases = testCases - other.testCases;
12054  return diff;
12055  }
12056 
12057  Totals& Totals::operator += ( Totals const& other ) {
12058  assertions += other.assertions;
12059  testCases += other.testCases;
12060  return *this;
12061  }
12062 
12063  Totals Totals::delta( Totals const& prevTotals ) const {
12064  Totals diff = *this - prevTotals;
12065  if( diff.assertions.failed > 0 )
12066  ++diff.testCases.failed;
12067  else if( diff.assertions.failedButOk > 0 )
12068  ++diff.testCases.failedButOk;
12069  else
12070  ++diff.testCases.passed;
12071  return diff;
12072  }
12073 
12074 }
12075 // end catch_totals.cpp
12076 // start catch_uncaught_exceptions.cpp
12077 
12078 #include <exception>
12079 
12080 namespace Catch {
12081  bool uncaught_exceptions() {
12082 #if defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
12083  return std::uncaught_exceptions() > 0;
12084 #else
12085  return std::uncaught_exception();
12086 #endif
12087  }
12088 } // end namespace Catch
12089 // end catch_uncaught_exceptions.cpp
12090 // start catch_version.cpp
12091 
12092 #include <ostream>
12093 
12094 namespace Catch {
12095 
12096  Version::Version
12097  ( unsigned int _majorVersion,
12098  unsigned int _minorVersion,
12099  unsigned int _patchNumber,
12100  char const * const _branchName,
12101  unsigned int _buildNumber )
12102  : majorVersion( _majorVersion ),
12103  minorVersion( _minorVersion ),
12104  patchNumber( _patchNumber ),
12105  branchName( _branchName ),
12106  buildNumber( _buildNumber )
12107  {}
12108 
12109  std::ostream& operator << ( std::ostream& os, Version const& version ) {
12110  os << version.majorVersion << '.'
12111  << version.minorVersion << '.'
12112  << version.patchNumber;
12113  // branchName is never null -> 0th char is \0 if it is empty
12114  if (version.branchName[0]) {
12115  os << '-' << version.branchName
12116  << '.' << version.buildNumber;
12117  }
12118  return os;
12119  }
12120 
12121  Version const& libraryVersion() {
12122  static Version version( 2, 5, 0, "", 0 );
12123  return version;
12124  }
12125 
12126 }
12127 // end catch_version.cpp
12128 // start catch_wildcard_pattern.cpp
12129 
12130 #include <sstream>
12131 
12132 namespace Catch {
12133 
12134  WildcardPattern::WildcardPattern( std::string const& pattern,
12135  CaseSensitive::Choice caseSensitivity )
12136  : m_caseSensitivity( caseSensitivity ),
12137  m_pattern( adjustCase( pattern ) )
12138  {
12139  if( startsWith( m_pattern, '*' ) ) {
12140  m_pattern = m_pattern.substr( 1 );
12141  m_wildcard = WildcardAtStart;
12142  }
12143  if( endsWith( m_pattern, '*' ) ) {
12144  m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
12145  m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
12146  }
12147  }
12148 
12149  bool WildcardPattern::matches( std::string const& str ) const {
12150  switch( m_wildcard ) {
12151  case NoWildcard:
12152  return m_pattern == adjustCase( str );
12153  case WildcardAtStart:
12154  return endsWith( adjustCase( str ), m_pattern );
12155  case WildcardAtEnd:
12156  return startsWith( adjustCase( str ), m_pattern );
12157  case WildcardAtBothEnds:
12158  return contains( adjustCase( str ), m_pattern );
12159  default:
12160  CATCH_INTERNAL_ERROR( "Unknown enum" );
12161  }
12162  }
12163 
12164  std::string WildcardPattern::adjustCase( std::string const& str ) const {
12165  return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;
12166  }
12167 }
12168 // end catch_wildcard_pattern.cpp
12169 // start catch_xmlwriter.cpp
12170 
12171 #include <iomanip>
12172 
12173 using uchar = unsigned char;
12174 
12175 namespace Catch {
12176 
12177 namespace {
12178 
12179  size_t trailingBytes(unsigned char c) {
12180  if ((c & 0xE0) == 0xC0) {
12181  return 2;
12182  }
12183  if ((c & 0xF0) == 0xE0) {
12184  return 3;
12185  }
12186  if ((c & 0xF8) == 0xF0) {
12187  return 4;
12188  }
12189  CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
12190  }
12191 
12192  uint32_t headerValue(unsigned char c) {
12193  if ((c & 0xE0) == 0xC0) {
12194  return c & 0x1F;
12195  }
12196  if ((c & 0xF0) == 0xE0) {
12197  return c & 0x0F;
12198  }
12199  if ((c & 0xF8) == 0xF0) {
12200  return c & 0x07;
12201  }
12202  CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
12203  }
12204 
12205  void hexEscapeChar(std::ostream& os, unsigned char c) {
12206  os << "\\x"
12207  << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
12208  << static_cast<int>(c);
12209  }
12210 
12211 } // anonymous namespace
12212 
12213  XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )
12214  : m_str( str ),
12215  m_forWhat( forWhat )
12216  {}
12217 
12218  void XmlEncode::encodeTo( std::ostream& os ) const {
12219  // Apostrophe escaping not necessary if we always use " to write attributes
12220  // (see: http://www.w3.org/TR/xml/#syntax)
12221 
12222  for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
12223  uchar c = m_str[idx];
12224  switch (c) {
12225  case '<': os << "&lt;"; break;
12226  case '&': os << "&amp;"; break;
12227 
12228  case '>':
12229  // See: http://www.w3.org/TR/xml/#syntax
12230  if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
12231  os << "&gt;";
12232  else
12233  os << c;
12234  break;
12235 
12236  case '\"':
12237  if (m_forWhat == ForAttributes)
12238  os << "&quot;";
12239  else
12240  os << c;
12241  break;
12242 
12243  default:
12244  // Check for control characters and invalid utf-8
12245 
12246  // Escape control characters in standard ascii
12247  // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
12248  if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
12249  hexEscapeChar(os, c);
12250  break;
12251  }
12252 
12253  // Plain ASCII: Write it to stream
12254  if (c < 0x7F) {
12255  os << c;
12256  break;
12257  }
12258 
12259  // UTF-8 territory
12260  // Check if the encoding is valid and if it is not, hex escape bytes.
12261  // Important: We do not check the exact decoded values for validity, only the encoding format
12262  // First check that this bytes is a valid lead byte:
12263  // This means that it is not encoded as 1111 1XXX
12264  // Or as 10XX XXXX
12265  if (c < 0xC0 ||
12266  c >= 0xF8) {
12267  hexEscapeChar(os, c);
12268  break;
12269  }
12270 
12271  auto encBytes = trailingBytes(c);
12272  // Are there enough bytes left to avoid accessing out-of-bounds memory?
12273  if (idx + encBytes - 1 >= m_str.size()) {
12274  hexEscapeChar(os, c);
12275  break;
12276  }
12277  // The header is valid, check data
12278  // The next encBytes bytes must together be a valid utf-8
12279  // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)
12280  bool valid = true;
12281  uint32_t value = headerValue(c);
12282  for (std::size_t n = 1; n < encBytes; ++n) {
12283  uchar nc = m_str[idx + n];
12284  valid &= ((nc & 0xC0) == 0x80);
12285  value = (value << 6) | (nc & 0x3F);
12286  }
12287 
12288  if (
12289  // Wrong bit pattern of following bytes
12290  (!valid) ||
12291  // Overlong encodings
12292  (value < 0x80) ||
12293  (0x80 <= value && value < 0x800 && encBytes > 2) ||
12294  (0x800 < value && value < 0x10000 && encBytes > 3) ||
12295  // Encoded value out of range
12296  (value >= 0x110000)
12297  ) {
12298  hexEscapeChar(os, c);
12299  break;
12300  }
12301 
12302  // If we got here, this is in fact a valid(ish) utf-8 sequence
12303  for (std::size_t n = 0; n < encBytes; ++n) {
12304  os << m_str[idx + n];
12305  }
12306  idx += encBytes - 1;
12307  break;
12308  }
12309  }
12310  }
12311 
12312  std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
12313  xmlEncode.encodeTo( os );
12314  return os;
12315  }
12316 
12317  XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer )
12318  : m_writer( writer )
12319  {}
12320 
12321  XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept
12322  : m_writer( other.m_writer ){
12323  other.m_writer = nullptr;
12324  }
12325  XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept {
12326  if ( m_writer ) {
12327  m_writer->endElement();
12328  }
12329  m_writer = other.m_writer;
12330  other.m_writer = nullptr;
12331  return *this;
12332  }
12333 
12334  XmlWriter::ScopedElement::~ScopedElement() {
12335  if( m_writer )
12336  m_writer->endElement();
12337  }
12338 
12339  XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, bool indent ) {
12340  m_writer->writeText( text, indent );
12341  return *this;
12342  }
12343 
12344  XmlWriter::XmlWriter( std::ostream& os ) : m_os( os )
12345  {
12346  writeDeclaration();
12347  }
12348 
12349  XmlWriter::~XmlWriter() {
12350  while( !m_tags.empty() )
12351  endElement();
12352  }
12353 
12354  XmlWriter& XmlWriter::startElement( std::string const& name ) {
12355  ensureTagClosed();
12356  newlineIfNecessary();
12357  m_os << m_indent << '<' << name;
12358  m_tags.push_back( name );
12359  m_indent += " ";
12360  m_tagIsOpen = true;
12361  return *this;
12362  }
12363 
12364  XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name ) {
12365  ScopedElement scoped( this );
12366  startElement( name );
12367  return scoped;
12368  }
12369 
12370  XmlWriter& XmlWriter::endElement() {
12371  newlineIfNecessary();
12372  m_indent = m_indent.substr( 0, m_indent.size()-2 );
12373  if( m_tagIsOpen ) {
12374  m_os << "/>";
12375  m_tagIsOpen = false;
12376  }
12377  else {
12378  m_os << m_indent << "</" << m_tags.back() << ">";
12379  }
12380  m_os << std::endl;
12381  m_tags.pop_back();
12382  return *this;
12383  }
12384 
12385  XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) {
12386  if( !name.empty() && !attribute.empty() )
12387  m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
12388  return *this;
12389  }
12390 
12391  XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) {
12392  m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
12393  return *this;
12394  }
12395 
12396  XmlWriter& XmlWriter::writeText( std::string const& text, bool indent ) {
12397  if( !text.empty() ){
12398  bool tagWasOpen = m_tagIsOpen;
12399  ensureTagClosed();
12400  if( tagWasOpen && indent )
12401  m_os << m_indent;
12402  m_os << XmlEncode( text );
12403  m_needsNewline = true;
12404  }
12405  return *this;
12406  }
12407 
12408  XmlWriter& XmlWriter::writeComment( std::string const& text ) {
12409  ensureTagClosed();
12410  m_os << m_indent << "<!--" << text << "-->";
12411  m_needsNewline = true;
12412  return *this;
12413  }
12414 
12415  void XmlWriter::writeStylesheetRef( std::string const& url ) {
12416  m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
12417  }
12418 
12419  XmlWriter& XmlWriter::writeBlankLine() {
12420  ensureTagClosed();
12421  m_os << '\n';
12422  return *this;
12423  }
12424 
12425  void XmlWriter::ensureTagClosed() {
12426  if( m_tagIsOpen ) {
12427  m_os << ">" << std::endl;
12428  m_tagIsOpen = false;
12429  }
12430  }
12431 
12432  void XmlWriter::writeDeclaration() {
12433  m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
12434  }
12435 
12436  void XmlWriter::newlineIfNecessary() {
12437  if( m_needsNewline ) {
12438  m_os << std::endl;
12439  m_needsNewline = false;
12440  }
12441  }
12442 }
12443 // end catch_xmlwriter.cpp
12444 // start catch_reporter_bases.cpp
12445 
12446 #include <cstring>
12447 #include <cfloat>
12448 #include <cstdio>
12449 #include <cassert>
12450 #include <memory>
12451 
12452 namespace Catch {
12453  void prepareExpandedExpression(AssertionResult& result) {
12454  result.getExpandedExpression();
12455  }
12456 
12457  // Because formatting using c++ streams is stateful, drop down to C is required
12458  // Alternatively we could use stringstream, but its performance is... not good.
12459  std::string getFormattedDuration( double duration ) {
12460  // Max exponent + 1 is required to represent the whole part
12461  // + 1 for decimal point
12462  // + 3 for the 3 decimal places
12463  // + 1 for null terminator
12464  const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
12465  char buffer[maxDoubleSize];
12466 
12467  // Save previous errno, to prevent sprintf from overwriting it
12468  ErrnoGuard guard;
12469 #ifdef _MSC_VER
12470  sprintf_s(buffer, "%.3f", duration);
12471 #else
12472  sprintf(buffer, "%.3f", duration);
12473 #endif
12474  return std::string(buffer);
12475  }
12476 
12477  TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)
12478  :StreamingReporterBase(_config) {}
12479 
12480  std::set<Verbosity> TestEventListenerBase::getSupportedVerbosities() {
12481  return { Verbosity::Quiet, Verbosity::Normal, Verbosity::High };
12482  }
12483 
12484  void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}
12485 
12486  bool TestEventListenerBase::assertionEnded(AssertionStats const &) {
12487  return false;
12488  }
12489 
12490 } // end namespace Catch
12491 // end catch_reporter_bases.cpp
12492 // start catch_reporter_compact.cpp
12493 
12494 namespace {
12495 
12496 #ifdef CATCH_PLATFORM_MAC
12497  const char* failedString() { return "FAILED"; }
12498  const char* passedString() { return "PASSED"; }
12499 #else
12500  const char* failedString() { return "failed"; }
12501  const char* passedString() { return "passed"; }
12502 #endif
12503 
12504  // Colour::LightGrey
12505  Catch::Colour::Code dimColour() { return Catch::Colour::FileName; }
12506 
12507  std::string bothOrAll( std::size_t count ) {
12508  return count == 1 ? std::string() :
12509  count == 2 ? "both " : "all " ;
12510  }
12511 
12512 } // anon namespace
12513 
12514 namespace Catch {
12515 namespace {
12516 // Colour, message variants:
12517 // - white: No tests ran.
12518 // - red: Failed [both/all] N test cases, failed [both/all] M assertions.
12519 // - white: Passed [both/all] N test cases (no assertions).
12520 // - red: Failed N tests cases, failed M assertions.
12521 // - green: Passed [both/all] N tests cases with M assertions.
12522 void printTotals(std::ostream& out, const Totals& totals) {
12523  if (totals.testCases.total() == 0) {
12524  out << "No tests ran.";
12525  } else if (totals.testCases.failed == totals.testCases.total()) {
12526  Colour colour(Colour::ResultError);
12527  const std::string qualify_assertions_failed =
12528  totals.assertions.failed == totals.assertions.total() ?
12529  bothOrAll(totals.assertions.failed) : std::string();
12530  out <<
12531  "Failed " << bothOrAll(totals.testCases.failed)
12532  << pluralise(totals.testCases.failed, "test case") << ", "
12533  "failed " << qualify_assertions_failed <<
12534  pluralise(totals.assertions.failed, "assertion") << '.';
12535  } else if (totals.assertions.total() == 0) {
12536  out <<
12537  "Passed " << bothOrAll(totals.testCases.total())
12538  << pluralise(totals.testCases.total(), "test case")
12539  << " (no assertions).";
12540  } else if (totals.assertions.failed) {
12541  Colour colour(Colour::ResultError);
12542  out <<
12543  "Failed " << pluralise(totals.testCases.failed, "test case") << ", "
12544  "failed " << pluralise(totals.assertions.failed, "assertion") << '.';
12545  } else {
12546  Colour colour(Colour::ResultSuccess);
12547  out <<
12548  "Passed " << bothOrAll(totals.testCases.passed)
12549  << pluralise(totals.testCases.passed, "test case") <<
12550  " with " << pluralise(totals.assertions.passed, "assertion") << '.';
12551  }
12552 }
12553 
12554 // Implementation of CompactReporter formatting
12555 class AssertionPrinter {
12556 public:
12557  AssertionPrinter& operator= (AssertionPrinter const&) = delete;
12558  AssertionPrinter(AssertionPrinter const&) = delete;
12559  AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
12560  : stream(_stream)
12561  , result(_stats.assertionResult)
12562  , messages(_stats.infoMessages)
12563  , itMessage(_stats.infoMessages.begin())
12564  , printInfoMessages(_printInfoMessages) {}
12565 
12566  void print() {
12567  printSourceInfo();
12568 
12569  itMessage = messages.begin();
12570 
12571  switch (result.getResultType()) {
12572  case ResultWas::Ok:
12573  printResultType(Colour::ResultSuccess, passedString());
12574  printOriginalExpression();
12575  printReconstructedExpression();
12576  if (!result.hasExpression())
12577  printRemainingMessages(Colour::None);
12578  else
12579  printRemainingMessages();
12580  break;
12581  case ResultWas::ExpressionFailed:
12582  if (result.isOk())
12583  printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok"));
12584  else
12585  printResultType(Colour::Error, failedString());
12586  printOriginalExpression();
12587  printReconstructedExpression();
12588  printRemainingMessages();
12589  break;
12590  case ResultWas::ThrewException:
12591  printResultType(Colour::Error, failedString());
12592  printIssue("unexpected exception with message:");
12593  printMessage();
12594  printExpressionWas();
12595  printRemainingMessages();
12596  break;
12597  case ResultWas::FatalErrorCondition:
12598  printResultType(Colour::Error, failedString());
12599  printIssue("fatal error condition with message:");
12600  printMessage();
12601  printExpressionWas();
12602  printRemainingMessages();
12603  break;
12604  case ResultWas::DidntThrowException:
12605  printResultType(Colour::Error, failedString());
12606  printIssue("expected exception, got none");
12607  printExpressionWas();
12608  printRemainingMessages();
12609  break;
12610  case ResultWas::Info:
12611  printResultType(Colour::None, "info");
12612  printMessage();
12613  printRemainingMessages();
12614  break;
12615  case ResultWas::Warning:
12616  printResultType(Colour::None, "warning");
12617  printMessage();
12618  printRemainingMessages();
12619  break;
12620  case ResultWas::ExplicitFailure:
12621  printResultType(Colour::Error, failedString());
12622  printIssue("explicitly");
12623  printRemainingMessages(Colour::None);
12624  break;
12625  // These cases are here to prevent compiler warnings
12626  case ResultWas::Unknown:
12627  case ResultWas::FailureBit:
12628  case ResultWas::Exception:
12629  printResultType(Colour::Error, "** internal error **");
12630  break;
12631  }
12632  }
12633 
12634 private:
12635  void printSourceInfo() const {
12636  Colour colourGuard(Colour::FileName);
12637  stream << result.getSourceInfo() << ':';
12638  }
12639 
12640  void printResultType(Colour::Code colour, std::string const& passOrFail) const {
12641  if (!passOrFail.empty()) {
12642  {
12643  Colour colourGuard(colour);
12644  stream << ' ' << passOrFail;
12645  }
12646  stream << ':';
12647  }
12648  }
12649 
12650  void printIssue(std::string const& issue) const {
12651  stream << ' ' << issue;
12652  }
12653 
12654  void printExpressionWas() {
12655  if (result.hasExpression()) {
12656  stream << ';';
12657  {
12658  Colour colour(dimColour());
12659  stream << " expression was:";
12660  }
12661  printOriginalExpression();
12662  }
12663  }
12664 
12665  void printOriginalExpression() const {
12666  if (result.hasExpression()) {
12667  stream << ' ' << result.getExpression();
12668  }
12669  }
12670 
12671  void printReconstructedExpression() const {
12672  if (result.hasExpandedExpression()) {
12673  {
12674  Colour colour(dimColour());
12675  stream << " for: ";
12676  }
12677  stream << result.getExpandedExpression();
12678  }
12679  }
12680 
12681  void printMessage() {
12682  if (itMessage != messages.end()) {
12683  stream << " '" << itMessage->message << '\'';
12684  ++itMessage;
12685  }
12686  }
12687 
12688  void printRemainingMessages(Colour::Code colour = dimColour()) {
12689  if (itMessage == messages.end())
12690  return;
12691 
12692  // using messages.end() directly yields (or auto) compilation error:
12693  std::vector<MessageInfo>::const_iterator itEnd = messages.end();
12694  const std::size_t N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
12695 
12696  {
12697  Colour colourGuard(colour);
12698  stream << " with " << pluralise(N, "message") << ':';
12699  }
12700 
12701  for (; itMessage != itEnd; ) {
12702  // If this assertion is a warning ignore any INFO messages
12703  if (printInfoMessages || itMessage->type != ResultWas::Info) {
12704  stream << " '" << itMessage->message << '\'';
12705  if (++itMessage != itEnd) {
12706  Colour colourGuard(dimColour());
12707  stream << " and";
12708  }
12709  }
12710  }
12711  }
12712 
12713 private:
12714  std::ostream& stream;
12715  AssertionResult const& result;
12716  std::vector<MessageInfo> messages;
12717  std::vector<MessageInfo>::const_iterator itMessage;
12718  bool printInfoMessages;
12719 };
12720 
12721 } // anon namespace
12722 
12723  std::string CompactReporter::getDescription() {
12724  return "Reports test results on a single line, suitable for IDEs";
12725  }
12726 
12727  ReporterPreferences CompactReporter::getPreferences() const {
12728  return m_reporterPrefs;
12729  }
12730 
12731  void CompactReporter::noMatchingTestCases( std::string const& spec ) {
12732  stream << "No test cases matched '" << spec << '\'' << std::endl;
12733  }
12734 
12735  void CompactReporter::assertionStarting( AssertionInfo const& ) {}
12736 
12737  bool CompactReporter::assertionEnded( AssertionStats const& _assertionStats ) {
12738  AssertionResult const& result = _assertionStats.assertionResult;
12739 
12740  bool printInfoMessages = true;
12741 
12742  // Drop out if result was successful and we're not printing those
12743  if( !m_config->includeSuccessfulResults() && result.isOk() ) {
12744  if( result.getResultType() != ResultWas::Warning )
12745  return false;
12746  printInfoMessages = false;
12747  }
12748 
12749  AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
12750  printer.print();
12751 
12752  stream << std::endl;
12753  return true;
12754  }
12755 
12756  void CompactReporter::sectionEnded(SectionStats const& _sectionStats) {
12757  if (m_config->showDurations() == ShowDurations::Always) {
12758  stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
12759  }
12760  }
12761 
12762  void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) {
12763  printTotals( stream, _testRunStats.totals );
12764  stream << '\n' << std::endl;
12765  StreamingReporterBase::testRunEnded( _testRunStats );
12766  }
12767 
12768  CompactReporter::~CompactReporter() {}
12769 
12770  CATCH_REGISTER_REPORTER( "compact", CompactReporter )
12771 
12772 } // end namespace Catch
12773 // end catch_reporter_compact.cpp
12774 // start catch_reporter_console.cpp
12775 
12776 #include <cfloat>
12777 #include <cstdio>
12778 
12779 #if defined(_MSC_VER)
12780 #pragma warning(push)
12781 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
12782  // Note that 4062 (not all labels are handled
12783  // and default is missing) is enabled
12784 #endif
12785 
12786 namespace Catch {
12787 
12788 namespace {
12789 
12790 // Formatter impl for ConsoleReporter
12791 class ConsoleAssertionPrinter {
12792 public:
12793  ConsoleAssertionPrinter& operator= (ConsoleAssertionPrinter const&) = delete;
12794  ConsoleAssertionPrinter(ConsoleAssertionPrinter const&) = delete;
12795  ConsoleAssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
12796  : stream(_stream),
12797  stats(_stats),
12798  result(_stats.assertionResult),
12799  colour(Colour::None),
12800  message(result.getMessage()),
12801  messages(_stats.infoMessages),
12802  printInfoMessages(_printInfoMessages) {
12803  switch (result.getResultType()) {
12804  case ResultWas::Ok:
12805  colour = Colour::Success;
12806  passOrFail = "PASSED";
12807  //if( result.hasMessage() )
12808  if (_stats.infoMessages.size() == 1)
12809  messageLabel = "with message";
12810  if (_stats.infoMessages.size() > 1)
12811  messageLabel = "with messages";
12812  break;
12813  case ResultWas::ExpressionFailed:
12814  if (result.isOk()) {
12815  colour = Colour::Success;
12816  passOrFail = "FAILED - but was ok";
12817  } else {
12818  colour = Colour::Error;
12819  passOrFail = "FAILED";
12820  }
12821  if (_stats.infoMessages.size() == 1)
12822  messageLabel = "with message";
12823  if (_stats.infoMessages.size() > 1)
12824  messageLabel = "with messages";
12825  break;
12826  case ResultWas::ThrewException:
12827  colour = Colour::Error;
12828  passOrFail = "FAILED";
12829  messageLabel = "due to unexpected exception with ";
12830  if (_stats.infoMessages.size() == 1)
12831  messageLabel += "message";
12832  if (_stats.infoMessages.size() > 1)
12833  messageLabel += "messages";
12834  break;
12835  case ResultWas::FatalErrorCondition:
12836  colour = Colour::Error;
12837  passOrFail = "FAILED";
12838  messageLabel = "due to a fatal error condition";
12839  break;
12840  case ResultWas::DidntThrowException:
12841  colour = Colour::Error;
12842  passOrFail = "FAILED";
12843  messageLabel = "because no exception was thrown where one was expected";
12844  break;
12845  case ResultWas::Info:
12846  messageLabel = "info";
12847  break;
12848  case ResultWas::Warning:
12849  messageLabel = "warning";
12850  break;
12851  case ResultWas::ExplicitFailure:
12852  passOrFail = "FAILED";
12853  colour = Colour::Error;
12854  if (_stats.infoMessages.size() == 1)
12855  messageLabel = "explicitly with message";
12856  if (_stats.infoMessages.size() > 1)
12857  messageLabel = "explicitly with messages";
12858  break;
12859  // These cases are here to prevent compiler warnings
12860  case ResultWas::Unknown:
12861  case ResultWas::FailureBit:
12862  case ResultWas::Exception:
12863  passOrFail = "** internal error **";
12864  colour = Colour::Error;
12865  break;
12866  }
12867  }
12868 
12869  void print() const {
12870  printSourceInfo();
12871  if (stats.totals.assertions.total() > 0) {
12872  printResultType();
12873  printOriginalExpression();
12874  printReconstructedExpression();
12875  } else {
12876  stream << '\n';
12877  }
12878  printMessage();
12879  }
12880 
12881 private:
12882  void printResultType() const {
12883  if (!passOrFail.empty()) {
12884  Colour colourGuard(colour);
12885  stream << passOrFail << ":\n";
12886  }
12887  }
12888  void printOriginalExpression() const {
12889  if (result.hasExpression()) {
12890  Colour colourGuard(Colour::OriginalExpression);
12891  stream << " ";
12892  stream << result.getExpressionInMacro();
12893  stream << '\n';
12894  }
12895  }
12896  void printReconstructedExpression() const {
12897  if (result.hasExpandedExpression()) {
12898  stream << "with expansion:\n";
12899  Colour colourGuard(Colour::ReconstructedExpression);
12900  stream << Column(result.getExpandedExpression()).indent(2) << '\n';
12901  }
12902  }
12903  void printMessage() const {
12904  if (!messageLabel.empty())
12905  stream << messageLabel << ':' << '\n';
12906  for (auto const& msg : messages) {
12907  // If this assertion is a warning ignore any INFO messages
12908  if (printInfoMessages || msg.type != ResultWas::Info)
12909  stream << Column(msg.message).indent(2) << '\n';
12910  }
12911  }
12912  void printSourceInfo() const {
12913  Colour colourGuard(Colour::FileName);
12914  stream << result.getSourceInfo() << ": ";
12915  }
12916 
12917  std::ostream& stream;
12918  AssertionStats const& stats;
12919  AssertionResult const& result;
12920  Colour::Code colour;
12921  std::string passOrFail;
12922  std::string messageLabel;
12923  std::string message;
12924  std::vector<MessageInfo> messages;
12925  bool printInfoMessages;
12926 };
12927 
12928 std::size_t makeRatio(std::size_t number, std::size_t total) {
12929  std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0;
12930  return (ratio == 0 && number > 0) ? 1 : ratio;
12931 }
12932 
12933 std::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k) {
12934  if (i > j && i > k)
12935  return i;
12936  else if (j > k)
12937  return j;
12938  else
12939  return k;
12940 }
12941 
12942 struct ColumnInfo {
12943  enum Justification { Left, Right };
12944  std::string name;
12945  int width;
12946  Justification justification;
12947 };
12948 struct ColumnBreak {};
12949 struct RowBreak {};
12950 
12951 class Duration {
12952  enum class Unit {
12953  Auto,
12954  Nanoseconds,
12955  Microseconds,
12956  Milliseconds,
12957  Seconds,
12958  Minutes
12959  };
12960  static const uint64_t s_nanosecondsInAMicrosecond = 1000;
12961  static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond;
12962  static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;
12963  static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;
12964 
12965  uint64_t m_inNanoseconds;
12966  Unit m_units;
12967 
12968 public:
12969  explicit Duration(uint64_t inNanoseconds, Unit units = Unit::Auto)
12970  : m_inNanoseconds(inNanoseconds),
12971  m_units(units) {
12972  if (m_units == Unit::Auto) {
12973  if (m_inNanoseconds < s_nanosecondsInAMicrosecond)
12974  m_units = Unit::Nanoseconds;
12975  else if (m_inNanoseconds < s_nanosecondsInAMillisecond)
12976  m_units = Unit::Microseconds;
12977  else if (m_inNanoseconds < s_nanosecondsInASecond)
12978  m_units = Unit::Milliseconds;
12979  else if (m_inNanoseconds < s_nanosecondsInAMinute)
12980  m_units = Unit::Seconds;
12981  else
12982  m_units = Unit::Minutes;
12983  }
12984 
12985  }
12986 
12987  auto value() const -> double {
12988  switch (m_units) {
12989  case Unit::Microseconds:
12990  return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond);
12991  case Unit::Milliseconds:
12992  return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond);
12993  case Unit::Seconds:
12994  return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond);
12995  case Unit::Minutes:
12996  return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute);
12997  default:
12998  return static_cast<double>(m_inNanoseconds);
12999  }
13000  }
13001  auto unitsAsString() const -> std::string {
13002  switch (m_units) {
13003  case Unit::Nanoseconds:
13004  return "ns";
13005  case Unit::Microseconds:
13006  return "µs";
13007  case Unit::Milliseconds:
13008  return "ms";
13009  case Unit::Seconds:
13010  return "s";
13011  case Unit::Minutes:
13012  return "m";
13013  default:
13014  return "** internal error **";
13015  }
13016 
13017  }
13018  friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& {
13019  return os << duration.value() << " " << duration.unitsAsString();
13020  }
13021 };
13022 } // end anon namespace
13023 
13024 class TablePrinter {
13025  std::ostream& m_os;
13026  std::vector<ColumnInfo> m_columnInfos;
13027  std::ostringstream m_oss;
13028  int m_currentColumn = -1;
13029  bool m_isOpen = false;
13030 
13031 public:
13032  TablePrinter( std::ostream& os, std::vector<ColumnInfo> columnInfos )
13033  : m_os( os ),
13034  m_columnInfos( std::move( columnInfos ) ) {}
13035 
13036  auto columnInfos() const -> std::vector<ColumnInfo> const& {
13037  return m_columnInfos;
13038  }
13039 
13040  void open() {
13041  if (!m_isOpen) {
13042  m_isOpen = true;
13043  *this << RowBreak();
13044  for (auto const& info : m_columnInfos)
13045  *this << info.name << ColumnBreak();
13046  *this << RowBreak();
13047  m_os << Catch::getLineOfChars<'-'>() << "\n";
13048  }
13049  }
13050  void close() {
13051  if (m_isOpen) {
13052  *this << RowBreak();
13053  m_os << std::endl;
13054  m_isOpen = false;
13055  }
13056  }
13057 
13058  template<typename T>
13059  friend TablePrinter& operator << (TablePrinter& tp, T const& value) {
13060  tp.m_oss << value;
13061  return tp;
13062  }
13063 
13064  friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) {
13065  auto colStr = tp.m_oss.str();
13066  // This takes account of utf8 encodings
13067  auto strSize = Catch::StringRef(colStr).numberOfCharacters();
13068  tp.m_oss.str("");
13069  tp.open();
13070  if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) {
13071  tp.m_currentColumn = -1;
13072  tp.m_os << "\n";
13073  }
13074  tp.m_currentColumn++;
13075 
13076  auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
13077  auto padding = (strSize + 2 < static_cast<std::size_t>(colInfo.width))
13078  ? std::string(colInfo.width - (strSize + 2), ' ')
13079  : std::string();
13080  if (colInfo.justification == ColumnInfo::Left)
13081  tp.m_os << colStr << padding << " ";
13082  else
13083  tp.m_os << padding << colStr << " ";
13084  return tp;
13085  }
13086 
13087  friend TablePrinter& operator << (TablePrinter& tp, RowBreak) {
13088  if (tp.m_currentColumn > 0) {
13089  tp.m_os << "\n";
13090  tp.m_currentColumn = -1;
13091  }
13092  return tp;
13093  }
13094 };
13095 
13096 ConsoleReporter::ConsoleReporter(ReporterConfig const& config)
13097  : StreamingReporterBase(config),
13098  m_tablePrinter(new TablePrinter(config.stream(),
13099  {
13100  { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 32, ColumnInfo::Left },
13101  { "iters", 8, ColumnInfo::Right },
13102  { "elapsed ns", 14, ColumnInfo::Right },
13103  { "average", 14, ColumnInfo::Right }
13104  })) {}
13105 ConsoleReporter::~ConsoleReporter() = default;
13106 
13107 std::string ConsoleReporter::getDescription() {
13108  return "Reports test results as plain lines of text";
13109 }
13110 
13111 void ConsoleReporter::noMatchingTestCases(std::string const& spec) {
13112  stream << "No test cases matched '" << spec << '\'' << std::endl;
13113 }
13114 
13115 void ConsoleReporter::assertionStarting(AssertionInfo const&) {}
13116 
13117 bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {
13118  AssertionResult const& result = _assertionStats.assertionResult;
13119 
13120  bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
13121 
13122  // Drop out if result was successful but we're not printing them.
13123  if (!includeResults && result.getResultType() != ResultWas::Warning)
13124  return false;
13125 
13126  lazyPrint();
13127 
13128  ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults);
13129  printer.print();
13130  stream << std::endl;
13131  return true;
13132 }
13133 
13134 void ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) {
13135  m_headerPrinted = false;
13136  StreamingReporterBase::sectionStarting(_sectionInfo);
13137 }
13138 void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) {
13139  m_tablePrinter->close();
13140  if (_sectionStats.missingAssertions) {
13141  lazyPrint();
13142  Colour colour(Colour::ResultError);
13143  if (m_sectionStack.size() > 1)
13144  stream << "\nNo assertions in section";
13145  else
13146  stream << "\nNo assertions in test case";
13147  stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
13148  }
13149  if (m_config->showDurations() == ShowDurations::Always) {
13150  stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
13151  }
13152  if (m_headerPrinted) {
13153  m_headerPrinted = false;
13154  }
13155  StreamingReporterBase::sectionEnded(_sectionStats);
13156 }
13157 
13158 void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {
13159  lazyPrintWithoutClosingBenchmarkTable();
13160 
13161  auto nameCol = Column( info.name ).width( static_cast<std::size_t>( m_tablePrinter->columnInfos()[0].width - 2 ) );
13162 
13163  bool firstLine = true;
13164  for (auto line : nameCol) {
13165  if (!firstLine)
13166  (*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();
13167  else
13168  firstLine = false;
13169 
13170  (*m_tablePrinter) << line << ColumnBreak();
13171  }
13172 }
13173 void ConsoleReporter::benchmarkEnded(BenchmarkStats const& stats) {
13174  Duration average(stats.elapsedTimeInNanoseconds / stats.iterations);
13175  (*m_tablePrinter)
13176  << stats.iterations << ColumnBreak()
13177  << stats.elapsedTimeInNanoseconds << ColumnBreak()
13178  << average << ColumnBreak();
13179 }
13180 
13181 void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {
13182  m_tablePrinter->close();
13183  StreamingReporterBase::testCaseEnded(_testCaseStats);
13184  m_headerPrinted = false;
13185 }
13186 void ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats) {
13187  if (currentGroupInfo.used) {
13188  printSummaryDivider();
13189  stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
13190  printTotals(_testGroupStats.totals);
13191  stream << '\n' << std::endl;
13192  }
13193  StreamingReporterBase::testGroupEnded(_testGroupStats);
13194 }
13195 void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
13196  printTotalsDivider(_testRunStats.totals);
13197  printTotals(_testRunStats.totals);
13198  stream << std::endl;
13199  StreamingReporterBase::testRunEnded(_testRunStats);
13200 }
13201 
13202 void ConsoleReporter::lazyPrint() {
13203 
13204  m_tablePrinter->close();
13205  lazyPrintWithoutClosingBenchmarkTable();
13206 }
13207 
13208 void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() {
13209 
13210  if (!currentTestRunInfo.used)
13211  lazyPrintRunInfo();
13212  if (!currentGroupInfo.used)
13213  lazyPrintGroupInfo();
13214 
13215  if (!m_headerPrinted) {
13216  printTestCaseAndSectionHeader();
13217  m_headerPrinted = true;
13218  }
13219 }
13220 void ConsoleReporter::lazyPrintRunInfo() {
13221  stream << '\n' << getLineOfChars<'~'>() << '\n';
13222  Colour colour(Colour::SecondaryText);
13223  stream << currentTestRunInfo->name
13224  << " is a Catch v" << libraryVersion() << " host application.\n"
13225  << "Run with -? for options\n\n";
13226 
13227  if (m_config->rngSeed() != 0)
13228  stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
13229 
13230  currentTestRunInfo.used = true;
13231 }
13232 void ConsoleReporter::lazyPrintGroupInfo() {
13233  if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) {
13234  printClosedHeader("Group: " + currentGroupInfo->name);
13235  currentGroupInfo.used = true;
13236  }
13237 }
13238 void ConsoleReporter::printTestCaseAndSectionHeader() {
13239  assert(!m_sectionStack.empty());
13240  printOpenHeader(currentTestCaseInfo->name);
13241 
13242  if (m_sectionStack.size() > 1) {
13243  Colour colourGuard(Colour::Headers);
13244 
13245  auto
13246  it = m_sectionStack.begin() + 1, // Skip first section (test case)
13247  itEnd = m_sectionStack.end();
13248  for (; it != itEnd; ++it)
13249  printHeaderString(it->name, 2);
13250  }
13251 
13252  SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
13253 
13254  if (!lineInfo.empty()) {
13255  stream << getLineOfChars<'-'>() << '\n';
13256  Colour colourGuard(Colour::FileName);
13257  stream << lineInfo << '\n';
13258  }
13259  stream << getLineOfChars<'.'>() << '\n' << std::endl;
13260 }
13261 
13262 void ConsoleReporter::printClosedHeader(std::string const& _name) {
13263  printOpenHeader(_name);
13264  stream << getLineOfChars<'.'>() << '\n';
13265 }
13266 void ConsoleReporter::printOpenHeader(std::string const& _name) {
13267  stream << getLineOfChars<'-'>() << '\n';
13268  {
13269  Colour colourGuard(Colour::Headers);
13270  printHeaderString(_name);
13271  }
13272 }
13273 
13274 // if string has a : in first line will set indent to follow it on
13275 // subsequent lines
13276 void ConsoleReporter::printHeaderString(std::string const& _string, std::size_t indent) {
13277  std::size_t i = _string.find(": ");
13278  if (i != std::string::npos)
13279  i += 2;
13280  else
13281  i = 0;
13282  stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n';
13283 }
13284 
13285 struct SummaryColumn {
13286 
13287  SummaryColumn( std::string _label, Colour::Code _colour )
13288  : label( std::move( _label ) ),
13289  colour( _colour ) {}
13290  SummaryColumn addRow( std::size_t count ) {
13291  ReusableStringStream rss;
13292  rss << count;
13293  std::string row = rss.str();
13294  for (auto& oldRow : rows) {
13295  while (oldRow.size() < row.size())
13296  oldRow = ' ' + oldRow;
13297  while (oldRow.size() > row.size())
13298  row = ' ' + row;
13299  }
13300  rows.push_back(row);
13301  return *this;
13302  }
13303 
13304  std::string label;
13305  Colour::Code colour;
13306  std::vector<std::string> rows;
13307 
13308 };
13309 
13310 void ConsoleReporter::printTotals( Totals const& totals ) {
13311  if (totals.testCases.total() == 0) {
13312  stream << Colour(Colour::Warning) << "No tests ran\n";
13313  } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) {
13314  stream << Colour(Colour::ResultSuccess) << "All tests passed";
13315  stream << " ("
13316  << pluralise(totals.assertions.passed, "assertion") << " in "
13317  << pluralise(totals.testCases.passed, "test case") << ')'
13318  << '\n';
13319  } else {
13320 
13321  std::vector<SummaryColumn> columns;
13322  columns.push_back(SummaryColumn("", Colour::None)
13323  .addRow(totals.testCases.total())
13324  .addRow(totals.assertions.total()));
13325  columns.push_back(SummaryColumn("passed", Colour::Success)
13326  .addRow(totals.testCases.passed)
13327  .addRow(totals.assertions.passed));
13328  columns.push_back(SummaryColumn("failed", Colour::ResultError)
13329  .addRow(totals.testCases.failed)
13330  .addRow(totals.assertions.failed));
13331  columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure)
13332  .addRow(totals.testCases.failedButOk)
13333  .addRow(totals.assertions.failedButOk));
13334 
13335  printSummaryRow("test cases", columns, 0);
13336  printSummaryRow("assertions", columns, 1);
13337  }
13338 }
13339 void ConsoleReporter::printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row) {
13340  for (auto col : cols) {
13341  std::string value = col.rows[row];
13342  if (col.label.empty()) {
13343  stream << label << ": ";
13344  if (value != "0")
13345  stream << value;
13346  else
13347  stream << Colour(Colour::Warning) << "- none -";
13348  } else if (value != "0") {
13349  stream << Colour(Colour::LightGrey) << " | ";
13350  stream << Colour(col.colour)
13351  << value << ' ' << col.label;
13352  }
13353  }
13354  stream << '\n';
13355 }
13356 
13357 void ConsoleReporter::printTotalsDivider(Totals const& totals) {
13358  if (totals.testCases.total() > 0) {
13359  std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());
13360  std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());
13361  std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());
13362  while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
13363  findMax(failedRatio, failedButOkRatio, passedRatio)++;
13364  while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)
13365  findMax(failedRatio, failedButOkRatio, passedRatio)--;
13366 
13367  stream << Colour(Colour::Error) << std::string(failedRatio, '=');
13368  stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '=');
13369  if (totals.testCases.allPassed())
13370  stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '=');
13371  else
13372  stream << Colour(Colour::Success) << std::string(passedRatio, '=');
13373  } else {
13374  stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '=');
13375  }
13376  stream << '\n';
13377 }
13378 void ConsoleReporter::printSummaryDivider() {
13379  stream << getLineOfChars<'-'>() << '\n';
13380 }
13381 
13382 CATCH_REGISTER_REPORTER("console", ConsoleReporter)
13383 
13384 } // end namespace Catch
13385 
13386 #if defined(_MSC_VER)
13387 #pragma warning(pop)
13388 #endif
13389 // end catch_reporter_console.cpp
13390 // start catch_reporter_junit.cpp
13391 
13392 #include <cassert>
13393 #include <sstream>
13394 #include <ctime>
13395 #include <algorithm>
13396 
13397 namespace Catch {
13398 
13399  namespace {
13400  std::string getCurrentTimestamp() {
13401  // Beware, this is not reentrant because of backward compatibility issues
13402  // Also, UTC only, again because of backward compatibility (%z is C++11)
13403  time_t rawtime;
13404  std::time(&rawtime);
13405  auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
13406 
13407 #ifdef _MSC_VER
13408  std::tm timeInfo = {};
13409  gmtime_s(&timeInfo, &rawtime);
13410 #else
13411  std::tm* timeInfo;
13412  timeInfo = std::gmtime(&rawtime);
13413 #endif
13414 
13415  char timeStamp[timeStampSize];
13416  const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
13417 
13418 #ifdef _MSC_VER
13419  std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
13420 #else
13421  std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
13422 #endif
13423  return std::string(timeStamp);
13424  }
13425 
13426  std::string fileNameTag(const std::vector<std::string> &tags) {
13427  auto it = std::find_if(begin(tags),
13428  end(tags),
13429  [] (std::string const& tag) {return tag.front() == '#'; });
13430  if (it != tags.end())
13431  return it->substr(1);
13432  return std::string();
13433  }
13434  } // anonymous namespace
13435 
13436  JunitReporter::JunitReporter( ReporterConfig const& _config )
13437  : CumulativeReporterBase( _config ),
13438  xml( _config.stream() )
13439  {
13440  m_reporterPrefs.shouldRedirectStdOut = true;
13441  m_reporterPrefs.shouldReportAllAssertions = true;
13442  }
13443 
13444  JunitReporter::~JunitReporter() {}
13445 
13446  std::string JunitReporter::getDescription() {
13447  return "Reports test results in an XML format that looks like Ant's junitreport target";
13448  }
13449 
13450  void JunitReporter::noMatchingTestCases( std::string const& /*spec*/ ) {}
13451 
13452  void JunitReporter::testRunStarting( TestRunInfo const& runInfo ) {
13453  CumulativeReporterBase::testRunStarting( runInfo );
13454  xml.startElement( "testsuites" );
13455  }
13456 
13457  void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) {
13458  suiteTimer.start();
13459  stdOutForSuite.clear();
13460  stdErrForSuite.clear();
13461  unexpectedExceptions = 0;
13462  CumulativeReporterBase::testGroupStarting( groupInfo );
13463  }
13464 
13465  void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) {
13466  m_okToFail = testCaseInfo.okToFail();
13467  }
13468 
13469  bool JunitReporter::assertionEnded( AssertionStats const& assertionStats ) {
13470  if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
13471  unexpectedExceptions++;
13472  return CumulativeReporterBase::assertionEnded( assertionStats );
13473  }
13474 
13475  void JunitReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
13476  stdOutForSuite += testCaseStats.stdOut;
13477  stdErrForSuite += testCaseStats.stdErr;
13478  CumulativeReporterBase::testCaseEnded( testCaseStats );
13479  }
13480 
13481  void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
13482  double suiteTime = suiteTimer.getElapsedSeconds();
13483  CumulativeReporterBase::testGroupEnded( testGroupStats );
13484  writeGroup( *m_testGroups.back(), suiteTime );
13485  }
13486 
13487  void JunitReporter::testRunEndedCumulative() {
13488  xml.endElement();
13489  }
13490 
13491  void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
13492  XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
13493  TestGroupStats const& stats = groupNode.value;
13494  xml.writeAttribute( "name", stats.groupInfo.name );
13495  xml.writeAttribute( "errors", unexpectedExceptions );
13496  xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
13497  xml.writeAttribute( "tests", stats.totals.assertions.total() );
13498  xml.writeAttribute( "hostname", "tbd" ); // !TBD
13499  if( m_config->showDurations() == ShowDurations::Never )
13500  xml.writeAttribute( "time", "" );
13501  else
13502  xml.writeAttribute( "time", suiteTime );
13503  xml.writeAttribute( "timestamp", getCurrentTimestamp() );
13504 
13505  // Write test cases
13506  for( auto const& child : groupNode.children )
13507  writeTestCase( *child );
13508 
13509  xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), false );
13510  xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), false );
13511  }
13512 
13513  void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) {
13514  TestCaseStats const& stats = testCaseNode.value;
13515 
13516  // All test cases have exactly one section - which represents the
13517  // test case itself. That section may have 0-n nested sections
13518  assert( testCaseNode.children.size() == 1 );
13519  SectionNode const& rootSection = *testCaseNode.children.front();
13520 
13521  std::string className = stats.testInfo.className;
13522 
13523  if( className.empty() ) {
13524  className = fileNameTag(stats.testInfo.tags);
13525  if ( className.empty() )
13526  className = "global";
13527  }
13528 
13529  if ( !m_config->name().empty() )
13530  className = m_config->name() + "." + className;
13531 
13532  writeSection( className, "", rootSection );
13533  }
13534 
13535  void JunitReporter::writeSection( std::string const& className,
13536  std::string const& rootName,
13537  SectionNode const& sectionNode ) {
13538  std::string name = trim( sectionNode.stats.sectionInfo.name );
13539  if( !rootName.empty() )
13540  name = rootName + '/' + name;
13541 
13542  if( !sectionNode.assertions.empty() ||
13543  !sectionNode.stdOut.empty() ||
13544  !sectionNode.stdErr.empty() ) {
13545  XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
13546  if( className.empty() ) {
13547  xml.writeAttribute( "classname", name );
13548  xml.writeAttribute( "name", "root" );
13549  }
13550  else {
13551  xml.writeAttribute( "classname", className );
13552  xml.writeAttribute( "name", name );
13553  }
13554  xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) );
13555 
13556  writeAssertions( sectionNode );
13557 
13558  if( !sectionNode.stdOut.empty() )
13559  xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
13560  if( !sectionNode.stdErr.empty() )
13561  xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
13562  }
13563  for( auto const& childNode : sectionNode.childSections )
13564  if( className.empty() )
13565  writeSection( name, "", *childNode );
13566  else
13567  writeSection( className, name, *childNode );
13568  }
13569 
13570  void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {
13571  for( auto const& assertion : sectionNode.assertions )
13572  writeAssertion( assertion );
13573  }
13574 
13575  void JunitReporter::writeAssertion( AssertionStats const& stats ) {
13576  AssertionResult const& result = stats.assertionResult;
13577  if( !result.isOk() ) {
13578  std::string elementName;
13579  switch( result.getResultType() ) {
13580  case ResultWas::ThrewException:
13581  case ResultWas::FatalErrorCondition:
13582  elementName = "error";
13583  break;
13584  case ResultWas::ExplicitFailure:
13585  elementName = "failure";
13586  break;
13587  case ResultWas::ExpressionFailed:
13588  elementName = "failure";
13589  break;
13590  case ResultWas::DidntThrowException:
13591  elementName = "failure";
13592  break;
13593 
13594  // We should never see these here:
13595  case ResultWas::Info:
13596  case ResultWas::Warning:
13597  case ResultWas::Ok:
13598  case ResultWas::Unknown:
13599  case ResultWas::FailureBit:
13600  case ResultWas::Exception:
13601  elementName = "internalError";
13602  break;
13603  }
13604 
13605  XmlWriter::ScopedElement e = xml.scopedElement( elementName );
13606 
13607  xml.writeAttribute( "message", result.getExpandedExpression() );
13608  xml.writeAttribute( "type", result.getTestMacroName() );
13609 
13610  ReusableStringStream rss;
13611  if( !result.getMessage().empty() )
13612  rss << result.getMessage() << '\n';
13613  for( auto const& msg : stats.infoMessages )
13614  if( msg.type == ResultWas::Info )
13615  rss << msg.message << '\n';
13616 
13617  rss << "at " << result.getSourceInfo();
13618  xml.writeText( rss.str(), false );
13619  }
13620  }
13621 
13622  CATCH_REGISTER_REPORTER( "junit", JunitReporter )
13623 
13624 } // end namespace Catch
13625 // end catch_reporter_junit.cpp
13626 // start catch_reporter_listening.cpp
13627 
13628 #include <cassert>
13629 
13630 namespace Catch {
13631 
13632  ListeningReporter::ListeningReporter() {
13633  // We will assume that listeners will always want all assertions
13634  m_preferences.shouldReportAllAssertions = true;
13635  }
13636 
13637  void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) {
13638  m_listeners.push_back( std::move( listener ) );
13639  }
13640 
13641  void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {
13642  assert(!m_reporter && "Listening reporter can wrap only 1 real reporter");
13643  m_reporter = std::move( reporter );
13644  m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;
13645  }
13646 
13647  ReporterPreferences ListeningReporter::getPreferences() const {
13648  return m_preferences;
13649  }
13650 
13651  std::set<Verbosity> ListeningReporter::getSupportedVerbosities() {
13652  return std::set<Verbosity>{ };
13653  }
13654 
13655  void ListeningReporter::noMatchingTestCases( std::string const& spec ) {
13656  for ( auto const& listener : m_listeners ) {
13657  listener->noMatchingTestCases( spec );
13658  }
13659  m_reporter->noMatchingTestCases( spec );
13660  }
13661 
13662  void ListeningReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {
13663  for ( auto const& listener : m_listeners ) {
13664  listener->benchmarkStarting( benchmarkInfo );
13665  }
13666  m_reporter->benchmarkStarting( benchmarkInfo );
13667  }
13668  void ListeningReporter::benchmarkEnded( BenchmarkStats const& benchmarkStats ) {
13669  for ( auto const& listener : m_listeners ) {
13670  listener->benchmarkEnded( benchmarkStats );
13671  }
13672  m_reporter->benchmarkEnded( benchmarkStats );
13673  }
13674 
13675  void ListeningReporter::testRunStarting( TestRunInfo const& testRunInfo ) {
13676  for ( auto const& listener : m_listeners ) {
13677  listener->testRunStarting( testRunInfo );
13678  }
13679  m_reporter->testRunStarting( testRunInfo );
13680  }
13681 
13682  void ListeningReporter::testGroupStarting( GroupInfo const& groupInfo ) {
13683  for ( auto const& listener : m_listeners ) {
13684  listener->testGroupStarting( groupInfo );
13685  }
13686  m_reporter->testGroupStarting( groupInfo );
13687  }
13688 
13689  void ListeningReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
13690  for ( auto const& listener : m_listeners ) {
13691  listener->testCaseStarting( testInfo );
13692  }
13693  m_reporter->testCaseStarting( testInfo );
13694  }
13695 
13696  void ListeningReporter::sectionStarting( SectionInfo const& sectionInfo ) {
13697  for ( auto const& listener : m_listeners ) {
13698  listener->sectionStarting( sectionInfo );
13699  }
13700  m_reporter->sectionStarting( sectionInfo );
13701  }
13702 
13703  void ListeningReporter::assertionStarting( AssertionInfo const& assertionInfo ) {
13704  for ( auto const& listener : m_listeners ) {
13705  listener->assertionStarting( assertionInfo );
13706  }
13707  m_reporter->assertionStarting( assertionInfo );
13708  }
13709 
13710  // The return value indicates if the messages buffer should be cleared:
13711  bool ListeningReporter::assertionEnded( AssertionStats const& assertionStats ) {
13712  for( auto const& listener : m_listeners ) {
13713  static_cast<void>( listener->assertionEnded( assertionStats ) );
13714  }
13715  return m_reporter->assertionEnded( assertionStats );
13716  }
13717 
13718  void ListeningReporter::sectionEnded( SectionStats const& sectionStats ) {
13719  for ( auto const& listener : m_listeners ) {
13720  listener->sectionEnded( sectionStats );
13721  }
13722  m_reporter->sectionEnded( sectionStats );
13723  }
13724 
13725  void ListeningReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
13726  for ( auto const& listener : m_listeners ) {
13727  listener->testCaseEnded( testCaseStats );
13728  }
13729  m_reporter->testCaseEnded( testCaseStats );
13730  }
13731 
13732  void ListeningReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
13733  for ( auto const& listener : m_listeners ) {
13734  listener->testGroupEnded( testGroupStats );
13735  }
13736  m_reporter->testGroupEnded( testGroupStats );
13737  }
13738 
13739  void ListeningReporter::testRunEnded( TestRunStats const& testRunStats ) {
13740  for ( auto const& listener : m_listeners ) {
13741  listener->testRunEnded( testRunStats );
13742  }
13743  m_reporter->testRunEnded( testRunStats );
13744  }
13745 
13746  void ListeningReporter::skipTest( TestCaseInfo const& testInfo ) {
13747  for ( auto const& listener : m_listeners ) {
13748  listener->skipTest( testInfo );
13749  }
13750  m_reporter->skipTest( testInfo );
13751  }
13752 
13753  bool ListeningReporter::isMulti() const {
13754  return true;
13755  }
13756 
13757 } // end namespace Catch
13758 // end catch_reporter_listening.cpp
13759 // start catch_reporter_xml.cpp
13760 
13761 #if defined(_MSC_VER)
13762 #pragma warning(push)
13763 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
13764  // Note that 4062 (not all labels are handled
13765  // and default is missing) is enabled
13766 #endif
13767 
13768 namespace Catch {
13769  XmlReporter::XmlReporter( ReporterConfig const& _config )
13770  : StreamingReporterBase( _config ),
13771  m_xml(_config.stream())
13772  {
13773  m_reporterPrefs.shouldRedirectStdOut = true;
13774  m_reporterPrefs.shouldReportAllAssertions = true;
13775  }
13776 
13777  XmlReporter::~XmlReporter() = default;
13778 
13779  std::string XmlReporter::getDescription() {
13780  return "Reports test results as an XML document";
13781  }
13782 
13783  std::string XmlReporter::getStylesheetRef() const {
13784  return std::string();
13785  }
13786 
13787  void XmlReporter::writeSourceInfo( SourceLineInfo const& sourceInfo ) {
13788  m_xml
13789  .writeAttribute( "filename", sourceInfo.file )
13790  .writeAttribute( "line", sourceInfo.line );
13791  }
13792 
13793  void XmlReporter::noMatchingTestCases( std::string const& s ) {
13794  StreamingReporterBase::noMatchingTestCases( s );
13795  }
13796 
13797  void XmlReporter::testRunStarting( TestRunInfo const& testInfo ) {
13798  StreamingReporterBase::testRunStarting( testInfo );
13799  std::string stylesheetRef = getStylesheetRef();
13800  if( !stylesheetRef.empty() )
13801  m_xml.writeStylesheetRef( stylesheetRef );
13802  m_xml.startElement( "Catch" );
13803  if( !m_config->name().empty() )
13804  m_xml.writeAttribute( "name", m_config->name() );
13805  if( m_config->rngSeed() != 0 )
13806  m_xml.scopedElement( "Randomness" )
13807  .writeAttribute( "seed", m_config->rngSeed() );
13808  }
13809 
13810  void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) {
13811  StreamingReporterBase::testGroupStarting( groupInfo );
13812  m_xml.startElement( "Group" )
13813  .writeAttribute( "name", groupInfo.name );
13814  }
13815 
13816  void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
13817  StreamingReporterBase::testCaseStarting(testInfo);
13818  m_xml.startElement( "TestCase" )
13819  .writeAttribute( "name", trim( testInfo.name ) )
13820  .writeAttribute( "description", testInfo.description )
13821  .writeAttribute( "tags", testInfo.tagsAsString() );
13822 
13823  writeSourceInfo( testInfo.lineInfo );
13824 
13825  if ( m_config->showDurations() == ShowDurations::Always )
13826  m_testCaseTimer.start();
13827  m_xml.ensureTagClosed();
13828  }
13829 
13830  void XmlReporter::sectionStarting( SectionInfo const& sectionInfo ) {
13831  StreamingReporterBase::sectionStarting( sectionInfo );
13832  if( m_sectionDepth++ > 0 ) {
13833  m_xml.startElement( "Section" )
13834  .writeAttribute( "name", trim( sectionInfo.name ) );
13835  writeSourceInfo( sectionInfo.lineInfo );
13836  m_xml.ensureTagClosed();
13837  }
13838  }
13839 
13840  void XmlReporter::assertionStarting( AssertionInfo const& ) { }
13841 
13842  bool XmlReporter::assertionEnded( AssertionStats const& assertionStats ) {
13843 
13844  AssertionResult const& result = assertionStats.assertionResult;
13845 
13846  bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
13847 
13848  if( includeResults || result.getResultType() == ResultWas::Warning ) {
13849  // Print any info messages in <Info> tags.
13850  for( auto const& msg : assertionStats.infoMessages ) {
13851  if( msg.type == ResultWas::Info && includeResults ) {
13852  m_xml.scopedElement( "Info" )
13853  .writeText( msg.message );
13854  } else if ( msg.type == ResultWas::Warning ) {
13855  m_xml.scopedElement( "Warning" )
13856  .writeText( msg.message );
13857  }
13858  }
13859  }
13860 
13861  // Drop out if result was successful but we're not printing them.
13862  if( !includeResults && result.getResultType() != ResultWas::Warning )
13863  return true;
13864 
13865  // Print the expression if there is one.
13866  if( result.hasExpression() ) {
13867  m_xml.startElement( "Expression" )
13868  .writeAttribute( "success", result.succeeded() )
13869  .writeAttribute( "type", result.getTestMacroName() );
13870 
13871  writeSourceInfo( result.getSourceInfo() );
13872 
13873  m_xml.scopedElement( "Original" )
13874  .writeText( result.getExpression() );
13875  m_xml.scopedElement( "Expanded" )
13876  .writeText( result.getExpandedExpression() );
13877  }
13878 
13879  // And... Print a result applicable to each result type.
13880  switch( result.getResultType() ) {
13881  case ResultWas::ThrewException:
13882  m_xml.startElement( "Exception" );
13883  writeSourceInfo( result.getSourceInfo() );
13884  m_xml.writeText( result.getMessage() );
13885  m_xml.endElement();
13886  break;
13887  case ResultWas::FatalErrorCondition:
13888  m_xml.startElement( "FatalErrorCondition" );
13889  writeSourceInfo( result.getSourceInfo() );
13890  m_xml.writeText( result.getMessage() );
13891  m_xml.endElement();
13892  break;
13893  case ResultWas::Info:
13894  m_xml.scopedElement( "Info" )
13895  .writeText( result.getMessage() );
13896  break;
13897  case ResultWas::Warning:
13898  // Warning will already have been written
13899  break;
13900  case ResultWas::ExplicitFailure:
13901  m_xml.startElement( "Failure" );
13902  writeSourceInfo( result.getSourceInfo() );
13903  m_xml.writeText( result.getMessage() );
13904  m_xml.endElement();
13905  break;
13906  default:
13907  break;
13908  }
13909 
13910  if( result.hasExpression() )
13911  m_xml.endElement();
13912 
13913  return true;
13914  }
13915 
13916  void XmlReporter::sectionEnded( SectionStats const& sectionStats ) {
13917  StreamingReporterBase::sectionEnded( sectionStats );
13918  if( --m_sectionDepth > 0 ) {
13919  XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
13920  e.writeAttribute( "successes", sectionStats.assertions.passed );
13921  e.writeAttribute( "failures", sectionStats.assertions.failed );
13922  e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
13923 
13924  if ( m_config->showDurations() == ShowDurations::Always )
13925  e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
13926 
13927  m_xml.endElement();
13928  }
13929  }
13930 
13931  void XmlReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
13932  StreamingReporterBase::testCaseEnded( testCaseStats );
13933  XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
13934  e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
13935 
13936  if ( m_config->showDurations() == ShowDurations::Always )
13937  e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
13938 
13939  if( !testCaseStats.stdOut.empty() )
13940  m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false );
13941  if( !testCaseStats.stdErr.empty() )
13942  m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false );
13943 
13944  m_xml.endElement();
13945  }
13946 
13947  void XmlReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
13948  StreamingReporterBase::testGroupEnded( testGroupStats );
13949  // TODO: Check testGroupStats.aborting and act accordingly.
13950  m_xml.scopedElement( "OverallResults" )
13951  .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
13952  .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
13953  .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
13954  m_xml.endElement();
13955  }
13956 
13957  void XmlReporter::testRunEnded( TestRunStats const& testRunStats ) {
13958  StreamingReporterBase::testRunEnded( testRunStats );
13959  m_xml.scopedElement( "OverallResults" )
13960  .writeAttribute( "successes", testRunStats.totals.assertions.passed )
13961  .writeAttribute( "failures", testRunStats.totals.assertions.failed )
13962  .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
13963  m_xml.endElement();
13964  }
13965 
13966  CATCH_REGISTER_REPORTER( "xml", XmlReporter )
13967 
13968 } // end namespace Catch
13969 
13970 #if defined(_MSC_VER)
13971 #pragma warning(pop)
13972 #endif
13973 // end catch_reporter_xml.cpp
13974 
13975 namespace Catch {
13976  LeakDetector leakDetector;
13977 }
13978 
13979 #ifdef __clang__
13980 #pragma clang diagnostic pop
13981 #endif
13982 
13983 // end catch_impl.hpp
13984 #endif
13985 
13986 #ifdef CATCH_CONFIG_MAIN
13987 // start catch_default_main.hpp
13988 
13989 #ifndef __OBJC__
13990 
13991 #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
13992 // Standard C/C++ Win32 Unicode wmain entry point
13993 extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
13994 #else
13995 // Standard C/C++ main entry point
13996 int main (int argc, char * argv[]) {
13997 #endif
13998 
13999  return Catch::Session().run( argc, argv );
14000 }
14001 
14002 #else // __OBJC__
14003 
14004 // Objective-C entry point
14005 int main (int argc, char * const argv[]) {
14006 #if !CATCH_ARC_ENABLED
14007  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
14008 #endif
14009 
14010  Catch::registerTestMethods();
14011  int result = Catch::Session().run( argc, (char**)argv );
14012 
14013 #if !CATCH_ARC_ENABLED
14014  [pool drain];
14015 #endif
14016 
14017  return result;
14018 }
14019 
14020 #endif // __OBJC__
14021 
14022 // end catch_default_main.hpp
14023 #endif
14024 
14025 #if !defined(CATCH_CONFIG_IMPL_ONLY)
14026 
14027 #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
14028 # undef CLARA_CONFIG_MAIN
14029 #endif
14030 
14031 #if !defined(CATCH_CONFIG_DISABLE)
14032 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
14034 #ifdef CATCH_CONFIG_PREFIX_ALL
14035 
14036 #define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
14037 #define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
14038 
14039 #define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", __VA_ARGS__ )
14040 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
14041 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
14042 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14043 #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
14044 #endif// CATCH_CONFIG_DISABLE_MATCHERS
14045 #define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
14046 
14047 #define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14048 #define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
14049 #define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14050 #define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14051 #define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
14052 
14053 #define CATCH_CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", __VA_ARGS__ )
14054 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
14055 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
14056 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14057 #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
14058 #endif // CATCH_CONFIG_DISABLE_MATCHERS
14059 #define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14060 
14061 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14062 #define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
14063 
14064 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
14065 #endif // CATCH_CONFIG_DISABLE_MATCHERS
14066 
14067 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
14068 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
14069 #define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE",__VA_ARGS__ )
14070 
14071 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
14072 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
14073 #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
14074 #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
14075 #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
14076 #define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
14077 #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
14078 #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14079 #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14080 
14081 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
14082 
14083 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
14084 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
14085 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
14086 #else
14087 #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
14088 #define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
14089 #endif
14090 
14091 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
14092 #define CATCH_STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__ , #__VA_ARGS__ ); CATCH_SUCCEED( #__VA_ARGS__ )
14093 #define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ )
14094 #else
14095 #define CATCH_STATIC_REQUIRE( ... ) CATCH_REQUIRE( __VA_ARGS__ )
14096 #define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ )
14097 #endif
14098 
14099 // "BDD-style" convenience wrappers
14100 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
14101 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
14102 #define CATCH_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
14103 #define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
14104 #define CATCH_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
14105 #define CATCH_AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
14106 #define CATCH_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
14107 #define CATCH_AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )
14108 
14109 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
14110 #else
14111 
14112 #define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
14113 #define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
14114 
14115 #define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
14116 #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
14117 #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
14118 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14119 #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
14120 #endif // CATCH_CONFIG_DISABLE_MATCHERS
14121 #define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
14122 
14123 #define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14124 #define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
14125 #define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14126 #define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14127 #define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
14128 
14129 #define CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14130 #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
14131 #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
14132 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14133 #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
14134 #endif // CATCH_CONFIG_DISABLE_MATCHERS
14135 #define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14136 
14137 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14138 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
14139 
14140 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
14141 #endif // CATCH_CONFIG_DISABLE_MATCHERS
14142 
14143 #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
14144 #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
14145 #define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ )
14146 
14147 #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
14148 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
14149 #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
14150 #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
14151 #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
14152 #define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
14153 #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
14154 #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14155 #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
14156 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
14157 
14158 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
14159 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
14160 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
14161 #else
14162 #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
14163 #define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
14164 #endif
14165 
14166 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
14167 #define STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__, #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ )
14168 #define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" )
14169 #else
14170 #define STATIC_REQUIRE( ... ) REQUIRE( __VA_ARGS__ )
14171 #define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ )
14172 #endif
14173 
14174 #endif
14175 
14176 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
14177 
14178 // "BDD-style" convenience wrappers
14179 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
14180 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
14181 
14182 #define GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
14183 #define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
14184 #define WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
14185 #define AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
14186 #define THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
14187 #define AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )
14188 
14189 using Catch::Detail::Approx;
14190 
14191 #else // CATCH_CONFIG_DISABLE
14192 
14194 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
14195 #ifdef CATCH_CONFIG_PREFIX_ALL
14196 
14197 #define CATCH_REQUIRE( ... ) (void)(0)
14198 #define CATCH_REQUIRE_FALSE( ... ) (void)(0)
14199 
14200 #define CATCH_REQUIRE_THROWS( ... ) (void)(0)
14201 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
14202 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
14203 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14204 #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
14205 #endif// CATCH_CONFIG_DISABLE_MATCHERS
14206 #define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)
14207 
14208 #define CATCH_CHECK( ... ) (void)(0)
14209 #define CATCH_CHECK_FALSE( ... ) (void)(0)
14210 #define CATCH_CHECKED_IF( ... ) if (__VA_ARGS__)
14211 #define CATCH_CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
14212 #define CATCH_CHECK_NOFAIL( ... ) (void)(0)
14213 
14214 #define CATCH_CHECK_THROWS( ... ) (void)(0)
14215 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
14216 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) (void)(0)
14217 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14218 #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
14219 #endif // CATCH_CONFIG_DISABLE_MATCHERS
14220 #define CATCH_CHECK_NOTHROW( ... ) (void)(0)
14221 
14222 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14223 #define CATCH_CHECK_THAT( arg, matcher ) (void)(0)
14224 
14225 #define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
14226 #endif // CATCH_CONFIG_DISABLE_MATCHERS
14227 
14228 #define CATCH_INFO( msg ) (void)(0)
14229 #define CATCH_WARN( msg ) (void)(0)
14230 #define CATCH_CAPTURE( msg ) (void)(0)
14231 
14232 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
14233 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
14234 #define CATCH_METHOD_AS_TEST_CASE( method, ... )
14235 #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
14236 #define CATCH_SECTION( ... )
14237 #define CATCH_DYNAMIC_SECTION( ... )
14238 #define CATCH_FAIL( ... ) (void)(0)
14239 #define CATCH_FAIL_CHECK( ... ) (void)(0)
14240 #define CATCH_SUCCEED( ... ) (void)(0)
14241 
14242 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
14243 
14244 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
14245 #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____ ) )
14246 #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 )
14247 #else
14248 #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____ ) ) )
14249 #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 ) )
14250 #endif
14251 
14252 // "BDD-style" convenience wrappers
14253 #define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
14254 #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 )
14255 #define CATCH_GIVEN( desc )
14256 #define CATCH_AND_GIVEN( desc )
14257 #define CATCH_WHEN( desc )
14258 #define CATCH_AND_WHEN( desc )
14259 #define CATCH_THEN( desc )
14260 #define CATCH_AND_THEN( desc )
14261 
14262 #define CATCH_STATIC_REQUIRE( ... ) (void)(0)
14263 #define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0)
14264 
14265 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
14266 #else
14267 
14268 #define REQUIRE( ... ) (void)(0)
14269 #define REQUIRE_FALSE( ... ) (void)(0)
14270 
14271 #define REQUIRE_THROWS( ... ) (void)(0)
14272 #define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
14273 #define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
14274 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14275 #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
14276 #endif // CATCH_CONFIG_DISABLE_MATCHERS
14277 #define REQUIRE_NOTHROW( ... ) (void)(0)
14278 
14279 #define CHECK( ... ) (void)(0)
14280 #define CHECK_FALSE( ... ) (void)(0)
14281 #define CHECKED_IF( ... ) if (__VA_ARGS__)
14282 #define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
14283 #define CHECK_NOFAIL( ... ) (void)(0)
14284 
14285 #define CHECK_THROWS( ... ) (void)(0)
14286 #define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
14287 #define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
14288 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14289 #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
14290 #endif // CATCH_CONFIG_DISABLE_MATCHERS
14291 #define CHECK_NOTHROW( ... ) (void)(0)
14292 
14293 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14294 #define CHECK_THAT( arg, matcher ) (void)(0)
14295 
14296 #define REQUIRE_THAT( arg, matcher ) (void)(0)
14297 #endif // CATCH_CONFIG_DISABLE_MATCHERS
14298 
14299 #define INFO( msg ) (void)(0)
14300 #define WARN( msg ) (void)(0)
14301 #define CAPTURE( msg ) (void)(0)
14302 
14303 #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
14304 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
14305 #define METHOD_AS_TEST_CASE( method, ... )
14306 #define REGISTER_TEST_CASE( Function, ... ) (void)(0)
14307 #define SECTION( ... )
14308 #define DYNAMIC_SECTION( ... )
14309 #define FAIL( ... ) (void)(0)
14310 #define FAIL_CHECK( ... ) (void)(0)
14311 #define SUCCEED( ... ) (void)(0)
14312 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
14313 
14314 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
14315 #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____ ) )
14316 #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 )
14317 #else
14318 #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____ ) ) )
14319 #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 ) )
14320 #endif
14321 
14322 #define STATIC_REQUIRE( ... ) (void)(0)
14323 #define STATIC_REQUIRE_FALSE( ... ) (void)(0)
14324 
14325 #endif
14326 
14327 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
14328 
14329 // "BDD-style" convenience wrappers
14330 #define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) )
14331 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
14332 
14333 #define GIVEN( desc )
14334 #define AND_GIVEN( desc )
14335 #define WHEN( desc )
14336 #define AND_WHEN( desc )
14337 #define THEN( desc )
14338 #define AND_THEN( desc )
14339 
14340 using Catch::Detail::Approx;
14341 
14342 #endif
14343 
14344 #endif // ! CATCH_CONFIG_IMPL_ONLY
14345 
14346 // start catch_reenable_warnings.h
14347 
14348 
14349 #ifdef __clang__
14350 # ifdef __ICC // icpc defines the __clang__ macro
14351 # pragma warning(pop)
14352 # else
14353 # pragma clang diagnostic pop
14354 # endif
14355 #elif defined __GNUC__
14356 # pragma GCC diagnostic pop
14357 #endif
14358 
14359 // end catch_reenable_warnings.h
14360 // end catch.hpp
14361 #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
14362 
QTestData & addRow(const char *format,...)
QString escape(const QString &plain)
QTextStream & right(QTextStream &stream)
A non-owning string class (similar to the forthcoming std::string_view) Note that, because a StringRef may be a substring of another string, it may not be null terminated.
Definition: catch.hpp:512
QTextStream & reset(QTextStream &stream)
QTextStream & left(QTextStream &stream)
CaseSensitive
typedef HANDLE
char * toString(const T &value)