catch.hpp
Go to the documentation of this file.
1 /*
2  * Catch v2.4.2
3  * Generated: 2018-10-26 21:12:29.223927
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 4
18 #define CATCH_VERSION_PATCH 2
19 
20 #ifdef __clang__
21 # pragma clang system_header
22 #elif defined __GNUC__
23 # pragma GCC system_header
24 #endif
25 
26 // start catch_suppress_warnings.h
27 
28 #ifdef __clang__
29 # ifdef __ICC // icpc defines the __clang__ macro
30 # pragma warning(push)
31 # pragma warning(disable: 161 1682)
32 # else // __ICC
33 # pragma clang diagnostic push
34 # pragma clang diagnostic ignored "-Wpadded"
35 # pragma clang diagnostic ignored "-Wswitch-enum"
36 # pragma clang diagnostic ignored "-Wcovered-switch-default"
37 # endif
38 #elif defined __GNUC__
39  // 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 #endif // _MSC_VER
230 
232 // Check if we are compiled with -fno-exceptions or equivalent
233 #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
234 # define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
235 #endif
236 
238 // DJGPP
239 #ifdef __DJGPP__
240 # define CATCH_INTERNAL_CONFIG_NO_WCHAR
241 #endif // __DJGPP__
242 
244 
245 // Use of __COUNTER__ is suppressed during code analysis in
246 // CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
247 // handled by it.
248 // Otherwise all supported compilers support COUNTER macro,
249 // but user still might want to turn it off
250 #if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
251  #define CATCH_INTERNAL_CONFIG_COUNTER
252 #endif
253 
255 // Check if string_view is available and usable
256 // The check is split apart to work around v140 (VS2015) preprocessor issue...
257 #if defined(__has_include)
258 #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
259 # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
260 #endif
261 #endif
262 
264 // Check if variant is available and usable
265 #if defined(__has_include)
266 # if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
267 # if defined(__clang__) && (__clang_major__ < 8)
268  // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
269  // fix should be in clang 8, workaround in libstdc++ 8.2
270 # include <ciso646>
271 # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
272 # define CATCH_CONFIG_NO_CPP17_VARIANT
273 # else
274 # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
275 # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
276 # endif // defined(__clang__) && (__clang_major__ < 8)
277 # endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
278 #endif // __has_include
279 
280 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
281 # define CATCH_CONFIG_COUNTER
282 #endif
283 #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)
284 # define CATCH_CONFIG_WINDOWS_SEH
285 #endif
286 // This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
287 #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)
288 # define CATCH_CONFIG_POSIX_SIGNALS
289 #endif
290 // This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.
291 #if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
292 # define CATCH_CONFIG_WCHAR
293 #endif
294 
295 #if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
296 # define CATCH_CONFIG_CPP11_TO_STRING
297 #endif
298 
299 #if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
300 # define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
301 #endif
302 
303 #if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
304 # define CATCH_CONFIG_CPP17_STRING_VIEW
305 #endif
306 
307 #if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
308 # define CATCH_CONFIG_CPP17_VARIANT
309 #endif
310 
311 #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
312 # define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
313 #endif
314 
315 #if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE)
316 # define CATCH_CONFIG_NEW_CAPTURE
317 #endif
318 
319 #if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
320 # define CATCH_CONFIG_DISABLE_EXCEPTIONS
321 #endif
322 
323 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
324 # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
325 # define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
326 #endif
327 #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
328 # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
329 # define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
330 #endif
331 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
332 # define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
333 # define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
334 #endif
335 
336 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
337 #define CATCH_TRY if ((true))
338 #define CATCH_CATCH_ALL if ((false))
339 #define CATCH_CATCH_ANON(type) if ((false))
340 #else
341 #define CATCH_TRY try
342 #define CATCH_CATCH_ALL catch (...)
343 #define CATCH_CATCH_ANON(type) catch (type)
344 #endif
345 
346 // end catch_compiler_capabilities.h
347 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
348 #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
349 #ifdef CATCH_CONFIG_COUNTER
350 # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
351 #else
352 # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
353 #endif
354 
355 #include <iosfwd>
356 #include <string>
357 #include <cstdint>
358 
359 // We need a dummy global operator<< so we can bring it into Catch namespace later
361 std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);
362 
363 namespace Catch {
364 
365  struct CaseSensitive { enum Choice {
367  No
368  }; };
369 
370  class NonCopyable {
371  NonCopyable( NonCopyable const& ) = delete;
372  NonCopyable( NonCopyable && ) = delete;
373  NonCopyable& operator = ( NonCopyable const& ) = delete;
374  NonCopyable& operator = ( NonCopyable && ) = delete;
375 
376  protected:
377  NonCopyable();
378  virtual ~NonCopyable();
379  };
380 
381  struct SourceLineInfo {
382 
383  SourceLineInfo() = delete;
384  SourceLineInfo( char const* _file, std::size_t _line ) noexcept
385  : file( _file ),
386  line( _line )
387  {}
388 
389  SourceLineInfo( SourceLineInfo const& other ) = default;
390  SourceLineInfo( SourceLineInfo && ) = default;
391  SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
392  SourceLineInfo& operator = ( SourceLineInfo && ) = default;
393 
394  bool empty() const noexcept;
395  bool operator == ( SourceLineInfo const& other ) const noexcept;
396  bool operator < ( SourceLineInfo const& other ) const noexcept;
397 
398  char const* file;
399  std::size_t line;
400  };
401 
402  std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
403 
404  // Bring in operator<< from global namespace into Catch namespace
405  // This is necessary because the overload of operator<< above makes
406  // lookup stop at namespace Catch
407  using ::operator<<;
408 
409  // Use this in variadic streaming macros to allow
410  // >> +StreamEndStop
411  // as well as
412  // >> stuff +StreamEndStop
413  struct StreamEndStop {
414  std::string operator+() const;
415  };
416  template<typename T>
417  T const& operator + ( T const& value, StreamEndStop ) {
418  return value;
419  }
420 }
421 
422 #define CATCH_INTERNAL_LINEINFO \
423  ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
424 
425 // end catch_common.h
426 namespace Catch {
427 
429  RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
430  };
431 
432 } // end namespace Catch
433 
434 #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
435  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
436  namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
437  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
438 
439 // end catch_tag_alias_autoregistrar.h
440 // start catch_test_registry.h
441 
442 // start catch_interfaces_testcase.h
443 
444 #include <vector>
445 #include <memory>
446 
447 namespace Catch {
448 
449  class TestSpec;
450 
451  struct ITestInvoker {
452  virtual void invoke () const = 0;
453  virtual ~ITestInvoker();
454  };
455 
456  using ITestCasePtr = std::shared_ptr<ITestInvoker>;
457 
458  class TestCase;
459  struct IConfig;
460 
462  virtual ~ITestCaseRegistry();
463  virtual std::vector<TestCase> const& getAllTests() const = 0;
464  virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
465  };
466 
467  bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
468  std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
469  std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
470 
471 }
472 
473 // end catch_interfaces_testcase.h
474 // start catch_stringref.h
475 
476 #include <cstddef>
477 #include <string>
478 #include <iosfwd>
479 
480 namespace Catch {
481 
482  class StringData;
483 
491  class StringRef {
492  public:
493  using size_type = std::size_t;
494 
495  private:
496  friend struct StringRefTestAccess;
497 
498  char const* m_start;
500 
501  char* m_data = nullptr;
502 
503  void takeOwnership();
504 
505  static constexpr char const* const s_empty = "";
506 
507  public: // construction/ assignment
508  StringRef() noexcept
509  : StringRef( s_empty, 0 )
510  {}
511 
512  StringRef( StringRef const& other ) noexcept
513  : m_start( other.m_start ),
514  m_size( other.m_size )
515  {}
516 
517  StringRef( StringRef&& other ) noexcept
518  : m_start( other.m_start ),
519  m_size( other.m_size ),
520  m_data( other.m_data )
521  {
522  other.m_data = nullptr;
523  }
524 
525  StringRef( char const* rawChars ) noexcept;
526 
527  StringRef( char const* rawChars, size_type size ) noexcept
528  : m_start( rawChars ),
529  m_size( size )
530  {}
531 
532  StringRef( std::string const& stdString ) noexcept
533  : m_start( stdString.c_str() ),
534  m_size( stdString.size() )
535  {}
536 
537  ~StringRef() noexcept {
538  delete[] m_data;
539  }
540 
541  auto operator = ( StringRef const &other ) noexcept -> StringRef& {
542  delete[] m_data;
543  m_data = nullptr;
544  m_start = other.m_start;
545  m_size = other.m_size;
546  return *this;
547  }
548 
549  operator std::string() const;
550 
551  void swap( StringRef& other ) noexcept;
552 
553  public: // operators
554  auto operator == ( StringRef const& other ) const noexcept -> bool;
555  auto operator != ( StringRef const& other ) const noexcept -> bool;
556 
557  auto operator[] ( size_type index ) const noexcept -> char;
558 
559  public: // named queries
560  auto empty() const noexcept -> bool {
561  return m_size == 0;
562  }
563  auto size() const noexcept -> size_type {
564  return m_size;
565  }
566 
567  auto numberOfCharacters() const noexcept -> size_type;
568  auto c_str() const -> char const*;
569 
570  public: // substrings and searches
571  auto substr( size_type start, size_type size ) const noexcept -> StringRef;
572 
573  // Returns the current start pointer.
574  // Note that the pointer can change when if the StringRef is a substring
575  auto currentData() const noexcept -> char const*;
576 
577  private: // ownership queries - may not be consistent between calls
578  auto isOwned() const noexcept -> bool;
579  auto isSubstring() const noexcept -> bool;
580  };
581 
582  auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string;
583  auto operator + ( StringRef const& lhs, char const* rhs ) -> std::string;
584  auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string;
585 
586  auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
587  auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
588 
589  inline auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
590  return StringRef( rawChars, size );
591  }
592 
593 } // namespace Catch
594 
595 inline auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
596  return Catch::StringRef( rawChars, size );
597 }
598 
599 // end catch_stringref.h
600 namespace Catch {
601 
602 template<typename C>
604  void (C::*m_testAsMethod)();
605 public:
606  TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}
607 
608  void invoke() const override {
609  C obj;
610  (obj.*m_testAsMethod)();
611  }
612 };
613 
614 auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;
615 
616 template<typename C>
617 auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {
618  return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod );
619 }
620 
621 struct NameAndTags {
622  NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;
625 };
626 
628  AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;
629  ~AutoReg();
630 };
631 
632 } // end namespace Catch
633 
634 #define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
635 #define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__
636 #define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
637 #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
638 
639 #if defined(CATCH_CONFIG_DISABLE)
640  #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
641  static void TestName()
642  #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
643  namespace{ \
644  struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \
645  void test(); \
646  }; \
647  } \
648  void TestName::test()
649 
650 #endif
651 
653  #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
654  static void TestName(); \
655  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
656  namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
657  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
658  static void TestName()
659  #define INTERNAL_CATCH_TESTCASE( ... ) \
660  INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
661 
663  #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
664  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
665  namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
666  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
667 
669  #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
670  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
671  namespace{ \
672  struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \
673  void test(); \
674  }; \
675  Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
676  } \
677  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
678  void TestName::test()
679  #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
680  INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
681 
683  #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
684  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
685  Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
686  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
687 
688 // end catch_test_registry.h
689 // start catch_capture.hpp
690 
691 // start catch_assertionhandler.h
692 
693 // start catch_assertioninfo.h
694 
695 // start catch_result_type.h
696 
697 namespace Catch {
698 
699  // ResultWas::OfType enum
700  struct ResultWas { enum OfType {
701  Unknown = -1,
702  Ok = 0,
703  Info = 1,
704  Warning = 2,
705 
706  FailureBit = 0x10,
707 
708  ExpressionFailed = FailureBit | 1,
709  ExplicitFailure = FailureBit | 2,
710 
711  Exception = 0x100 | FailureBit,
712 
713  ThrewException = Exception | 1,
714  DidntThrowException = Exception | 2,
715 
716  FatalErrorCondition = 0x200 | FailureBit
717 
718  }; };
719 
720  bool isOk( ResultWas::OfType resultType );
721  bool isJustInfo( int flags );
722 
723  // ResultDisposition::Flags enum
724  struct ResultDisposition { enum Flags {
725  Normal = 0x01,
726 
727  ContinueOnFailure = 0x02, // Failures fail test, but execution continues
728  FalseTest = 0x04, // Prefix expression with !
729  SuppressFail = 0x08 // Failures are reported but do not fail the test
730  }; };
731 
733 
734  bool shouldContinueOnFailure( int flags );
735  inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
736  bool shouldSuppressFailure( int flags );
737 
738 } // end namespace Catch
739 
740 // end catch_result_type.h
741 namespace Catch {
742 
744  {
749 
750  // We want to delete this constructor but a compiler bug in 4.8 means
751  // the struct is then treated as non-aggregate
752  //AssertionInfo() = delete;
753  };
754 
755 } // end namespace Catch
756 
757 // end catch_assertioninfo.h
758 // start catch_decomposer.h
759 
760 // start catch_tostring.h
761 
762 #include <vector>
763 #include <cstddef>
764 #include <type_traits>
765 #include <string>
766 // start catch_stream.h
767 
768 #include <iosfwd>
769 #include <cstddef>
770 #include <ostream>
771 
772 namespace Catch {
773 
774  std::ostream& cout();
775  std::ostream& cerr();
776  std::ostream& clog();
777 
778  class StringRef;
779 
780  struct IStream {
781  virtual ~IStream();
782  virtual std::ostream& stream() const = 0;
783  };
784 
785  auto makeStream( StringRef const &filename ) -> IStream const*;
786 
788  std::size_t m_index;
789  std::ostream* m_oss;
790  public:
793 
794  auto str() const -> std::string;
795 
796  template<typename T>
797  auto operator << ( T const& value ) -> ReusableStringStream& {
798  *m_oss << value;
799  return *this;
800  }
801  auto get() -> std::ostream& { return *m_oss; }
802  };
803 }
804 
805 // end catch_stream.h
806 
807 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
808 #include <string_view>
809 #endif
810 
811 #ifdef __OBJC__
812 // start catch_objc_arc.hpp
813 
814 #import <Foundation/Foundation.h>
815 
816 #ifdef __has_feature
817 #define CATCH_ARC_ENABLED __has_feature(objc_arc)
818 #else
819 #define CATCH_ARC_ENABLED 0
820 #endif
821 
822 void arcSafeRelease( NSObject* obj );
823 id performOptionalSelector( id obj, SEL sel );
824 
825 #if !CATCH_ARC_ENABLED
826 inline void arcSafeRelease( NSObject* obj ) {
827  [obj release];
828 }
829 inline id performOptionalSelector( id obj, SEL sel ) {
830  if( [obj respondsToSelector: sel] )
831  return [obj performSelector: sel];
832  return nil;
833 }
834 #define CATCH_UNSAFE_UNRETAINED
835 #define CATCH_ARC_STRONG
836 #else
837 inline void arcSafeRelease( NSObject* ){}
838 inline id performOptionalSelector( id obj, SEL sel ) {
839 #ifdef __clang__
840 #pragma clang diagnostic push
841 #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
842 #endif
843  if( [obj respondsToSelector: sel] )
844  return [obj performSelector: sel];
845 #ifdef __clang__
846 #pragma clang diagnostic pop
847 #endif
848  return nil;
849 }
850 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
851 #define CATCH_ARC_STRONG __strong
852 #endif
853 
854 // end catch_objc_arc.hpp
855 #endif
856 
857 #ifdef _MSC_VER
858 #pragma warning(push)
859 #pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
860 #endif
861 
862 namespace Catch {
863  namespace Detail {
864 
865  extern const std::string unprintableString;
866 
867  std::string rawMemoryToString( const void *object, std::size_t size );
868 
869  template<typename T>
870  std::string rawMemoryToString( const T& object ) {
871  return rawMemoryToString( &object, sizeof(object) );
872  }
873 
874  template<typename T>
876  template<typename SS, typename TT>
877  static auto test(int)
878  -> decltype(std::declval<SS&>() << std::declval<TT>(), std::true_type());
879 
880  template<typename, typename>
881  static auto test(...)->std::false_type;
882 
883  public:
884  static const bool value = decltype(test<std::ostream, const T&>(0))::value;
885  };
886 
887  template<typename E>
888  std::string convertUnknownEnumToString( E e );
889 
890  template<typename T>
891  typename std::enable_if<
893  std::string>::type convertUnstreamable( T const& ) {
895  }
896  template<typename T>
897  typename std::enable_if<
899  std::string>::type convertUnstreamable(T const& ex) {
900  return ex.what();
901  }
902 
903  template<typename T>
904  typename std::enable_if<
906  , std::string>::type convertUnstreamable( T const& value ) {
907  return convertUnknownEnumToString( value );
908  }
909 
910 #if defined(_MANAGED)
911  template<typename T>
913  std::string clrReferenceToString( T^ ref ) {
914  if (ref == nullptr)
915  return std::string("null");
916  auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
917  cli::pin_ptr<System::Byte> p = &bytes[0];
918  return std::string(reinterpret_cast<char const *>(p), bytes->Length);
919  }
920 #endif
921 
922  } // namespace Detail
923 
924  // If we decide for C++14, change these to enable_if_ts
925  template <typename T, typename = void>
926  struct StringMaker {
927  template <typename Fake = T>
928  static
930  convert(const Fake& value) {
932  // NB: call using the function-like syntax to avoid ambiguity with
933  // user-defined templated operator<< under clang.
934  rss.operator<<(value);
935  return rss.str();
936  }
937 
938  template <typename Fake = T>
939  static
941  convert( const Fake& value ) {
942 #if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
943  return Detail::convertUnstreamable(value);
944 #else
945  return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
946 #endif
947  }
948  };
949 
950  namespace Detail {
951 
952  // This function dispatches all stringification requests inside of Catch.
953  // Should be preferably called fully qualified, like ::Catch::Detail::stringify
954  template <typename T>
955  std::string stringify(const T& e) {
956  return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);
957  }
958 
959  template<typename E>
960  std::string convertUnknownEnumToString( E e ) {
961  return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));
962  }
963 
964 #if defined(_MANAGED)
965  template <typename T>
966  std::string stringify( T^ e ) {
967  return ::Catch::StringMaker<T^>::convert(e);
968  }
969 #endif
970 
971  } // namespace Detail
972 
973  // Some predefined specializations
974 
975  template<>
976  struct StringMaker<std::string> {
977  static std::string convert(const std::string& str);
978  };
979 
980 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
981  template<>
982  struct StringMaker<std::string_view> {
983  static std::string convert(std::string_view str);
984  };
985 #endif
986 
987  template<>
988  struct StringMaker<char const *> {
989  static std::string convert(char const * str);
990  };
991  template<>
992  struct StringMaker<char *> {
993  static std::string convert(char * str);
994  };
995 
996 #ifdef CATCH_CONFIG_WCHAR
997  template<>
998  struct StringMaker<std::wstring> {
999  static std::string convert(const std::wstring& wstr);
1000  };
1001 
1002 # ifdef CATCH_CONFIG_CPP17_STRING_VIEW
1003  template<>
1004  struct StringMaker<std::wstring_view> {
1005  static std::string convert(std::wstring_view str);
1006  };
1007 # endif
1008 
1009  template<>
1010  struct StringMaker<wchar_t const *> {
1011  static std::string convert(wchar_t const * str);
1012  };
1013  template<>
1014  struct StringMaker<wchar_t *> {
1015  static std::string convert(wchar_t * str);
1016  };
1017 #endif
1018 
1019  // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
1020  // while keeping string semantics?
1021  template<int SZ>
1022  struct StringMaker<char[SZ]> {
1023  static std::string convert(char const* str) {
1024  return ::Catch::Detail::stringify(std::string{ str });
1025  }
1026  };
1027  template<int SZ>
1028  struct StringMaker<signed char[SZ]> {
1029  static std::string convert(signed char const* str) {
1030  return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
1031  }
1032  };
1033  template<int SZ>
1034  struct StringMaker<unsigned char[SZ]> {
1035  static std::string convert(unsigned char const* str) {
1036  return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });
1037  }
1038  };
1039 
1040  template<>
1041  struct StringMaker<int> {
1042  static std::string convert(int value);
1043  };
1044  template<>
1045  struct StringMaker<long> {
1046  static std::string convert(long value);
1047  };
1048  template<>
1049  struct StringMaker<long long> {
1050  static std::string convert(long long value);
1051  };
1052  template<>
1053  struct StringMaker<unsigned int> {
1054  static std::string convert(unsigned int value);
1055  };
1056  template<>
1057  struct StringMaker<unsigned long> {
1058  static std::string convert(unsigned long value);
1059  };
1060  template<>
1061  struct StringMaker<unsigned long long> {
1062  static std::string convert(unsigned long long value);
1063  };
1064 
1065  template<>
1066  struct StringMaker<bool> {
1067  static std::string convert(bool b);
1068  };
1069 
1070  template<>
1071  struct StringMaker<char> {
1072  static std::string convert(char c);
1073  };
1074  template<>
1075  struct StringMaker<signed char> {
1076  static std::string convert(signed char c);
1077  };
1078  template<>
1079  struct StringMaker<unsigned char> {
1080  static std::string convert(unsigned char c);
1081  };
1082 
1083  template<>
1084  struct StringMaker<std::nullptr_t> {
1085  static std::string convert(std::nullptr_t);
1086  };
1087 
1088  template<>
1089  struct StringMaker<float> {
1090  static std::string convert(float value);
1091  };
1092  template<>
1093  struct StringMaker<double> {
1094  static std::string convert(double value);
1095  };
1096 
1097  template <typename T>
1098  struct StringMaker<T*> {
1099  template <typename U>
1100  static std::string convert(U* p) {
1101  if (p) {
1103  } else {
1104  return "nullptr";
1105  }
1106  }
1107  };
1108 
1109  template <typename R, typename C>
1110  struct StringMaker<R C::*> {
1111  static std::string convert(R C::* p) {
1112  if (p) {
1114  } else {
1115  return "nullptr";
1116  }
1117  }
1118  };
1119 
1120 #if defined(_MANAGED)
1121  template <typename T>
1122  struct StringMaker<T^> {
1123  static std::string convert( T^ ref ) {
1124  return ::Catch::Detail::clrReferenceToString(ref);
1125  }
1126  };
1127 #endif
1128 
1129  namespace Detail {
1130  template<typename InputIterator>
1131  std::string rangeToString(InputIterator first, InputIterator last) {
1133  rss << "{ ";
1134  if (first != last) {
1135  rss << ::Catch::Detail::stringify(*first);
1136  for (++first; first != last; ++first)
1137  rss << ", " << ::Catch::Detail::stringify(*first);
1138  }
1139  rss << " }";
1140  return rss.str();
1141  }
1142  }
1143 
1144 #ifdef __OBJC__
1145  template<>
1146  struct StringMaker<NSString*> {
1147  static std::string convert(NSString * nsstring) {
1148  if (!nsstring)
1149  return "nil";
1150  return std::string("@") + [nsstring UTF8String];
1151  }
1152  };
1153  template<>
1154  struct StringMaker<NSObject*> {
1155  static std::string convert(NSObject* nsObject) {
1156  return ::Catch::Detail::stringify([nsObject description]);
1157  }
1158 
1159  };
1160  namespace Detail {
1161  inline std::string stringify( NSString* nsstring ) {
1162  return StringMaker<NSString*>::convert( nsstring );
1163  }
1164 
1165  } // namespace Detail
1166 #endif // __OBJC__
1167 
1168 } // namespace Catch
1169 
1171 // Separate std-lib types stringification, so it can be selectively enabled
1172 // This means that we do not bring in
1173 
1174 #if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
1175 # define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
1176 # define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
1177 # define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
1178 # define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
1179 #endif
1180 
1181 // Separate std::pair specialization
1182 #if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
1183 #include <utility>
1184 namespace Catch {
1185  template<typename T1, typename T2>
1186  struct StringMaker<std::pair<T1, T2> > {
1187  static std::string convert(const std::pair<T1, T2>& pair) {
1189  rss << "{ "
1190  << ::Catch::Detail::stringify(pair.first)
1191  << ", "
1192  << ::Catch::Detail::stringify(pair.second)
1193  << " }";
1194  return rss.str();
1195  }
1196  };
1197 }
1198 #endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
1199 
1200 // Separate std::tuple specialization
1201 #if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
1202 #include <tuple>
1203 namespace Catch {
1204  namespace Detail {
1205  template<
1206  typename Tuple,
1207  std::size_t N = 0,
1209  >
1210  struct TupleElementPrinter {
1211  static void print(const Tuple& tuple, std::ostream& os) {
1212  os << (N ? ", " : " ")
1213  << ::Catch::Detail::stringify(std::get<N>(tuple));
1214  TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
1215  }
1216  };
1217 
1218  template<
1219  typename Tuple,
1220  std::size_t N
1221  >
1222  struct TupleElementPrinter<Tuple, N, false> {
1223  static void print(const Tuple&, std::ostream&) {}
1224  };
1225 
1226  }
1227 
1228  template<typename ...Types>
1229  struct StringMaker<std::tuple<Types...>> {
1230  static std::string convert(const std::tuple<Types...>& tuple) {
1232  rss << '{';
1233  Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
1234  rss << " }";
1235  return rss.str();
1236  }
1237  };
1238 }
1239 #endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
1240 
1241 #if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
1242 #include <variant>
1243 namespace Catch {
1244  template<>
1245  struct StringMaker<std::monostate> {
1246  static std::string convert(const std::monostate&) {
1247  return "{ }";
1248  }
1249  };
1250 
1251  template<typename... Elements>
1252  struct StringMaker<std::variant<Elements...>> {
1253  static std::string convert(const std::variant<Elements...>& variant) {
1254  if (variant.valueless_by_exception()) {
1255  return "{valueless variant}";
1256  } else {
1257  return std::visit(
1258  [](const auto& value) {
1260  },
1261  variant
1262  );
1263  }
1264  }
1265  };
1266 }
1267 #endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
1268 
1269 namespace Catch {
1270  struct not_this_one {}; // Tag type for detecting which begin/ end are being selected
1271 
1272  // Import begin/ end from std here so they are considered alongside the fallback (...) overloads in this namespace
1273  using std::begin;
1274  using std::end;
1275 
1276  not_this_one begin( ... );
1277  not_this_one end( ... );
1278 
1279  template <typename T>
1280  struct is_range {
1281  static const bool value =
1282  !std::is_same<decltype(begin(std::declval<T>())), not_this_one>::value &&
1283  !std::is_same<decltype(end(std::declval<T>())), not_this_one>::value;
1284  };
1285 
1286 #if defined(_MANAGED) // Managed types are never ranges
1287  template <typename T>
1288  struct is_range<T^> {
1289  static const bool value = false;
1290  };
1291 #endif
1292 
1293  template<typename Range>
1294  std::string rangeToString( Range const& range ) {
1295  return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
1296  }
1297 
1298  // Handle vector<bool> specially
1299  template<typename Allocator>
1300  std::string rangeToString( std::vector<bool, Allocator> const& v ) {
1302  rss << "{ ";
1303  bool first = true;
1304  for( bool b : v ) {
1305  if( first )
1306  first = false;
1307  else
1308  rss << ", ";
1309  rss << ::Catch::Detail::stringify( b );
1310  }
1311  rss << " }";
1312  return rss.str();
1313  }
1314 
1315  template<typename R>
1316  struct StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {
1317  static std::string convert( R const& range ) {
1318  return rangeToString( range );
1319  }
1320  };
1321 
1322  template <typename T, int SZ>
1323  struct StringMaker<T[SZ]> {
1324  static std::string convert(T const(&arr)[SZ]) {
1325  return rangeToString(arr);
1326  }
1327  };
1328 
1329 } // namespace Catch
1330 
1331 // Separate std::chrono::duration specialization
1332 #if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
1333 #include <ctime>
1334 #include <ratio>
1335 #include <chrono>
1336 
1337 namespace Catch {
1338 
1339 template <class Ratio>
1340 struct ratio_string {
1341  static std::string symbol();
1342 };
1343 
1344 template <class Ratio>
1345 std::string ratio_string<Ratio>::symbol() {
1347  rss << '[' << Ratio::num << '/'
1348  << Ratio::den << ']';
1349  return rss.str();
1350 }
1351 template <>
1352 struct ratio_string<std::atto> {
1353  static std::string symbol();
1354 };
1355 template <>
1356 struct ratio_string<std::femto> {
1357  static std::string symbol();
1358 };
1359 template <>
1360 struct ratio_string<std::pico> {
1361  static std::string symbol();
1362 };
1363 template <>
1364 struct ratio_string<std::nano> {
1365  static std::string symbol();
1366 };
1367 template <>
1368 struct ratio_string<std::micro> {
1369  static std::string symbol();
1370 };
1371 template <>
1372 struct ratio_string<std::milli> {
1373  static std::string symbol();
1374 };
1375 
1377  // std::chrono::duration specializations
1378  template<typename Value, typename Ratio>
1379  struct StringMaker<std::chrono::duration<Value, Ratio>> {
1380  static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {
1382  rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
1383  return rss.str();
1384  }
1385  };
1386  template<typename Value>
1387  struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
1388  static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {
1390  rss << duration.count() << " s";
1391  return rss.str();
1392  }
1393  };
1394  template<typename Value>
1395  struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
1396  static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {
1398  rss << duration.count() << " m";
1399  return rss.str();
1400  }
1401  };
1402  template<typename Value>
1403  struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
1404  static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {
1406  rss << duration.count() << " h";
1407  return rss.str();
1408  }
1409  };
1410 
1412  // std::chrono::time_point specialization
1413  // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
1414  template<typename Clock, typename Duration>
1415  struct StringMaker<std::chrono::time_point<Clock, Duration>> {
1416  static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {
1417  return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
1418  }
1419  };
1420  // std::chrono::time_point<system_clock> specialization
1421  template<typename Duration>
1422  struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {
1423  static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {
1424  auto converted = std::chrono::system_clock::to_time_t(time_point);
1425 
1426 #ifdef _MSC_VER
1427  std::tm timeInfo = {};
1428  gmtime_s(&timeInfo, &converted);
1429 #else
1430  std::tm* timeInfo = std::gmtime(&converted);
1431 #endif
1432 
1433  auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
1434  char timeStamp[timeStampSize];
1435  const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
1436 
1437 #ifdef _MSC_VER
1438  std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
1439 #else
1440  std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
1441 #endif
1442  return std::string(timeStamp);
1443  }
1444  };
1445 }
1446 #endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
1447 
1448 #ifdef _MSC_VER
1449 #pragma warning(pop)
1450 #endif
1451 
1452 // end catch_tostring.h
1453 #include <iosfwd>
1454 
1455 #ifdef _MSC_VER
1456 #pragma warning(push)
1457 #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
1458 #pragma warning(disable:4018) // more "signed/unsigned mismatch"
1459 #pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
1460 #pragma warning(disable:4180) // qualifier applied to function type has no meaning
1461 #endif
1462 
1463 namespace Catch {
1464 
1466  auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
1467  auto getResult() const -> bool { return m_result; }
1468  virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
1469 
1470  ITransientExpression( bool isBinaryExpression, bool result )
1471  : m_isBinaryExpression( isBinaryExpression ),
1472  m_result( result )
1473  {}
1474 
1475  // We don't actually need a virtual destructor, but many static analysers
1476  // complain if it's not here :-(
1477  virtual ~ITransientExpression();
1478 
1480  bool m_result;
1481 
1482  };
1483 
1484  void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
1485 
1486  template<typename LhsT, typename RhsT>
1488  LhsT m_lhs;
1490  RhsT m_rhs;
1491 
1492  void streamReconstructedExpression( std::ostream &os ) const override {
1494  ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
1495  }
1496 
1497  public:
1498  BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
1499  : ITransientExpression{ true, comparisonResult },
1500  m_lhs( lhs ),
1501  m_op( op ),
1502  m_rhs( rhs )
1503  {}
1504  };
1505 
1506  template<typename LhsT>
1508  LhsT m_lhs;
1509 
1510  void streamReconstructedExpression( std::ostream &os ) const override {
1511  os << Catch::Detail::stringify( m_lhs );
1512  }
1513 
1514  public:
1515  explicit UnaryExpr( LhsT lhs )
1516  : ITransientExpression{ false, lhs ? true : false },
1517  m_lhs( lhs )
1518  {}
1519  };
1520 
1521  // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
1522  template<typename LhsT, typename RhsT>
1523  auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }
1524  template<typename T>
1525  auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
1526  template<typename T>
1527  auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
1528  template<typename T>
1529  auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
1530  template<typename T>
1531  auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
1532 
1533  template<typename LhsT, typename RhsT>
1534  auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }
1535  template<typename T>
1536  auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
1537  template<typename T>
1538  auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
1539  template<typename T>
1540  auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
1541  template<typename T>
1542  auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
1543 
1544  template<typename LhsT>
1545  class ExprLhs {
1546  LhsT m_lhs;
1547  public:
1548  explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
1549 
1550  template<typename RhsT>
1551  auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
1552  return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs };
1553  }
1554  auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
1555  return { m_lhs == rhs, m_lhs, "==", rhs };
1556  }
1557 
1558  template<typename RhsT>
1559  auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
1560  return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs };
1561  }
1562  auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
1563  return { m_lhs != rhs, m_lhs, "!=", rhs };
1564  }
1565 
1566  template<typename RhsT>
1567  auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
1568  return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs };
1569  }
1570  template<typename RhsT>
1571  auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
1572  return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs };
1573  }
1574  template<typename RhsT>
1575  auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
1576  return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs };
1577  }
1578  template<typename RhsT>
1579  auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
1580  return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs };
1581  }
1582 
1583  auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
1584  return UnaryExpr<LhsT>{ m_lhs };
1585  }
1586  };
1587 
1588  void handleExpression( ITransientExpression const& expr );
1589 
1590  template<typename T>
1591  void handleExpression( ExprLhs<T> const& expr ) {
1592  handleExpression( expr.makeUnaryExpr() );
1593  }
1594 
1595  struct Decomposer {
1596  template<typename T>
1597  auto operator <= ( T const& lhs ) -> ExprLhs<T const&> {
1598  return ExprLhs<T const&>{ lhs };
1599  }
1600 
1601  auto operator <=( bool value ) -> ExprLhs<bool> {
1602  return ExprLhs<bool>{ value };
1603  }
1604  };
1605 
1606 } // end namespace Catch
1607 
1608 #ifdef _MSC_VER
1609 #pragma warning(pop)
1610 #endif
1611 
1612 // end catch_decomposer.h
1613 // start catch_interfaces_capture.h
1614 
1615 #include <string>
1616 
1617 namespace Catch {
1618 
1619  class AssertionResult;
1620  struct AssertionInfo;
1621  struct SectionInfo;
1622  struct SectionEndInfo;
1623  struct MessageInfo;
1624  struct Counts;
1625  struct BenchmarkInfo;
1626  struct BenchmarkStats;
1627  struct AssertionReaction;
1628  struct SourceLineInfo;
1629 
1630  struct ITransientExpression;
1631  struct IGeneratorTracker;
1632 
1634 
1635  virtual ~IResultCapture();
1636 
1637  virtual bool sectionStarted( SectionInfo const& sectionInfo,
1638  Counts& assertions ) = 0;
1639  virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
1640  virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
1641 
1642  virtual auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
1643 
1644  virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
1645  virtual void benchmarkEnded( BenchmarkStats const& stats ) = 0;
1646 
1647  virtual void pushScopedMessage( MessageInfo const& message ) = 0;
1648  virtual void popScopedMessage( MessageInfo const& message ) = 0;
1649 
1650  virtual void handleFatalErrorCondition( StringRef message ) = 0;
1651 
1652  virtual void handleExpr
1653  ( AssertionInfo const& info,
1654  ITransientExpression const& expr,
1655  AssertionReaction& reaction ) = 0;
1656  virtual void handleMessage
1657  ( AssertionInfo const& info,
1658  ResultWas::OfType resultType,
1659  StringRef const& message,
1660  AssertionReaction& reaction ) = 0;
1661  virtual void handleUnexpectedExceptionNotThrown
1662  ( AssertionInfo const& info,
1663  AssertionReaction& reaction ) = 0;
1664  virtual void handleUnexpectedInflightException
1665  ( AssertionInfo const& info,
1666  std::string const& message,
1667  AssertionReaction& reaction ) = 0;
1668  virtual void handleIncomplete
1669  ( AssertionInfo const& info ) = 0;
1670  virtual void handleNonExpr
1671  ( AssertionInfo const &info,
1672  ResultWas::OfType resultType,
1673  AssertionReaction &reaction ) = 0;
1674 
1675  virtual bool lastAssertionPassed() = 0;
1676  virtual void assertionPassed() = 0;
1677 
1678  // Deprecated, do not use:
1679  virtual std::string getCurrentTestName() const = 0;
1680  virtual const AssertionResult* getLastResult() const = 0;
1681  virtual void exceptionEarlyReported() = 0;
1682  };
1683 
1685 }
1686 
1687 // end catch_interfaces_capture.h
1688 namespace Catch {
1689 
1691  struct AssertionResultData;
1692  struct IResultCapture;
1693  class RunContext;
1694 
1696  friend class AssertionHandler;
1697  friend struct AssertionStats;
1698  friend class RunContext;
1699 
1700  ITransientExpression const* m_transientExpression = nullptr;
1702  public:
1703  LazyExpression( bool isNegated );
1704  LazyExpression( LazyExpression const& other );
1705  LazyExpression& operator = ( LazyExpression const& ) = delete;
1706 
1707  explicit operator bool() const;
1708 
1709  friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&;
1710  };
1711 
1713  bool shouldDebugBreak = false;
1714  bool shouldThrow = false;
1715  };
1716 
1720  bool m_completed = false;
1722 
1723  public:
1725  ( StringRef const& macroName,
1726  SourceLineInfo const& lineInfo,
1727  StringRef capturedExpression,
1728  ResultDisposition::Flags resultDisposition );
1730  if ( !m_completed ) {
1731  m_resultCapture.handleIncomplete( m_assertionInfo );
1732  }
1733  }
1734 
1735  template<typename T>
1736  void handleExpr( ExprLhs<T> const& expr ) {
1737  handleExpr( expr.makeUnaryExpr() );
1738  }
1739  void handleExpr( ITransientExpression const& expr );
1740 
1741  void handleMessage(ResultWas::OfType resultType, StringRef const& message);
1742 
1743  void handleExceptionThrownAsExpected();
1744  void handleUnexpectedExceptionNotThrown();
1745  void handleExceptionNotThrownAsExpected();
1746  void handleThrowingCallSkipped();
1747  void handleUnexpectedInflightException();
1748 
1749  void complete();
1750  void setCompleted();
1751 
1752  // query
1753  auto allowThrows() const -> bool;
1754  };
1755 
1756  void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString );
1757 
1758 } // namespace Catch
1759 
1760 // end catch_assertionhandler.h
1761 // start catch_message.h
1762 
1763 #include <string>
1764 #include <vector>
1765 
1766 namespace Catch {
1767 
1768  struct MessageInfo {
1769  MessageInfo( StringRef const& _macroName,
1770  SourceLineInfo const& _lineInfo,
1771  ResultWas::OfType _type );
1772 
1774  std::string message;
1777  unsigned int sequence;
1778 
1779  bool operator == ( MessageInfo const& other ) const;
1780  bool operator < ( MessageInfo const& other ) const;
1781  private:
1782  static unsigned int globalCount;
1783  };
1784 
1785  struct MessageStream {
1786 
1787  template<typename T>
1789  m_stream << value;
1790  return *this;
1791  }
1792 
1794  };
1795 
1797  MessageBuilder( StringRef const& macroName,
1798  SourceLineInfo const& lineInfo,
1799  ResultWas::OfType type );
1800 
1801  template<typename T>
1803  m_stream << value;
1804  return *this;
1805  }
1806 
1808  };
1809 
1811  public:
1812  explicit ScopedMessage( MessageBuilder const& builder );
1813  ~ScopedMessage();
1814 
1816  };
1817 
1818  class Capturer {
1819  std::vector<MessageInfo> m_messages;
1820  IResultCapture& m_resultCapture = getResultCapture();
1821  size_t m_captured = 0;
1822  public:
1823  Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
1824  ~Capturer();
1825 
1826  void captureValue( size_t index, StringRef value );
1827 
1828  template<typename T>
1829  void captureValues( size_t index, T&& value ) {
1830  captureValue( index, Catch::Detail::stringify( value ) );
1831  }
1832 
1833  template<typename T, typename... Ts>
1834  void captureValues( size_t index, T&& value, Ts&&... values ) {
1835  captureValues( index, value );
1836  captureValues( index+1, values... );
1837  }
1838  };
1839 
1840 } // end namespace Catch
1841 
1842 // end catch_message.h
1843 #if !defined(CATCH_CONFIG_DISABLE)
1844 
1845 #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
1846  #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
1847 #else
1848  #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
1849 #endif
1850 
1851 #if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
1852 
1854 // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
1855 // macros.
1856 #define INTERNAL_CATCH_TRY
1857 #define INTERNAL_CATCH_CATCH( capturer )
1858 
1859 #else // CATCH_CONFIG_FAST_COMPILE
1860 
1861 #define INTERNAL_CATCH_TRY try
1862 #define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); }
1863 
1864 #endif
1865 
1866 #define INTERNAL_CATCH_REACT( handler ) handler.complete();
1867 
1869 #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
1870  do { \
1871  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
1872  INTERNAL_CATCH_TRY { \
1873  CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
1874  catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
1875  CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
1876  } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
1877  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
1878  } 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
1879  // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
1880 
1882 #define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
1883  INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
1884  if( Catch::getResultCapture().lastAssertionPassed() )
1885 
1887 #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
1888  INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
1889  if( !Catch::getResultCapture().lastAssertionPassed() )
1890 
1892 #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
1893  do { \
1894  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
1895  try { \
1896  static_cast<void>(__VA_ARGS__); \
1897  catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
1898  } \
1899  catch( ... ) { \
1900  catchAssertionHandler.handleUnexpectedInflightException(); \
1901  } \
1902  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
1903  } while( false )
1904 
1906 #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
1907  do { \
1908  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
1909  if( catchAssertionHandler.allowThrows() ) \
1910  try { \
1911  static_cast<void>(__VA_ARGS__); \
1912  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
1913  } \
1914  catch( ... ) { \
1915  catchAssertionHandler.handleExceptionThrownAsExpected(); \
1916  } \
1917  else \
1918  catchAssertionHandler.handleThrowingCallSkipped(); \
1919  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
1920  } while( false )
1921 
1923 #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
1924  do { \
1925  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
1926  if( catchAssertionHandler.allowThrows() ) \
1927  try { \
1928  static_cast<void>(expr); \
1929  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
1930  } \
1931  catch( exceptionType const& ) { \
1932  catchAssertionHandler.handleExceptionThrownAsExpected(); \
1933  } \
1934  catch( ... ) { \
1935  catchAssertionHandler.handleUnexpectedInflightException(); \
1936  } \
1937  else \
1938  catchAssertionHandler.handleThrowingCallSkipped(); \
1939  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
1940  } while( false )
1941 
1943 #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
1944  do { \
1945  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
1946  catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
1947  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
1948  } while( false )
1949 
1951 #define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
1952  auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \
1953  varName.captureValues( 0, __VA_ARGS__ )
1954 
1956 #define INTERNAL_CATCH_INFO( macroName, log ) \
1957  Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
1958 
1960 // Although this is matcher-based, it can be used with just a string
1961 #define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
1962  do { \
1963  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
1964  if( catchAssertionHandler.allowThrows() ) \
1965  try { \
1966  static_cast<void>(__VA_ARGS__); \
1967  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
1968  } \
1969  catch( ... ) { \
1970  Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \
1971  } \
1972  else \
1973  catchAssertionHandler.handleThrowingCallSkipped(); \
1974  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
1975  } while( false )
1976 
1977 #endif // CATCH_CONFIG_DISABLE
1978 
1979 // end catch_capture.hpp
1980 // start catch_section.h
1981 
1982 // start catch_section_info.h
1983 
1984 // start catch_totals.h
1985 
1986 #include <cstddef>
1987 
1988 namespace Catch {
1989 
1990  struct Counts {
1991  Counts operator - ( Counts const& other ) const;
1992  Counts& operator += ( Counts const& other );
1993 
1994  std::size_t total() const;
1995  bool allPassed() const;
1996  bool allOk() const;
1997 
1998  std::size_t passed = 0;
1999  std::size_t failed = 0;
2000  std::size_t failedButOk = 0;
2001  };
2002 
2003  struct Totals {
2004 
2005  Totals operator - ( Totals const& other ) const;
2006  Totals& operator += ( Totals const& other );
2007 
2008  Totals delta( Totals const& prevTotals ) const;
2009 
2010  int error = 0;
2013  };
2014 }
2015 
2016 // end catch_totals.h
2017 #include <string>
2018 
2019 namespace Catch {
2020 
2021  struct SectionInfo {
2022  SectionInfo
2023  ( SourceLineInfo const& _lineInfo,
2024  std::string const& _name );
2025 
2026  // Deprecated
2027  SectionInfo
2028  ( SourceLineInfo const& _lineInfo,
2029  std::string const& _name,
2030  std::string const& ) : SectionInfo( _lineInfo, _name ) {}
2031 
2032  std::string name;
2033  std::string description; // !Deprecated: this will always be empty
2035  };
2036 
2041  };
2042 
2043 } // end namespace Catch
2044 
2045 // end catch_section_info.h
2046 // start catch_timer.h
2047 
2048 #include <cstdint>
2049 
2050 namespace Catch {
2051 
2052  auto getCurrentNanosecondsSinceEpoch() -> uint64_t;
2053  auto getEstimatedClockResolution() -> uint64_t;
2054 
2055  class Timer {
2056  uint64_t m_nanoseconds = 0;
2057  public:
2058  void start();
2059  auto getElapsedNanoseconds() const -> uint64_t;
2060  auto getElapsedMicroseconds() const -> uint64_t;
2061  auto getElapsedMilliseconds() const -> unsigned int;
2062  auto getElapsedSeconds() const -> double;
2063  };
2064 
2065 } // namespace Catch
2066 
2067 // end catch_timer.h
2068 #include <string>
2069 
2070 namespace Catch {
2071 
2073  public:
2074  Section( SectionInfo const& info );
2075  ~Section();
2076 
2077  // This indicates whether the section should be executed or not
2078  explicit operator bool() const;
2079 
2080  private:
2082 
2083  std::string m_name;
2087  };
2088 
2089 } // end namespace Catch
2090 
2091 #define INTERNAL_CATCH_SECTION( ... ) \
2092  CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
2093  if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
2094  CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
2095 
2096 #define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
2097  CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
2098  if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \
2099  CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
2100 
2101 // end catch_section.h
2102 // start catch_benchmark.h
2103 
2104 #include <cstdint>
2105 #include <string>
2106 
2107 namespace Catch {
2108 
2110 
2111  std::string m_name;
2112  std::size_t m_count = 0;
2113  std::size_t m_iterationsToRun = 1;
2114  uint64_t m_resolution;
2116 
2117  static auto getResolution() -> uint64_t;
2118  public:
2119  // Keep most of this inline as it's on the code path that is being timed
2121  : m_name( name ),
2122  m_resolution( getResolution() )
2123  {
2124  reportStart();
2125  m_timer.start();
2126  }
2127 
2128  explicit operator bool() {
2129  if( m_count < m_iterationsToRun )
2130  return true;
2131  return needsMoreIterations();
2132  }
2133 
2134  void increment() {
2135  ++m_count;
2136  }
2137 
2138  void reportStart();
2139  auto needsMoreIterations() -> bool;
2140  };
2141 
2142 } // end namespace Catch
2143 
2144 #define BENCHMARK( name ) \
2145  for( Catch::BenchmarkLooper looper( name ); looper; looper.increment() )
2146 
2147 // end catch_benchmark.h
2148 // start catch_interfaces_exception.h
2149 
2150 // start catch_interfaces_registry_hub.h
2151 
2152 #include <string>
2153 #include <memory>
2154 
2155 namespace Catch {
2156 
2157  class TestCase;
2158  struct ITestCaseRegistry;
2159  struct IExceptionTranslatorRegistry;
2160  struct IExceptionTranslator;
2161  struct IReporterRegistry;
2162  struct IReporterFactory;
2163  struct ITagAliasRegistry;
2164  class StartupExceptionRegistry;
2165 
2166  using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
2167 
2168  struct IRegistryHub {
2169  virtual ~IRegistryHub();
2170 
2171  virtual IReporterRegistry const& getReporterRegistry() const = 0;
2172  virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
2173  virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
2174 
2175  virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0;
2176 
2177  virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
2178  };
2179 
2181  virtual ~IMutableRegistryHub();
2182  virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0;
2183  virtual void registerListener( IReporterFactoryPtr const& factory ) = 0;
2184  virtual void registerTest( TestCase const& testInfo ) = 0;
2185  virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
2186  virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
2187  virtual void registerStartupException() noexcept = 0;
2188  };
2189 
2190  IRegistryHub const& getRegistryHub();
2192  void cleanUp();
2193  std::string translateActiveException();
2194 
2195 }
2196 
2197 // end catch_interfaces_registry_hub.h
2198 #if defined(CATCH_CONFIG_DISABLE)
2199  #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \
2200  static std::string translatorName( signature )
2201 #endif
2202 
2203 #include <exception>
2204 #include <string>
2205 #include <vector>
2206 
2207 namespace Catch {
2208  using exceptionTranslateFunction = std::string(*)();
2209 
2210  struct IExceptionTranslator;
2211  using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;
2212 
2214  virtual ~IExceptionTranslator();
2215  virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
2216  };
2217 
2219  virtual ~IExceptionTranslatorRegistry();
2220 
2221  virtual std::string translateActiveException() const = 0;
2222  };
2223 
2225  template<typename T>
2227  public:
2228 
2229  ExceptionTranslator( std::string(*translateFunction)( T& ) )
2230  : m_translateFunction( translateFunction )
2231  {}
2232 
2233  std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override {
2234  try {
2235  if( it == itEnd )
2236  std::rethrow_exception(std::current_exception());
2237  else
2238  return (*it)->translate( it+1, itEnd );
2239  }
2240  catch( T& ex ) {
2241  return m_translateFunction( ex );
2242  }
2243  }
2244 
2245  protected:
2246  std::string(*m_translateFunction)( T& );
2247  };
2248 
2249  public:
2250  template<typename T>
2251  ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
2253  ( new ExceptionTranslator<T>( translateFunction ) );
2254  }
2255  };
2256 }
2257 
2259 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
2260  static std::string translatorName( signature ); \
2261  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
2262  namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \
2263  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
2264  static std::string translatorName( signature )
2265 
2266 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
2267 
2268 // end catch_interfaces_exception.h
2269 // start catch_approx.h
2270 
2271 #include <type_traits>
2272 
2273 namespace Catch {
2274 namespace Detail {
2275 
2276  class Approx {
2277  private:
2278  bool equalityComparisonImpl(double other) const;
2279  // Validates the new margin (margin >= 0)
2280  // out-of-line to avoid including stdexcept in the header
2281  void setMargin(double margin);
2282  // Validates the new epsilon (0 < epsilon < 1)
2283  // out-of-line to avoid including stdexcept in the header
2284  void setEpsilon(double epsilon);
2285 
2286  public:
2287  explicit Approx ( double value );
2288 
2289  static Approx custom();
2290 
2291  Approx operator-() const;
2292 
2294  Approx operator()( T const& value ) {
2295  Approx approx( static_cast<double>(value) );
2296  approx.m_epsilon = m_epsilon;
2297  approx.m_margin = m_margin;
2298  approx.m_scale = m_scale;
2299  return approx;
2300  }
2301 
2303  explicit Approx( T const& value ): Approx(static_cast<double>(value))
2304  {}
2305 
2307  friend bool operator == ( const T& lhs, Approx const& rhs ) {
2308  auto lhs_v = static_cast<double>(lhs);
2309  return rhs.equalityComparisonImpl(lhs_v);
2310  }
2311 
2313  friend bool operator == ( Approx const& lhs, const T& rhs ) {
2314  return operator==( rhs, lhs );
2315  }
2316 
2318  friend bool operator != ( T const& lhs, Approx const& rhs ) {
2319  return !operator==( lhs, rhs );
2320  }
2321 
2323  friend bool operator != ( Approx const& lhs, T const& rhs ) {
2324  return !operator==( rhs, lhs );
2325  }
2326 
2328  friend bool operator <= ( T const& lhs, Approx const& rhs ) {
2329  return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;
2330  }
2331 
2333  friend bool operator <= ( Approx const& lhs, T const& rhs ) {
2334  return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
2335  }
2336 
2338  friend bool operator >= ( T const& lhs, Approx const& rhs ) {
2339  return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;
2340  }
2341 
2343  friend bool operator >= ( Approx const& lhs, T const& rhs ) {
2344  return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
2345  }
2346 
2348  Approx& epsilon( T const& newEpsilon ) {
2349  double epsilonAsDouble = static_cast<double>(newEpsilon);
2350  setEpsilon(epsilonAsDouble);
2351  return *this;
2352  }
2353 
2355  Approx& margin( T const& newMargin ) {
2356  double marginAsDouble = static_cast<double>(newMargin);
2357  setMargin(marginAsDouble);
2358  return *this;
2359  }
2360 
2362  Approx& scale( T const& newScale ) {
2363  m_scale = static_cast<double>(newScale);
2364  return *this;
2365  }
2366 
2367  std::string toString() const;
2368 
2369  private:
2370  double m_epsilon;
2371  double m_margin;
2372  double m_scale;
2373  double m_value;
2374  };
2375 } // end namespace Detail
2376 
2377 namespace literals {
2378  Detail::Approx operator "" _a(long double val);
2379  Detail::Approx operator "" _a(unsigned long long val);
2380 } // end namespace literals
2381 
2382 template<>
2384  static std::string convert(Catch::Detail::Approx const& value);
2385 };
2386 
2387 } // end namespace Catch
2388 
2389 // end catch_approx.h
2390 // start catch_string_manip.h
2391 
2392 #include <string>
2393 #include <iosfwd>
2394 
2395 namespace Catch {
2396 
2397  bool startsWith( std::string const& s, std::string const& prefix );
2398  bool startsWith( std::string const& s, char prefix );
2399  bool endsWith( std::string const& s, std::string const& suffix );
2400  bool endsWith( std::string const& s, char suffix );
2401  bool contains( std::string const& s, std::string const& infix );
2402  void toLowerInPlace( std::string& s );
2403  std::string toLower( std::string const& s );
2404  std::string trim( std::string const& str );
2405  bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
2406 
2407  struct pluralise {
2408  pluralise( std::size_t count, std::string const& label );
2409 
2410  friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
2411 
2412  std::size_t m_count;
2413  std::string m_label;
2414  };
2415 }
2416 
2417 // end catch_string_manip.h
2418 #ifndef CATCH_CONFIG_DISABLE_MATCHERS
2419 // start catch_capture_matchers.h
2420 
2421 // start catch_matchers.h
2422 
2423 #include <string>
2424 #include <vector>
2425 
2426 namespace Catch {
2427 namespace Matchers {
2428  namespace Impl {
2429 
2430  template<typename ArgT> struct MatchAllOf;
2431  template<typename ArgT> struct MatchAnyOf;
2432  template<typename ArgT> struct MatchNotOf;
2433 
2435  public:
2436  MatcherUntypedBase() = default;
2437  MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
2438  MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete;
2439  std::string toString() const;
2440 
2441  protected:
2442  virtual ~MatcherUntypedBase();
2443  virtual std::string describe() const = 0;
2444  mutable std::string m_cachedToString;
2445  };
2446 
2447 #ifdef __clang__
2448 # pragma clang diagnostic push
2449 # pragma clang diagnostic ignored "-Wnon-virtual-dtor"
2450 #endif
2451 
2452  template<typename ObjectT>
2453  struct MatcherMethod {
2454  virtual bool match( ObjectT const& arg ) const = 0;
2455  };
2456  template<typename PtrT>
2457  struct MatcherMethod<PtrT*> {
2458  virtual bool match( PtrT* arg ) const = 0;
2459  };
2460 
2461 #ifdef __clang__
2462 # pragma clang diagnostic pop
2463 #endif
2464 
2465  template<typename T>
2467 
2468  MatchAllOf<T> operator && ( MatcherBase const& other ) const;
2469  MatchAnyOf<T> operator || ( MatcherBase const& other ) const;
2470  MatchNotOf<T> operator ! () const;
2471  };
2472 
2473  template<typename ArgT>
2474  struct MatchAllOf : MatcherBase<ArgT> {
2475  bool match( ArgT const& arg ) const override {
2476  for( auto matcher : m_matchers ) {
2477  if (!matcher->match(arg))
2478  return false;
2479  }
2480  return true;
2481  }
2482  std::string describe() const override {
2483  std::string description;
2484  description.reserve( 4 + m_matchers.size()*32 );
2485  description += "( ";
2486  bool first = true;
2487  for( auto matcher : m_matchers ) {
2488  if( first )
2489  first = false;
2490  else
2491  description += " and ";
2492  description += matcher->toString();
2493  }
2494  description += " )";
2495  return description;
2496  }
2497 
2498  MatchAllOf<ArgT>& operator && ( MatcherBase<ArgT> const& other ) {
2499  m_matchers.push_back( &other );
2500  return *this;
2501  }
2502 
2503  std::vector<MatcherBase<ArgT> const*> m_matchers;
2504  };
2505  template<typename ArgT>
2506  struct MatchAnyOf : MatcherBase<ArgT> {
2507 
2508  bool match( ArgT const& arg ) const override {
2509  for( auto matcher : m_matchers ) {
2510  if (matcher->match(arg))
2511  return true;
2512  }
2513  return false;
2514  }
2515  std::string describe() const override {
2516  std::string description;
2517  description.reserve( 4 + m_matchers.size()*32 );
2518  description += "( ";
2519  bool first = true;
2520  for( auto matcher : m_matchers ) {
2521  if( first )
2522  first = false;
2523  else
2524  description += " or ";
2525  description += matcher->toString();
2526  }
2527  description += " )";
2528  return description;
2529  }
2530 
2531  MatchAnyOf<ArgT>& operator || ( MatcherBase<ArgT> const& other ) {
2532  m_matchers.push_back( &other );
2533  return *this;
2534  }
2535 
2536  std::vector<MatcherBase<ArgT> const*> m_matchers;
2537  };
2538 
2539  template<typename ArgT>
2540  struct MatchNotOf : MatcherBase<ArgT> {
2541 
2542  MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
2543 
2544  bool match( ArgT const& arg ) const override {
2545  return !m_underlyingMatcher.match( arg );
2546  }
2547 
2548  std::string describe() const override {
2549  return "not " + m_underlyingMatcher.toString();
2550  }
2552  };
2553 
2554  template<typename T>
2556  return MatchAllOf<T>() && *this && other;
2557  }
2558  template<typename T>
2560  return MatchAnyOf<T>() || *this || other;
2561  }
2562  template<typename T>
2564  return MatchNotOf<T>( *this );
2565  }
2566 
2567  } // namespace Impl
2568 
2569 } // namespace Matchers
2570 
2571 using namespace Matchers;
2573 
2574 } // namespace Catch
2575 
2576 // end catch_matchers.h
2577 // start catch_matchers_floating.h
2578 
2579 #include <type_traits>
2580 #include <cmath>
2581 
2582 namespace Catch {
2583 namespace Matchers {
2584 
2585  namespace Floating {
2586 
2587  enum class FloatingPointKind : uint8_t;
2588 
2589  struct WithinAbsMatcher : MatcherBase<double> {
2590  WithinAbsMatcher(double target, double margin);
2591  bool match(double const& matchee) const override;
2592  std::string describe() const override;
2593  private:
2594  double m_target;
2595  double m_margin;
2596  };
2597 
2598  struct WithinUlpsMatcher : MatcherBase<double> {
2599  WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType);
2600  bool match(double const& matchee) const override;
2601  std::string describe() const override;
2602  private:
2603  double m_target;
2604  int m_ulps;
2605  FloatingPointKind m_type;
2606  };
2607 
2608  } // namespace Floating
2609 
2610  // The following functions create the actual matcher objects.
2611  // This allows the types to be inferred
2612  Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff);
2613  Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff);
2614  Floating::WithinAbsMatcher WithinAbs(double target, double margin);
2615 
2616 } // namespace Matchers
2617 } // namespace Catch
2618 
2619 // end catch_matchers_floating.h
2620 // start catch_matchers_generic.hpp
2621 
2622 #include <functional>
2623 #include <string>
2624 
2625 namespace Catch {
2626 namespace Matchers {
2627 namespace Generic {
2628 
2629 namespace Detail {
2630  std::string finalizeDescription(const std::string& desc);
2631 }
2632 
2633 template <typename T>
2634 class PredicateMatcher : public MatcherBase<T> {
2635  std::function<bool(T const&)> m_predicate;
2636  std::string m_description;
2637 public:
2638 
2639  PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr)
2640  :m_predicate(std::move(elem)),
2641  m_description(Detail::finalizeDescription(descr))
2642  {}
2643 
2644  bool match( T const& item ) const override {
2645  return m_predicate(item);
2646  }
2647 
2648  std::string describe() const override {
2649  return m_description;
2650  }
2651 };
2652 
2653 } // namespace Generic
2654 
2655  // The following functions create the actual matcher objects.
2656  // The user has to explicitly specify type to the function, because
2657  // infering std::function<bool(T const&)> is hard (but possible) and
2658  // requires a lot of TMP.
2659  template<typename T>
2660  Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") {
2661  return Generic::PredicateMatcher<T>(predicate, description);
2662  }
2663 
2664 } // namespace Matchers
2665 } // namespace Catch
2666 
2667 // end catch_matchers_generic.hpp
2668 // start catch_matchers_string.h
2669 
2670 #include <string>
2671 
2672 namespace Catch {
2673 namespace Matchers {
2674 
2675  namespace StdString {
2676 
2678  {
2679  CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );
2680  std::string adjustString( std::string const& str ) const;
2681  std::string caseSensitivitySuffix() const;
2682 
2684  std::string m_str;
2685  };
2686 
2687  struct StringMatcherBase : MatcherBase<std::string> {
2688  StringMatcherBase( std::string const& operation, CasedString const& comparator );
2689  std::string describe() const override;
2690 
2692  std::string m_operation;
2693  };
2694 
2696  EqualsMatcher( CasedString const& comparator );
2697  bool match( std::string const& source ) const override;
2698  };
2700  ContainsMatcher( CasedString const& comparator );
2701  bool match( std::string const& source ) const override;
2702  };
2704  StartsWithMatcher( CasedString const& comparator );
2705  bool match( std::string const& source ) const override;
2706  };
2708  EndsWithMatcher( CasedString const& comparator );
2709  bool match( std::string const& source ) const override;
2710  };
2711 
2712  struct RegexMatcher : MatcherBase<std::string> {
2713  RegexMatcher( std::string regex, CaseSensitive::Choice caseSensitivity );
2714  bool match( std::string const& matchee ) const override;
2715  std::string describe() const override;
2716 
2717  private:
2718  std::string m_regex;
2720  };
2721 
2722  } // namespace StdString
2723 
2724  // The following functions create the actual matcher objects.
2725  // This allows the types to be inferred
2726 
2727  StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
2728  StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
2729  StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
2730  StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
2731  StdString::RegexMatcher Matches( std::string const& regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
2732 
2733 } // namespace Matchers
2734 } // namespace Catch
2735 
2736 // end catch_matchers_string.h
2737 // start catch_matchers_vector.h
2738 
2739 #include <algorithm>
2740 
2741 namespace Catch {
2742 namespace Matchers {
2743 
2744  namespace Vector {
2745  namespace Detail {
2746  template <typename InputIterator, typename T>
2747  size_t count(InputIterator first, InputIterator last, T const& item) {
2748  size_t cnt = 0;
2749  for (; first != last; ++first) {
2750  if (*first == item) {
2751  ++cnt;
2752  }
2753  }
2754  return cnt;
2755  }
2756  template <typename InputIterator, typename T>
2757  bool contains(InputIterator first, InputIterator last, T const& item) {
2758  for (; first != last; ++first) {
2759  if (*first == item) {
2760  return true;
2761  }
2762  }
2763  return false;
2764  }
2765  }
2766 
2767  template<typename T>
2768  struct ContainsElementMatcher : MatcherBase<std::vector<T>> {
2769 
2770  ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
2771 
2772  bool match(std::vector<T> const &v) const override {
2773  for (auto const& el : v) {
2774  if (el == m_comparator) {
2775  return true;
2776  }
2777  }
2778  return false;
2779  }
2780 
2781  std::string describe() const override {
2782  return "Contains: " + ::Catch::Detail::stringify( m_comparator );
2783  }
2784 
2785  T const& m_comparator;
2786  };
2787 
2788  template<typename T>
2789  struct ContainsMatcher : MatcherBase<std::vector<T>> {
2790 
2791  ContainsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
2792 
2793  bool match(std::vector<T> const &v) const override {
2794  // !TBD: see note in EqualsMatcher
2795  if (m_comparator.size() > v.size())
2796  return false;
2797  for (auto const& comparator : m_comparator) {
2798  auto present = false;
2799  for (const auto& el : v) {
2800  if (el == comparator) {
2801  present = true;
2802  break;
2803  }
2804  }
2805  if (!present) {
2806  return false;
2807  }
2808  }
2809  return true;
2810  }
2811  std::string describe() const override {
2812  return "Contains: " + ::Catch::Detail::stringify( m_comparator );
2813  }
2814 
2815  std::vector<T> const& m_comparator;
2816  };
2817 
2818  template<typename T>
2819  struct EqualsMatcher : MatcherBase<std::vector<T>> {
2820 
2821  EqualsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
2822 
2823  bool match(std::vector<T> const &v) const override {
2824  // !TBD: This currently works if all elements can be compared using !=
2825  // - a more general approach would be via a compare template that defaults
2826  // to using !=. but could be specialised for, e.g. std::vector<T> etc
2827  // - then just call that directly
2828  if (m_comparator.size() != v.size())
2829  return false;
2830  for (std::size_t i = 0; i < v.size(); ++i)
2831  if (m_comparator[i] != v[i])
2832  return false;
2833  return true;
2834  }
2835  std::string describe() const override {
2836  return "Equals: " + ::Catch::Detail::stringify( m_comparator );
2837  }
2838  std::vector<T> const& m_comparator;
2839  };
2840 
2841  template<typename T>
2842  struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>> {
2843  UnorderedEqualsMatcher(std::vector<T> const& target) : m_target(target) {}
2844  bool match(std::vector<T> const& vec) const override {
2845  // Note: This is a reimplementation of std::is_permutation,
2846  // because I don't want to include <algorithm> inside the common path
2847  if (m_target.size() != vec.size()) {
2848  return false;
2849  }
2850  auto lfirst = m_target.begin(), llast = m_target.end();
2851  auto rfirst = vec.begin(), rlast = vec.end();
2852  // Cut common prefix to optimize checking of permuted parts
2853  while (lfirst != llast && *lfirst == *rfirst) {
2854  ++lfirst; ++rfirst;
2855  }
2856  if (lfirst == llast) {
2857  return true;
2858  }
2859 
2860  for (auto mid = lfirst; mid != llast; ++mid) {
2861  // Skip already counted items
2862  if (Detail::contains(lfirst, mid, *mid)) {
2863  continue;
2864  }
2865  size_t num_vec = Detail::count(rfirst, rlast, *mid);
2866  if (num_vec == 0 || Detail::count(lfirst, llast, *mid) != num_vec) {
2867  return false;
2868  }
2869  }
2870 
2871  return true;
2872  }
2873 
2874  std::string describe() const override {
2875  return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
2876  }
2877  private:
2878  std::vector<T> const& m_target;
2879  };
2880 
2881  } // namespace Vector
2882 
2883  // The following functions create the actual matcher objects.
2884  // This allows the types to be inferred
2885 
2886  template<typename T>
2887  Vector::ContainsMatcher<T> Contains( std::vector<T> const& comparator ) {
2888  return Vector::ContainsMatcher<T>( comparator );
2889  }
2890 
2891  template<typename T>
2893  return Vector::ContainsElementMatcher<T>( comparator );
2894  }
2895 
2896  template<typename T>
2897  Vector::EqualsMatcher<T> Equals( std::vector<T> const& comparator ) {
2898  return Vector::EqualsMatcher<T>( comparator );
2899  }
2900 
2901  template<typename T>
2902  Vector::UnorderedEqualsMatcher<T> UnorderedEquals(std::vector<T> const& target) {
2903  return Vector::UnorderedEqualsMatcher<T>(target);
2904  }
2905 
2906 } // namespace Matchers
2907 } // namespace Catch
2908 
2909 // end catch_matchers_vector.h
2910 namespace Catch {
2911 
2912  template<typename ArgT, typename MatcherT>
2914  ArgT const& m_arg;
2915  MatcherT m_matcher;
2917  public:
2918  MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString )
2919  : ITransientExpression{ true, matcher.match( arg ) },
2920  m_arg( arg ),
2921  m_matcher( matcher ),
2922  m_matcherString( matcherString )
2923  {}
2924 
2925  void streamReconstructedExpression( std::ostream &os ) const override {
2926  auto matcherAsString = m_matcher.toString();
2927  os << Catch::Detail::stringify( m_arg ) << ' ';
2928  if( matcherAsString == Detail::unprintableString )
2929  os << m_matcherString;
2930  else
2931  os << matcherAsString;
2932  }
2933  };
2934 
2936 
2937  void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString );
2938 
2939  template<typename ArgT, typename MatcherT>
2940  auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString ) -> MatchExpr<ArgT, MatcherT> {
2941  return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );
2942  }
2943 
2944 } // namespace Catch
2945 
2947 #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
2948  do { \
2949  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
2950  INTERNAL_CATCH_TRY { \
2951  catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \
2952  } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
2953  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2954  } while( false )
2955 
2957 #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
2958  do { \
2959  Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
2960  if( catchAssertionHandler.allowThrows() ) \
2961  try { \
2962  static_cast<void>(__VA_ARGS__ ); \
2963  catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
2964  } \
2965  catch( exceptionType const& ex ) { \
2966  catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \
2967  } \
2968  catch( ... ) { \
2969  catchAssertionHandler.handleUnexpectedInflightException(); \
2970  } \
2971  else \
2972  catchAssertionHandler.handleThrowingCallSkipped(); \
2973  INTERNAL_CATCH_REACT( catchAssertionHandler ) \
2974  } while( false )
2975 
2976 // end catch_capture_matchers.h
2977 #endif
2978 // start catch_generators.hpp
2979 
2980 // start catch_interfaces_generatortracker.h
2981 
2982 
2983 #include <memory>
2984 
2985 namespace Catch {
2986 
2987  namespace Generators {
2989  protected:
2990  size_t m_size = 0;
2991 
2992  public:
2993  GeneratorBase( size_t size ) : m_size( size ) {}
2994  virtual ~GeneratorBase();
2995  auto size() const -> size_t { return m_size; }
2996  };
2997  using GeneratorBasePtr = std::unique_ptr<GeneratorBase>;
2998 
2999  } // namespace Generators
3000 
3002  virtual ~IGeneratorTracker();
3003  virtual auto hasGenerator() const -> bool = 0;
3004  virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;
3005  virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0;
3006  virtual auto getIndex() const -> std::size_t = 0;
3007  };
3008 
3009 } // namespace Catch
3010 
3011 // end catch_interfaces_generatortracker.h
3012 // start catch_enforce.h
3013 
3014 #include <stdexcept>
3015 
3016 namespace Catch {
3017 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
3018  template <typename Ex>
3019  [[noreturn]]
3020  void throw_exception(Ex const& e) {
3021  throw e;
3022  }
3023 #else // ^^ Exceptions are enabled // Exceptions are disabled vv
3024  [[noreturn]]
3025  void throw_exception(std::exception const& e);
3026 #endif
3027 } // namespace Catch;
3028 
3029 #define CATCH_PREPARE_EXCEPTION( type, msg ) \
3030  type( ( Catch::ReusableStringStream() << msg ).str() )
3031 #define CATCH_INTERNAL_ERROR( msg ) \
3032  Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg))
3033 #define CATCH_ERROR( msg ) \
3034  Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::domain_error, msg ))
3035 #define CATCH_RUNTIME_ERROR( msg ) \
3036  Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::runtime_error, msg ))
3037 #define CATCH_ENFORCE( condition, msg ) \
3038  do{ if( !(condition) ) CATCH_ERROR( msg ); } while(false)
3039 
3040 // end catch_enforce.h
3041 #include <memory>
3042 #include <vector>
3043 #include <cassert>
3044 
3045 #include <utility>
3046 
3047 namespace Catch {
3048 namespace Generators {
3049 
3050  // !TBD move this into its own location?
3051  namespace pf{
3052  template<typename T, typename... Args>
3053  std::unique_ptr<T> make_unique( Args&&... args ) {
3054  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
3055  }
3056  }
3057 
3058  template<typename T>
3059  struct IGenerator {
3060  virtual ~IGenerator() {}
3061  virtual auto get( size_t index ) const -> T = 0;
3062  };
3063 
3064  template<typename T>
3065  class SingleValueGenerator : public IGenerator<T> {
3067  public:
3068  SingleValueGenerator( T const& value ) : m_value( value ) {}
3069 
3070  auto get( size_t ) const -> T override {
3071  return m_value;
3072  }
3073  };
3074 
3075  template<typename T>
3076  class FixedValuesGenerator : public IGenerator<T> {
3077  std::vector<T> m_values;
3078 
3079  public:
3080  FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {}
3081 
3082  auto get( size_t index ) const -> T override {
3083  return m_values[index];
3084  }
3085  };
3086 
3087  template<typename T>
3088  class RangeGenerator : public IGenerator<T> {
3089  T const m_first;
3090  T const m_last;
3091 
3092  public:
3093  RangeGenerator( T const& first, T const& last ) : m_first( first ), m_last( last ) {
3094  assert( m_last > m_first );
3095  }
3096 
3097  auto get( size_t index ) const -> T override {
3098  // ToDo:: introduce a safe cast to catch potential overflows
3099  return static_cast<T>(m_first+index);
3100  }
3101  };
3102 
3103  template<typename T>
3105  auto get( size_t ) const -> T override {
3106  CATCH_INTERNAL_ERROR("A Null Generator is always empty");
3107  }
3108  };
3109 
3110  template<typename T>
3111  class Generator {
3112  std::unique_ptr<IGenerator<T>> m_generator;
3113  size_t m_size;
3114 
3115  public:
3116  Generator( size_t size, std::unique_ptr<IGenerator<T>> generator )
3117  : m_generator( std::move( generator ) ),
3118  m_size( size )
3119  {}
3120 
3121  auto size() const -> size_t { return m_size; }
3122  auto operator[]( size_t index ) const -> T {
3123  assert( index < m_size );
3124  return m_generator->get( index );
3125  }
3126  };
3127 
3128  std::vector<size_t> randomiseIndices( size_t selectionSize, size_t sourceSize );
3129 
3130  template<typename T>
3131  class GeneratorRandomiser : public IGenerator<T> {
3133 
3134  std::vector<size_t> m_indices;
3135  public:
3136  GeneratorRandomiser( Generator<T>&& baseGenerator, size_t numberOfItems )
3137  : m_baseGenerator( std::move( baseGenerator ) ),
3138  m_indices( randomiseIndices( numberOfItems, m_baseGenerator.size() ) )
3139  {}
3140 
3141  auto get( size_t index ) const -> T override {
3142  return m_baseGenerator[m_indices[index]];
3143  }
3144  };
3145 
3146  template<typename T>
3148 
3149  template<typename T>
3151 
3152  template<>
3153  auto all<int>() -> Generator<int>;
3154 
3155  template<typename T>
3156  auto range( T const& first, T const& last ) -> Generator<T> {
3157  return Generator<T>( (last-first), pf::make_unique<RangeGenerator<T>>( first, last ) );
3158  }
3159 
3160  template<typename T>
3161  auto random( T const& first, T const& last ) -> Generator<T> {
3162  auto gen = range( first, last );
3163  auto size = gen.size();
3164 
3165  return Generator<T>( size, pf::make_unique<GeneratorRandomiser<T>>( std::move( gen ), size ) );
3166  }
3167  template<typename T>
3168  auto random( size_t size ) -> Generator<T> {
3169  return Generator<T>( size, pf::make_unique<GeneratorRandomiser<T>>( all<T>(), size ) );
3170  }
3171 
3172  template<typename T>
3173  auto values( std::initializer_list<T> values ) -> Generator<T> {
3174  return Generator<T>( values.size(), pf::make_unique<FixedValuesGenerator<T>>( values ) );
3175  }
3176  template<typename T>
3177  auto value( T const& val ) -> Generator<T> {
3178  return Generator<T>( 1, pf::make_unique<SingleValueGenerator<T>>( val ) );
3179  }
3180 
3181  template<typename T>
3182  auto as() -> Generator<T> {
3183  return Generator<T>( 0, pf::make_unique<NullGenerator<T>>() );
3184  }
3185 
3186  template<typename... Ts>
3187  auto table( std::initializer_list<std::tuple<Ts...>>&& tuples ) -> Generator<std::tuple<Ts...>> {
3188  return values<std::tuple<Ts...>>( std::forward<std::initializer_list<std::tuple<Ts...>>>( tuples ) );
3189  }
3190 
3191  template<typename T>
3193  std::vector<Generator<T>> m_generators;
3194 
3195  using type = T;
3196 
3198 
3199  void populate( T&& val ) {
3200  m_size += 1;
3201  m_generators.emplace_back( value( std::move( val ) ) );
3202  }
3203  template<typename U>
3204  void populate( U&& val ) {
3205  populate( T( std::move( val ) ) );
3206  }
3207  void populate( Generator<T>&& generator ) {
3208  m_size += generator.size();
3209  m_generators.emplace_back( std::move( generator ) );
3210  }
3211 
3212  template<typename U, typename... Gs>
3213  void populate( U&& valueOrGenerator, Gs... moreGenerators ) {
3214  populate( std::forward<U>( valueOrGenerator ) );
3215  populate( std::forward<Gs>( moreGenerators )... );
3216  }
3217 
3218  auto operator[]( size_t index ) const -> T {
3219  size_t sizes = 0;
3220  for( auto const& gen : m_generators ) {
3221  auto localIndex = index-sizes;
3222  sizes += gen.size();
3223  if( index < sizes )
3224  return gen[localIndex];
3225  }
3226  CATCH_INTERNAL_ERROR("Index '" << index << "' is out of range (" << sizes << ')');
3227  }
3228  };
3229 
3230  template<typename T, typename... Gs>
3231  auto makeGenerators( Generator<T>&& generator, Gs... moreGenerators ) -> Generators<T> {
3232  Generators<T> generators;
3233  generators.m_generators.reserve( 1+sizeof...(Gs) );
3234  generators.populate( std::move( generator ), std::forward<Gs>( moreGenerators )... );
3235  return generators;
3236  }
3237  template<typename T>
3238  auto makeGenerators( Generator<T>&& generator ) -> Generators<T> {
3239  Generators<T> generators;
3240  generators.populate( std::move( generator ) );
3241  return generators;
3242  }
3243  template<typename T, typename... Gs>
3244  auto makeGenerators( T&& val, Gs... moreGenerators ) -> Generators<T> {
3245  return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );
3246  }
3247  template<typename T, typename U, typename... Gs>
3248  auto makeGenerators( U&& val, Gs... moreGenerators ) -> Generators<T> {
3249  return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );
3250  }
3251 
3252  auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
3253 
3254  template<typename L>
3255  // Note: The type after -> is weird, because VS2015 cannot parse
3256  // the expression used in the typedef inside, when it is in
3257  // return type. Yeah, ¯\_(ツ)_/¯
3258  auto generate( SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>()[0]) {
3259  using UnderlyingType = typename decltype(generatorExpression())::type;
3260 
3261  IGeneratorTracker& tracker = acquireGeneratorTracker( lineInfo );
3262  if( !tracker.hasGenerator() )
3263  tracker.setGenerator( pf::make_unique<Generators<UnderlyingType>>( generatorExpression() ) );
3264 
3265  auto const& generator = static_cast<Generators<UnderlyingType> const&>( *tracker.getGenerator() );
3266  return generator[tracker.getIndex()];
3267  }
3268 
3269 } // namespace Generators
3270 } // namespace Catch
3271 
3272 #define GENERATE( ... ) \
3273  Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, []{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
3274 
3275 // end catch_generators.hpp
3276 
3277 // These files are included here so the single_include script doesn't put them
3278 // in the conditionally compiled sections
3279 // start catch_test_case_info.h
3280 
3281 #include <string>
3282 #include <vector>
3283 #include <memory>
3284 
3285 #ifdef __clang__
3286 #pragma clang diagnostic push
3287 #pragma clang diagnostic ignored "-Wpadded"
3288 #endif
3289 
3290 namespace Catch {
3291 
3292  struct ITestInvoker;
3293 
3294  struct TestCaseInfo {
3296  None = 0,
3297  IsHidden = 1 << 1,
3298  ShouldFail = 1 << 2,
3299  MayFail = 1 << 3,
3300  Throws = 1 << 4,
3301  NonPortable = 1 << 5,
3302  Benchmark = 1 << 6
3303  };
3304 
3305  TestCaseInfo( std::string const& _name,
3306  std::string const& _className,
3307  std::string const& _description,
3308  std::vector<std::string> const& _tags,
3309  SourceLineInfo const& _lineInfo );
3310 
3311  friend void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags );
3312 
3313  bool isHidden() const;
3314  bool throws() const;
3315  bool okToFail() const;
3316  bool expectedToFail() const;
3317 
3318  std::string tagsAsString() const;
3319 
3320  std::string name;
3321  std::string className;
3322  std::string description;
3323  std::vector<std::string> tags;
3324  std::vector<std::string> lcaseTags;
3327  };
3328 
3329  class TestCase : public TestCaseInfo {
3330  public:
3331 
3332  TestCase( ITestInvoker* testCase, TestCaseInfo&& info );
3333 
3334  TestCase withName( std::string const& _newName ) const;
3335 
3336  void invoke() const;
3337 
3338  TestCaseInfo const& getTestCaseInfo() const;
3339 
3340  bool operator == ( TestCase const& other ) const;
3341  bool operator < ( TestCase const& other ) const;
3342 
3343  private:
3344  std::shared_ptr<ITestInvoker> test;
3345  };
3346 
3347  TestCase makeTestCase( ITestInvoker* testCase,
3348  std::string const& className,
3349  NameAndTags const& nameAndTags,
3350  SourceLineInfo const& lineInfo );
3351 }
3352 
3353 #ifdef __clang__
3354 #pragma clang diagnostic pop
3355 #endif
3356 
3357 // end catch_test_case_info.h
3358 // start catch_interfaces_runner.h
3359 
3360 namespace Catch {
3361 
3362  struct IRunner {
3363  virtual ~IRunner();
3364  virtual bool aborting() const = 0;
3365  };
3366 }
3367 
3368 // end catch_interfaces_runner.h
3369 
3370 #ifdef __OBJC__
3371 // start catch_objc.hpp
3372 
3373 #import <objc/runtime.h>
3374 
3375 #include <string>
3376 
3377 // NB. Any general catch headers included here must be included
3378 // in catch.hpp first to make sure they are included by the single
3379 // header for non obj-usage
3380 
3382 // This protocol is really only here for (self) documenting purposes, since
3383 // all its methods are optional.
3384 @protocol OcFixture
3385 
3386 @optional
3387 
3388 -(void) setUp;
3389 -(void) tearDown;
3390 
3391 @end
3392 
3393 namespace Catch {
3394 
3395  class OcMethod : public ITestInvoker {
3396 
3397  public:
3398  OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
3399 
3400  virtual void invoke() const {
3401  id obj = [[m_cls alloc] init];
3402 
3403  performOptionalSelector( obj, @selector(setUp) );
3404  performOptionalSelector( obj, m_sel );
3405  performOptionalSelector( obj, @selector(tearDown) );
3406 
3407  arcSafeRelease( obj );
3408  }
3409  private:
3410  virtual ~OcMethod() {}
3411 
3412  Class m_cls;
3413  SEL m_sel;
3414  };
3415 
3416  namespace Detail{
3417 
3418  inline std::string getAnnotation( Class cls,
3419  std::string const& annotationName,
3420  std::string const& testCaseName ) {
3421  NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
3422  SEL sel = NSSelectorFromString( selStr );
3423  arcSafeRelease( selStr );
3424  id value = performOptionalSelector( cls, sel );
3425  if( value )
3426  return [(NSString*)value UTF8String];
3427  return "";
3428  }
3429  }
3430 
3431  inline std::size_t registerTestMethods() {
3432  std::size_t noTestMethods = 0;
3433  int noClasses = objc_getClassList( nullptr, 0 );
3434 
3435  Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
3436  objc_getClassList( classes, noClasses );
3437 
3438  for( int c = 0; c < noClasses; c++ ) {
3439  Class cls = classes[c];
3440  {
3441  u_int count;
3442  Method* methods = class_copyMethodList( cls, &count );
3443  for( u_int m = 0; m < count ; m++ ) {
3444  SEL selector = method_getName(methods[m]);
3445  std::string methodName = sel_getName(selector);
3446  if( startsWith( methodName, "Catch_TestCase_" ) ) {
3447  std::string testCaseName = methodName.substr( 15 );
3448  std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
3449  std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
3450  const char* className = class_getName( cls );
3451 
3452  getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo("",0) ) );
3453  noTestMethods++;
3454  }
3455  }
3456  free(methods);
3457  }
3458  }
3459  return noTestMethods;
3460  }
3461 
3462 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
3463 
3464  namespace Matchers {
3465  namespace Impl {
3466  namespace NSStringMatchers {
3467 
3468  struct StringHolder : MatcherBase<NSString*>{
3469  StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
3470  StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
3471  StringHolder() {
3472  arcSafeRelease( m_substr );
3473  }
3474 
3475  bool match( NSString* arg ) const override {
3476  return false;
3477  }
3478 
3479  NSString* CATCH_ARC_STRONG m_substr;
3480  };
3481 
3482  struct Equals : StringHolder {
3483  Equals( NSString* substr ) : StringHolder( substr ){}
3484 
3485  bool match( NSString* str ) const override {
3486  return (str != nil || m_substr == nil ) &&
3487  [str isEqualToString:m_substr];
3488  }
3489 
3490  std::string describe() const override {
3491  return "equals string: " + Catch::Detail::stringify( m_substr );
3492  }
3493  };
3494 
3495  struct Contains : StringHolder {
3496  Contains( NSString* substr ) : StringHolder( substr ){}
3497 
3498  bool match( NSString* str ) const {
3499  return (str != nil || m_substr == nil ) &&
3500  [str rangeOfString:m_substr].location != NSNotFound;
3501  }
3502 
3503  std::string describe() const override {
3504  return "contains string: " + Catch::Detail::stringify( m_substr );
3505  }
3506  };
3507 
3508  struct StartsWith : StringHolder {
3509  StartsWith( NSString* substr ) : StringHolder( substr ){}
3510 
3511  bool match( NSString* str ) const override {
3512  return (str != nil || m_substr == nil ) &&
3513  [str rangeOfString:m_substr].location == 0;
3514  }
3515 
3516  std::string describe() const override {
3517  return "starts with: " + Catch::Detail::stringify( m_substr );
3518  }
3519  };
3520  struct EndsWith : StringHolder {
3521  EndsWith( NSString* substr ) : StringHolder( substr ){}
3522 
3523  bool match( NSString* str ) const override {
3524  return (str != nil || m_substr == nil ) &&
3525  [str rangeOfString:m_substr].location == [str length] - [m_substr length];
3526  }
3527 
3528  std::string describe() const override {
3529  return "ends with: " + Catch::Detail::stringify( m_substr );
3530  }
3531  };
3532 
3533  } // namespace NSStringMatchers
3534  } // namespace Impl
3535 
3537  Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
3538 
3540  Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
3541 
3543  StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
3544 
3546  EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
3547 
3548  } // namespace Matchers
3549 
3550  using namespace Matchers;
3551 
3552 #endif // CATCH_CONFIG_DISABLE_MATCHERS
3553 
3554 } // namespace Catch
3555 
3557 #define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix
3558 #define OC_TEST_CASE2( name, desc, uniqueSuffix ) \
3559 +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \
3560 { \
3561 return @ name; \
3562 } \
3563 +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \
3564 { \
3565 return @ desc; \
3566 } \
3567 -(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix )
3568 
3569 #define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ )
3570 
3571 // end catch_objc.hpp
3572 #endif
3573 
3574 #ifdef CATCH_CONFIG_EXTERNAL_INTERFACES
3575 // start catch_external_interfaces.h
3576 
3577 // start catch_reporter_bases.hpp
3578 
3579 // start catch_interfaces_reporter.h
3580 
3581 // start catch_config.hpp
3582 
3583 // start catch_test_spec_parser.h
3584 
3585 #ifdef __clang__
3586 #pragma clang diagnostic push
3587 #pragma clang diagnostic ignored "-Wpadded"
3588 #endif
3589 
3590 // start catch_test_spec.h
3591 
3592 #ifdef __clang__
3593 #pragma clang diagnostic push
3594 #pragma clang diagnostic ignored "-Wpadded"
3595 #endif
3596 
3597 // start catch_wildcard_pattern.h
3598 
3599 namespace Catch
3600 {
3601  class WildcardPattern {
3602  enum WildcardPosition {
3603  NoWildcard = 0,
3604  WildcardAtStart = 1,
3605  WildcardAtEnd = 2,
3606  WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
3607  };
3608 
3609  public:
3610 
3611  WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity );
3612  virtual ~WildcardPattern() = default;
3613  virtual bool matches( std::string const& str ) const;
3614 
3615  private:
3616  std::string adjustCase( std::string const& str ) const;
3617  CaseSensitive::Choice m_caseSensitivity;
3618  WildcardPosition m_wildcard = NoWildcard;
3619  std::string m_pattern;
3620  };
3621 }
3622 
3623 // end catch_wildcard_pattern.h
3624 #include <string>
3625 #include <vector>
3626 #include <memory>
3627 
3628 namespace Catch {
3629 
3630  class TestSpec {
3631  struct Pattern {
3632  virtual ~Pattern();
3633  virtual bool matches( TestCaseInfo const& testCase ) const = 0;
3634  };
3635  using PatternPtr = std::shared_ptr<Pattern>;
3636 
3637  class NamePattern : public Pattern {
3638  public:
3639  NamePattern( std::string const& name );
3640  virtual ~NamePattern();
3641  virtual bool matches( TestCaseInfo const& testCase ) const override;
3642  private:
3643  WildcardPattern m_wildcardPattern;
3644  };
3645 
3646  class TagPattern : public Pattern {
3647  public:
3648  TagPattern( std::string const& tag );
3649  virtual ~TagPattern();
3650  virtual bool matches( TestCaseInfo const& testCase ) const override;
3651  private:
3652  std::string m_tag;
3653  };
3654 
3655  class ExcludedPattern : public Pattern {
3656  public:
3657  ExcludedPattern( PatternPtr const& underlyingPattern );
3658  virtual ~ExcludedPattern();
3659  virtual bool matches( TestCaseInfo const& testCase ) const override;
3660  private:
3661  PatternPtr m_underlyingPattern;
3662  };
3663 
3664  struct Filter {
3665  std::vector<PatternPtr> m_patterns;
3666 
3667  bool matches( TestCaseInfo const& testCase ) const;
3668  };
3669 
3670  public:
3671  bool hasFilters() const;
3672  bool matches( TestCaseInfo const& testCase ) const;
3673 
3674  private:
3675  std::vector<Filter> m_filters;
3676 
3677  friend class TestSpecParser;
3678  };
3679 }
3680 
3681 #ifdef __clang__
3682 #pragma clang diagnostic pop
3683 #endif
3684 
3685 // end catch_test_spec.h
3686 // start catch_interfaces_tag_alias_registry.h
3687 
3688 #include <string>
3689 
3690 namespace Catch {
3691 
3692  struct TagAlias;
3693 
3694  struct ITagAliasRegistry {
3695  virtual ~ITagAliasRegistry();
3696  // Nullptr if not present
3697  virtual TagAlias const* find( std::string const& alias ) const = 0;
3698  virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
3699 
3700  static ITagAliasRegistry const& get();
3701  };
3702 
3703 } // end namespace Catch
3704 
3705 // end catch_interfaces_tag_alias_registry.h
3706 namespace Catch {
3707 
3708  class TestSpecParser {
3709  enum Mode{ None, Name, QuotedName, Tag, EscapedName };
3710  Mode m_mode = None;
3711  bool m_exclusion = false;
3712  std::size_t m_start = std::string::npos, m_pos = 0;
3713  std::string m_arg;
3714  std::vector<std::size_t> m_escapeChars;
3715  TestSpec::Filter m_currentFilter;
3716  TestSpec m_testSpec;
3717  ITagAliasRegistry const* m_tagAliases = nullptr;
3718 
3719  public:
3720  TestSpecParser( ITagAliasRegistry const& tagAliases );
3721 
3722  TestSpecParser& parse( std::string const& arg );
3723  TestSpec testSpec();
3724 
3725  private:
3726  void visitChar( char c );
3727  void startNewMode( Mode mode, std::size_t start );
3728  void escape();
3729  std::string subString() const;
3730 
3731  template<typename T>
3732  void addPattern() {
3733  std::string token = subString();
3734  for( std::size_t i = 0; i < m_escapeChars.size(); ++i )
3735  token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 );
3736  m_escapeChars.clear();
3737  if( startsWith( token, "exclude:" ) ) {
3738  m_exclusion = true;
3739  token = token.substr( 8 );
3740  }
3741  if( !token.empty() ) {
3742  TestSpec::PatternPtr pattern = std::make_shared<T>( token );
3743  if( m_exclusion )
3744  pattern = std::make_shared<TestSpec::ExcludedPattern>( pattern );
3745  m_currentFilter.m_patterns.push_back( pattern );
3746  }
3747  m_exclusion = false;
3748  m_mode = None;
3749  }
3750 
3751  void addFilter();
3752  };
3753  TestSpec parseTestSpec( std::string const& arg );
3754 
3755 } // namespace Catch
3756 
3757 #ifdef __clang__
3758 #pragma clang diagnostic pop
3759 #endif
3760 
3761 // end catch_test_spec_parser.h
3762 // start catch_interfaces_config.h
3763 
3764 #include <iosfwd>
3765 #include <string>
3766 #include <vector>
3767 #include <memory>
3768 
3769 namespace Catch {
3770 
3771  enum class Verbosity {
3772  Quiet = 0,
3773  Normal,
3774  High
3775  };
3776 
3777  struct WarnAbout { enum What {
3778  Nothing = 0x00,
3779  NoAssertions = 0x01,
3780  NoTests = 0x02
3781  }; };
3782 
3783  struct ShowDurations { enum OrNot {
3784  DefaultForReporter,
3785  Always,
3786  Never
3787  }; };
3788  struct RunTests { enum InWhatOrder {
3789  InDeclarationOrder,
3790  InLexicographicalOrder,
3791  InRandomOrder
3792  }; };
3793  struct UseColour { enum YesOrNo {
3794  Auto,
3795  Yes,
3796  No
3797  }; };
3798  struct WaitForKeypress { enum When {
3799  Never,
3800  BeforeStart = 1,
3801  BeforeExit = 2,
3802  BeforeStartAndExit = BeforeStart | BeforeExit
3803  }; };
3804 
3805  class TestSpec;
3806 
3807  struct IConfig : NonCopyable {
3808 
3809  virtual ~IConfig();
3810 
3811  virtual bool allowThrows() const = 0;
3812  virtual std::ostream& stream() const = 0;
3813  virtual std::string name() const = 0;
3814  virtual bool includeSuccessfulResults() const = 0;
3815  virtual bool shouldDebugBreak() const = 0;
3816  virtual bool warnAboutMissingAssertions() const = 0;
3817  virtual bool warnAboutNoTests() const = 0;
3818  virtual int abortAfter() const = 0;
3819  virtual bool showInvisibles() const = 0;
3820  virtual ShowDurations::OrNot showDurations() const = 0;
3821  virtual TestSpec const& testSpec() const = 0;
3822  virtual bool hasTestFilters() const = 0;
3823  virtual RunTests::InWhatOrder runOrder() const = 0;
3824  virtual unsigned int rngSeed() const = 0;
3825  virtual int benchmarkResolutionMultiple() const = 0;
3826  virtual UseColour::YesOrNo useColour() const = 0;
3827  virtual std::vector<std::string> const& getSectionsToRun() const = 0;
3828  virtual Verbosity verbosity() const = 0;
3829  };
3830 
3831  using IConfigPtr = std::shared_ptr<IConfig const>;
3832 }
3833 
3834 // end catch_interfaces_config.h
3835 // Libstdc++ doesn't like incomplete classes for unique_ptr
3836 
3837 #include <memory>
3838 #include <vector>
3839 #include <string>
3840 
3841 #ifndef CATCH_CONFIG_CONSOLE_WIDTH
3842 #define CATCH_CONFIG_CONSOLE_WIDTH 80
3843 #endif
3844 
3845 namespace Catch {
3846 
3847  struct IStream;
3848 
3849  struct ConfigData {
3850  bool listTests = false;
3851  bool listTags = false;
3852  bool listReporters = false;
3853  bool listTestNamesOnly = false;
3854 
3855  bool showSuccessfulTests = false;
3856  bool shouldDebugBreak = false;
3857  bool noThrow = false;
3858  bool showHelp = false;
3859  bool showInvisibles = false;
3860  bool filenamesAsTags = false;
3861  bool libIdentify = false;
3862 
3863  int abortAfter = -1;
3864  unsigned int rngSeed = 0;
3865  int benchmarkResolutionMultiple = 100;
3866 
3867  Verbosity verbosity = Verbosity::Normal;
3868  WarnAbout::What warnings = WarnAbout::Nothing;
3869  ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;
3870  RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;
3871  UseColour::YesOrNo useColour = UseColour::Auto;
3872  WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
3873 
3874  std::string outputFilename;
3875  std::string name;
3876  std::string processName;
3877 #ifndef CATCH_CONFIG_DEFAULT_REPORTER
3878 #define CATCH_CONFIG_DEFAULT_REPORTER "console"
3879 #endif
3880  std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER;
3881 #undef CATCH_CONFIG_DEFAULT_REPORTER
3882 
3883  std::vector<std::string> testsOrTags;
3884  std::vector<std::string> sectionsToRun;
3885  };
3886 
3887  class Config : public IConfig {
3888  public:
3889 
3890  Config() = default;
3891  Config( ConfigData const& data );
3892  virtual ~Config() = default;
3893 
3894  std::string const& getFilename() const;
3895 
3896  bool listTests() const;
3897  bool listTestNamesOnly() const;
3898  bool listTags() const;
3899  bool listReporters() const;
3900 
3901  std::string getProcessName() const;
3902  std::string const& getReporterName() const;
3903 
3904  std::vector<std::string> const& getTestsOrTags() const;
3905  std::vector<std::string> const& getSectionsToRun() const override;
3906 
3907  virtual TestSpec const& testSpec() const override;
3908  bool hasTestFilters() const override;
3909 
3910  bool showHelp() const;
3911 
3912  // IConfig interface
3913  bool allowThrows() const override;
3914  std::ostream& stream() const override;
3915  std::string name() const override;
3916  bool includeSuccessfulResults() const override;
3917  bool warnAboutMissingAssertions() const override;
3918  bool warnAboutNoTests() const override;
3919  ShowDurations::OrNot showDurations() const override;
3920  RunTests::InWhatOrder runOrder() const override;
3921  unsigned int rngSeed() const override;
3922  int benchmarkResolutionMultiple() const override;
3923  UseColour::YesOrNo useColour() const override;
3924  bool shouldDebugBreak() const override;
3925  int abortAfter() const override;
3926  bool showInvisibles() const override;
3927  Verbosity verbosity() const override;
3928 
3929  private:
3930 
3931  IStream const* openStream();
3932  ConfigData m_data;
3933 
3934  std::unique_ptr<IStream const> m_stream;
3935  TestSpec m_testSpec;
3936  bool m_hasTestFilters = false;
3937  };
3938 
3939 } // end namespace Catch
3940 
3941 // end catch_config.hpp
3942 // start catch_assertionresult.h
3943 
3944 #include <string>
3945 
3946 namespace Catch {
3947 
3948  struct AssertionResultData
3949  {
3950  AssertionResultData() = delete;
3951 
3952  AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression );
3953 
3954  std::string message;
3955  mutable std::string reconstructedExpression;
3956  LazyExpression lazyExpression;
3957  ResultWas::OfType resultType;
3958 
3959  std::string reconstructExpression() const;
3960  };
3961 
3962  class AssertionResult {
3963  public:
3964  AssertionResult() = delete;
3965  AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
3966 
3967  bool isOk() const;
3968  bool succeeded() const;
3969  ResultWas::OfType getResultType() const;
3970  bool hasExpression() const;
3971  bool hasMessage() const;
3972  std::string getExpression() const;
3973  std::string getExpressionInMacro() const;
3974  bool hasExpandedExpression() const;
3975  std::string getExpandedExpression() const;
3976  std::string getMessage() const;
3977  SourceLineInfo getSourceInfo() const;
3978  StringRef getTestMacroName() const;
3979 
3980  //protected:
3981  AssertionInfo m_info;
3982  AssertionResultData m_resultData;
3983  };
3984 
3985 } // end namespace Catch
3986 
3987 // end catch_assertionresult.h
3988 // start catch_option.hpp
3989 
3990 namespace Catch {
3991 
3992  // An optional type
3993  template<typename T>
3994  class Option {
3995  public:
3996  Option() : nullableValue( nullptr ) {}
3997  Option( T const& _value )
3998  : nullableValue( new( storage ) T( _value ) )
3999  {}
4000  Option( Option const& _other )
4001  : nullableValue( _other ? new( storage ) T( *_other ) : nullptr )
4002  {}
4003 
4004  ~Option() {
4005  reset();
4006  }
4007 
4008  Option& operator= ( Option const& _other ) {
4009  if( &_other != this ) {
4010  reset();
4011  if( _other )
4012  nullableValue = new( storage ) T( *_other );
4013  }
4014  return *this;
4015  }
4016  Option& operator = ( T const& _value ) {
4017  reset();
4018  nullableValue = new( storage ) T( _value );
4019  return *this;
4020  }
4021 
4022  void reset() {
4023  if( nullableValue )
4024  nullableValue->~T();
4025  nullableValue = nullptr;
4026  }
4027 
4028  T& operator*() { return *nullableValue; }
4029  T const& operator*() const { return *nullableValue; }
4030  T* operator->() { return nullableValue; }
4031  const T* operator->() const { return nullableValue; }
4032 
4033  T valueOr( T const& defaultValue ) const {
4034  return nullableValue ? *nullableValue : defaultValue;
4035  }
4036 
4037  bool some() const { return nullableValue != nullptr; }
4038  bool none() const { return nullableValue == nullptr; }
4039 
4040  bool operator !() const { return nullableValue == nullptr; }
4041  explicit operator bool() const {
4042  return some();
4043  }
4044 
4045  private:
4046  T *nullableValue;
4047  alignas(alignof(T)) char storage[sizeof(T)];
4048  };
4049 
4050 } // end namespace Catch
4051 
4052 // end catch_option.hpp
4053 #include <string>
4054 #include <iosfwd>
4055 #include <map>
4056 #include <set>
4057 #include <memory>
4058 
4059 namespace Catch {
4060 
4061  struct ReporterConfig {
4062  explicit ReporterConfig( IConfigPtr const& _fullConfig );
4063 
4064  ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream );
4065 
4066  std::ostream& stream() const;
4067  IConfigPtr fullConfig() const;
4068 
4069  private:
4070  std::ostream* m_stream;
4071  IConfigPtr m_fullConfig;
4072  };
4073 
4074  struct ReporterPreferences {
4075  bool shouldRedirectStdOut = false;
4076  bool shouldReportAllAssertions = false;
4077  };
4078 
4079  template<typename T>
4080  struct LazyStat : Option<T> {
4081  LazyStat& operator=( T const& _value ) {
4082  Option<T>::operator=( _value );
4083  used = false;
4084  return *this;
4085  }
4086  void reset() {
4087  Option<T>::reset();
4088  used = false;
4089  }
4090  bool used = false;
4091  };
4092 
4093  struct TestRunInfo {
4094  TestRunInfo( std::string const& _name );
4095  std::string name;
4096  };
4097  struct GroupInfo {
4098  GroupInfo( std::string const& _name,
4099  std::size_t _groupIndex,
4100  std::size_t _groupsCount );
4101 
4102  std::string name;
4103  std::size_t groupIndex;
4104  std::size_t groupsCounts;
4105  };
4106 
4107  struct AssertionStats {
4108  AssertionStats( AssertionResult const& _assertionResult,
4109  std::vector<MessageInfo> const& _infoMessages,
4110  Totals const& _totals );
4111 
4112  AssertionStats( AssertionStats const& ) = default;
4113  AssertionStats( AssertionStats && ) = default;
4114  AssertionStats& operator = ( AssertionStats const& ) = default;
4115  AssertionStats& operator = ( AssertionStats && ) = default;
4116  virtual ~AssertionStats();
4117 
4118  AssertionResult assertionResult;
4119  std::vector<MessageInfo> infoMessages;
4120  Totals totals;
4121  };
4122 
4123  struct SectionStats {
4124  SectionStats( SectionInfo const& _sectionInfo,
4125  Counts const& _assertions,
4126  double _durationInSeconds,
4127  bool _missingAssertions );
4128  SectionStats( SectionStats const& ) = default;
4129  SectionStats( SectionStats && ) = default;
4130  SectionStats& operator = ( SectionStats const& ) = default;
4131  SectionStats& operator = ( SectionStats && ) = default;
4132  virtual ~SectionStats();
4133 
4134  SectionInfo sectionInfo;
4135  Counts assertions;
4136  double durationInSeconds;
4137  bool missingAssertions;
4138  };
4139 
4140  struct TestCaseStats {
4141  TestCaseStats( TestCaseInfo const& _testInfo,
4142  Totals const& _totals,
4143  std::string const& _stdOut,
4144  std::string const& _stdErr,
4145  bool _aborting );
4146 
4147  TestCaseStats( TestCaseStats const& ) = default;
4148  TestCaseStats( TestCaseStats && ) = default;
4149  TestCaseStats& operator = ( TestCaseStats const& ) = default;
4150  TestCaseStats& operator = ( TestCaseStats && ) = default;
4151  virtual ~TestCaseStats();
4152 
4153  TestCaseInfo testInfo;
4154  Totals totals;
4155  std::string stdOut;
4156  std::string stdErr;
4157  bool aborting;
4158  };
4159 
4160  struct TestGroupStats {
4161  TestGroupStats( GroupInfo const& _groupInfo,
4162  Totals const& _totals,
4163  bool _aborting );
4164  TestGroupStats( GroupInfo const& _groupInfo );
4165 
4166  TestGroupStats( TestGroupStats const& ) = default;
4167  TestGroupStats( TestGroupStats && ) = default;
4168  TestGroupStats& operator = ( TestGroupStats const& ) = default;
4169  TestGroupStats& operator = ( TestGroupStats && ) = default;
4170  virtual ~TestGroupStats();
4171 
4172  GroupInfo groupInfo;
4173  Totals totals;
4174  bool aborting;
4175  };
4176 
4177  struct TestRunStats {
4178  TestRunStats( TestRunInfo const& _runInfo,
4179  Totals const& _totals,
4180  bool _aborting );
4181 
4182  TestRunStats( TestRunStats const& ) = default;
4183  TestRunStats( TestRunStats && ) = default;
4184  TestRunStats& operator = ( TestRunStats const& ) = default;
4185  TestRunStats& operator = ( TestRunStats && ) = default;
4186  virtual ~TestRunStats();
4187 
4188  TestRunInfo runInfo;
4189  Totals totals;
4190  bool aborting;
4191  };
4192 
4193  struct BenchmarkInfo {
4194  std::string name;
4195  };
4196  struct BenchmarkStats {
4197  BenchmarkInfo info;
4198  std::size_t iterations;
4199  uint64_t elapsedTimeInNanoseconds;
4200  };
4201 
4202  struct IStreamingReporter {
4203  virtual ~IStreamingReporter() = default;
4204 
4205  // Implementing class must also provide the following static methods:
4206  // static std::string getDescription();
4207  // static std::set<Verbosity> getSupportedVerbosities()
4208 
4209  virtual ReporterPreferences getPreferences() const = 0;
4210 
4211  virtual void noMatchingTestCases( std::string const& spec ) = 0;
4212 
4213  virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
4214  virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
4215 
4216  virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
4217  virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
4218 
4219  // *** experimental ***
4220  virtual void benchmarkStarting( BenchmarkInfo const& ) {}
4221 
4222  virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
4223 
4224  // The return value indicates if the messages buffer should be cleared:
4225  virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
4226 
4227  // *** experimental ***
4228  virtual void benchmarkEnded( BenchmarkStats const& ) {}
4229 
4230  virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
4231  virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
4232  virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
4233  virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
4234 
4235  virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
4236 
4237  // Default empty implementation provided
4238  virtual void fatalErrorEncountered( StringRef name );
4239 
4240  virtual bool isMulti() const;
4241  };
4242  using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>;
4243 
4244  struct IReporterFactory {
4245  virtual ~IReporterFactory();
4246  virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0;
4247  virtual std::string getDescription() const = 0;
4248  };
4249  using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;
4250 
4251  struct IReporterRegistry {
4252  using FactoryMap = std::map<std::string, IReporterFactoryPtr>;
4253  using Listeners = std::vector<IReporterFactoryPtr>;
4254 
4255  virtual ~IReporterRegistry();
4256  virtual IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const = 0;
4257  virtual FactoryMap const& getFactories() const = 0;
4258  virtual Listeners const& getListeners() const = 0;
4259  };
4260 
4261 } // end namespace Catch
4262 
4263 // end catch_interfaces_reporter.h
4264 #include <algorithm>
4265 #include <cstring>
4266 #include <cfloat>
4267 #include <cstdio>
4268 #include <cassert>
4269 #include <memory>
4270 #include <ostream>
4271 
4272 namespace Catch {
4273  void prepareExpandedExpression(AssertionResult& result);
4274 
4275  // Returns double formatted as %.3f (format expected on output)
4276  std::string getFormattedDuration( double duration );
4277 
4278  template<typename DerivedT>
4279  struct StreamingReporterBase : IStreamingReporter {
4280 
4281  StreamingReporterBase( ReporterConfig const& _config )
4282  : m_config( _config.fullConfig() ),
4283  stream( _config.stream() )
4284  {
4285  m_reporterPrefs.shouldRedirectStdOut = false;
4286  if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
4287  CATCH_ERROR( "Verbosity level not supported by this reporter" );
4288  }
4289 
4290  ReporterPreferences getPreferences() const override {
4291  return m_reporterPrefs;
4292  }
4293 
4294  static std::set<Verbosity> getSupportedVerbosities() {
4295  return { Verbosity::Normal };
4296  }
4297 
4298  ~StreamingReporterBase() override = default;
4299 
4300  void noMatchingTestCases(std::string const&) override {}
4301 
4302  void testRunStarting(TestRunInfo const& _testRunInfo) override {
4303  currentTestRunInfo = _testRunInfo;
4304  }
4305  void testGroupStarting(GroupInfo const& _groupInfo) override {
4306  currentGroupInfo = _groupInfo;
4307  }
4308 
4309  void testCaseStarting(TestCaseInfo const& _testInfo) override {
4310  currentTestCaseInfo = _testInfo;
4311  }
4312  void sectionStarting(SectionInfo const& _sectionInfo) override {
4313  m_sectionStack.push_back(_sectionInfo);
4314  }
4315 
4316  void sectionEnded(SectionStats const& /* _sectionStats */) override {
4317  m_sectionStack.pop_back();
4318  }
4319  void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {
4320  currentTestCaseInfo.reset();
4321  }
4322  void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override {
4323  currentGroupInfo.reset();
4324  }
4325  void testRunEnded(TestRunStats const& /* _testRunStats */) override {
4326  currentTestCaseInfo.reset();
4327  currentGroupInfo.reset();
4328  currentTestRunInfo.reset();
4329  }
4330 
4331  void skipTest(TestCaseInfo const&) override {
4332  // Don't do anything with this by default.
4333  // It can optionally be overridden in the derived class.
4334  }
4335 
4336  IConfigPtr m_config;
4337  std::ostream& stream;
4338 
4339  LazyStat<TestRunInfo> currentTestRunInfo;
4340  LazyStat<GroupInfo> currentGroupInfo;
4341  LazyStat<TestCaseInfo> currentTestCaseInfo;
4342 
4343  std::vector<SectionInfo> m_sectionStack;
4344  ReporterPreferences m_reporterPrefs;
4345  };
4346 
4347  template<typename DerivedT>
4348  struct CumulativeReporterBase : IStreamingReporter {
4349  template<typename T, typename ChildNodeT>
4350  struct Node {
4351  explicit Node( T const& _value ) : value( _value ) {}
4352  virtual ~Node() {}
4353 
4354  using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;
4355  T value;
4356  ChildNodes children;
4357  };
4358  struct SectionNode {
4359  explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}
4360  virtual ~SectionNode() = default;
4361 
4362  bool operator == (SectionNode const& other) const {
4363  return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
4364  }
4365  bool operator == (std::shared_ptr<SectionNode> const& other) const {
4366  return operator==(*other);
4367  }
4368 
4369  SectionStats stats;
4370  using ChildSections = std::vector<std::shared_ptr<SectionNode>>;
4371  using Assertions = std::vector<AssertionStats>;
4372  ChildSections childSections;
4373  Assertions assertions;
4374  std::string stdOut;
4375  std::string stdErr;
4376  };
4377 
4378  struct BySectionInfo {
4379  BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
4380  BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
4381  bool operator() (std::shared_ptr<SectionNode> const& node) const {
4382  return ((node->stats.sectionInfo.name == m_other.name) &&
4383  (node->stats.sectionInfo.lineInfo == m_other.lineInfo));
4384  }
4385  void operator=(BySectionInfo const&) = delete;
4386 
4387  private:
4388  SectionInfo const& m_other;
4389  };
4390 
4391  using TestCaseNode = Node<TestCaseStats, SectionNode>;
4392  using TestGroupNode = Node<TestGroupStats, TestCaseNode>;
4393  using TestRunNode = Node<TestRunStats, TestGroupNode>;
4394 
4395  CumulativeReporterBase( ReporterConfig const& _config )
4396  : m_config( _config.fullConfig() ),
4397  stream( _config.stream() )
4398  {
4399  m_reporterPrefs.shouldRedirectStdOut = false;
4400  if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
4401  CATCH_ERROR( "Verbosity level not supported by this reporter" );
4402  }
4403  ~CumulativeReporterBase() override = default;
4404 
4405  ReporterPreferences getPreferences() const override {
4406  return m_reporterPrefs;
4407  }
4408 
4409  static std::set<Verbosity> getSupportedVerbosities() {
4410  return { Verbosity::Normal };
4411  }
4412 
4413  void testRunStarting( TestRunInfo const& ) override {}
4414  void testGroupStarting( GroupInfo const& ) override {}
4415 
4416  void testCaseStarting( TestCaseInfo const& ) override {}
4417 
4418  void sectionStarting( SectionInfo const& sectionInfo ) override {
4419  SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
4420  std::shared_ptr<SectionNode> node;
4421  if( m_sectionStack.empty() ) {
4422  if( !m_rootSection )
4423  m_rootSection = std::make_shared<SectionNode>( incompleteStats );
4424  node = m_rootSection;
4425  }
4426  else {
4427  SectionNode& parentNode = *m_sectionStack.back();
4428  auto it =
4429  std::find_if( parentNode.childSections.begin(),
4430  parentNode.childSections.end(),
4431  BySectionInfo( sectionInfo ) );
4432  if( it == parentNode.childSections.end() ) {
4433  node = std::make_shared<SectionNode>( incompleteStats );
4434  parentNode.childSections.push_back( node );
4435  }
4436  else
4437  node = *it;
4438  }
4439  m_sectionStack.push_back( node );
4440  m_deepestSection = std::move(node);
4441  }
4442 
4443  void assertionStarting(AssertionInfo const&) override {}
4444 
4445  bool assertionEnded(AssertionStats const& assertionStats) override {
4446  assert(!m_sectionStack.empty());
4447  // AssertionResult holds a pointer to a temporary DecomposedExpression,
4448  // which getExpandedExpression() calls to build the expression string.
4449  // Our section stack copy of the assertionResult will likely outlive the
4450  // temporary, so it must be expanded or discarded now to avoid calling
4451  // a destroyed object later.
4452  prepareExpandedExpression(const_cast<AssertionResult&>( assertionStats.assertionResult ) );
4453  SectionNode& sectionNode = *m_sectionStack.back();
4454  sectionNode.assertions.push_back(assertionStats);
4455  return true;
4456  }
4457  void sectionEnded(SectionStats const& sectionStats) override {
4458  assert(!m_sectionStack.empty());
4459  SectionNode& node = *m_sectionStack.back();
4460  node.stats = sectionStats;
4461  m_sectionStack.pop_back();
4462  }
4463  void testCaseEnded(TestCaseStats const& testCaseStats) override {
4464  auto node = std::make_shared<TestCaseNode>(testCaseStats);
4465  assert(m_sectionStack.size() == 0);
4466  node->children.push_back(m_rootSection);
4467  m_testCases.push_back(node);
4468  m_rootSection.reset();
4469 
4470  assert(m_deepestSection);
4471  m_deepestSection->stdOut = testCaseStats.stdOut;
4472  m_deepestSection->stdErr = testCaseStats.stdErr;
4473  }
4474  void testGroupEnded(TestGroupStats const& testGroupStats) override {
4475  auto node = std::make_shared<TestGroupNode>(testGroupStats);
4476  node->children.swap(m_testCases);
4477  m_testGroups.push_back(node);
4478  }
4479  void testRunEnded(TestRunStats const& testRunStats) override {
4480  auto node = std::make_shared<TestRunNode>(testRunStats);
4481  node->children.swap(m_testGroups);
4482  m_testRuns.push_back(node);
4483  testRunEndedCumulative();
4484  }
4485  virtual void testRunEndedCumulative() = 0;
4486 
4487  void skipTest(TestCaseInfo const&) override {}
4488 
4489  IConfigPtr m_config;
4490  std::ostream& stream;
4491  std::vector<AssertionStats> m_assertions;
4492  std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;
4493  std::vector<std::shared_ptr<TestCaseNode>> m_testCases;
4494  std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;
4495 
4496  std::vector<std::shared_ptr<TestRunNode>> m_testRuns;
4497 
4498  std::shared_ptr<SectionNode> m_rootSection;
4499  std::shared_ptr<SectionNode> m_deepestSection;
4500  std::vector<std::shared_ptr<SectionNode>> m_sectionStack;
4501  ReporterPreferences m_reporterPrefs;
4502  };
4503 
4504  template<char C>
4505  char const* getLineOfChars() {
4506  static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
4507  if( !*line ) {
4508  std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
4509  line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
4510  }
4511  return line;
4512  }
4513 
4514  struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> {
4515  TestEventListenerBase( ReporterConfig const& _config );
4516 
4517  void assertionStarting(AssertionInfo const&) override;
4518  bool assertionEnded(AssertionStats const&) override;
4519  };
4520 
4521 } // end namespace Catch
4522 
4523 // end catch_reporter_bases.hpp
4524 // start catch_console_colour.h
4525 
4526 namespace Catch {
4527 
4528  struct Colour {
4529  enum Code {
4530  None = 0,
4531 
4532  White,
4533  Red,
4534  Green,
4535  Blue,
4536  Cyan,
4537  Yellow,
4538  Grey,
4539 
4540  Bright = 0x10,
4541 
4542  BrightRed = Bright | Red,
4543  BrightGreen = Bright | Green,
4544  LightGrey = Bright | Grey,
4545  BrightWhite = Bright | White,
4546  BrightYellow = Bright | Yellow,
4547 
4548  // By intention
4549  FileName = LightGrey,
4550  Warning = BrightYellow,
4551  ResultError = BrightRed,
4552  ResultSuccess = BrightGreen,
4553  ResultExpectedFailure = Warning,
4554 
4555  Error = BrightRed,
4556  Success = Green,
4557 
4558  OriginalExpression = Cyan,
4559  ReconstructedExpression = BrightYellow,
4560 
4561  SecondaryText = LightGrey,
4562  Headers = White
4563  };
4564 
4565  // Use constructed object for RAII guard
4566  Colour( Code _colourCode );
4567  Colour( Colour&& other ) noexcept;
4568  Colour& operator=( Colour&& other ) noexcept;
4569  ~Colour();
4570 
4571  // Use static method for one-shot changes
4572  static void use( Code _colourCode );
4573 
4574  private:
4575  bool m_moved = false;
4576  };
4577 
4578  std::ostream& operator << ( std::ostream& os, Colour const& );
4579 
4580 } // end namespace Catch
4581 
4582 // end catch_console_colour.h
4583 // start catch_reporter_registrars.hpp
4584 
4585 
4586 namespace Catch {
4587 
4588  template<typename T>
4589  class ReporterRegistrar {
4590 
4591  class ReporterFactory : public IReporterFactory {
4592 
4593  virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override {
4594  return std::unique_ptr<T>( new T( config ) );
4595  }
4596 
4597  virtual std::string getDescription() const override {
4598  return T::getDescription();
4599  }
4600  };
4601 
4602  public:
4603 
4604  explicit ReporterRegistrar( std::string const& name ) {
4605  getMutableRegistryHub().registerReporter( name, std::make_shared<ReporterFactory>() );
4606  }
4607  };
4608 
4609  template<typename T>
4610  class ListenerRegistrar {
4611 
4612  class ListenerFactory : public IReporterFactory {
4613 
4614  virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override {
4615  return std::unique_ptr<T>( new T( config ) );
4616  }
4617  virtual std::string getDescription() const override {
4618  return std::string();
4619  }
4620  };
4621 
4622  public:
4623 
4624  ListenerRegistrar() {
4625  getMutableRegistryHub().registerListener( std::make_shared<ListenerFactory>() );
4626  }
4627  };
4628 }
4629 
4630 #if !defined(CATCH_CONFIG_DISABLE)
4631 
4632 #define CATCH_REGISTER_REPORTER( name, reporterType ) \
4633  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
4634  namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \
4635  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
4636 
4637 #define CATCH_REGISTER_LISTENER( listenerType ) \
4638  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
4639  namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \
4640  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
4641 #else // CATCH_CONFIG_DISABLE
4642 
4643 #define CATCH_REGISTER_REPORTER(name, reporterType)
4644 #define CATCH_REGISTER_LISTENER(listenerType)
4645 
4646 #endif // CATCH_CONFIG_DISABLE
4647 
4648 // end catch_reporter_registrars.hpp
4649 // Allow users to base their work off existing reporters
4650 // start catch_reporter_compact.h
4651 
4652 namespace Catch {
4653 
4654  struct CompactReporter : StreamingReporterBase<CompactReporter> {
4655 
4656  using StreamingReporterBase::StreamingReporterBase;
4657 
4658  ~CompactReporter() override;
4659 
4660  static std::string getDescription();
4661 
4662  ReporterPreferences getPreferences() const override;
4663 
4664  void noMatchingTestCases(std::string const& spec) override;
4665 
4666  void assertionStarting(AssertionInfo const&) override;
4667 
4668  bool assertionEnded(AssertionStats const& _assertionStats) override;
4669 
4670  void sectionEnded(SectionStats const& _sectionStats) override;
4671 
4672  void testRunEnded(TestRunStats const& _testRunStats) override;
4673 
4674  };
4675 
4676 } // end namespace Catch
4677 
4678 // end catch_reporter_compact.h
4679 // start catch_reporter_console.h
4680 
4681 #if defined(_MSC_VER)
4682 #pragma warning(push)
4683 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
4684  // Note that 4062 (not all labels are handled
4685  // and default is missing) is enabled
4686 #endif
4687 
4688 namespace Catch {
4689  // Fwd decls
4690  struct SummaryColumn;
4691  class TablePrinter;
4692 
4693  struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> {
4694  std::unique_ptr<TablePrinter> m_tablePrinter;
4695 
4696  ConsoleReporter(ReporterConfig const& config);
4697  ~ConsoleReporter() override;
4698  static std::string getDescription();
4699 
4700  void noMatchingTestCases(std::string const& spec) override;
4701 
4702  void assertionStarting(AssertionInfo const&) override;
4703 
4704  bool assertionEnded(AssertionStats const& _assertionStats) override;
4705 
4706  void sectionStarting(SectionInfo const& _sectionInfo) override;
4707  void sectionEnded(SectionStats const& _sectionStats) override;
4708 
4709  void benchmarkStarting(BenchmarkInfo const& info) override;
4710  void benchmarkEnded(BenchmarkStats const& stats) override;
4711 
4712  void testCaseEnded(TestCaseStats const& _testCaseStats) override;
4713  void testGroupEnded(TestGroupStats const& _testGroupStats) override;
4714  void testRunEnded(TestRunStats const& _testRunStats) override;
4715 
4716  private:
4717 
4718  void lazyPrint();
4719 
4720  void lazyPrintWithoutClosingBenchmarkTable();
4721  void lazyPrintRunInfo();
4722  void lazyPrintGroupInfo();
4723  void printTestCaseAndSectionHeader();
4724 
4725  void printClosedHeader(std::string const& _name);
4726  void printOpenHeader(std::string const& _name);
4727 
4728  // if string has a : in first line will set indent to follow it on
4729  // subsequent lines
4730  void printHeaderString(std::string const& _string, std::size_t indent = 0);
4731 
4732  void printTotals(Totals const& totals);
4733  void printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row);
4734 
4735  void printTotalsDivider(Totals const& totals);
4736  void printSummaryDivider();
4737 
4738  private:
4739  bool m_headerPrinted = false;
4740  };
4741 
4742 } // end namespace Catch
4743 
4744 #if defined(_MSC_VER)
4745 #pragma warning(pop)
4746 #endif
4747 
4748 // end catch_reporter_console.h
4749 // start catch_reporter_junit.h
4750 
4751 // start catch_xmlwriter.h
4752 
4753 #include <vector>
4754 
4755 namespace Catch {
4756 
4757  class XmlEncode {
4758  public:
4759  enum ForWhat { ForTextNodes, ForAttributes };
4760 
4761  XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes );
4762 
4763  void encodeTo( std::ostream& os ) const;
4764 
4765  friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );
4766 
4767  private:
4768  std::string m_str;
4769  ForWhat m_forWhat;
4770  };
4771 
4772  class XmlWriter {
4773  public:
4774 
4775  class ScopedElement {
4776  public:
4777  ScopedElement( XmlWriter* writer );
4778 
4779  ScopedElement( ScopedElement&& other ) noexcept;
4780  ScopedElement& operator=( ScopedElement&& other ) noexcept;
4781 
4782  ~ScopedElement();
4783 
4784  ScopedElement& writeText( std::string const& text, bool indent = true );
4785 
4786  template<typename T>
4787  ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
4788  m_writer->writeAttribute( name, attribute );
4789  return *this;
4790  }
4791 
4792  private:
4793  mutable XmlWriter* m_writer = nullptr;
4794  };
4795 
4796  XmlWriter( std::ostream& os = Catch::cout() );
4797  ~XmlWriter();
4798 
4799  XmlWriter( XmlWriter const& ) = delete;
4800  XmlWriter& operator=( XmlWriter const& ) = delete;
4801 
4802  XmlWriter& startElement( std::string const& name );
4803 
4804  ScopedElement scopedElement( std::string const& name );
4805 
4806  XmlWriter& endElement();
4807 
4808  XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );
4809 
4810  XmlWriter& writeAttribute( std::string const& name, bool attribute );
4811 
4812  template<typename T>
4813  XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
4815  rss << attribute;
4816  return writeAttribute( name, rss.str() );
4817  }
4818 
4819  XmlWriter& writeText( std::string const& text, bool indent = true );
4820 
4821  XmlWriter& writeComment( std::string const& text );
4822 
4823  void writeStylesheetRef( std::string const& url );
4824 
4825  XmlWriter& writeBlankLine();
4826 
4827  void ensureTagClosed();
4828 
4829  private:
4830 
4831  void writeDeclaration();
4832 
4833  void newlineIfNecessary();
4834 
4835  bool m_tagIsOpen = false;
4836  bool m_needsNewline = false;
4837  std::vector<std::string> m_tags;
4838  std::string m_indent;
4839  std::ostream& m_os;
4840  };
4841 
4842 }
4843 
4844 // end catch_xmlwriter.h
4845 namespace Catch {
4846 
4847  class JunitReporter : public CumulativeReporterBase<JunitReporter> {
4848  public:
4849  JunitReporter(ReporterConfig const& _config);
4850 
4851  ~JunitReporter() override;
4852 
4853  static std::string getDescription();
4854 
4855  void noMatchingTestCases(std::string const& /*spec*/) override;
4856 
4857  void testRunStarting(TestRunInfo const& runInfo) override;
4858 
4859  void testGroupStarting(GroupInfo const& groupInfo) override;
4860 
4861  void testCaseStarting(TestCaseInfo const& testCaseInfo) override;
4862  bool assertionEnded(AssertionStats const& assertionStats) override;
4863 
4864  void testCaseEnded(TestCaseStats const& testCaseStats) override;
4865 
4866  void testGroupEnded(TestGroupStats const& testGroupStats) override;
4867 
4868  void testRunEndedCumulative() override;
4869 
4870  void writeGroup(TestGroupNode const& groupNode, double suiteTime);
4871 
4872  void writeTestCase(TestCaseNode const& testCaseNode);
4873 
4874  void writeSection(std::string const& className,
4875  std::string const& rootName,
4876  SectionNode const& sectionNode);
4877 
4878  void writeAssertions(SectionNode const& sectionNode);
4879  void writeAssertion(AssertionStats const& stats);
4880 
4881  XmlWriter xml;
4882  Timer suiteTimer;
4883  std::string stdOutForSuite;
4884  std::string stdErrForSuite;
4885  unsigned int unexpectedExceptions = 0;
4886  bool m_okToFail = false;
4887  };
4888 
4889 } // end namespace Catch
4890 
4891 // end catch_reporter_junit.h
4892 // start catch_reporter_xml.h
4893 
4894 namespace Catch {
4895  class XmlReporter : public StreamingReporterBase<XmlReporter> {
4896  public:
4897  XmlReporter(ReporterConfig const& _config);
4898 
4899  ~XmlReporter() override;
4900 
4901  static std::string getDescription();
4902 
4903  virtual std::string getStylesheetRef() const;
4904 
4905  void writeSourceInfo(SourceLineInfo const& sourceInfo);
4906 
4907  public: // StreamingReporterBase
4908 
4909  void noMatchingTestCases(std::string const& s) override;
4910 
4911  void testRunStarting(TestRunInfo const& testInfo) override;
4912 
4913  void testGroupStarting(GroupInfo const& groupInfo) override;
4914 
4915  void testCaseStarting(TestCaseInfo const& testInfo) override;
4916 
4917  void sectionStarting(SectionInfo const& sectionInfo) override;
4918 
4919  void assertionStarting(AssertionInfo const&) override;
4920 
4921  bool assertionEnded(AssertionStats const& assertionStats) override;
4922 
4923  void sectionEnded(SectionStats const& sectionStats) override;
4924 
4925  void testCaseEnded(TestCaseStats const& testCaseStats) override;
4926 
4927  void testGroupEnded(TestGroupStats const& testGroupStats) override;
4928 
4929  void testRunEnded(TestRunStats const& testRunStats) override;
4930 
4931  private:
4932  Timer m_testCaseTimer;
4933  XmlWriter m_xml;
4934  int m_sectionDepth = 0;
4935  };
4936 
4937 } // end namespace Catch
4938 
4939 // end catch_reporter_xml.h
4940 
4941 // end catch_external_interfaces.h
4942 #endif
4943 
4944 #endif // ! CATCH_CONFIG_IMPL_ONLY
4945 
4946 #ifdef CATCH_IMPL
4947 // start catch_impl.hpp
4948 
4949 #ifdef __clang__
4950 #pragma clang diagnostic push
4951 #pragma clang diagnostic ignored "-Wweak-vtables"
4952 #endif
4953 
4954 // Keep these here for external reporters
4955 // start catch_test_case_tracker.h
4956 
4957 #include <string>
4958 #include <vector>
4959 #include <memory>
4960 
4961 namespace Catch {
4962 namespace TestCaseTracking {
4963 
4964  struct NameAndLocation {
4965  std::string name;
4966  SourceLineInfo location;
4967 
4968  NameAndLocation( std::string const& _name, SourceLineInfo const& _location );
4969  };
4970 
4971  struct ITracker;
4972 
4973  using ITrackerPtr = std::shared_ptr<ITracker>;
4974 
4975  struct ITracker {
4976  virtual ~ITracker();
4977 
4978  // static queries
4979  virtual NameAndLocation const& nameAndLocation() const = 0;
4980 
4981  // dynamic queries
4982  virtual bool isComplete() const = 0; // Successfully completed or failed
4983  virtual bool isSuccessfullyCompleted() const = 0;
4984  virtual bool isOpen() const = 0; // Started but not complete
4985  virtual bool hasChildren() const = 0;
4986 
4987  virtual ITracker& parent() = 0;
4988 
4989  // actions
4990  virtual void close() = 0; // Successfully complete
4991  virtual void fail() = 0;
4992  virtual void markAsNeedingAnotherRun() = 0;
4993 
4994  virtual void addChild( ITrackerPtr const& child ) = 0;
4995  virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0;
4996  virtual void openChild() = 0;
4997 
4998  // Debug/ checking
4999  virtual bool isSectionTracker() const = 0;
5000  virtual bool isIndexTracker() const = 0;
5001  };
5002 
5003  class TrackerContext {
5004 
5005  enum RunState {
5006  NotStarted,
5007  Executing,
5008  CompletedCycle
5009  };
5010 
5011  ITrackerPtr m_rootTracker;
5012  ITracker* m_currentTracker = nullptr;
5013  RunState m_runState = NotStarted;
5014 
5015  public:
5016 
5017  static TrackerContext& instance();
5018 
5019  ITracker& startRun();
5020  void endRun();
5021 
5022  void startCycle();
5023  void completeCycle();
5024 
5025  bool completedCycle() const;
5026  ITracker& currentTracker();
5027  void setCurrentTracker( ITracker* tracker );
5028  };
5029 
5030  class TrackerBase : public ITracker {
5031  protected:
5032  enum CycleState {
5033  NotStarted,
5034  Executing,
5035  ExecutingChildren,
5036  NeedsAnotherRun,
5037  CompletedSuccessfully,
5038  Failed
5039  };
5040 
5041  using Children = std::vector<ITrackerPtr>;
5042  NameAndLocation m_nameAndLocation;
5043  TrackerContext& m_ctx;
5044  ITracker* m_parent;
5045  Children m_children;
5046  CycleState m_runState = NotStarted;
5047 
5048  public:
5049  TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
5050 
5051  NameAndLocation const& nameAndLocation() const override;
5052  bool isComplete() const override;
5053  bool isSuccessfullyCompleted() const override;
5054  bool isOpen() const override;
5055  bool hasChildren() const override;
5056 
5057  void addChild( ITrackerPtr const& child ) override;
5058 
5059  ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override;
5060  ITracker& parent() override;
5061 
5062  void openChild() override;
5063 
5064  bool isSectionTracker() const override;
5065  bool isIndexTracker() const override;
5066 
5067  void open();
5068 
5069  void close() override;
5070  void fail() override;
5071  void markAsNeedingAnotherRun() override;
5072 
5073  private:
5074  void moveToParent();
5075  void moveToThis();
5076  };
5077 
5078  class SectionTracker : public TrackerBase {
5079  std::vector<std::string> m_filters;
5080  public:
5081  SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
5082 
5083  bool isSectionTracker() const override;
5084 
5085  static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation );
5086 
5087  void tryOpen();
5088 
5089  void addInitialFilters( std::vector<std::string> const& filters );
5090  void addNextFilters( std::vector<std::string> const& filters );
5091  };
5092 
5093  class IndexTracker : public TrackerBase {
5094  int m_size;
5095  int m_index = -1;
5096  public:
5097  IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size );
5098 
5099  bool isIndexTracker() const override;
5100  void close() override;
5101 
5102  static IndexTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size );
5103 
5104  int index() const;
5105 
5106  void moveNext();
5107  };
5108 
5109 } // namespace TestCaseTracking
5110 
5111 using TestCaseTracking::ITracker;
5112 using TestCaseTracking::TrackerContext;
5113 using TestCaseTracking::SectionTracker;
5114 using TestCaseTracking::IndexTracker;
5115 
5116 } // namespace Catch
5117 
5118 // end catch_test_case_tracker.h
5119 
5120 // start catch_leak_detector.h
5121 
5122 namespace Catch {
5123 
5124  struct LeakDetector {
5125  LeakDetector();
5126  ~LeakDetector();
5127  };
5128 
5129 }
5130 // end catch_leak_detector.h
5131 // Cpp files will be included in the single-header file here
5132 // start catch_approx.cpp
5133 
5134 #include <cmath>
5135 #include <limits>
5136 
5137 namespace {
5138 
5139 // Performs equivalent check of std::fabs(lhs - rhs) <= margin
5140 // But without the subtraction to allow for INFINITY in comparison
5141 bool marginComparison(double lhs, double rhs, double margin) {
5142  return (lhs + margin >= rhs) && (rhs + margin >= lhs);
5143 }
5144 
5145 }
5146 
5147 namespace Catch {
5148 namespace Detail {
5149 
5150  Approx::Approx ( double value )
5151  : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
5152  m_margin( 0.0 ),
5153  m_scale( 0.0 ),
5154  m_value( value )
5155  {}
5156 
5157  Approx Approx::custom() {
5158  return Approx( 0 );
5159  }
5160 
5161  Approx Approx::operator-() const {
5162  auto temp(*this);
5163  temp.m_value = -temp.m_value;
5164  return temp;
5165  }
5166 
5167  std::string Approx::toString() const {
5169  rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
5170  return rss.str();
5171  }
5172 
5173  bool Approx::equalityComparisonImpl(const double other) const {
5174  // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
5175  // Thanks to Richard Harris for his help refining the scaled margin value
5176  return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
5177  }
5178 
5179  void Approx::setMargin(double margin) {
5180  CATCH_ENFORCE(margin >= 0,
5181  "Invalid Approx::margin: " << margin << '.'
5182  << " Approx::Margin has to be non-negative.");
5183  m_margin = margin;
5184  }
5185 
5186  void Approx::setEpsilon(double epsilon) {
5187  CATCH_ENFORCE(epsilon >= 0 && epsilon <= 1.0,
5188  "Invalid Approx::epsilon: " << epsilon << '.'
5189  << " Approx::epsilon has to be in [0, 1]");
5190  m_epsilon = epsilon;
5191  }
5192 
5193 } // end namespace Detail
5194 
5195 namespace literals {
5196  Detail::Approx operator "" _a(long double val) {
5197  return Detail::Approx(val);
5198  }
5199  Detail::Approx operator "" _a(unsigned long long val) {
5200  return Detail::Approx(val);
5201  }
5202 } // end namespace literals
5203 
5205  return value.toString();
5206 }
5207 
5208 } // end namespace Catch
5209 // end catch_approx.cpp
5210 // start catch_assertionhandler.cpp
5211 
5212 // start catch_context.h
5213 
5214 #include <memory>
5215 
5216 namespace Catch {
5217 
5218  struct IResultCapture;
5219  struct IRunner;
5220  struct IConfig;
5221  struct IMutableContext;
5222 
5223  using IConfigPtr = std::shared_ptr<IConfig const>;
5224 
5225  struct IContext
5226  {
5227  virtual ~IContext();
5228 
5229  virtual IResultCapture* getResultCapture() = 0;
5230  virtual IRunner* getRunner() = 0;
5231  virtual IConfigPtr const& getConfig() const = 0;
5232  };
5233 
5234  struct IMutableContext : IContext
5235  {
5236  virtual ~IMutableContext();
5237  virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
5238  virtual void setRunner( IRunner* runner ) = 0;
5239  virtual void setConfig( IConfigPtr const& config ) = 0;
5240 
5241  private:
5242  static IMutableContext *currentContext;
5243  friend IMutableContext& getCurrentMutableContext();
5244  friend void cleanUpContext();
5245  static void createContext();
5246  };
5247 
5248  inline IMutableContext& getCurrentMutableContext()
5249  {
5250  if( !IMutableContext::currentContext )
5251  IMutableContext::createContext();
5252  return *IMutableContext::currentContext;
5253  }
5254 
5255  inline IContext& getCurrentContext()
5256  {
5257  return getCurrentMutableContext();
5258  }
5259 
5260  void cleanUpContext();
5261 }
5262 
5263 // end catch_context.h
5264 // start catch_debugger.h
5265 
5266 namespace Catch {
5267  bool isDebuggerActive();
5268 }
5269 
5270 #ifdef CATCH_PLATFORM_MAC
5271 
5272  #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
5273 
5274 #elif defined(CATCH_PLATFORM_LINUX)
5275  // If we can use inline assembler, do it because this allows us to break
5276  // directly at the location of the failing check instead of breaking inside
5277  // raise() called from it, i.e. one stack frame below.
5278  #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
5279  #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
5280  #else // Fall back to the generic way.
5281  #include <signal.h>
5282 
5283  #define CATCH_TRAP() raise(SIGTRAP)
5284  #endif
5285 #elif defined(_MSC_VER)
5286  #define CATCH_TRAP() __debugbreak()
5287 #elif defined(__MINGW32__)
5288  extern "C" __declspec(dllimport) void __stdcall DebugBreak();
5289  #define CATCH_TRAP() DebugBreak()
5290 #endif
5291 
5292 #ifdef CATCH_TRAP
5293  #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); }
5294 #else
5295  namespace Catch {
5296  inline void doNothing() {}
5297  }
5298  #define CATCH_BREAK_INTO_DEBUGGER() Catch::doNothing()
5299 #endif
5300 
5301 // end catch_debugger.h
5302 // start catch_run_context.h
5303 
5304 // start catch_fatal_condition.h
5305 
5306 // start catch_windows_h_proxy.h
5307 
5308 
5309 #if defined(CATCH_PLATFORM_WINDOWS)
5310 
5311 #if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
5312 # define CATCH_DEFINED_NOMINMAX
5313 # define NOMINMAX
5314 #endif
5315 #if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
5316 # define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
5317 # define WIN32_LEAN_AND_MEAN
5318 #endif
5319 
5320 #ifdef __AFXDLL
5321 #include <AfxWin.h>
5322 #else
5323 #include <windows.h>
5324 #endif
5325 
5326 #ifdef CATCH_DEFINED_NOMINMAX
5327 # undef NOMINMAX
5328 #endif
5329 #ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
5330 # undef WIN32_LEAN_AND_MEAN
5331 #endif
5332 
5333 #endif // defined(CATCH_PLATFORM_WINDOWS)
5334 
5335 // end catch_windows_h_proxy.h
5336 #if defined( CATCH_CONFIG_WINDOWS_SEH )
5337 
5338 namespace Catch {
5339 
5340  struct FatalConditionHandler {
5341 
5342  static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
5343  FatalConditionHandler();
5344  static void reset();
5345  ~FatalConditionHandler();
5346 
5347  private:
5348  static bool isSet;
5349  static ULONG guaranteeSize;
5350  static PVOID exceptionHandlerHandle;
5351  };
5352 
5353 } // namespace Catch
5354 
5355 #elif defined ( CATCH_CONFIG_POSIX_SIGNALS )
5356 
5357 #include <signal.h>
5358 
5359 namespace Catch {
5360 
5361  struct FatalConditionHandler {
5362 
5363  static bool isSet;
5364  static struct sigaction oldSigActions[];
5365  static stack_t oldSigStack;
5366  static char altStackMem[];
5367 
5368  static void handleSignal( int sig );
5369 
5370  FatalConditionHandler();
5371  ~FatalConditionHandler();
5372  static void reset();
5373  };
5374 
5375 } // namespace Catch
5376 
5377 #else
5378 
5379 namespace Catch {
5380  struct FatalConditionHandler {
5381  void reset();
5382  };
5383 }
5384 
5385 #endif
5386 
5387 // end catch_fatal_condition.h
5388 #include <string>
5389 
5390 namespace Catch {
5391 
5392  struct IMutableContext;
5393 
5395 
5396  class RunContext : public IResultCapture, public IRunner {
5397 
5398  public:
5399  RunContext( RunContext const& ) = delete;
5400  RunContext& operator =( RunContext const& ) = delete;
5401 
5402  explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr&& reporter );
5403 
5404  ~RunContext() override;
5405 
5406  void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount );
5407  void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount );
5408 
5409  Totals runTest(TestCase const& testCase);
5410 
5411  IConfigPtr config() const;
5412  IStreamingReporter& reporter() const;
5413 
5414  public: // IResultCapture
5415 
5416  // Assertion handlers
5417  void handleExpr
5418  ( AssertionInfo const& info,
5419  ITransientExpression const& expr,
5420  AssertionReaction& reaction ) override;
5421  void handleMessage
5422  ( AssertionInfo const& info,
5423  ResultWas::OfType resultType,
5424  StringRef const& message,
5425  AssertionReaction& reaction ) override;
5426  void handleUnexpectedExceptionNotThrown
5427  ( AssertionInfo const& info,
5428  AssertionReaction& reaction ) override;
5429  void handleUnexpectedInflightException
5430  ( AssertionInfo const& info,
5431  std::string const& message,
5432  AssertionReaction& reaction ) override;
5433  void handleIncomplete
5434  ( AssertionInfo const& info ) override;
5435  void handleNonExpr
5436  ( AssertionInfo const &info,
5437  ResultWas::OfType resultType,
5438  AssertionReaction &reaction ) override;
5439 
5440  bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override;
5441 
5442  void sectionEnded( SectionEndInfo const& endInfo ) override;
5443  void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
5444 
5445  auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
5446 
5447  void benchmarkStarting( BenchmarkInfo const& info ) override;
5448  void benchmarkEnded( BenchmarkStats const& stats ) override;
5449 
5450  void pushScopedMessage( MessageInfo const& message ) override;
5451  void popScopedMessage( MessageInfo const& message ) override;
5452 
5453  std::string getCurrentTestName() const override;
5454 
5455  const AssertionResult* getLastResult() const override;
5456 
5457  void exceptionEarlyReported() override;
5458 
5459  void handleFatalErrorCondition( StringRef message ) override;
5460 
5461  bool lastAssertionPassed() override;
5462 
5463  void assertionPassed() override;
5464 
5465  public:
5466  // !TBD We need to do this another way!
5467  bool aborting() const final;
5468 
5469  private:
5470 
5471  void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr );
5472  void invokeActiveTestCase();
5473 
5474  void resetAssertionInfo();
5475  bool testForMissingAssertions( Counts& assertions );
5476 
5477  void assertionEnded( AssertionResult const& result );
5478  void reportExpr
5479  ( AssertionInfo const &info,
5480  ResultWas::OfType resultType,
5481  ITransientExpression const *expr,
5482  bool negated );
5483 
5484  void populateReaction( AssertionReaction& reaction );
5485 
5486  private:
5487 
5488  void handleUnfinishedSections();
5489 
5490  TestRunInfo m_runInfo;
5491  IMutableContext& m_context;
5492  TestCase const* m_activeTestCase = nullptr;
5493  ITracker* m_testCaseTracker;
5494  Option<AssertionResult> m_lastResult;
5495 
5496  IConfigPtr m_config;
5497  Totals m_totals;
5498  IStreamingReporterPtr m_reporter;
5499  std::vector<MessageInfo> m_messages;
5500  AssertionInfo m_lastAssertionInfo;
5501  std::vector<SectionEndInfo> m_unfinishedSections;
5502  std::vector<ITracker*> m_activeSections;
5503  TrackerContext m_trackerContext;
5504  bool m_lastAssertionPassed = false;
5505  bool m_shouldReportUnexpected = true;
5506  bool m_includeSuccessfulResults;
5507  };
5508 
5509 } // end namespace Catch
5510 
5511 // end catch_run_context.h
5512 namespace Catch {
5513 
5514  namespace {
5515  auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
5516  expr.streamReconstructedExpression( os );
5517  return os;
5518  }
5519  }
5520 
5521  LazyExpression::LazyExpression( bool isNegated )
5522  : m_isNegated( isNegated )
5523  {}
5524 
5525  LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {}
5526 
5527  LazyExpression::operator bool() const {
5528  return m_transientExpression != nullptr;
5529  }
5530 
5531  auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& {
5532  if( lazyExpr.m_isNegated )
5533  os << "!";
5534 
5535  if( lazyExpr ) {
5536  if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() )
5537  os << "(" << *lazyExpr.m_transientExpression << ")";
5538  else
5539  os << *lazyExpr.m_transientExpression;
5540  }
5541  else {
5542  os << "{** error - unchecked empty expression requested **}";
5543  }
5544  return os;
5545  }
5546 
5548  ( StringRef const& macroName,
5549  SourceLineInfo const& lineInfo,
5550  StringRef capturedExpression,
5551  ResultDisposition::Flags resultDisposition )
5552  : m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },
5553  m_resultCapture( getResultCapture() )
5554  {}
5555 
5557  m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );
5558  }
5559  void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) {
5560  m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction );
5561  }
5562 
5563  auto AssertionHandler::allowThrows() const -> bool {
5564  return getCurrentContext().getConfig()->allowThrows();
5565  }
5566 
5568  setCompleted();
5569  if( m_reaction.shouldDebugBreak ) {
5570 
5571  // If you find your debugger stopping you here then go one level up on the
5572  // call-stack for the code that caused it (typically a failed assertion)
5573 
5574  // (To go back to the test and change execution, jump over the throw, next)
5575  CATCH_BREAK_INTO_DEBUGGER();
5576  }
5577  if (m_reaction.shouldThrow) {
5578 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
5580 #else
5581  CATCH_ERROR( "Test failure requires aborting test!" );
5582 #endif
5583  }
5584  }
5586  m_completed = true;
5587  }
5588 
5590  m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction );
5591  }
5592 
5594  m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
5595  }
5597  m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
5598  }
5599 
5601  m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction );
5602  }
5603 
5605  m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
5606  }
5607 
5608  // This is the overload that takes a string and infers the Equals matcher from it
5609  // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
5610  void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString ) {
5611  handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );
5612  }
5613 
5614 } // namespace Catch
5615 // end catch_assertionhandler.cpp
5616 // start catch_assertionresult.cpp
5617 
5618 namespace Catch {
5619  AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression):
5620  lazyExpression(_lazyExpression),
5621  resultType(_resultType) {}
5622 
5623  std::string AssertionResultData::reconstructExpression() const {
5624 
5625  if( reconstructedExpression.empty() ) {
5626  if( lazyExpression ) {
5628  rss << lazyExpression;
5629  reconstructedExpression = rss.str();
5630  }
5631  }
5632  return reconstructedExpression;
5633  }
5634 
5635  AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
5636  : m_info( info ),
5637  m_resultData( data )
5638  {}
5639 
5640  // Result was a success
5641  bool AssertionResult::succeeded() const {
5642  return Catch::isOk( m_resultData.resultType );
5643  }
5644 
5645  // Result was a success, or failure is suppressed
5646  bool AssertionResult::isOk() const {
5647  return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
5648  }
5649 
5650  ResultWas::OfType AssertionResult::getResultType() const {
5651  return m_resultData.resultType;
5652  }
5653 
5654  bool AssertionResult::hasExpression() const {
5655  return m_info.capturedExpression[0] != 0;
5656  }
5657 
5658  bool AssertionResult::hasMessage() const {
5659  return !m_resultData.message.empty();
5660  }
5661 
5662  std::string AssertionResult::getExpression() const {
5663  if( isFalseTest( m_info.resultDisposition ) )
5664  return "!(" + m_info.capturedExpression + ")";
5665  else
5666  return m_info.capturedExpression;
5667  }
5668 
5669  std::string AssertionResult::getExpressionInMacro() const {
5670  std::string expr;
5671  if( m_info.macroName[0] == 0 )
5672  expr = m_info.capturedExpression;
5673  else {
5674  expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
5675  expr += m_info.macroName;
5676  expr += "( ";
5677  expr += m_info.capturedExpression;
5678  expr += " )";
5679  }
5680  return expr;
5681  }
5682 
5683  bool AssertionResult::hasExpandedExpression() const {
5684  return hasExpression() && getExpandedExpression() != getExpression();
5685  }
5686 
5687  std::string AssertionResult::getExpandedExpression() const {
5688  std::string expr = m_resultData.reconstructExpression();
5689  return expr.empty()
5690  ? getExpression()
5691  : expr;
5692  }
5693 
5694  std::string AssertionResult::getMessage() const {
5695  return m_resultData.message;
5696  }
5697  SourceLineInfo AssertionResult::getSourceInfo() const {
5698  return m_info.lineInfo;
5699  }
5700 
5701  StringRef AssertionResult::getTestMacroName() const {
5702  return m_info.macroName;
5703  }
5704 
5705 } // end namespace Catch
5706 // end catch_assertionresult.cpp
5707 // start catch_benchmark.cpp
5708 
5709 namespace Catch {
5710 
5711  auto BenchmarkLooper::getResolution() -> uint64_t {
5712  return getEstimatedClockResolution() * getCurrentContext().getConfig()->benchmarkResolutionMultiple();
5713  }
5714 
5716  getResultCapture().benchmarkStarting( { m_name } );
5717  }
5718  auto BenchmarkLooper::needsMoreIterations() -> bool {
5719  auto elapsed = m_timer.getElapsedNanoseconds();
5720 
5721  // Exponentially increasing iterations until we're confident in our timer resolution
5722  if( elapsed < m_resolution ) {
5723  m_iterationsToRun *= 10;
5724  return true;
5725  }
5726 
5727  getResultCapture().benchmarkEnded( { { m_name }, m_count, elapsed } );
5728  return false;
5729  }
5730 
5731 } // end namespace Catch
5732 // end catch_benchmark.cpp
5733 // start catch_capture_matchers.cpp
5734 
5735 namespace Catch {
5736 
5738 
5739  // This is the general overload that takes a any string matcher
5740  // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
5741  // the Equals matcher (so the header does not mention matchers)
5742  void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString ) {
5743  std::string exceptionMessage = Catch::translateActiveException();
5744  MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );
5745  handler.handleExpr( expr );
5746  }
5747 
5748 } // namespace Catch
5749 // end catch_capture_matchers.cpp
5750 // start catch_commandline.cpp
5751 
5752 // start catch_commandline.h
5753 
5754 // start catch_clara.h
5755 
5756 // Use Catch's value for console width (store Clara's off to the side, if present)
5757 #ifdef CLARA_CONFIG_CONSOLE_WIDTH
5758 #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
5759 #undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
5760 #endif
5761 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1
5762 
5763 #ifdef __clang__
5764 #pragma clang diagnostic push
5765 #pragma clang diagnostic ignored "-Wweak-vtables"
5766 #pragma clang diagnostic ignored "-Wexit-time-destructors"
5767 #pragma clang diagnostic ignored "-Wshadow"
5768 #endif
5769 
5770 // start clara.hpp
5771 // Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
5772 //
5773 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5774 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5775 //
5776 // See https://github.com/philsquared/Clara for more details
5777 
5778 // Clara v1.1.5
5779 
5780 
5781 #ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
5782 #define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80
5783 #endif
5784 
5785 #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
5786 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH
5787 #endif
5788 
5789 #ifndef CLARA_CONFIG_OPTIONAL_TYPE
5790 #ifdef __has_include
5791 #if __has_include(<optional>) && __cplusplus >= 201703L
5792 #include <optional>
5793 #define CLARA_CONFIG_OPTIONAL_TYPE std::optional
5794 #endif
5795 #endif
5796 #endif
5797 
5798 // ----------- #included from clara_textflow.hpp -----------
5799 
5800 // TextFlowCpp
5801 //
5802 // A single-header library for wrapping and laying out basic text, by Phil Nash
5803 //
5804 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5805 // file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5806 //
5807 // This project is hosted at https://github.com/philsquared/textflowcpp
5808 
5809 
5810 #include <cassert>
5811 #include <ostream>
5812 #include <sstream>
5813 #include <vector>
5814 
5815 #ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
5816 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80
5817 #endif
5818 
5819 namespace Catch {
5820 namespace clara {
5821 namespace TextFlow {
5822 
5823 inline auto isWhitespace(char c) -> bool {
5824  static std::string chars = " \t\n\r";
5825  return chars.find(c) != std::string::npos;
5826 }
5827 inline auto isBreakableBefore(char c) -> bool {
5828  static std::string chars = "[({<|";
5829  return chars.find(c) != std::string::npos;
5830 }
5831 inline auto isBreakableAfter(char c) -> bool {
5832  static std::string chars = "])}>.,:;*+-=&/\\";
5833  return chars.find(c) != std::string::npos;
5834 }
5835 
5836 class Columns;
5837 
5838 class Column {
5839  std::vector<std::string> m_strings;
5840  size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
5841  size_t m_indent = 0;
5842  size_t m_initialIndent = std::string::npos;
5843 
5844 public:
5845  class iterator {
5846  friend Column;
5847 
5848  Column const& m_column;
5849  size_t m_stringIndex = 0;
5850  size_t m_pos = 0;
5851 
5852  size_t m_len = 0;
5853  size_t m_end = 0;
5854  bool m_suffix = false;
5855 
5856  iterator(Column const& column, size_t stringIndex)
5857  : m_column(column),
5858  m_stringIndex(stringIndex) {}
5859 
5860  auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
5861 
5862  auto isBoundary(size_t at) const -> bool {
5863  assert(at > 0);
5864  assert(at <= line().size());
5865 
5866  return at == line().size() ||
5867  (isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) ||
5868  isBreakableBefore(line()[at]) ||
5869  isBreakableAfter(line()[at - 1]);
5870  }
5871 
5872  void calcLength() {
5873  assert(m_stringIndex < m_column.m_strings.size());
5874 
5875  m_suffix = false;
5876  auto width = m_column.m_width - indent();
5877  m_end = m_pos;
5878  while (m_end < line().size() && line()[m_end] != '\n')
5879  ++m_end;
5880 
5881  if (m_end < m_pos + width) {
5882  m_len = m_end - m_pos;
5883  } else {
5884  size_t len = width;
5885  while (len > 0 && !isBoundary(m_pos + len))
5886  --len;
5887  while (len > 0 && isWhitespace(line()[m_pos + len - 1]))
5888  --len;
5889 
5890  if (len > 0) {
5891  m_len = len;
5892  } else {
5893  m_suffix = true;
5894  m_len = width - 1;
5895  }
5896  }
5897  }
5898 
5899  auto indent() const -> size_t {
5900  auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
5901  return initial == std::string::npos ? m_column.m_indent : initial;
5902  }
5903 
5904  auto addIndentAndSuffix(std::string const &plain) const -> std::string {
5905  return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain);
5906  }
5907 
5908  public:
5909  using difference_type = std::ptrdiff_t;
5910  using value_type = std::string;
5911  using pointer = value_type * ;
5912  using reference = value_type & ;
5913  using iterator_category = std::forward_iterator_tag;
5914 
5915  explicit iterator(Column const& column) : m_column(column) {
5916  assert(m_column.m_width > m_column.m_indent);
5917  assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent);
5918  calcLength();
5919  if (m_len == 0)
5920  m_stringIndex++; // Empty string
5921  }
5922 
5923  auto operator *() const -> std::string {
5924  assert(m_stringIndex < m_column.m_strings.size());
5925  assert(m_pos <= m_end);
5926  return addIndentAndSuffix(line().substr(m_pos, m_len));
5927  }
5928 
5929  auto operator ++() -> iterator& {
5930  m_pos += m_len;
5931  if (m_pos < line().size() && line()[m_pos] == '\n')
5932  m_pos += 1;
5933  else
5934  while (m_pos < line().size() && isWhitespace(line()[m_pos]))
5935  ++m_pos;
5936 
5937  if (m_pos == line().size()) {
5938  m_pos = 0;
5939  ++m_stringIndex;
5940  }
5941  if (m_stringIndex < m_column.m_strings.size())
5942  calcLength();
5943  return *this;
5944  }
5945  auto operator ++(int) -> iterator {
5946  iterator prev(*this);
5947  operator++();
5948  return prev;
5949  }
5950 
5951  auto operator ==(iterator const& other) const -> bool {
5952  return
5953  m_pos == other.m_pos &&
5954  m_stringIndex == other.m_stringIndex &&
5955  &m_column == &other.m_column;
5956  }
5957  auto operator !=(iterator const& other) const -> bool {
5958  return !operator==(other);
5959  }
5960  };
5961  using const_iterator = iterator;
5962 
5963  explicit Column(std::string const& text) { m_strings.push_back(text); }
5964 
5965  auto width(size_t newWidth) -> Column& {
5966  assert(newWidth > 0);
5967  m_width = newWidth;
5968  return *this;
5969  }
5970  auto indent(size_t newIndent) -> Column& {
5971  m_indent = newIndent;
5972  return *this;
5973  }
5974  auto initialIndent(size_t newIndent) -> Column& {
5975  m_initialIndent = newIndent;
5976  return *this;
5977  }
5978 
5979  auto width() const -> size_t { return m_width; }
5980  auto begin() const -> iterator { return iterator(*this); }
5981  auto end() const -> iterator { return { *this, m_strings.size() }; }
5982 
5983  inline friend std::ostream& operator << (std::ostream& os, Column const& col) {
5984  bool first = true;
5985  for (auto line : col) {
5986  if (first)
5987  first = false;
5988  else
5989  os << "\n";
5990  os << line;
5991  }
5992  return os;
5993  }
5994 
5995  auto operator + (Column const& other)->Columns;
5996 
5997  auto toString() const -> std::string {
5998  std::ostringstream oss;
5999  oss << *this;
6000  return oss.str();
6001  }
6002 };
6003 
6004 class Spacer : public Column {
6005 
6006 public:
6007  explicit Spacer(size_t spaceWidth) : Column("") {
6008  width(spaceWidth);
6009  }
6010 };
6011 
6012 class Columns {
6013  std::vector<Column> m_columns;
6014 
6015 public:
6016 
6017  class iterator {
6018  friend Columns;
6019  struct EndTag {};
6020 
6021  std::vector<Column> const& m_columns;
6022  std::vector<Column::iterator> m_iterators;
6023  size_t m_activeIterators;
6024 
6025  iterator(Columns const& columns, EndTag)
6026  : m_columns(columns.m_columns),
6027  m_activeIterators(0) {
6028  m_iterators.reserve(m_columns.size());
6029 
6030  for (auto const& col : m_columns)
6031  m_iterators.push_back(col.end());
6032  }
6033 
6034  public:
6035  using difference_type = std::ptrdiff_t;
6036  using value_type = std::string;
6037  using pointer = value_type * ;
6038  using reference = value_type & ;
6039  using iterator_category = std::forward_iterator_tag;
6040 
6041  explicit iterator(Columns const& columns)
6042  : m_columns(columns.m_columns),
6043  m_activeIterators(m_columns.size()) {
6044  m_iterators.reserve(m_columns.size());
6045 
6046  for (auto const& col : m_columns)
6047  m_iterators.push_back(col.begin());
6048  }
6049 
6050  auto operator ==(iterator const& other) const -> bool {
6051  return m_iterators == other.m_iterators;
6052  }
6053  auto operator !=(iterator const& other) const -> bool {
6054  return m_iterators != other.m_iterators;
6055  }
6056  auto operator *() const -> std::string {
6057  std::string row, padding;
6058 
6059  for (size_t i = 0; i < m_columns.size(); ++i) {
6060  auto width = m_columns[i].width();
6061  if (m_iterators[i] != m_columns[i].end()) {
6062  std::string col = *m_iterators[i];
6063  row += padding + col;
6064  if (col.size() < width)
6065  padding = std::string(width - col.size(), ' ');
6066  else
6067  padding = "";
6068  } else {
6069  padding += std::string(width, ' ');
6070  }
6071  }
6072  return row;
6073  }
6074  auto operator ++() -> iterator& {
6075  for (size_t i = 0; i < m_columns.size(); ++i) {
6076  if (m_iterators[i] != m_columns[i].end())
6077  ++m_iterators[i];
6078  }
6079  return *this;
6080  }
6081  auto operator ++(int) -> iterator {
6082  iterator prev(*this);
6083  operator++();
6084  return prev;
6085  }
6086  };
6087  using const_iterator = iterator;
6088 
6089  auto begin() const -> iterator { return iterator(*this); }
6090  auto end() const -> iterator { return { *this, iterator::EndTag() }; }
6091 
6092  auto operator += (Column const& col) -> Columns& {
6093  m_columns.push_back(col);
6094  return *this;
6095  }
6096  auto operator + (Column const& col) -> Columns {
6097  Columns combined = *this;
6098  combined += col;
6099  return combined;
6100  }
6101 
6102  inline friend std::ostream& operator << (std::ostream& os, Columns const& cols) {
6103 
6104  bool first = true;
6105  for (auto line : cols) {
6106  if (first)
6107  first = false;
6108  else
6109  os << "\n";
6110  os << line;
6111  }
6112  return os;
6113  }
6114 
6115  auto toString() const -> std::string {
6116  std::ostringstream oss;
6117  oss << *this;
6118  return oss.str();
6119  }
6120 };
6121 
6122 inline auto Column::operator + (Column const& other) -> Columns {
6123  Columns cols;
6124  cols += *this;
6125  cols += other;
6126  return cols;
6127 }
6128 }
6129 
6130 }
6131 }
6132 
6133 // ----------- end of #include from clara_textflow.hpp -----------
6134 // ........... back in clara.hpp
6135 
6136 #include <string>
6137 #include <memory>
6138 #include <set>
6139 #include <algorithm>
6140 
6141 #if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) )
6142 #define CATCH_PLATFORM_WINDOWS
6143 #endif
6144 
6145 namespace Catch { namespace clara {
6146 namespace detail {
6147 
6148  // Traits for extracting arg and return type of lambdas (for single argument lambdas)
6149  template<typename L>
6150  struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {};
6151 
6152  template<typename ClassT, typename ReturnT, typename... Args>
6153  struct UnaryLambdaTraits<ReturnT( ClassT::* )( Args... ) const> {
6154  static const bool isValid = false;
6155  };
6156 
6157  template<typename ClassT, typename ReturnT, typename ArgT>
6158  struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {
6159  static const bool isValid = true;
6160  using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;
6161  using ReturnType = ReturnT;
6162  };
6163 
6164  class TokenStream;
6165 
6166  // Transport for raw args (copied from main args, or supplied via init list for testing)
6167  class Args {
6168  friend TokenStream;
6169  std::string m_exeName;
6170  std::vector<std::string> m_args;
6171 
6172  public:
6173  Args( int argc, char const* const* argv )
6174  : m_exeName(argv[0]),
6175  m_args(argv + 1, argv + argc) {}
6176 
6177  Args( std::initializer_list<std::string> args )
6178  : m_exeName( *args.begin() ),
6179  m_args( args.begin()+1, args.end() )
6180  {}
6181 
6182  auto exeName() const -> std::string {
6183  return m_exeName;
6184  }
6185  };
6186 
6187  // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string
6188  // may encode an option + its argument if the : or = form is used
6189  enum class TokenType {
6190  Option, Argument
6191  };
6192  struct Token {
6193  TokenType type;
6194  std::string token;
6195  };
6196 
6197  inline auto isOptPrefix( char c ) -> bool {
6198  return c == '-'
6199 #ifdef CATCH_PLATFORM_WINDOWS
6200  || c == '/'
6201 #endif
6202  ;
6203  }
6204 
6205  // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
6206  class TokenStream {
6207  using Iterator = std::vector<std::string>::const_iterator;
6208  Iterator it;
6209  Iterator itEnd;
6210  std::vector<Token> m_tokenBuffer;
6211 
6212  void loadBuffer() {
6213  m_tokenBuffer.resize( 0 );
6214 
6215  // Skip any empty strings
6216  while( it != itEnd && it->empty() )
6217  ++it;
6218 
6219  if( it != itEnd ) {
6220  auto const &next = *it;
6221  if( isOptPrefix( next[0] ) ) {
6222  auto delimiterPos = next.find_first_of( " :=" );
6223  if( delimiterPos != std::string::npos ) {
6224  m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
6225  m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } );
6226  } else {
6227  if( next[1] != '-' && next.size() > 2 ) {
6228  std::string opt = "- ";
6229  for( size_t i = 1; i < next.size(); ++i ) {
6230  opt[1] = next[i];
6231  m_tokenBuffer.push_back( { TokenType::Option, opt } );
6232  }
6233  } else {
6234  m_tokenBuffer.push_back( { TokenType::Option, next } );
6235  }
6236  }
6237  } else {
6238  m_tokenBuffer.push_back( { TokenType::Argument, next } );
6239  }
6240  }
6241  }
6242 
6243  public:
6244  explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {}
6245 
6246  TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) {
6247  loadBuffer();
6248  }
6249 
6250  explicit operator bool() const {
6251  return !m_tokenBuffer.empty() || it != itEnd;
6252  }
6253 
6254  auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); }
6255 
6256  auto operator*() const -> Token {
6257  assert( !m_tokenBuffer.empty() );
6258  return m_tokenBuffer.front();
6259  }
6260 
6261  auto operator->() const -> Token const * {
6262  assert( !m_tokenBuffer.empty() );
6263  return &m_tokenBuffer.front();
6264  }
6265 
6266  auto operator++() -> TokenStream & {
6267  if( m_tokenBuffer.size() >= 2 ) {
6268  m_tokenBuffer.erase( m_tokenBuffer.begin() );
6269  } else {
6270  if( it != itEnd )
6271  ++it;
6272  loadBuffer();
6273  }
6274  return *this;
6275  }
6276  };
6277 
6278  class ResultBase {
6279  public:
6280  enum Type {
6281  Ok, LogicError, RuntimeError
6282  };
6283 
6284  protected:
6285  ResultBase( Type type ) : m_type( type ) {}
6286  virtual ~ResultBase() = default;
6287 
6288  virtual void enforceOk() const = 0;
6289 
6290  Type m_type;
6291  };
6292 
6293  template<typename T>
6294  class ResultValueBase : public ResultBase {
6295  public:
6296  auto value() const -> T const & {
6297  enforceOk();
6298  return m_value;
6299  }
6300 
6301  protected:
6302  ResultValueBase( Type type ) : ResultBase( type ) {}
6303 
6304  ResultValueBase( ResultValueBase const &other ) : ResultBase( other ) {
6305  if( m_type == ResultBase::Ok )
6306  new( &m_value ) T( other.m_value );
6307  }
6308 
6309  ResultValueBase( Type, T const &value ) : ResultBase( Ok ) {
6310  new( &m_value ) T( value );
6311  }
6312 
6313  auto operator=( ResultValueBase const &other ) -> ResultValueBase & {
6314  if( m_type == ResultBase::Ok )
6315  m_value.~T();
6316  ResultBase::operator=(other);
6317  if( m_type == ResultBase::Ok )
6318  new( &m_value ) T( other.m_value );
6319  return *this;
6320  }
6321 
6322  ~ResultValueBase() override {
6323  if( m_type == Ok )
6324  m_value.~T();
6325  }
6326 
6327  union {
6328  T m_value;
6329  };
6330  };
6331 
6332  template<>
6333  class ResultValueBase<void> : public ResultBase {
6334  protected:
6335  using ResultBase::ResultBase;
6336  };
6337 
6338  template<typename T = void>
6339  class BasicResult : public ResultValueBase<T> {
6340  public:
6341  template<typename U>
6342  explicit BasicResult( BasicResult<U> const &other )
6343  : ResultValueBase<T>( other.type() ),
6344  m_errorMessage( other.errorMessage() )
6345  {
6346  assert( type() != ResultBase::Ok );
6347  }
6348 
6349  template<typename U>
6350  static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; }
6351  static auto ok() -> BasicResult { return { ResultBase::Ok }; }
6352  static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; }
6353  static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; }
6354 
6355  explicit operator bool() const { return m_type == ResultBase::Ok; }
6356  auto type() const -> ResultBase::Type { return m_type; }
6357  auto errorMessage() const -> std::string { return m_errorMessage; }
6358 
6359  protected:
6360  void enforceOk() const override {
6361 
6362  // Errors shouldn't reach this point, but if they do
6363  // the actual error message will be in m_errorMessage
6364  assert( m_type != ResultBase::LogicError );
6365  assert( m_type != ResultBase::RuntimeError );
6366  if( m_type != ResultBase::Ok )
6367  std::abort();
6368  }
6369 
6370  std::string m_errorMessage; // Only populated if resultType is an error
6371 
6372  BasicResult( ResultBase::Type type, std::string const &message )
6373  : ResultValueBase<T>(type),
6374  m_errorMessage(message)
6375  {
6376  assert( m_type != ResultBase::Ok );
6377  }
6378 
6379  using ResultValueBase<T>::ResultValueBase;
6380  using ResultBase::m_type;
6381  };
6382 
6383  enum class ParseResultType {
6384  Matched, NoMatch, ShortCircuitAll, ShortCircuitSame
6385  };
6386 
6387  class ParseState {
6388  public:
6389 
6390  ParseState( ParseResultType type, TokenStream const &remainingTokens )
6391  : m_type(type),
6392  m_remainingTokens( remainingTokens )
6393  {}
6394 
6395  auto type() const -> ParseResultType { return m_type; }
6396  auto remainingTokens() const -> TokenStream { return m_remainingTokens; }
6397 
6398  private:
6399  ParseResultType m_type;
6400  TokenStream m_remainingTokens;
6401  };
6402 
6403  using Result = BasicResult<void>;
6404  using ParserResult = BasicResult<ParseResultType>;
6405  using InternalParseResult = BasicResult<ParseState>;
6406 
6407  struct HelpColumns {
6408  std::string left;
6409  std::string right;
6410  };
6411 
6412  template<typename T>
6413  inline auto convertInto( std::string const &source, T& target ) -> ParserResult {
6414  std::stringstream ss;
6415  ss << source;
6416  ss >> target;
6417  if( ss.fail() )
6418  return ParserResult::runtimeError( "Unable to convert '" + source + "' to destination type" );
6419  else
6420  return ParserResult::ok( ParseResultType::Matched );
6421  }
6422  inline auto convertInto( std::string const &source, std::string& target ) -> ParserResult {
6423  target = source;
6424  return ParserResult::ok( ParseResultType::Matched );
6425  }
6426  inline auto convertInto( std::string const &source, bool &target ) -> ParserResult {
6427  std::string srcLC = source;
6428  std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast<char>( ::tolower(c) ); } );
6429  if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
6430  target = true;
6431  else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
6432  target = false;
6433  else
6434  return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" );
6435  return ParserResult::ok( ParseResultType::Matched );
6436  }
6437 #ifdef CLARA_CONFIG_OPTIONAL_TYPE
6438  template<typename T>
6439  inline auto convertInto( std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target ) -> ParserResult {
6440  T temp;
6441  auto result = convertInto( source, temp );
6442  if( result )
6443  target = std::move(temp);
6444  return result;
6445  }
6446 #endif // CLARA_CONFIG_OPTIONAL_TYPE
6447 
6448  struct NonCopyable {
6449  NonCopyable() = default;
6450  NonCopyable( NonCopyable const & ) = delete;
6451  NonCopyable( NonCopyable && ) = delete;
6452  NonCopyable &operator=( NonCopyable const & ) = delete;
6453  NonCopyable &operator=( NonCopyable && ) = delete;
6454  };
6455 
6456  struct BoundRef : NonCopyable {
6457  virtual ~BoundRef() = default;
6458  virtual auto isContainer() const -> bool { return false; }
6459  virtual auto isFlag() const -> bool { return false; }
6460  };
6461  struct BoundValueRefBase : BoundRef {
6462  virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
6463  };
6464  struct BoundFlagRefBase : BoundRef {
6465  virtual auto setFlag( bool flag ) -> ParserResult = 0;
6466  virtual auto isFlag() const -> bool { return true; }
6467  };
6468 
6469  template<typename T>
6470  struct BoundValueRef : BoundValueRefBase {
6471  T &m_ref;
6472 
6473  explicit BoundValueRef( T &ref ) : m_ref( ref ) {}
6474 
6475  auto setValue( std::string const &arg ) -> ParserResult override {
6476  return convertInto( arg, m_ref );
6477  }
6478  };
6479 
6480  template<typename T>
6481  struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
6482  std::vector<T> &m_ref;
6483 
6484  explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {}
6485 
6486  auto isContainer() const -> bool override { return true; }
6487 
6488  auto setValue( std::string const &arg ) -> ParserResult override {
6489  T temp;
6490  auto result = convertInto( arg, temp );
6491  if( result )
6492  m_ref.push_back( temp );
6493  return result;
6494  }
6495  };
6496 
6497  struct BoundFlagRef : BoundFlagRefBase {
6498  bool &m_ref;
6499 
6500  explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {}
6501 
6502  auto setFlag( bool flag ) -> ParserResult override {
6503  m_ref = flag;
6504  return ParserResult::ok( ParseResultType::Matched );
6505  }
6506  };
6507 
6508  template<typename ReturnType>
6509  struct LambdaInvoker {
6510  static_assert( std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult" );
6511 
6512  template<typename L, typename ArgType>
6513  static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
6514  return lambda( arg );
6515  }
6516  };
6517 
6518  template<>
6519  struct LambdaInvoker<void> {
6520  template<typename L, typename ArgType>
6521  static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {
6522  lambda( arg );
6523  return ParserResult::ok( ParseResultType::Matched );
6524  }
6525  };
6526 
6527  template<typename ArgType, typename L>
6528  inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {
6529  ArgType temp{};
6530  auto result = convertInto( arg, temp );
6531  return !result
6532  ? result
6533  : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
6534  }
6535 
6536  template<typename L>
6537  struct BoundLambda : BoundValueRefBase {
6538  L m_lambda;
6539 
6540  static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
6541  explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {}
6542 
6543  auto setValue( std::string const &arg ) -> ParserResult override {
6544  return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>( m_lambda, arg );
6545  }
6546  };
6547 
6548  template<typename L>
6549  struct BoundFlagLambda : BoundFlagRefBase {
6550  L m_lambda;
6551 
6552  static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
6553  static_assert( std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, "flags must be boolean" );
6554 
6555  explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {}
6556 
6557  auto setFlag( bool flag ) -> ParserResult override {
6558  return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( m_lambda, flag );
6559  }
6560  };
6561 
6562  enum class Optionality { Optional, Required };
6563 
6564  struct Parser;
6565 
6566  class ParserBase {
6567  public:
6568  virtual ~ParserBase() = default;
6569  virtual auto validate() const -> Result { return Result::ok(); }
6570  virtual auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult = 0;
6571  virtual auto cardinality() const -> size_t { return 1; }
6572 
6573  auto parse( Args const &args ) const -> InternalParseResult {
6574  return parse( args.exeName(), TokenStream( args ) );
6575  }
6576  };
6577 
6578  template<typename DerivedT>
6579  class ComposableParserImpl : public ParserBase {
6580  public:
6581  template<typename T>
6582  auto operator|( T const &other ) const -> Parser;
6583 
6584  template<typename T>
6585  auto operator+( T const &other ) const -> Parser;
6586  };
6587 
6588  // Common code and state for Args and Opts
6589  template<typename DerivedT>
6590  class ParserRefImpl : public ComposableParserImpl<DerivedT> {
6591  protected:
6592  Optionality m_optionality = Optionality::Optional;
6593  std::shared_ptr<BoundRef> m_ref;
6594  std::string m_hint;
6595  std::string m_description;
6596 
6597  explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {}
6598 
6599  public:
6600  template<typename T>
6601  ParserRefImpl( T &ref, std::string const &hint )
6602  : m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
6603  m_hint( hint )
6604  {}
6605 
6606  template<typename LambdaT>
6607  ParserRefImpl( LambdaT const &ref, std::string const &hint )
6608  : m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),
6609  m_hint(hint)
6610  {}
6611 
6612  auto operator()( std::string const &description ) -> DerivedT & {
6613  m_description = description;
6614  return static_cast<DerivedT &>( *this );
6615  }
6616 
6617  auto optional() -> DerivedT & {
6618  m_optionality = Optionality::Optional;
6619  return static_cast<DerivedT &>( *this );
6620  };
6621 
6622  auto required() -> DerivedT & {
6623  m_optionality = Optionality::Required;
6624  return static_cast<DerivedT &>( *this );
6625  };
6626 
6627  auto isOptional() const -> bool {
6628  return m_optionality == Optionality::Optional;
6629  }
6630 
6631  auto cardinality() const -> size_t override {
6632  if( m_ref->isContainer() )
6633  return 0;
6634  else
6635  return 1;
6636  }
6637 
6638  auto hint() const -> std::string { return m_hint; }
6639  };
6640 
6641  class ExeName : public ComposableParserImpl<ExeName> {
6642  std::shared_ptr<std::string> m_name;
6643  std::shared_ptr<BoundValueRefBase> m_ref;
6644 
6645  template<typename LambdaT>
6646  static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {
6647  return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
6648  }
6649 
6650  public:
6651  ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}
6652 
6653  explicit ExeName( std::string &ref ) : ExeName() {
6654  m_ref = std::make_shared<BoundValueRef<std::string>>( ref );
6655  }
6656 
6657  template<typename LambdaT>
6658  explicit ExeName( LambdaT const& lambda ) : ExeName() {
6659  m_ref = std::make_shared<BoundLambda<LambdaT>>( lambda );
6660  }
6661 
6662  // The exe name is not parsed out of the normal tokens, but is handled specially
6663  auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
6664  return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
6665  }
6666 
6667  auto name() const -> std::string { return *m_name; }
6668  auto set( std::string const& newName ) -> ParserResult {
6669 
6670  auto lastSlash = newName.find_last_of( "\\/" );
6671  auto filename = ( lastSlash == std::string::npos )
6672  ? newName
6673  : newName.substr( lastSlash+1 );
6674 
6675  *m_name = filename;
6676  if( m_ref )
6677  return m_ref->setValue( filename );
6678  else
6679  return ParserResult::ok( ParseResultType::Matched );
6680  }
6681  };
6682 
6683  class Arg : public ParserRefImpl<Arg> {
6684  public:
6685  using ParserRefImpl::ParserRefImpl;
6686 
6687  auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override {
6688  auto validationResult = validate();
6689  if( !validationResult )
6690  return InternalParseResult( validationResult );
6691 
6692  auto remainingTokens = tokens;
6693  auto const &token = *remainingTokens;
6694  if( token.type != TokenType::Argument )
6695  return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
6696 
6697  assert( !m_ref->isFlag() );
6698  auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
6699 
6700  auto result = valueRef->setValue( remainingTokens->token );
6701  if( !result )
6702  return InternalParseResult( result );
6703  else
6704  return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
6705  }
6706  };
6707 
6708  inline auto normaliseOpt( std::string const &optName ) -> std::string {
6709 #ifdef CATCH_PLATFORM_WINDOWS
6710  if( optName[0] == '/' )
6711  return "-" + optName.substr( 1 );
6712  else
6713 #endif
6714  return optName;
6715  }
6716 
6717  class Opt : public ParserRefImpl<Opt> {
6718  protected:
6719  std::vector<std::string> m_optNames;
6720 
6721  public:
6722  template<typename LambdaT>
6723  explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared<BoundFlagLambda<LambdaT>>( ref ) ) {}
6724 
6725  explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared<BoundFlagRef>( ref ) ) {}
6726 
6727  template<typename LambdaT>
6728  Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
6729 
6730  template<typename T>
6731  Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}
6732 
6733  auto operator[]( std::string const &optName ) -> Opt & {
6734  m_optNames.push_back( optName );
6735  return *this;
6736  }
6737 
6738  auto getHelpColumns() const -> std::vector<HelpColumns> {
6739  std::ostringstream oss;
6740  bool first = true;
6741  for( auto const &opt : m_optNames ) {
6742  if (first)
6743  first = false;
6744  else
6745  oss << ", ";
6746  oss << opt;
6747  }
6748  if( !m_hint.empty() )
6749  oss << " <" << m_hint << ">";
6750  return { { oss.str(), m_description } };
6751  }
6752 
6753  auto isMatch( std::string const &optToken ) const -> bool {
6754  auto normalisedToken = normaliseOpt( optToken );
6755  for( auto const &name : m_optNames ) {
6756  if( normaliseOpt( name ) == normalisedToken )
6757  return true;
6758  }
6759  return false;
6760  }
6761 
6762  using ParserBase::parse;
6763 
6764  auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {
6765  auto validationResult = validate();
6766  if( !validationResult )
6767  return InternalParseResult( validationResult );
6768 
6769  auto remainingTokens = tokens;
6770  if( remainingTokens && remainingTokens->type == TokenType::Option ) {
6771  auto const &token = *remainingTokens;
6772  if( isMatch(token.token ) ) {
6773  if( m_ref->isFlag() ) {
6774  auto flagRef = static_cast<detail::BoundFlagRefBase*>( m_ref.get() );
6775  auto result = flagRef->setFlag( true );
6776  if( !result )
6777  return InternalParseResult( result );
6778  if( result.value() == ParseResultType::ShortCircuitAll )
6779  return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
6780  } else {
6781  auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );
6782  ++remainingTokens;
6783  if( !remainingTokens )
6784  return InternalParseResult::runtimeError( "Expected argument following " + token.token );
6785  auto const &argToken = *remainingTokens;
6786  if( argToken.type != TokenType::Argument )
6787  return InternalParseResult::runtimeError( "Expected argument following " + token.token );
6788  auto result = valueRef->setValue( argToken.token );
6789  if( !result )
6790  return InternalParseResult( result );
6791  if( result.value() == ParseResultType::ShortCircuitAll )
6792  return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
6793  }
6794  return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
6795  }
6796  }
6797  return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
6798  }
6799 
6800  auto validate() const -> Result override {
6801  if( m_optNames.empty() )
6802  return Result::logicError( "No options supplied to Opt" );
6803  for( auto const &name : m_optNames ) {
6804  if( name.empty() )
6805  return Result::logicError( "Option name cannot be empty" );
6806 #ifdef CATCH_PLATFORM_WINDOWS
6807  if( name[0] != '-' && name[0] != '/' )
6808  return Result::logicError( "Option name must begin with '-' or '/'" );
6809 #else
6810  if( name[0] != '-' )
6811  return Result::logicError( "Option name must begin with '-'" );
6812 #endif
6813  }
6814  return ParserRefImpl::validate();
6815  }
6816  };
6817 
6818  struct Help : Opt {
6819  Help( bool &showHelpFlag )
6820  : Opt([&]( bool flag ) {
6821  showHelpFlag = flag;
6822  return ParserResult::ok( ParseResultType::ShortCircuitAll );
6823  })
6824  {
6825  static_cast<Opt &>( *this )
6826  ("display usage information")
6827  ["-?"]["-h"]["--help"]
6828  .optional();
6829  }
6830  };
6831 
6832  struct Parser : ParserBase {
6833 
6834  mutable ExeName m_exeName;
6835  std::vector<Opt> m_options;
6836  std::vector<Arg> m_args;
6837 
6838  auto operator|=( ExeName const &exeName ) -> Parser & {
6839  m_exeName = exeName;
6840  return *this;
6841  }
6842 
6843  auto operator|=( Arg const &arg ) -> Parser & {
6844  m_args.push_back(arg);
6845  return *this;
6846  }
6847 
6848  auto operator|=( Opt const &opt ) -> Parser & {
6849  m_options.push_back(opt);
6850  return *this;
6851  }
6852 
6853  auto operator|=( Parser const &other ) -> Parser & {
6854  m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
6855  m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
6856  return *this;
6857  }
6858 
6859  template<typename T>
6860  auto operator|( T const &other ) const -> Parser {
6861  return Parser( *this ) |= other;
6862  }
6863 
6864  // Forward deprecated interface with '+' instead of '|'
6865  template<typename T>
6866  auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }
6867  template<typename T>
6868  auto operator+( T const &other ) const -> Parser { return operator|( other ); }
6869 
6870  auto getHelpColumns() const -> std::vector<HelpColumns> {
6871  std::vector<HelpColumns> cols;
6872  for (auto const &o : m_options) {
6873  auto childCols = o.getHelpColumns();
6874  cols.insert( cols.end(), childCols.begin(), childCols.end() );
6875  }
6876  return cols;
6877  }
6878 
6879  void writeToStream( std::ostream &os ) const {
6880  if (!m_exeName.name().empty()) {
6881  os << "usage:\n" << " " << m_exeName.name() << " ";
6882  bool required = true, first = true;
6883  for( auto const &arg : m_args ) {
6884  if (first)
6885  first = false;
6886  else
6887  os << " ";
6888  if( arg.isOptional() && required ) {
6889  os << "[";
6890  required = false;
6891  }
6892  os << "<" << arg.hint() << ">";
6893  if( arg.cardinality() == 0 )
6894  os << " ... ";
6895  }
6896  if( !required )
6897  os << "]";
6898  if( !m_options.empty() )
6899  os << " options";
6900  os << "\n\nwhere options are:" << std::endl;
6901  }
6902 
6903  auto rows = getHelpColumns();
6904  size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
6905  size_t optWidth = 0;
6906  for( auto const &cols : rows )
6907  optWidth = (std::max)(optWidth, cols.left.size() + 2);
6908 
6909  optWidth = (std::min)(optWidth, consoleWidth/2);
6910 
6911  for( auto const &cols : rows ) {
6912  auto row =
6913  TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
6914  TextFlow::Spacer(4) +
6915  TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth );
6916  os << row << std::endl;
6917  }
6918  }
6919 
6920  friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream& {
6921  parser.writeToStream( os );
6922  return os;
6923  }
6924 
6925  auto validate() const -> Result override {
6926  for( auto const &opt : m_options ) {
6927  auto result = opt.validate();
6928  if( !result )
6929  return result;
6930  }
6931  for( auto const &arg : m_args ) {
6932  auto result = arg.validate();
6933  if( !result )
6934  return result;
6935  }
6936  return Result::ok();
6937  }
6938 
6939  using ParserBase::parse;
6940 
6941  auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override {
6942 
6943  struct ParserInfo {
6944  ParserBase const* parser = nullptr;
6945  size_t count = 0;
6946  };
6947  const size_t totalParsers = m_options.size() + m_args.size();
6948  assert( totalParsers < 512 );
6949  // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do
6950  ParserInfo parseInfos[512];
6951 
6952  {
6953  size_t i = 0;
6954  for (auto const &opt : m_options) parseInfos[i++].parser = &opt;
6955  for (auto const &arg : m_args) parseInfos[i++].parser = &arg;
6956  }
6957 
6958  m_exeName.set( exeName );
6959 
6960  auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
6961  while( result.value().remainingTokens() ) {
6962  bool tokenParsed = false;
6963 
6964  for( size_t i = 0; i < totalParsers; ++i ) {
6965  auto& parseInfo = parseInfos[i];
6966  if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) {
6967  result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
6968  if (!result)
6969  return result;
6970  if (result.value().type() != ParseResultType::NoMatch) {
6971  tokenParsed = true;
6972  ++parseInfo.count;
6973  break;
6974  }
6975  }
6976  }
6977 
6978  if( result.value().type() == ParseResultType::ShortCircuitAll )
6979  return result;
6980  if( !tokenParsed )
6981  return InternalParseResult::runtimeError( "Unrecognised token: " + result.value().remainingTokens()->token );
6982  }
6983  // !TBD Check missing required options
6984  return result;
6985  }
6986  };
6987 
6988  template<typename DerivedT>
6989  template<typename T>
6990  auto ComposableParserImpl<DerivedT>::operator|( T const &other ) const -> Parser {
6991  return Parser() | static_cast<DerivedT const &>( *this ) | other;
6992  }
6993 } // namespace detail
6994 
6995 // A Combined parser
6996 using detail::Parser;
6997 
6998 // A parser for options
6999 using detail::Opt;
7000 
7001 // A parser for arguments
7002 using detail::Arg;
7003 
7004 // Wrapper for argc, argv from main()
7005 using detail::Args;
7006 
7007 // Specifies the name of the executable
7008 using detail::ExeName;
7009 
7010 // Convenience wrapper for option parser that specifies the help option
7011 using detail::Help;
7012 
7013 // enum of result types from a parse
7014 using detail::ParseResultType;
7015 
7016 // Result type for parser operation
7017 using detail::ParserResult;
7018 
7019 }} // namespace Catch::clara
7020 
7021 // end clara.hpp
7022 #ifdef __clang__
7023 #pragma clang diagnostic pop
7024 #endif
7025 
7026 // Restore Clara's value for console width, if present
7027 #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
7028 #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
7029 #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
7030 #endif
7031 
7032 // end catch_clara.h
7033 namespace Catch {
7034 
7035  clara::Parser makeCommandLineParser( ConfigData& config );
7036 
7037 } // end namespace Catch
7038 
7039 // end catch_commandline.h
7040 #include <fstream>
7041 #include <ctime>
7042 
7043 namespace Catch {
7044 
7045  clara::Parser makeCommandLineParser( ConfigData& config ) {
7046 
7047  using namespace clara;
7048 
7049  auto const setWarning = [&]( std::string const& warning ) {
7050  auto warningSet = [&]() {
7051  if( warning == "NoAssertions" )
7052  return WarnAbout::NoAssertions;
7053 
7054  if ( warning == "NoTests" )
7055  return WarnAbout::NoTests;
7056 
7057  return WarnAbout::Nothing;
7058  }();
7059 
7060  if (warningSet == WarnAbout::Nothing)
7061  return ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" );
7062  config.warnings = static_cast<WarnAbout::What>( config.warnings | warningSet );
7063  return ParserResult::ok( ParseResultType::Matched );
7064  };
7065  auto const loadTestNamesFromFile = [&]( std::string const& filename ) {
7066  std::ifstream f( filename.c_str() );
7067  if( !f.is_open() )
7068  return ParserResult::runtimeError( "Unable to load input file: '" + filename + "'" );
7069 
7070  std::string line;
7071  while( std::getline( f, line ) ) {
7072  line = trim(line);
7073  if( !line.empty() && !startsWith( line, '#' ) ) {
7074  if( !startsWith( line, '"' ) )
7075  line = '"' + line + '"';
7076  config.testsOrTags.push_back( line + ',' );
7077  }
7078  }
7079  return ParserResult::ok( ParseResultType::Matched );
7080  };
7081  auto const setTestOrder = [&]( std::string const& order ) {
7082  if( startsWith( "declared", order ) )
7083  config.runOrder = RunTests::InDeclarationOrder;
7084  else if( startsWith( "lexical", order ) )
7085  config.runOrder = RunTests::InLexicographicalOrder;
7086  else if( startsWith( "random", order ) )
7087  config.runOrder = RunTests::InRandomOrder;
7088  else
7089  return clara::ParserResult::runtimeError( "Unrecognised ordering: '" + order + "'" );
7090  return ParserResult::ok( ParseResultType::Matched );
7091  };
7092  auto const setRngSeed = [&]( std::string const& seed ) {
7093  if( seed != "time" )
7094  return clara::detail::convertInto( seed, config.rngSeed );
7095  config.rngSeed = static_cast<unsigned int>( std::time(nullptr) );
7096  return ParserResult::ok( ParseResultType::Matched );
7097  };
7098  auto const setColourUsage = [&]( std::string const& useColour ) {
7099  auto mode = toLower( useColour );
7100 
7101  if( mode == "yes" )
7102  config.useColour = UseColour::Yes;
7103  else if( mode == "no" )
7104  config.useColour = UseColour::No;
7105  else if( mode == "auto" )
7106  config.useColour = UseColour::Auto;
7107  else
7108  return ParserResult::runtimeError( "colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised" );
7109  return ParserResult::ok( ParseResultType::Matched );
7110  };
7111  auto const setWaitForKeypress = [&]( std::string const& keypress ) {
7112  auto keypressLc = toLower( keypress );
7113  if( keypressLc == "start" )
7114  config.waitForKeypress = WaitForKeypress::BeforeStart;
7115  else if( keypressLc == "exit" )
7116  config.waitForKeypress = WaitForKeypress::BeforeExit;
7117  else if( keypressLc == "both" )
7118  config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
7119  else
7120  return ParserResult::runtimeError( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" );
7121  return ParserResult::ok( ParseResultType::Matched );
7122  };
7123  auto const setVerbosity = [&]( std::string const& verbosity ) {
7124  auto lcVerbosity = toLower( verbosity );
7125  if( lcVerbosity == "quiet" )
7126  config.verbosity = Verbosity::Quiet;
7127  else if( lcVerbosity == "normal" )
7128  config.verbosity = Verbosity::Normal;
7129  else if( lcVerbosity == "high" )
7130  config.verbosity = Verbosity::High;
7131  else
7132  return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" );
7133  return ParserResult::ok( ParseResultType::Matched );
7134  };
7135  auto const setReporter = [&]( std::string const& reporter ) {
7136  IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
7137 
7138  auto lcReporter = toLower( reporter );
7139  auto result = factories.find( lcReporter );
7140 
7141  if( factories.end() != result )
7142  config.reporterName = lcReporter;
7143  else
7144  return ParserResult::runtimeError( "Unrecognized reporter, '" + reporter + "'. Check available with --list-reporters" );
7145  return ParserResult::ok( ParseResultType::Matched );
7146  };
7147 
7148  auto cli
7149  = ExeName( config.processName )
7150  | Help( config.showHelp )
7151  | Opt( config.listTests )
7152  ["-l"]["--list-tests"]
7153  ( "list all/matching test cases" )
7154  | Opt( config.listTags )
7155  ["-t"]["--list-tags"]
7156  ( "list all/matching tags" )
7157  | Opt( config.showSuccessfulTests )
7158  ["-s"]["--success"]
7159  ( "include successful tests in output" )
7160  | Opt( config.shouldDebugBreak )
7161  ["-b"]["--break"]
7162  ( "break into debugger on failure" )
7163  | Opt( config.noThrow )
7164  ["-e"]["--nothrow"]
7165  ( "skip exception tests" )
7166  | Opt( config.showInvisibles )
7167  ["-i"]["--invisibles"]
7168  ( "show invisibles (tabs, newlines)" )
7169  | Opt( config.outputFilename, "filename" )
7170  ["-o"]["--out"]
7171  ( "output filename" )
7172  | Opt( setReporter, "name" )
7173  ["-r"]["--reporter"]
7174  ( "reporter to use (defaults to console)" )
7175  | Opt( config.name, "name" )
7176  ["-n"]["--name"]
7177  ( "suite name" )
7178  | Opt( [&]( bool ){ config.abortAfter = 1; } )
7179  ["-a"]["--abort"]
7180  ( "abort at first failure" )
7181  | Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" )
7182  ["-x"]["--abortx"]
7183  ( "abort after x failures" )
7184  | Opt( setWarning, "warning name" )
7185  ["-w"]["--warn"]
7186  ( "enable warnings" )
7187  | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" )
7188  ["-d"]["--durations"]
7189  ( "show test durations" )
7190  | Opt( loadTestNamesFromFile, "filename" )
7191  ["-f"]["--input-file"]
7192  ( "load test names to run from a file" )
7193  | Opt( config.filenamesAsTags )
7194  ["-#"]["--filenames-as-tags"]
7195  ( "adds a tag for the filename" )
7196  | Opt( config.sectionsToRun, "section name" )
7197  ["-c"]["--section"]
7198  ( "specify section to run" )
7199  | Opt( setVerbosity, "quiet|normal|high" )
7200  ["-v"]["--verbosity"]
7201  ( "set output verbosity" )
7202  | Opt( config.listTestNamesOnly )
7203  ["--list-test-names-only"]
7204  ( "list all/matching test cases names only" )
7205  | Opt( config.listReporters )
7206  ["--list-reporters"]
7207  ( "list all reporters" )
7208  | Opt( setTestOrder, "decl|lex|rand" )
7209  ["--order"]
7210  ( "test case order (defaults to decl)" )
7211  | Opt( setRngSeed, "'time'|number" )
7212  ["--rng-seed"]
7213  ( "set a specific seed for random numbers" )
7214  | Opt( setColourUsage, "yes|no" )
7215  ["--use-colour"]
7216  ( "should output be colourised" )
7217  | Opt( config.libIdentify )
7218  ["--libidentify"]
7219  ( "report name and version according to libidentify standard" )
7220  | Opt( setWaitForKeypress, "start|exit|both" )
7221  ["--wait-for-keypress"]
7222  ( "waits for a keypress before exiting" )
7223  | Opt( config.benchmarkResolutionMultiple, "multiplier" )
7224  ["--benchmark-resolution-multiple"]
7225  ( "multiple of clock resolution to run benchmarks" )
7226 
7227  | Arg( config.testsOrTags, "test name|pattern|tags" )
7228  ( "which test or tests to use" );
7229 
7230  return cli;
7231  }
7232 
7233 } // end namespace Catch
7234 // end catch_commandline.cpp
7235 // start catch_common.cpp
7236 
7237 #include <cstring>
7238 #include <ostream>
7239 
7240 namespace Catch {
7241 
7242  bool SourceLineInfo::empty() const noexcept {
7243  return file[0] == '\0';
7244  }
7245  bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept {
7246  return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
7247  }
7248  bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept {
7249  // We can assume that the same file will usually have the same pointer.
7250  // Thus, if the pointers are the same, there is no point in calling the strcmp
7251  return line < other.line || ( line == other.line && file != other.file && (std::strcmp(file, other.file) < 0));
7252  }
7253 
7254  std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
7255 #ifndef __GNUG__
7256  os << info.file << '(' << info.line << ')';
7257 #else
7258  os << info.file << ':' << info.line;
7259 #endif
7260  return os;
7261  }
7262 
7263  std::string StreamEndStop::operator+() const {
7264  return std::string();
7265  }
7266 
7267  NonCopyable::NonCopyable() = default;
7268  NonCopyable::~NonCopyable() = default;
7269 
7270 }
7271 // end catch_common.cpp
7272 // start catch_config.cpp
7273 
7274 namespace Catch {
7275 
7276  Config::Config( ConfigData const& data )
7277  : m_data( data ),
7278  m_stream( openStream() )
7279  {
7280  TestSpecParser parser(ITagAliasRegistry::get());
7281  if (data.testsOrTags.empty()) {
7282  parser.parse("~[.]"); // All not hidden tests
7283  }
7284  else {
7285  m_hasTestFilters = true;
7286  for( auto const& testOrTags : data.testsOrTags )
7287  parser.parse( testOrTags );
7288  }
7289  m_testSpec = parser.testSpec();
7290  }
7291 
7292  std::string const& Config::getFilename() const {
7293  return m_data.outputFilename ;
7294  }
7295 
7296  bool Config::listTests() const { return m_data.listTests; }
7297  bool Config::listTestNamesOnly() const { return m_data.listTestNamesOnly; }
7298  bool Config::listTags() const { return m_data.listTags; }
7299  bool Config::listReporters() const { return m_data.listReporters; }
7300 
7301  std::string Config::getProcessName() const { return m_data.processName; }
7302  std::string const& Config::getReporterName() const { return m_data.reporterName; }
7303 
7304  std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }
7305  std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
7306 
7307  TestSpec const& Config::testSpec() const { return m_testSpec; }
7308  bool Config::hasTestFilters() const { return m_hasTestFilters; }
7309 
7310  bool Config::showHelp() const { return m_data.showHelp; }
7311 
7312  // IConfig interface
7313  bool Config::allowThrows() const { return !m_data.noThrow; }
7314  std::ostream& Config::stream() const { return m_stream->stream(); }
7315  std::string Config::name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
7316  bool Config::includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
7317  bool Config::warnAboutMissingAssertions() const { return !!(m_data.warnings & WarnAbout::NoAssertions); }
7318  bool Config::warnAboutNoTests() const { return !!(m_data.warnings & WarnAbout::NoTests); }
7319  ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }
7320  RunTests::InWhatOrder Config::runOrder() const { return m_data.runOrder; }
7321  unsigned int Config::rngSeed() const { return m_data.rngSeed; }
7322  int Config::benchmarkResolutionMultiple() const { return m_data.benchmarkResolutionMultiple; }
7323  UseColour::YesOrNo Config::useColour() const { return m_data.useColour; }
7324  bool Config::shouldDebugBreak() const { return m_data.shouldDebugBreak; }
7325  int Config::abortAfter() const { return m_data.abortAfter; }
7326  bool Config::showInvisibles() const { return m_data.showInvisibles; }
7327  Verbosity Config::verbosity() const { return m_data.verbosity; }
7328 
7329  IStream const* Config::openStream() {
7330  return Catch::makeStream(m_data.outputFilename);
7331  }
7332 
7333 } // end namespace Catch
7334 // end catch_config.cpp
7335 // start catch_console_colour.cpp
7336 
7337 #if defined(__clang__)
7338 # pragma clang diagnostic push
7339 # pragma clang diagnostic ignored "-Wexit-time-destructors"
7340 #endif
7341 
7342 // start catch_errno_guard.h
7343 
7344 namespace Catch {
7345 
7346  class ErrnoGuard {
7347  public:
7348  ErrnoGuard();
7349  ~ErrnoGuard();
7350  private:
7351  int m_oldErrno;
7352  };
7353 
7354 }
7355 
7356 // end catch_errno_guard.h
7357 #include <sstream>
7358 
7359 namespace Catch {
7360  namespace {
7361 
7362  struct IColourImpl {
7363  virtual ~IColourImpl() = default;
7364  virtual void use( Colour::Code _colourCode ) = 0;
7365  };
7366 
7367  struct NoColourImpl : IColourImpl {
7368  void use( Colour::Code ) {}
7369 
7370  static IColourImpl* instance() {
7371  static NoColourImpl s_instance;
7372  return &s_instance;
7373  }
7374  };
7375 
7376  } // anon namespace
7377 } // namespace Catch
7378 
7379 #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
7380 # ifdef CATCH_PLATFORM_WINDOWS
7381 # define CATCH_CONFIG_COLOUR_WINDOWS
7382 # else
7383 # define CATCH_CONFIG_COLOUR_ANSI
7384 # endif
7385 #endif
7386 
7387 #if defined ( CATCH_CONFIG_COLOUR_WINDOWS )
7388 
7389 namespace Catch {
7390 namespace {
7391 
7392  class Win32ColourImpl : public IColourImpl {
7393  public:
7394  Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
7395  {
7396  CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
7397  GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
7398  originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
7399  originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
7400  }
7401 
7402  virtual void use( Colour::Code _colourCode ) override {
7403  switch( _colourCode ) {
7404  case Colour::None: return setTextAttribute( originalForegroundAttributes );
7405  case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
7406  case Colour::Red: return setTextAttribute( FOREGROUND_RED );
7407  case Colour::Green: return setTextAttribute( FOREGROUND_GREEN );
7408  case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE );
7409  case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
7410  case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
7411  case Colour::Grey: return setTextAttribute( 0 );
7412 
7413  case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY );
7414  case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
7415  case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
7416  case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
7417  case Colour::BrightYellow: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN );
7418 
7419  case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
7420 
7421  default:
7422  CATCH_ERROR( "Unknown colour requested" );
7423  }
7424  }
7425 
7426  private:
7427  void setTextAttribute( WORD _textAttribute ) {
7428  SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
7429  }
7430  HANDLE stdoutHandle;
7431  WORD originalForegroundAttributes;
7432  WORD originalBackgroundAttributes;
7433  };
7434 
7435  IColourImpl* platformColourInstance() {
7436  static Win32ColourImpl s_instance;
7437 
7438  IConfigPtr config = getCurrentContext().getConfig();
7439  UseColour::YesOrNo colourMode = config
7440  ? config->useColour()
7441  : UseColour::Auto;
7442  if( colourMode == UseColour::Auto )
7443  colourMode = UseColour::Yes;
7444  return colourMode == UseColour::Yes
7445  ? &s_instance
7446  : NoColourImpl::instance();
7447  }
7448 
7449 } // end anon namespace
7450 } // end namespace Catch
7451 
7452 #elif defined( CATCH_CONFIG_COLOUR_ANSI )
7453 
7454 #include <unistd.h>
7455 
7456 namespace Catch {
7457 namespace {
7458 
7459  // use POSIX/ ANSI console terminal codes
7460  // Thanks to Adam Strzelecki for original contribution
7461  // (http://github.com/nanoant)
7462  // https://github.com/philsquared/Catch/pull/131
7463  class PosixColourImpl : public IColourImpl {
7464  public:
7465  virtual void use( Colour::Code _colourCode ) override {
7466  switch( _colourCode ) {
7467  case Colour::None:
7468  case Colour::White: return setColour( "[0m" );
7469  case Colour::Red: return setColour( "[0;31m" );
7470  case Colour::Green: return setColour( "[0;32m" );
7471  case Colour::Blue: return setColour( "[0;34m" );
7472  case Colour::Cyan: return setColour( "[0;36m" );
7473  case Colour::Yellow: return setColour( "[0;33m" );
7474  case Colour::Grey: return setColour( "[1;30m" );
7475 
7476  case Colour::LightGrey: return setColour( "[0;37m" );
7477  case Colour::BrightRed: return setColour( "[1;31m" );
7478  case Colour::BrightGreen: return setColour( "[1;32m" );
7479  case Colour::BrightWhite: return setColour( "[1;37m" );
7480  case Colour::BrightYellow: return setColour( "[1;33m" );
7481 
7482  case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" );
7483  default: CATCH_INTERNAL_ERROR( "Unknown colour requested" );
7484  }
7485  }
7486  static IColourImpl* instance() {
7487  static PosixColourImpl s_instance;
7488  return &s_instance;
7489  }
7490 
7491  private:
7492  void setColour( const char* _escapeCode ) {
7493  Catch::cout() << '\033' << _escapeCode;
7494  }
7495  };
7496 
7497  bool useColourOnPlatform() {
7498  return
7499 #ifdef CATCH_PLATFORM_MAC
7500  !isDebuggerActive() &&
7501 #endif
7502 #if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
7503  isatty(STDOUT_FILENO)
7504 #else
7505  false
7506 #endif
7507  ;
7508  }
7509  IColourImpl* platformColourInstance() {
7510  ErrnoGuard guard;
7511  IConfigPtr config = getCurrentContext().getConfig();
7512  UseColour::YesOrNo colourMode = config
7513  ? config->useColour()
7514  : UseColour::Auto;
7515  if( colourMode == UseColour::Auto )
7516  colourMode = useColourOnPlatform()
7517  ? UseColour::Yes
7518  : UseColour::No;
7519  return colourMode == UseColour::Yes
7520  ? PosixColourImpl::instance()
7521  : NoColourImpl::instance();
7522  }
7523 
7524 } // end anon namespace
7525 } // end namespace Catch
7526 
7527 #else // not Windows or ANSI
7528 
7529 namespace Catch {
7530 
7531  static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
7532 
7533 } // end namespace Catch
7534 
7535 #endif // Windows/ ANSI/ None
7536 
7537 namespace Catch {
7538 
7539  Colour::Colour( Code _colourCode ) { use( _colourCode ); }
7540  Colour::Colour( Colour&& rhs ) noexcept {
7541  m_moved = rhs.m_moved;
7542  rhs.m_moved = true;
7543  }
7544  Colour& Colour::operator=( Colour&& rhs ) noexcept {
7545  m_moved = rhs.m_moved;
7546  rhs.m_moved = true;
7547  return *this;
7548  }
7549 
7550  Colour::~Colour(){ if( !m_moved ) use( None ); }
7551 
7552  void Colour::use( Code _colourCode ) {
7553  static IColourImpl* impl = platformColourInstance();
7554  impl->use( _colourCode );
7555  }
7556 
7557  std::ostream& operator << ( std::ostream& os, Colour const& ) {
7558  return os;
7559  }
7560 
7561 } // end namespace Catch
7562 
7563 #if defined(__clang__)
7564 # pragma clang diagnostic pop
7565 #endif
7566 
7567 // end catch_console_colour.cpp
7568 // start catch_context.cpp
7569 
7570 namespace Catch {
7571 
7572  class Context : public IMutableContext, NonCopyable {
7573 
7574  public: // IContext
7575  virtual IResultCapture* getResultCapture() override {
7576  return m_resultCapture;
7577  }
7578  virtual IRunner* getRunner() override {
7579  return m_runner;
7580  }
7581 
7582  virtual IConfigPtr const& getConfig() const override {
7583  return m_config;
7584  }
7585 
7586  virtual ~Context() override;
7587 
7588  public: // IMutableContext
7589  virtual void setResultCapture( IResultCapture* resultCapture ) override {
7590  m_resultCapture = resultCapture;
7591  }
7592  virtual void setRunner( IRunner* runner ) override {
7593  m_runner = runner;
7594  }
7595  virtual void setConfig( IConfigPtr const& config ) override {
7596  m_config = config;
7597  }
7598 
7599  friend IMutableContext& getCurrentMutableContext();
7600 
7601  private:
7602  IConfigPtr m_config;
7603  IRunner* m_runner = nullptr;
7604  IResultCapture* m_resultCapture = nullptr;
7605  };
7606 
7607  IMutableContext *IMutableContext::currentContext = nullptr;
7608 
7609  void IMutableContext::createContext()
7610  {
7611  currentContext = new Context();
7612  }
7613 
7614  void cleanUpContext() {
7615  delete IMutableContext::currentContext;
7616  IMutableContext::currentContext = nullptr;
7617  }
7618  IContext::~IContext() = default;
7619  IMutableContext::~IMutableContext() = default;
7620  Context::~Context() = default;
7621 }
7622 // end catch_context.cpp
7623 // start catch_debug_console.cpp
7624 
7625 // start catch_debug_console.h
7626 
7627 #include <string>
7628 
7629 namespace Catch {
7630  void writeToDebugConsole( std::string const& text );
7631 }
7632 
7633 // end catch_debug_console.h
7634 #ifdef CATCH_PLATFORM_WINDOWS
7635 
7636  namespace Catch {
7637  void writeToDebugConsole( std::string const& text ) {
7638  ::OutputDebugStringA( text.c_str() );
7639  }
7640  }
7641 
7642 #else
7643 
7644  namespace Catch {
7645  void writeToDebugConsole( std::string const& text ) {
7646  // !TBD: Need a version for Mac/ XCode and other IDEs
7647  Catch::cout() << text;
7648  }
7649  }
7650 
7651 #endif // Platform
7652 // end catch_debug_console.cpp
7653 // start catch_debugger.cpp
7654 
7655 #ifdef CATCH_PLATFORM_MAC
7656 
7657 # include <assert.h>
7658 # include <stdbool.h>
7659 # include <sys/types.h>
7660 # include <unistd.h>
7661 # include <sys/sysctl.h>
7662 # include <cstddef>
7663 # include <ostream>
7664 
7665 namespace Catch {
7666 
7667  // The following function is taken directly from the following technical note:
7668  // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
7669 
7670  // Returns true if the current process is being debugged (either
7671  // running under the debugger or has a debugger attached post facto).
7672  bool isDebuggerActive(){
7673 
7674  int mib[4];
7675  struct kinfo_proc info;
7676  std::size_t size;
7677 
7678  // Initialize the flags so that, if sysctl fails for some bizarre
7679  // reason, we get a predictable result.
7680 
7681  info.kp_proc.p_flag = 0;
7682 
7683  // Initialize mib, which tells sysctl the info we want, in this case
7684  // we're looking for information about a specific process ID.
7685 
7686  mib[0] = CTL_KERN;
7687  mib[1] = KERN_PROC;
7688  mib[2] = KERN_PROC_PID;
7689  mib[3] = getpid();
7690 
7691  // Call sysctl.
7692 
7693  size = sizeof(info);
7694  if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) {
7695  Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
7696  return false;
7697  }
7698 
7699  // We're being debugged if the P_TRACED flag is set.
7700 
7701  return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
7702  }
7703  } // namespace Catch
7704 
7705 #elif defined(CATCH_PLATFORM_LINUX)
7706  #include <fstream>
7707  #include <string>
7708 
7709  namespace Catch{
7710  // The standard POSIX way of detecting a debugger is to attempt to
7711  // ptrace() the process, but this needs to be done from a child and not
7712  // this process itself to still allow attaching to this process later
7713  // if wanted, so is rather heavy. Under Linux we have the PID of the
7714  // "debugger" (which doesn't need to be gdb, of course, it could also
7715  // be strace, for example) in /proc/$PID/status, so just get it from
7716  // there instead.
7717  bool isDebuggerActive(){
7718  // Libstdc++ has a bug, where std::ifstream sets errno to 0
7719  // This way our users can properly assert over errno values
7720  ErrnoGuard guard;
7721  std::ifstream in("/proc/self/status");
7722  for( std::string line; std::getline(in, line); ) {
7723  static const int PREFIX_LEN = 11;
7724  if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
7725  // We're traced if the PID is not 0 and no other PID starts
7726  // with 0 digit, so it's enough to check for just a single
7727  // character.
7728  return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
7729  }
7730  }
7731 
7732  return false;
7733  }
7734  } // namespace Catch
7735 #elif defined(_MSC_VER)
7736  extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
7737  namespace Catch {
7738  bool isDebuggerActive() {
7739  return IsDebuggerPresent() != 0;
7740  }
7741  }
7742 #elif defined(__MINGW32__)
7743  extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
7744  namespace Catch {
7745  bool isDebuggerActive() {
7746  return IsDebuggerPresent() != 0;
7747  }
7748  }
7749 #else
7750  namespace Catch {
7751  bool isDebuggerActive() { return false; }
7752  }
7753 #endif // Platform
7754 // end catch_debugger.cpp
7755 // start catch_decomposer.cpp
7756 
7757 namespace Catch {
7758 
7760 
7761  void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {
7762  if( lhs.size() + rhs.size() < 40 &&
7763  lhs.find('\n') == std::string::npos &&
7764  rhs.find('\n') == std::string::npos )
7765  os << lhs << " " << op << " " << rhs;
7766  else
7767  os << lhs << "\n" << op << "\n" << rhs;
7768  }
7769 }
7770 // end catch_decomposer.cpp
7771 // start catch_enforce.cpp
7772 
7773 namespace Catch {
7774 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)
7775  [[noreturn]]
7776  void throw_exception(std::exception const& e) {
7777  Catch::cerr() << "Catch will terminate because it needed to throw an exception.\n"
7778  << "The message was: " << e.what() << '\n';
7779  std::terminate();
7780  }
7781 #endif
7782 } // namespace Catch;
7783 // end catch_enforce.cpp
7784 // start catch_errno_guard.cpp
7785 
7786 #include <cerrno>
7787 
7788 namespace Catch {
7789  ErrnoGuard::ErrnoGuard():m_oldErrno(errno){}
7790  ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }
7791 }
7792 // end catch_errno_guard.cpp
7793 // start catch_exception_translator_registry.cpp
7794 
7795 // start catch_exception_translator_registry.h
7796 
7797 #include <vector>
7798 #include <string>
7799 #include <memory>
7800 
7801 namespace Catch {
7802 
7803  class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
7804  public:
7805  ~ExceptionTranslatorRegistry();
7806  virtual void registerTranslator( const IExceptionTranslator* translator );
7807  virtual std::string translateActiveException() const override;
7808  std::string tryTranslators() const;
7809 
7810  private:
7811  std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators;
7812  };
7813 }
7814 
7815 // end catch_exception_translator_registry.h
7816 #ifdef __OBJC__
7817 #import "Foundation/Foundation.h"
7818 #endif
7819 
7820 namespace Catch {
7821 
7822  ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {
7823  }
7824 
7825  void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) {
7826  m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );
7827  }
7828 
7829 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
7831  try {
7832 #ifdef __OBJC__
7833  // In Objective-C try objective-c exceptions first
7834  @try {
7835  return tryTranslators();
7836  }
7837  @catch (NSException *exception) {
7838  return Catch::Detail::stringify( [exception description] );
7839  }
7840 #else
7841  // Compiling a mixed mode project with MSVC means that CLR
7842  // exceptions will be caught in (...) as well. However, these
7843  // do not fill-in std::current_exception and thus lead to crash
7844  // when attempting rethrow.
7845  // /EHa switch also causes structured exceptions to be caught
7846  // here, but they fill-in current_exception properly, so
7847  // at worst the output should be a little weird, instead of
7848  // causing a crash.
7849  if (std::current_exception() == nullptr) {
7850  return "Non C++ exception. Possibly a CLR exception.";
7851  }
7852  return tryTranslators();
7853 #endif
7854  }
7855  catch( TestFailureException& ) {
7856  std::rethrow_exception(std::current_exception());
7857  }
7858  catch( std::exception& ex ) {
7859  return ex.what();
7860  }
7861  catch( std::string& msg ) {
7862  return msg;
7863  }
7864  catch( const char* msg ) {
7865  return msg;
7866  }
7867  catch(...) {
7868  return "Unknown exception";
7869  }
7870  }
7871 
7872 #else // ^^ Exceptions are enabled // Exceptions are disabled vv
7874  CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
7875  }
7876 #endif
7877 
7878  std::string ExceptionTranslatorRegistry::tryTranslators() const {
7879  if( m_translators.empty() )
7880  std::rethrow_exception(std::current_exception());
7881  else
7882  return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );
7883  }
7884 }
7885 // end catch_exception_translator_registry.cpp
7886 // start catch_fatal_condition.cpp
7887 
7888 #if defined(__GNUC__)
7889 # pragma GCC diagnostic push
7890 # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
7891 #endif
7892 
7893 #if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )
7894 
7895 namespace {
7896  // Report the error condition
7897  void reportFatal( char const * const message ) {
7898  Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
7899  }
7900 }
7901 
7902 #endif // signals/SEH handling
7903 
7904 #if defined( CATCH_CONFIG_WINDOWS_SEH )
7905 
7906 namespace Catch {
7907  struct SignalDefs { DWORD id; const char* name; };
7908 
7909  // There is no 1-1 mapping between signals and windows exceptions.
7910  // Windows can easily distinguish between SO and SigSegV,
7911  // but SigInt, SigTerm, etc are handled differently.
7912  static SignalDefs signalDefs[] = {
7913  { EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal" },
7914  { EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" },
7915  { EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" },
7916  { EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" },
7917  };
7918 
7919  LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
7920  for (auto const& def : signalDefs) {
7921  if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
7922  reportFatal(def.name);
7923  }
7924  }
7925  // If its not an exception we care about, pass it along.
7926  // This stops us from eating debugger breaks etc.
7927  return EXCEPTION_CONTINUE_SEARCH;
7928  }
7929 
7930  FatalConditionHandler::FatalConditionHandler() {
7931  isSet = true;
7932  // 32k seems enough for Catch to handle stack overflow,
7933  // but the value was found experimentally, so there is no strong guarantee
7934  guaranteeSize = 32 * 1024;
7935  exceptionHandlerHandle = nullptr;
7936  // Register as first handler in current chain
7937  exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
7938  // Pass in guarantee size to be filled
7939  SetThreadStackGuarantee(&guaranteeSize);
7940  }
7941 
7942  void FatalConditionHandler::reset() {
7943  if (isSet) {
7944  RemoveVectoredExceptionHandler(exceptionHandlerHandle);
7945  SetThreadStackGuarantee(&guaranteeSize);
7946  exceptionHandlerHandle = nullptr;
7947  isSet = false;
7948  }
7949  }
7950 
7951  FatalConditionHandler::~FatalConditionHandler() {
7952  reset();
7953  }
7954 
7955 bool FatalConditionHandler::isSet = false;
7956 ULONG FatalConditionHandler::guaranteeSize = 0;
7957 PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;
7958 
7959 } // namespace Catch
7960 
7961 #elif defined( CATCH_CONFIG_POSIX_SIGNALS )
7962 
7963 namespace Catch {
7964 
7965  struct SignalDefs {
7966  int id;
7967  const char* name;
7968  };
7969 
7970  // 32kb for the alternate stack seems to be sufficient. However, this value
7971  // is experimentally determined, so that's not guaranteed.
7972  constexpr static std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
7973 
7974  static SignalDefs signalDefs[] = {
7975  { SIGINT, "SIGINT - Terminal interrupt signal" },
7976  { SIGILL, "SIGILL - Illegal instruction signal" },
7977  { SIGFPE, "SIGFPE - Floating point error signal" },
7978  { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
7979  { SIGTERM, "SIGTERM - Termination request signal" },
7980  { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
7981  };
7982 
7983  void FatalConditionHandler::handleSignal( int sig ) {
7984  char const * name = "<unknown signal>";
7985  for (auto const& def : signalDefs) {
7986  if (sig == def.id) {
7987  name = def.name;
7988  break;
7989  }
7990  }
7991  reset();
7992  reportFatal(name);
7993  raise( sig );
7994  }
7995 
7996  FatalConditionHandler::FatalConditionHandler() {
7997  isSet = true;
7998  stack_t sigStack;
7999  sigStack.ss_sp = altStackMem;
8000  sigStack.ss_size = sigStackSize;
8001  sigStack.ss_flags = 0;
8002  sigaltstack(&sigStack, &oldSigStack);
8003  struct sigaction sa = { };
8004 
8005  sa.sa_handler = handleSignal;
8006  sa.sa_flags = SA_ONSTACK;
8007  for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {
8008  sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
8009  }
8010  }
8011 
8012  FatalConditionHandler::~FatalConditionHandler() {
8013  reset();
8014  }
8015 
8016  void FatalConditionHandler::reset() {
8017  if( isSet ) {
8018  // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
8019  for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
8020  sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
8021  }
8022  // Return the old stack
8023  sigaltstack(&oldSigStack, nullptr);
8024  isSet = false;
8025  }
8026  }
8027 
8028  bool FatalConditionHandler::isSet = false;
8029  struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
8030  stack_t FatalConditionHandler::oldSigStack = {};
8031  char FatalConditionHandler::altStackMem[sigStackSize] = {};
8032 
8033 } // namespace Catch
8034 
8035 #else
8036 
8037 namespace Catch {
8038  void FatalConditionHandler::reset() {}
8039 }
8040 
8041 #endif // signals/SEH handling
8042 
8043 #if defined(__GNUC__)
8044 # pragma GCC diagnostic pop
8045 #endif
8046 // end catch_fatal_condition.cpp
8047 // start catch_generators.cpp
8048 
8049 // start catch_random_number_generator.h
8050 
8051 #include <algorithm>
8052 #include <random>
8053 
8054 namespace Catch {
8055 
8056  struct IConfig;
8057 
8058  std::mt19937& rng();
8059  void seedRng( IConfig const& config );
8060  unsigned int rngSeed();
8061 
8062 }
8063 
8064 // end catch_random_number_generator.h
8065 #include <limits>
8066 #include <set>
8067 
8068 namespace Catch {
8069 
8071 
8072 namespace Generators {
8073 
8074  GeneratorBase::~GeneratorBase() {}
8075 
8076  std::vector<size_t> randomiseIndices( size_t selectionSize, size_t sourceSize ) {
8077 
8078  assert( selectionSize <= sourceSize );
8079  std::vector<size_t> indices;
8080  indices.reserve( selectionSize );
8081  std::uniform_int_distribution<size_t> uid( 0, sourceSize-1 );
8082 
8083  std::set<size_t> seen;
8084  // !TBD: improve this algorithm
8085  while( indices.size() < selectionSize ) {
8086  auto index = uid( rng() );
8087  if( seen.insert( index ).second )
8088  indices.push_back( index );
8089  }
8090  return indices;
8091  }
8092 
8093  auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
8094  return getResultCapture().acquireGeneratorTracker( lineInfo );
8095  }
8096 
8097  template<>
8098  auto all<int>() -> Generator<int> {
8099  return range( std::numeric_limits<int>::min(), std::numeric_limits<int>::max() );
8100  }
8101 
8102 } // namespace Generators
8103 } // namespace Catch
8104 // end catch_generators.cpp
8105 // start catch_interfaces_capture.cpp
8106 
8107 namespace Catch {
8108  IResultCapture::~IResultCapture() = default;
8109 }
8110 // end catch_interfaces_capture.cpp
8111 // start catch_interfaces_config.cpp
8112 
8113 namespace Catch {
8114  IConfig::~IConfig() = default;
8115 }
8116 // end catch_interfaces_config.cpp
8117 // start catch_interfaces_exception.cpp
8118 
8119 namespace Catch {
8122 }
8123 // end catch_interfaces_exception.cpp
8124 // start catch_interfaces_registry_hub.cpp
8125 
8126 namespace Catch {
8127  IRegistryHub::~IRegistryHub() = default;
8129 }
8130 // end catch_interfaces_registry_hub.cpp
8131 // start catch_interfaces_reporter.cpp
8132 
8133 // start catch_reporter_listening.h
8134 
8135 namespace Catch {
8136 
8137  class ListeningReporter : public IStreamingReporter {
8138  using Reporters = std::vector<IStreamingReporterPtr>;
8139  Reporters m_listeners;
8140  IStreamingReporterPtr m_reporter = nullptr;
8141  ReporterPreferences m_preferences;
8142 
8143  public:
8144  ListeningReporter();
8145 
8146  void addListener( IStreamingReporterPtr&& listener );
8147  void addReporter( IStreamingReporterPtr&& reporter );
8148 
8149  public: // IStreamingReporter
8150 
8151  ReporterPreferences getPreferences() const override;
8152 
8153  void noMatchingTestCases( std::string const& spec ) override;
8154 
8155  static std::set<Verbosity> getSupportedVerbosities();
8156 
8157  void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;
8158  void benchmarkEnded( BenchmarkStats const& benchmarkStats ) override;
8159 
8160  void testRunStarting( TestRunInfo const& testRunInfo ) override;
8161  void testGroupStarting( GroupInfo const& groupInfo ) override;
8162  void testCaseStarting( TestCaseInfo const& testInfo ) override;
8163  void sectionStarting( SectionInfo const& sectionInfo ) override;
8164  void assertionStarting( AssertionInfo const& assertionInfo ) override;
8165 
8166  // The return value indicates if the messages buffer should be cleared:
8167  bool assertionEnded( AssertionStats const& assertionStats ) override;
8168  void sectionEnded( SectionStats const& sectionStats ) override;
8169  void testCaseEnded( TestCaseStats const& testCaseStats ) override;
8170  void testGroupEnded( TestGroupStats const& testGroupStats ) override;
8171  void testRunEnded( TestRunStats const& testRunStats ) override;
8172 
8173  void skipTest( TestCaseInfo const& testInfo ) override;
8174  bool isMulti() const override;
8175 
8176  };
8177 
8178 } // end namespace Catch
8179 
8180 // end catch_reporter_listening.h
8181 namespace Catch {
8182 
8183  ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig )
8184  : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
8185 
8186  ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream )
8187  : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
8188 
8189  std::ostream& ReporterConfig::stream() const { return *m_stream; }
8190  IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; }
8191 
8192  TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {}
8193 
8194  GroupInfo::GroupInfo( std::string const& _name,
8195  std::size_t _groupIndex,
8196  std::size_t _groupsCount )
8197  : name( _name ),
8198  groupIndex( _groupIndex ),
8199  groupsCounts( _groupsCount )
8200  {}
8201 
8202  AssertionStats::AssertionStats( AssertionResult const& _assertionResult,
8203  std::vector<MessageInfo> const& _infoMessages,
8204  Totals const& _totals )
8205  : assertionResult( _assertionResult ),
8206  infoMessages( _infoMessages ),
8207  totals( _totals )
8208  {
8209  assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;
8210 
8211  if( assertionResult.hasMessage() ) {
8212  // Copy message into messages list.
8213  // !TBD This should have been done earlier, somewhere
8214  MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
8215  builder << assertionResult.getMessage();
8216  builder.m_info.message = builder.m_stream.str();
8217 
8218  infoMessages.push_back( builder.m_info );
8219  }
8220  }
8221 
8222  AssertionStats::~AssertionStats() = default;
8223 
8224  SectionStats::SectionStats( SectionInfo const& _sectionInfo,
8225  Counts const& _assertions,
8226  double _durationInSeconds,
8227  bool _missingAssertions )
8228  : sectionInfo( _sectionInfo ),
8229  assertions( _assertions ),
8230  durationInSeconds( _durationInSeconds ),
8231  missingAssertions( _missingAssertions )
8232  {}
8233 
8234  SectionStats::~SectionStats() = default;
8235 
8236  TestCaseStats::TestCaseStats( TestCaseInfo const& _testInfo,
8237  Totals const& _totals,
8238  std::string const& _stdOut,
8239  std::string const& _stdErr,
8240  bool _aborting )
8241  : testInfo( _testInfo ),
8242  totals( _totals ),
8243  stdOut( _stdOut ),
8244  stdErr( _stdErr ),
8245  aborting( _aborting )
8246  {}
8247 
8248  TestCaseStats::~TestCaseStats() = default;
8249 
8250  TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo,
8251  Totals const& _totals,
8252  bool _aborting )
8253  : groupInfo( _groupInfo ),
8254  totals( _totals ),
8255  aborting( _aborting )
8256  {}
8257 
8258  TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo )
8259  : groupInfo( _groupInfo ),
8260  aborting( false )
8261  {}
8262 
8263  TestGroupStats::~TestGroupStats() = default;
8264 
8265  TestRunStats::TestRunStats( TestRunInfo const& _runInfo,
8266  Totals const& _totals,
8267  bool _aborting )
8268  : runInfo( _runInfo ),
8269  totals( _totals ),
8270  aborting( _aborting )
8271  {}
8272 
8273  TestRunStats::~TestRunStats() = default;
8274 
8275  void IStreamingReporter::fatalErrorEncountered( StringRef ) {}
8276  bool IStreamingReporter::isMulti() const { return false; }
8277 
8278  IReporterFactory::~IReporterFactory() = default;
8279  IReporterRegistry::~IReporterRegistry() = default;
8280 
8281 } // end namespace Catch
8282 // end catch_interfaces_reporter.cpp
8283 // start catch_interfaces_runner.cpp
8284 
8285 namespace Catch {
8286  IRunner::~IRunner() = default;
8287 }
8288 // end catch_interfaces_runner.cpp
8289 // start catch_interfaces_testcase.cpp
8290 
8291 namespace Catch {
8292  ITestInvoker::~ITestInvoker() = default;
8294 }
8295 // end catch_interfaces_testcase.cpp
8296 // start catch_leak_detector.cpp
8297 
8298 #ifdef CATCH_CONFIG_WINDOWS_CRTDBG
8299 #include <crtdbg.h>
8300 
8301 namespace Catch {
8302 
8303  LeakDetector::LeakDetector() {
8304  int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
8305  flag |= _CRTDBG_LEAK_CHECK_DF;
8306  flag |= _CRTDBG_ALLOC_MEM_DF;
8307  _CrtSetDbgFlag(flag);
8308  _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
8309  _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
8310  // Change this to leaking allocation's number to break there
8311  _CrtSetBreakAlloc(-1);
8312  }
8313 }
8314 
8315 #else
8316 
8317  Catch::LeakDetector::LeakDetector() {}
8318 
8319 #endif
8320 
8321 Catch::LeakDetector::~LeakDetector() {
8322  Catch::cleanUp();
8323 }
8324 // end catch_leak_detector.cpp
8325 // start catch_list.cpp
8326 
8327 // start catch_list.h
8328 
8329 #include <set>
8330 
8331 namespace Catch {
8332 
8333  std::size_t listTests( Config const& config );
8334 
8335  std::size_t listTestsNamesOnly( Config const& config );
8336 
8337  struct TagInfo {
8338  void add( std::string const& spelling );
8339  std::string all() const;
8340 
8341  std::set<std::string> spellings;
8342  std::size_t count = 0;
8343  };
8344 
8345  std::size_t listTags( Config const& config );
8346 
8347  std::size_t listReporters();
8348 
8349  Option<std::size_t> list( Config const& config );
8350 
8351 } // end namespace Catch
8352 
8353 // end catch_list.h
8354 // start catch_text.h
8355 
8356 namespace Catch {
8357  using namespace clara::TextFlow;
8358 }
8359 
8360 // end catch_text.h
8361 #include <limits>
8362 #include <algorithm>
8363 #include <iomanip>
8364 
8365 namespace Catch {
8366 
8367  std::size_t listTests( Config const& config ) {
8368  TestSpec testSpec = config.testSpec();
8369  if( config.hasTestFilters() )
8370  Catch::cout() << "Matching test cases:\n";
8371  else {
8372  Catch::cout() << "All available test cases:\n";
8373  }
8374 
8375  auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
8376  for( auto const& testCaseInfo : matchedTestCases ) {
8377  Colour::Code colour = testCaseInfo.isHidden()
8378  ? Colour::SecondaryText
8379  : Colour::None;
8380  Colour colourGuard( colour );
8381 
8382  Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << "\n";
8383  if( config.verbosity() >= Verbosity::High ) {
8384  Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl;
8385  std::string description = testCaseInfo.description;
8386  if( description.empty() )
8387  description = "(NO DESCRIPTION)";
8388  Catch::cout() << Column( description ).indent(4) << std::endl;
8389  }
8390  if( !testCaseInfo.tags.empty() )
8391  Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << "\n";
8392  }
8393 
8394  if( !config.hasTestFilters() )
8395  Catch::cout() << pluralise( matchedTestCases.size(), "test case" ) << '\n' << std::endl;
8396  else
8397  Catch::cout() << pluralise( matchedTestCases.size(), "matching test case" ) << '\n' << std::endl;
8398  return matchedTestCases.size();
8399  }
8400 
8401  std::size_t listTestsNamesOnly( Config const& config ) {
8402  TestSpec testSpec = config.testSpec();
8403  std::size_t matchedTests = 0;
8404  std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
8405  for( auto const& testCaseInfo : matchedTestCases ) {
8406  matchedTests++;
8407  if( startsWith( testCaseInfo.name, '#' ) )
8408  Catch::cout() << '"' << testCaseInfo.name << '"';
8409  else
8410  Catch::cout() << testCaseInfo.name;
8411  if ( config.verbosity() >= Verbosity::High )
8412  Catch::cout() << "\t@" << testCaseInfo.lineInfo;
8413  Catch::cout() << std::endl;
8414  }
8415  return matchedTests;
8416  }
8417 
8418  void TagInfo::add( std::string const& spelling ) {
8419  ++count;
8420  spellings.insert( spelling );
8421  }
8422 
8423  std::string TagInfo::all() const {
8424  std::string out;
8425  for( auto const& spelling : spellings )
8426  out += "[" + spelling + "]";
8427  return out;
8428  }
8429 
8430  std::size_t listTags( Config const& config ) {
8431  TestSpec testSpec = config.testSpec();
8432  if( config.hasTestFilters() )
8433  Catch::cout() << "Tags for matching test cases:\n";
8434  else {
8435  Catch::cout() << "All available tags:\n";
8436  }
8437 
8438  std::map<std::string, TagInfo> tagCounts;
8439 
8440  std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
8441  for( auto const& testCase : matchedTestCases ) {
8442  for( auto const& tagName : testCase.getTestCaseInfo().tags ) {
8443  std::string lcaseTagName = toLower( tagName );
8444  auto countIt = tagCounts.find( lcaseTagName );
8445  if( countIt == tagCounts.end() )
8446  countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
8447  countIt->second.add( tagName );
8448  }
8449  }
8450 
8451  for( auto const& tagCount : tagCounts ) {
8453  rss << " " << std::setw(2) << tagCount.second.count << " ";
8454  auto str = rss.str();
8455  auto wrapper = Column( tagCount.second.all() )
8456  .initialIndent( 0 )
8457  .indent( str.size() )
8458  .width( CATCH_CONFIG_CONSOLE_WIDTH-10 );
8459  Catch::cout() << str << wrapper << '\n';
8460  }
8461  Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl;
8462  return tagCounts.size();
8463  }
8464 
8465  std::size_t listReporters() {
8466  Catch::cout() << "Available reporters:\n";
8467  IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
8468  std::size_t maxNameLen = 0;
8469  for( auto const& factoryKvp : factories )
8470  maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() );
8471 
8472  for( auto const& factoryKvp : factories ) {
8473  Catch::cout()
8474  << Column( factoryKvp.first + ":" )
8475  .indent(2)
8476  .width( 5+maxNameLen )
8477  + Column( factoryKvp.second->getDescription() )
8478  .initialIndent(0)
8479  .indent(2)
8480  .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 )
8481  << "\n";
8482  }
8483  Catch::cout() << std::endl;
8484  return factories.size();
8485  }
8486 
8487  Option<std::size_t> list( Config const& config ) {
8488  Option<std::size_t> listedCount;
8489  if( config.listTests() )
8490  listedCount = listedCount.valueOr(0) + listTests( config );
8491  if( config.listTestNamesOnly() )
8492  listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
8493  if( config.listTags() )
8494  listedCount = listedCount.valueOr(0) + listTags( config );
8495  if( config.listReporters() )
8496  listedCount = listedCount.valueOr(0) + listReporters();
8497  return listedCount;
8498  }
8499 
8500 } // end namespace Catch
8501 // end catch_list.cpp
8502 // start catch_matchers.cpp
8503 
8504 namespace Catch {
8505 namespace Matchers {
8506  namespace Impl {
8507 
8508  std::string MatcherUntypedBase::toString() const {
8509  if( m_cachedToString.empty() )
8510  m_cachedToString = describe();
8511  return m_cachedToString;
8512  }
8513 
8514  MatcherUntypedBase::~MatcherUntypedBase() = default;
8515 
8516  } // namespace Impl
8517 } // namespace Matchers
8518 
8519 using namespace Matchers;
8521 
8522 } // namespace Catch
8523 // end catch_matchers.cpp
8524 // start catch_matchers_floating.cpp
8525 
8526 // start catch_to_string.hpp
8527 
8528 #include <string>
8529 
8530 namespace Catch {
8531  template <typename T>
8532  std::string to_string(T const& t) {
8533 #if defined(CATCH_CONFIG_CPP11_TO_STRING)
8534  return std::to_string(t);
8535 #else
8537  rss << t;
8538  return rss.str();
8539 #endif
8540  }
8541 } // end namespace Catch
8542 
8543 // end catch_to_string.hpp
8544 #include <cstdlib>
8545 #include <cstdint>
8546 #include <cstring>
8547 
8548 namespace Catch {
8549 namespace Matchers {
8550 namespace Floating {
8551 enum class FloatingPointKind : uint8_t {
8552  Float,
8553  Double
8554 };
8555 }
8556 }
8557 }
8558 
8559 namespace {
8560 
8561 template <typename T>
8562 struct Converter;
8563 
8564 template <>
8565 struct Converter<float> {
8566  static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
8567  Converter(float f) {
8568  std::memcpy(&i, &f, sizeof(f));
8569  }
8570  int32_t i;
8571 };
8572 
8573 template <>
8574 struct Converter<double> {
8575  static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
8576  Converter(double d) {
8577  std::memcpy(&i, &d, sizeof(d));
8578  }
8579  int64_t i;
8580 };
8581 
8582 template <typename T>
8583 auto convert(T t) -> Converter<T> {
8584  return Converter<T>(t);
8585 }
8586 
8587 template <typename FP>
8588 bool almostEqualUlps(FP lhs, FP rhs, int maxUlpDiff) {
8589  // Comparison with NaN should always be false.
8590  // This way we can rule it out before getting into the ugly details
8591  if (std::isnan(lhs) || std::isnan(rhs)) {
8592  return false;
8593  }
8594 
8595  auto lc = convert(lhs);
8596  auto rc = convert(rhs);
8597 
8598  if ((lc.i < 0) != (rc.i < 0)) {
8599  // Potentially we can have +0 and -0
8600  return lhs == rhs;
8601  }
8602 
8603  auto ulpDiff = std::abs(lc.i - rc.i);
8604  return ulpDiff <= maxUlpDiff;
8605 }
8606 
8607 }
8608 
8609 namespace Catch {
8610 namespace Matchers {
8611 namespace Floating {
8612  WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
8613  :m_target{ target }, m_margin{ margin } {
8614  CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.'
8615  << " Margin has to be non-negative.");
8616  }
8617 
8618  // Performs equivalent check of std::fabs(lhs - rhs) <= margin
8619  // But without the subtraction to allow for INFINITY in comparison
8620  bool WithinAbsMatcher::match(double const& matchee) const {
8621  return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);
8622  }
8623 
8624  std::string WithinAbsMatcher::describe() const {
8625  return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target);
8626  }
8627 
8628  WithinUlpsMatcher::WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType)
8629  :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
8630  CATCH_ENFORCE(ulps >= 0, "Invalid ULP setting: " << ulps << '.'
8631  << " ULPs have to be non-negative.");
8632  }
8633 
8634 #if defined(__clang__)
8635 #pragma clang diagnostic push
8636 // Clang <3.5 reports on the default branch in the switch below
8637 #pragma clang diagnostic ignored "-Wunreachable-code"
8638 #endif
8639 
8640  bool WithinUlpsMatcher::match(double const& matchee) const {
8641  switch (m_type) {
8642  case FloatingPointKind::Float:
8643  return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps);
8644  case FloatingPointKind::Double:
8645  return almostEqualUlps<double>(matchee, m_target, m_ulps);
8646  default:
8647  CATCH_INTERNAL_ERROR( "Unknown FloatingPointKind value" );
8648  }
8649  }
8650 
8651 #if defined(__clang__)
8652 #pragma clang diagnostic pop
8653 #endif
8654 
8655  std::string WithinUlpsMatcher::describe() const {
8656  return "is within " + Catch::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : "");
8657  }
8658 
8659 }// namespace Floating
8660 
8661 Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff) {
8662  return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
8663 }
8664 
8665 Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff) {
8666  return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
8667 }
8668 
8669 Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
8670  return Floating::WithinAbsMatcher(target, margin);
8671 }
8672 
8673 } // namespace Matchers
8674 } // namespace Catch
8675 
8676 // end catch_matchers_floating.cpp
8677 // start catch_matchers_generic.cpp
8678 
8679 std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) {
8680  if (desc.empty()) {
8681  return "matches undescribed predicate";
8682  } else {
8683  return "matches predicate: \"" + desc + '"';
8684  }
8685 }
8686 // end catch_matchers_generic.cpp
8687 // start catch_matchers_string.cpp
8688 
8689 #include <regex>
8690 
8691 namespace Catch {
8692 namespace Matchers {
8693 
8694  namespace StdString {
8695 
8696  CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
8697  : m_caseSensitivity( caseSensitivity ),
8698  m_str( adjustString( str ) )
8699  {}
8700  std::string CasedString::adjustString( std::string const& str ) const {
8701  return m_caseSensitivity == CaseSensitive::No
8702  ? toLower( str )
8703  : str;
8704  }
8705  std::string CasedString::caseSensitivitySuffix() const {
8706  return m_caseSensitivity == CaseSensitive::No
8707  ? " (case insensitive)"
8708  : std::string();
8709  }
8710 
8711  StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )
8712  : m_comparator( comparator ),
8713  m_operation( operation ) {
8714  }
8715 
8716  std::string StringMatcherBase::describe() const {
8717  std::string description;
8718  description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +
8719  m_comparator.caseSensitivitySuffix().size());
8720  description += m_operation;
8721  description += ": \"";
8722  description += m_comparator.m_str;
8723  description += "\"";
8724  description += m_comparator.caseSensitivitySuffix();
8725  return description;
8726  }
8727 
8728  EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {}
8729 
8730  bool EqualsMatcher::match( std::string const& source ) const {
8731  return m_comparator.adjustString( source ) == m_comparator.m_str;
8732  }
8733 
8734  ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {}
8735 
8736  bool ContainsMatcher::match( std::string const& source ) const {
8737  return contains( m_comparator.adjustString( source ), m_comparator.m_str );
8738  }
8739 
8740  StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {}
8741 
8742  bool StartsWithMatcher::match( std::string const& source ) const {
8743  return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );
8744  }
8745 
8746  EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {}
8747 
8748  bool EndsWithMatcher::match( std::string const& source ) const {
8749  return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );
8750  }
8751 
8752  RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity): m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {}
8753 
8754  bool RegexMatcher::match(std::string const& matchee) const {
8755  auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway
8756  if (m_caseSensitivity == CaseSensitive::Choice::No) {
8757  flags |= std::regex::icase;
8758  }
8759  auto reg = std::regex(m_regex, flags);
8760  return std::regex_match(matchee, reg);
8761  }
8762 
8763  std::string RegexMatcher::describe() const {
8764  return "matches " + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? " case sensitively" : " case insensitively");
8765  }
8766 
8767  } // namespace StdString
8768 
8769  StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
8770  return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );
8771  }
8772  StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
8773  return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );
8774  }
8775  StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
8776  return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );
8777  }
8778  StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
8779  return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );
8780  }
8781 
8782  StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity) {
8783  return StdString::RegexMatcher(regex, caseSensitivity);
8784  }
8785 
8786 } // namespace Matchers
8787 } // namespace Catch
8788 // end catch_matchers_string.cpp
8789 // start catch_message.cpp
8790 
8791 // start catch_uncaught_exceptions.h
8792 
8793 namespace Catch {
8794  bool uncaught_exceptions();
8795 } // end namespace Catch
8796 
8797 // end catch_uncaught_exceptions.h
8798 #include <cassert>
8799 
8800 namespace Catch {
8801 
8802  MessageInfo::MessageInfo( StringRef const& _macroName,
8803  SourceLineInfo const& _lineInfo,
8804  ResultWas::OfType _type )
8805  : macroName( _macroName ),
8806  lineInfo( _lineInfo ),
8807  type( _type ),
8808  sequence( ++globalCount )
8809  {}
8810 
8811  bool MessageInfo::operator==( MessageInfo const& other ) const {
8812  return sequence == other.sequence;
8813  }
8814 
8815  bool MessageInfo::operator<( MessageInfo const& other ) const {
8816  return sequence < other.sequence;
8817  }
8818 
8819  // This may need protecting if threading support is added
8820  unsigned int MessageInfo::globalCount = 0;
8821 
8823 
8825  SourceLineInfo const& lineInfo,
8826  ResultWas::OfType type )
8827  :m_info(macroName, lineInfo, type) {}
8828 
8830 
8832  : m_info( builder.m_info )
8833  {
8834  m_info.message = builder.m_stream.str();
8835  getResultCapture().pushScopedMessage( m_info );
8836  }
8837 
8839  if ( !uncaught_exceptions() ){
8841  }
8842  }
8843 
8844  Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {
8845  auto start = std::string::npos;
8846  for( size_t pos = 0; pos <= names.size(); ++pos ) {
8847  char c = names[pos];
8848  if( pos == names.size() || c == ' ' || c == '\t' || c == ',' || c == ']' ) {
8849  if( start != std::string::npos ) {
8850  m_messages.push_back( MessageInfo( macroName, lineInfo, resultType ) );
8851  m_messages.back().message = names.substr( start, pos-start) + " := ";
8852  start = std::string::npos;
8853  }
8854  }
8855  else if( c != '[' && c != ']' && start == std::string::npos )
8856  start = pos;
8857  }
8858  }
8860  if ( !uncaught_exceptions() ){
8861  assert( m_captured == m_messages.size() );
8862  for( size_t i = 0; i < m_captured; ++i )
8863  m_resultCapture.popScopedMessage( m_messages[i] );
8864  }
8865  }
8866 
8867  void Capturer::captureValue( size_t index, StringRef value ) {
8868  assert( index < m_messages.size() );
8869  m_messages[index].message += value;
8870  m_resultCapture.pushScopedMessage( m_messages[index] );
8871  m_captured++;
8872  }
8873 
8874 } // end namespace Catch
8875 // end catch_message.cpp
8876 // start catch_output_redirect.cpp
8877 
8878 // start catch_output_redirect.h
8879 #ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
8880 #define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
8881 
8882 #include <cstdio>
8883 #include <iosfwd>
8884 #include <string>
8885 
8886 namespace Catch {
8887 
8888  class RedirectedStream {
8889  std::ostream& m_originalStream;
8890  std::ostream& m_redirectionStream;
8891  std::streambuf* m_prevBuf;
8892 
8893  public:
8894  RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream );
8895  ~RedirectedStream();
8896  };
8897 
8898  class RedirectedStdOut {
8899  ReusableStringStream m_rss;
8900  RedirectedStream m_cout;
8901  public:
8902  RedirectedStdOut();
8903  auto str() const -> std::string;
8904  };
8905 
8906  // StdErr has two constituent streams in C++, std::cerr and std::clog
8907  // This means that we need to redirect 2 streams into 1 to keep proper
8908  // order of writes
8909  class RedirectedStdErr {
8910  ReusableStringStream m_rss;
8911  RedirectedStream m_cerr;
8912  RedirectedStream m_clog;
8913  public:
8914  RedirectedStdErr();
8915  auto str() const -> std::string;
8916  };
8917 
8918 #if defined(CATCH_CONFIG_NEW_CAPTURE)
8919 
8920  // Windows's implementation of std::tmpfile is terrible (it tries
8921  // to create a file inside system folder, thus requiring elevated
8922  // privileges for the binary), so we have to use tmpnam(_s) and
8923  // create the file ourselves there.
8924  class TempFile {
8925  public:
8926  TempFile(TempFile const&) = delete;
8927  TempFile& operator=(TempFile const&) = delete;
8928  TempFile(TempFile&&) = delete;
8929  TempFile& operator=(TempFile&&) = delete;
8930 
8931  TempFile();
8932  ~TempFile();
8933 
8934  std::FILE* getFile();
8935  std::string getContents();
8936 
8937  private:
8938  std::FILE* m_file = nullptr;
8939  #if defined(_MSC_VER)
8940  char m_buffer[L_tmpnam] = { 0 };
8941  #endif
8942  };
8943 
8944  class OutputRedirect {
8945  public:
8946  OutputRedirect(OutputRedirect const&) = delete;
8947  OutputRedirect& operator=(OutputRedirect const&) = delete;
8948  OutputRedirect(OutputRedirect&&) = delete;
8949  OutputRedirect& operator=(OutputRedirect&&) = delete;
8950 
8951  OutputRedirect(std::string& stdout_dest, std::string& stderr_dest);
8952  ~OutputRedirect();
8953 
8954  private:
8955  int m_originalStdout = -1;
8956  int m_originalStderr = -1;
8957  TempFile m_stdoutFile;
8958  TempFile m_stderrFile;
8959  std::string& m_stdoutDest;
8960  std::string& m_stderrDest;
8961  };
8962 
8963 #endif
8964 
8965 } // end namespace Catch
8966 
8967 #endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
8968 // end catch_output_redirect.h
8969 #include <cstdio>
8970 #include <cstring>
8971 #include <fstream>
8972 #include <sstream>
8973 #include <stdexcept>
8974 
8975 #if defined(CATCH_CONFIG_NEW_CAPTURE)
8976  #if defined(_MSC_VER)
8977  #include <io.h> //_dup and _dup2
8978  #define dup _dup
8979  #define dup2 _dup2
8980  #define fileno _fileno
8981  #else
8982  #include <unistd.h> // dup and dup2
8983  #endif
8984 #endif
8985 
8986 namespace Catch {
8987 
8988  RedirectedStream::RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream )
8989  : m_originalStream( originalStream ),
8990  m_redirectionStream( redirectionStream ),
8991  m_prevBuf( m_originalStream.rdbuf() )
8992  {
8993  m_originalStream.rdbuf( m_redirectionStream.rdbuf() );
8994  }
8995 
8996  RedirectedStream::~RedirectedStream() {
8997  m_originalStream.rdbuf( m_prevBuf );
8998  }
8999 
9000  RedirectedStdOut::RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {}
9001  auto RedirectedStdOut::str() const -> std::string { return m_rss.str(); }
9002 
9003  RedirectedStdErr::RedirectedStdErr()
9004  : m_cerr( Catch::cerr(), m_rss.get() ),
9005  m_clog( Catch::clog(), m_rss.get() )
9006  {}
9007  auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }
9008 
9009 #if defined(CATCH_CONFIG_NEW_CAPTURE)
9010 
9011 #if defined(_MSC_VER)
9012  TempFile::TempFile() {
9013  if (tmpnam_s(m_buffer)) {
9014  CATCH_RUNTIME_ERROR("Could not get a temp filename");
9015  }
9016  if (fopen_s(&m_file, m_buffer, "w")) {
9017  char buffer[100];
9018  if (strerror_s(buffer, errno)) {
9019  CATCH_RUNTIME_ERROR("Could not translate errno to a string");
9020  }
9021  CATCH_RUNTIME_ERROR("Coul dnot open the temp file: '" << m_buffer << "' because: " << buffer);
9022  }
9023  }
9024 #else
9025  TempFile::TempFile() {
9026  m_file = std::tmpfile();
9027  if (!m_file) {
9028  CATCH_RUNTIME_ERROR("Could not create a temp file.");
9029  }
9030  }
9031 
9032 #endif
9033 
9034  TempFile::~TempFile() {
9035  // TBD: What to do about errors here?
9036  std::fclose(m_file);
9037  // We manually create the file on Windows only, on Linux
9038  // it will be autodeleted
9039 #if defined(_MSC_VER)
9040  std::remove(m_buffer);
9041 #endif
9042  }
9043 
9044  FILE* TempFile::getFile() {
9045  return m_file;
9046  }
9047 
9048  std::string TempFile::getContents() {
9049  std::stringstream sstr;
9050  char buffer[100] = {};
9051  std::rewind(m_file);
9052  while (std::fgets(buffer, sizeof(buffer), m_file)) {
9053  sstr << buffer;
9054  }
9055  return sstr.str();
9056  }
9057 
9058  OutputRedirect::OutputRedirect(std::string& stdout_dest, std::string& stderr_dest) :
9059  m_originalStdout(dup(1)),
9060  m_originalStderr(dup(2)),
9061  m_stdoutDest(stdout_dest),
9062  m_stderrDest(stderr_dest) {
9063  dup2(fileno(m_stdoutFile.getFile()), 1);
9064  dup2(fileno(m_stderrFile.getFile()), 2);
9065  }
9066 
9067  OutputRedirect::~OutputRedirect() {
9068  Catch::cout() << std::flush;
9069  fflush(stdout);
9070  // Since we support overriding these streams, we flush cerr
9071  // even though std::cerr is unbuffered
9072  Catch::cerr() << std::flush;
9073  Catch::clog() << std::flush;
9074  fflush(stderr);
9075 
9076  dup2(m_originalStdout, 1);
9077  dup2(m_originalStderr, 2);
9078 
9079  m_stdoutDest += m_stdoutFile.getContents();
9080  m_stderrDest += m_stderrFile.getContents();
9081  }
9082 
9083 #endif // CATCH_CONFIG_NEW_CAPTURE
9084 
9085 } // namespace Catch
9086 
9087 #if defined(CATCH_CONFIG_NEW_CAPTURE)
9088  #if defined(_MSC_VER)
9089  #undef dup
9090  #undef dup2
9091  #undef fileno
9092  #endif
9093 #endif
9094 // end catch_output_redirect.cpp
9095 // start catch_random_number_generator.cpp
9096 
9097 namespace Catch {
9098 
9099  std::mt19937& rng() {
9100  static std::mt19937 s_rng;
9101  return s_rng;
9102  }
9103 
9104  void seedRng( IConfig const& config ) {
9105  if( config.rngSeed() != 0 ) {
9106  std::srand( config.rngSeed() );
9107  rng().seed( config.rngSeed() );
9108  }
9109  }
9110 
9111  unsigned int rngSeed() {
9112  return getCurrentContext().getConfig()->rngSeed();
9113  }
9114 }
9115 // end catch_random_number_generator.cpp
9116 // start catch_registry_hub.cpp
9117 
9118 // start catch_test_case_registry_impl.h
9119 
9120 #include <vector>
9121 #include <set>
9122 #include <algorithm>
9123 #include <ios>
9124 
9125 namespace Catch {
9126 
9127  class TestCase;
9128  struct IConfig;
9129 
9130  std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases );
9131  bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
9132 
9133  void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions );
9134 
9135  std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
9136  std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
9137 
9138  class TestRegistry : public ITestCaseRegistry {
9139  public:
9140  virtual ~TestRegistry() = default;
9141 
9142  virtual void registerTest( TestCase const& testCase );
9143 
9144  std::vector<TestCase> const& getAllTests() const override;
9145  std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const override;
9146 
9147  private:
9148  std::vector<TestCase> m_functions;
9149  mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;
9150  mutable std::vector<TestCase> m_sortedFunctions;
9151  std::size_t m_unnamedCount = 0;
9152  std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
9153  };
9154 
9156 
9157  class TestInvokerAsFunction : public ITestInvoker {
9158  void(*m_testAsFunction)();
9159  public:
9160  TestInvokerAsFunction( void(*testAsFunction)() ) noexcept;
9161 
9162  void invoke() const override;
9163  };
9164 
9165  std::string extractClassName( StringRef const& classOrQualifiedMethodName );
9166 
9168 
9169 } // end namespace Catch
9170 
9171 // end catch_test_case_registry_impl.h
9172 // start catch_reporter_registry.h
9173 
9174 #include <map>
9175 
9176 namespace Catch {
9177 
9178  class ReporterRegistry : public IReporterRegistry {
9179 
9180  public:
9181 
9182  ~ReporterRegistry() override;
9183 
9184  IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const override;
9185 
9186  void registerReporter( std::string const& name, IReporterFactoryPtr const& factory );
9187  void registerListener( IReporterFactoryPtr const& factory );
9188 
9189  FactoryMap const& getFactories() const override;
9190  Listeners const& getListeners() const override;
9191 
9192  private:
9193  FactoryMap m_factories;
9194  Listeners m_listeners;
9195  };
9196 }
9197 
9198 // end catch_reporter_registry.h
9199 // start catch_tag_alias_registry.h
9200 
9201 // start catch_tag_alias.h
9202 
9203 #include <string>
9204 
9205 namespace Catch {
9206 
9207  struct TagAlias {
9208  TagAlias(std::string const& _tag, SourceLineInfo _lineInfo);
9209 
9210  std::string tag;
9211  SourceLineInfo lineInfo;
9212  };
9213 
9214 } // end namespace Catch
9215 
9216 // end catch_tag_alias.h
9217 #include <map>
9218 
9219 namespace Catch {
9220 
9221  class TagAliasRegistry : public ITagAliasRegistry {
9222  public:
9223  ~TagAliasRegistry() override;
9224  TagAlias const* find( std::string const& alias ) const override;
9225  std::string expandAliases( std::string const& unexpandedTestSpec ) const override;
9226  void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
9227 
9228  private:
9229  std::map<std::string, TagAlias> m_registry;
9230  };
9231 
9232 } // end namespace Catch
9233 
9234 // end catch_tag_alias_registry.h
9235 // start catch_startup_exception_registry.h
9236 
9237 #include <vector>
9238 #include <exception>
9239 
9240 namespace Catch {
9241 
9242  class StartupExceptionRegistry {
9243  public:
9244  void add(std::exception_ptr const& exception) noexcept;
9245  std::vector<std::exception_ptr> const& getExceptions() const noexcept;
9246  private:
9247  std::vector<std::exception_ptr> m_exceptions;
9248  };
9249 
9250 } // end namespace Catch
9251 
9252 // end catch_startup_exception_registry.h
9253 // start catch_singletons.hpp
9254 
9255 namespace Catch {
9256 
9257  struct ISingleton {
9258  virtual ~ISingleton();
9259  };
9260 
9261  void addSingleton( ISingleton* singleton );
9262  void cleanupSingletons();
9263 
9264  template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>
9265  class Singleton : SingletonImplT, public ISingleton {
9266 
9267  static auto getInternal() -> Singleton* {
9268  static Singleton* s_instance = nullptr;
9269  if( !s_instance ) {
9270  s_instance = new Singleton;
9271  addSingleton( s_instance );
9272  }
9273  return s_instance;
9274  }
9275 
9276  public:
9277  static auto get() -> InterfaceT const& {
9278  return *getInternal();
9279  }
9280  static auto getMutable() -> MutableInterfaceT& {
9281  return *getInternal();
9282  }
9283  };
9284 
9285 } // namespace Catch
9286 
9287 // end catch_singletons.hpp
9288 namespace Catch {
9289 
9290  namespace {
9291 
9292  class RegistryHub : public IRegistryHub, public IMutableRegistryHub,
9293  private NonCopyable {
9294 
9295  public: // IRegistryHub
9296  RegistryHub() = default;
9297  IReporterRegistry const& getReporterRegistry() const override {
9298  return m_reporterRegistry;
9299  }
9300  ITestCaseRegistry const& getTestCaseRegistry() const override {
9301  return m_testCaseRegistry;
9302  }
9303  IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override {
9304  return m_exceptionTranslatorRegistry;
9305  }
9306  ITagAliasRegistry const& getTagAliasRegistry() const override {
9307  return m_tagAliasRegistry;
9308  }
9309  StartupExceptionRegistry const& getStartupExceptionRegistry() const override {
9310  return m_exceptionRegistry;
9311  }
9312 
9313  public: // IMutableRegistryHub
9314  void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) override {
9315  m_reporterRegistry.registerReporter( name, factory );
9316  }
9317  void registerListener( IReporterFactoryPtr const& factory ) override {
9318  m_reporterRegistry.registerListener( factory );
9319  }
9320  void registerTest( TestCase const& testInfo ) override {
9321  m_testCaseRegistry.registerTest( testInfo );
9322  }
9323  void registerTranslator( const IExceptionTranslator* translator ) override {
9324  m_exceptionTranslatorRegistry.registerTranslator( translator );
9325  }
9326  void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override {
9327  m_tagAliasRegistry.add( alias, tag, lineInfo );
9328  }
9329  void registerStartupException() noexcept override {
9330  m_exceptionRegistry.add(std::current_exception());
9331  }
9332 
9333  private:
9334  TestRegistry m_testCaseRegistry;
9335  ReporterRegistry m_reporterRegistry;
9336  ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
9337  TagAliasRegistry m_tagAliasRegistry;
9338  StartupExceptionRegistry m_exceptionRegistry;
9339  };
9340  }
9341 
9342  using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>;
9343 
9344  IRegistryHub const& getRegistryHub() {
9345  return RegistryHubSingleton::get();
9346  }
9348  return RegistryHubSingleton::getMutable();
9349  }
9350  void cleanUp() {
9351  cleanupSingletons();
9352  cleanUpContext();
9353  }
9354  std::string translateActiveException() {
9356  }
9357 
9358 } // end namespace Catch
9359 // end catch_registry_hub.cpp
9360 // start catch_reporter_registry.cpp
9361 
9362 namespace Catch {
9363 
9364  ReporterRegistry::~ReporterRegistry() = default;
9365 
9366  IStreamingReporterPtr ReporterRegistry::create( std::string const& name, IConfigPtr const& config ) const {
9367  auto it = m_factories.find( name );
9368  if( it == m_factories.end() )
9369  return nullptr;
9370  return it->second->create( ReporterConfig( config ) );
9371  }
9372 
9373  void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) {
9374  m_factories.emplace(name, factory);
9375  }
9376  void ReporterRegistry::registerListener( IReporterFactoryPtr const& factory ) {
9377  m_listeners.push_back( factory );
9378  }
9379 
9380  IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const {
9381  return m_factories;
9382  }
9383  IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const {
9384  return m_listeners;
9385  }
9386 
9387 }
9388 // end catch_reporter_registry.cpp
9389 // start catch_result_type.cpp
9390 
9391 namespace Catch {
9392 
9393  bool isOk( ResultWas::OfType resultType ) {
9394  return ( resultType & ResultWas::FailureBit ) == 0;
9395  }
9396  bool isJustInfo( int flags ) {
9397  return flags == ResultWas::Info;
9398  }
9399 
9401  return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
9402  }
9403 
9404  bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
9405  bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
9406 
9407 } // end namespace Catch
9408 // end catch_result_type.cpp
9409 // start catch_run_context.cpp
9410 
9411 #include <cassert>
9412 #include <algorithm>
9413 #include <sstream>
9414 
9415 namespace Catch {
9416 
9417  namespace Generators {
9418  struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {
9419  size_t m_index = static_cast<size_t>( -1 );
9420  GeneratorBasePtr m_generator;
9421 
9422  GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
9423  : TrackerBase( nameAndLocation, ctx, parent )
9424  {}
9425  ~GeneratorTracker();
9426 
9427  static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {
9428  std::shared_ptr<GeneratorTracker> tracker;
9429 
9430  ITracker& currentTracker = ctx.currentTracker();
9431  if( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
9432  assert( childTracker );
9433  assert( childTracker->isIndexTracker() );
9434  tracker = std::static_pointer_cast<GeneratorTracker>( childTracker );
9435  }
9436  else {
9437  tracker = std::make_shared<GeneratorTracker>( nameAndLocation, ctx, &currentTracker );
9438  currentTracker.addChild( tracker );
9439  }
9440 
9441  if( !ctx.completedCycle() && !tracker->isComplete() ) {
9442  if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
9443  tracker->moveNext();
9444  tracker->open();
9445  }
9446 
9447  return *tracker;
9448  }
9449 
9450  void moveNext() {
9451  m_index++;
9452  m_children.clear();
9453  }
9454 
9455  // TrackerBase interface
9456  bool isIndexTracker() const override { return true; }
9457  auto hasGenerator() const -> bool override {
9458  return !!m_generator;
9459  }
9460  void close() override {
9461  TrackerBase::close();
9462  if( m_runState == CompletedSuccessfully && m_index < m_generator->size()-1 )
9463  m_runState = Executing;
9464  }
9465 
9466  // IGeneratorTracker interface
9467  auto getGenerator() const -> GeneratorBasePtr const& override {
9468  return m_generator;
9469  }
9470  void setGenerator( GeneratorBasePtr&& generator ) override {
9471  m_generator = std::move( generator );
9472  }
9473  auto getIndex() const -> size_t override {
9474  return m_index;
9475  }
9476  };
9477  GeneratorTracker::~GeneratorTracker() {}
9478  }
9479 
9480  RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
9481  : m_runInfo(_config->name()),
9482  m_context(getCurrentMutableContext()),
9483  m_config(_config),
9484  m_reporter(std::move(reporter)),
9485  m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
9486  m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )
9487  {
9488  m_context.setRunner(this);
9489  m_context.setConfig(m_config);
9490  m_context.setResultCapture(this);
9491  m_reporter->testRunStarting(m_runInfo);
9492  }
9493 
9494  RunContext::~RunContext() {
9495  m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
9496  }
9497 
9498  void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) {
9499  m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));
9500  }
9501 
9502  void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) {
9503  m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));
9504  }
9505 
9506  Totals RunContext::runTest(TestCase const& testCase) {
9507  Totals prevTotals = m_totals;
9508 
9509  std::string redirectedCout;
9510  std::string redirectedCerr;
9511 
9512  auto const& testInfo = testCase.getTestCaseInfo();
9513 
9514  m_reporter->testCaseStarting(testInfo);
9515 
9516  m_activeTestCase = &testCase;
9517 
9518  ITracker& rootTracker = m_trackerContext.startRun();
9519  assert(rootTracker.isSectionTracker());
9520  static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun());
9521  do {
9522  m_trackerContext.startCycle();
9523  m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));
9524  runCurrentTest(redirectedCout, redirectedCerr);
9525  } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());
9526 
9527  Totals deltaTotals = m_totals.delta(prevTotals);
9528  if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) {
9529  deltaTotals.assertions.failed++;
9530  deltaTotals.testCases.passed--;
9531  deltaTotals.testCases.failed++;
9532  }
9533  m_totals.testCases += deltaTotals.testCases;
9534  m_reporter->testCaseEnded(TestCaseStats(testInfo,
9535  deltaTotals,
9536  redirectedCout,
9537  redirectedCerr,
9538  aborting()));
9539 
9540  m_activeTestCase = nullptr;
9541  m_testCaseTracker = nullptr;
9542 
9543  return deltaTotals;
9544  }
9545 
9546  IConfigPtr RunContext::config() const {
9547  return m_config;
9548  }
9549 
9550  IStreamingReporter& RunContext::reporter() const {
9551  return *m_reporter;
9552  }
9553 
9554  void RunContext::assertionEnded(AssertionResult const & result) {
9555  if (result.getResultType() == ResultWas::Ok) {
9556  m_totals.assertions.passed++;
9557  m_lastAssertionPassed = true;
9558  } else if (!result.isOk()) {
9559  m_lastAssertionPassed = false;
9560  if( m_activeTestCase->getTestCaseInfo().okToFail() )
9561  m_totals.assertions.failedButOk++;
9562  else
9563  m_totals.assertions.failed++;
9564  }
9565  else {
9566  m_lastAssertionPassed = true;
9567  }
9568 
9569  // We have no use for the return value (whether messages should be cleared), because messages were made scoped
9570  // and should be let to clear themselves out.
9571  static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
9572 
9573  // Reset working state
9574  resetAssertionInfo();
9575  m_lastResult = result;
9576  }
9577  void RunContext::resetAssertionInfo() {
9578  m_lastAssertionInfo.macroName = StringRef();
9579  m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
9580  }
9581 
9582  bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) {
9583  ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));
9584  if (!sectionTracker.isOpen())
9585  return false;
9586  m_activeSections.push_back(&sectionTracker);
9587 
9588  m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
9589 
9590  m_reporter->sectionStarting(sectionInfo);
9591 
9592  assertions = m_totals.assertions;
9593 
9594  return true;
9595  }
9597  using namespace Generators;
9598  GeneratorTracker& tracker = GeneratorTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( "generator", lineInfo ) );
9599  assert( tracker.isOpen() );
9600  m_lastAssertionInfo.lineInfo = lineInfo;
9601  return tracker;
9602  }
9603 
9604  bool RunContext::testForMissingAssertions(Counts& assertions) {
9605  if (assertions.total() != 0)
9606  return false;
9607  if (!m_config->warnAboutMissingAssertions())
9608  return false;
9609  if (m_trackerContext.currentTracker().hasChildren())
9610  return false;
9611  m_totals.assertions.failed++;
9612  assertions.failed++;
9613  return true;
9614  }
9615 
9616  void RunContext::sectionEnded(SectionEndInfo const & endInfo) {
9617  Counts assertions = m_totals.assertions - endInfo.prevAssertions;
9618  bool missingAssertions = testForMissingAssertions(assertions);
9619 
9620  if (!m_activeSections.empty()) {
9621  m_activeSections.back()->close();
9622  m_activeSections.pop_back();
9623  }
9624 
9625  m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
9626  m_messages.clear();
9627  }
9628 
9629  void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {
9630  if (m_unfinishedSections.empty())
9631  m_activeSections.back()->fail();
9632  else
9633  m_activeSections.back()->close();
9634  m_activeSections.pop_back();
9635 
9636  m_unfinishedSections.push_back(endInfo);
9637  }
9638  void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {
9639  m_reporter->benchmarkStarting( info );
9640  }
9641  void RunContext::benchmarkEnded( BenchmarkStats const& stats ) {
9642  m_reporter->benchmarkEnded( stats );
9643  }
9644 
9645  void RunContext::pushScopedMessage(MessageInfo const & message) {
9646  m_messages.push_back(message);
9647  }
9648 
9649  void RunContext::popScopedMessage(MessageInfo const & message) {
9650  m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
9651  }
9652 
9653  std::string RunContext::getCurrentTestName() const {
9654  return m_activeTestCase
9655  ? m_activeTestCase->getTestCaseInfo().name
9656  : std::string();
9657  }
9658 
9659  const AssertionResult * RunContext::getLastResult() const {
9660  return &(*m_lastResult);
9661  }
9662 
9663  void RunContext::exceptionEarlyReported() {
9664  m_shouldReportUnexpected = false;
9665  }
9666 
9667  void RunContext::handleFatalErrorCondition( StringRef message ) {
9668  // First notify reporter that bad things happened
9669  m_reporter->fatalErrorEncountered(message);
9670 
9671  // Don't rebuild the result -- the stringification itself can cause more fatal errors
9672  // Instead, fake a result data.
9673  AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );
9674  tempResult.message = message;
9675  AssertionResult result(m_lastAssertionInfo, tempResult);
9676 
9677  assertionEnded(result);
9678 
9679  handleUnfinishedSections();
9680 
9681  // Recreate section for test case (as we will lose the one that was in scope)
9682  auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
9683  SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
9684 
9685  Counts assertions;
9686  assertions.failed = 1;
9687  SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);
9688  m_reporter->sectionEnded(testCaseSectionStats);
9689 
9690  auto const& testInfo = m_activeTestCase->getTestCaseInfo();
9691 
9692  Totals deltaTotals;
9693  deltaTotals.testCases.failed = 1;
9694  deltaTotals.assertions.failed = 1;
9695  m_reporter->testCaseEnded(TestCaseStats(testInfo,
9696  deltaTotals,
9697  std::string(),
9698  std::string(),
9699  false));
9700  m_totals.testCases.failed++;
9701  testGroupEnded(std::string(), m_totals, 1, 1);
9702  m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
9703  }
9704 
9705  bool RunContext::lastAssertionPassed() {
9706  return m_lastAssertionPassed;
9707  }
9708 
9709  void RunContext::assertionPassed() {
9710  m_lastAssertionPassed = true;
9711  ++m_totals.assertions.passed;
9712  resetAssertionInfo();
9713  }
9714 
9715  bool RunContext::aborting() const {
9716  return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter());
9717  }
9718 
9719  void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
9720  auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
9721  SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
9722  m_reporter->sectionStarting(testCaseSection);
9723  Counts prevAssertions = m_totals.assertions;
9724  double duration = 0;
9725  m_shouldReportUnexpected = true;
9726  m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal };
9727 
9728  seedRng(*m_config);
9729 
9730  Timer timer;
9731  CATCH_TRY {
9732  if (m_reporter->getPreferences().shouldRedirectStdOut) {
9733 #if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
9734  RedirectedStdOut redirectedStdOut;
9735  RedirectedStdErr redirectedStdErr;
9736 
9737  timer.start();
9738  invokeActiveTestCase();
9739  redirectedCout += redirectedStdOut.str();
9740  redirectedCerr += redirectedStdErr.str();
9741 #else
9742  OutputRedirect r(redirectedCout, redirectedCerr);
9743  timer.start();
9744  invokeActiveTestCase();
9745 #endif
9746  } else {
9747  timer.start();
9748  invokeActiveTestCase();
9749  }
9750  duration = timer.getElapsedSeconds();
9752  // This just means the test was aborted due to failure
9753  } CATCH_CATCH_ALL {
9754  // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
9755  // are reported without translation at the point of origin.
9756  if( m_shouldReportUnexpected ) {
9757  AssertionReaction dummyReaction;
9758  handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction );
9759  }
9760  }
9761  Counts assertions = m_totals.assertions - prevAssertions;
9762  bool missingAssertions = testForMissingAssertions(assertions);
9763 
9764  m_testCaseTracker->close();
9765  handleUnfinishedSections();
9766  m_messages.clear();
9767 
9768  SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
9769  m_reporter->sectionEnded(testCaseSectionStats);
9770  }
9771 
9772  void RunContext::invokeActiveTestCase() {
9773  FatalConditionHandler fatalConditionHandler; // Handle signals
9774  m_activeTestCase->invoke();
9775  fatalConditionHandler.reset();
9776  }
9777 
9778  void RunContext::handleUnfinishedSections() {
9779  // If sections ended prematurely due to an exception we stored their
9780  // infos here so we can tear them down outside the unwind process.
9781  for (auto it = m_unfinishedSections.rbegin(),
9782  itEnd = m_unfinishedSections.rend();
9783  it != itEnd;
9784  ++it)
9785  sectionEnded(*it);
9786  m_unfinishedSections.clear();
9787  }
9788 
9789  void RunContext::handleExpr(
9790  AssertionInfo const& info,
9791  ITransientExpression const& expr,
9792  AssertionReaction& reaction
9793  ) {
9794  m_reporter->assertionStarting( info );
9795 
9796  bool negated = isFalseTest( info.resultDisposition );
9797  bool result = expr.getResult() != negated;
9798 
9799  if( result ) {
9800  if (!m_includeSuccessfulResults) {
9801  assertionPassed();
9802  }
9803  else {
9804  reportExpr(info, ResultWas::Ok, &expr, negated);
9805  }
9806  }
9807  else {
9808  reportExpr(info, ResultWas::ExpressionFailed, &expr, negated );
9809  populateReaction( reaction );
9810  }
9811  }
9812  void RunContext::reportExpr(
9813  AssertionInfo const &info,
9814  ResultWas::OfType resultType,
9815  ITransientExpression const *expr,
9816  bool negated ) {
9817 
9818  m_lastAssertionInfo = info;
9819  AssertionResultData data( resultType, LazyExpression( negated ) );
9820 
9821  AssertionResult assertionResult{ info, data };
9822  assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;
9823 
9824  assertionEnded( assertionResult );
9825  }
9826 
9827  void RunContext::handleMessage(
9828  AssertionInfo const& info,
9829  ResultWas::OfType resultType,
9830  StringRef const& message,
9831  AssertionReaction& reaction
9832  ) {
9833  m_reporter->assertionStarting( info );
9834 
9835  m_lastAssertionInfo = info;
9836 
9837  AssertionResultData data( resultType, LazyExpression( false ) );
9838  data.message = message;
9839  AssertionResult assertionResult{ m_lastAssertionInfo, data };
9840  assertionEnded( assertionResult );
9841  if( !assertionResult.isOk() )
9842  populateReaction( reaction );
9843  }
9844  void RunContext::handleUnexpectedExceptionNotThrown(
9845  AssertionInfo const& info,
9846  AssertionReaction& reaction
9847  ) {
9848  handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction);
9849  }
9850 
9851  void RunContext::handleUnexpectedInflightException(
9852  AssertionInfo const& info,
9853  std::string const& message,
9854  AssertionReaction& reaction
9855  ) {
9856  m_lastAssertionInfo = info;
9857 
9858  AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
9859  data.message = message;
9860  AssertionResult assertionResult{ info, data };
9861  assertionEnded( assertionResult );
9862  populateReaction( reaction );
9863  }
9864 
9865  void RunContext::populateReaction( AssertionReaction& reaction ) {
9866  reaction.shouldDebugBreak = m_config->shouldDebugBreak();
9867  reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal);
9868  }
9869 
9870  void RunContext::handleIncomplete(
9871  AssertionInfo const& info
9872  ) {
9873  m_lastAssertionInfo = info;
9874 
9875  AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
9876  data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
9877  AssertionResult assertionResult{ info, data };
9878  assertionEnded( assertionResult );
9879  }
9880  void RunContext::handleNonExpr(
9881  AssertionInfo const &info,
9882  ResultWas::OfType resultType,
9883  AssertionReaction &reaction
9884  ) {
9885  m_lastAssertionInfo = info;
9886 
9887  AssertionResultData data( resultType, LazyExpression( false ) );
9888  AssertionResult assertionResult{ info, data };
9889  assertionEnded( assertionResult );
9890 
9891  if( !assertionResult.isOk() )
9892  populateReaction( reaction );
9893  }
9894 
9896  if (auto* capture = getCurrentContext().getResultCapture())
9897  return *capture;
9898  else
9899  CATCH_INTERNAL_ERROR("No result capture instance");
9900  }
9901 }
9902 // end catch_run_context.cpp
9903 // start catch_section.cpp
9904 
9905 namespace Catch {
9906 
9907  Section::Section( SectionInfo const& info )
9908  : m_info( info ),
9909  m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
9910  {
9911  m_timer.start();
9912  }
9913 
9914  Section::~Section() {
9915  if( m_sectionIncluded ) {
9916  SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };
9917  if( uncaught_exceptions() )
9918  getResultCapture().sectionEndedEarly( endInfo );
9919  else
9920  getResultCapture().sectionEnded( endInfo );
9921  }
9922  }
9923 
9924  // This indicates whether the section should be executed or not
9925  Section::operator bool() const {
9926  return m_sectionIncluded;
9927  }
9928 
9929 } // end namespace Catch
9930 // end catch_section.cpp
9931 // start catch_section_info.cpp
9932 
9933 namespace Catch {
9934 
9936  ( SourceLineInfo const& _lineInfo,
9937  std::string const& _name )
9938  : name( _name ),
9939  lineInfo( _lineInfo )
9940  {}
9941 
9942 } // end namespace Catch
9943 // end catch_section_info.cpp
9944 // start catch_session.cpp
9945 
9946 // start catch_session.h
9947 
9948 #include <memory>
9949 
9950 namespace Catch {
9951 
9952  class Session : NonCopyable {
9953  public:
9954 
9955  Session();
9956  ~Session() override;
9957 
9958  void showHelp() const;
9959  void libIdentify();
9960 
9961  int applyCommandLine( int argc, char const * const * argv );
9962  #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
9963  int applyCommandLine( int argc, wchar_t const * const * argv );
9964  #endif
9965 
9966  void useConfigData( ConfigData const& configData );
9967 
9968  template<typename CharT>
9969  int run(int argc, CharT const * const argv[]) {
9970  if (m_startupExceptions)
9971  return 1;
9972  int returnCode = applyCommandLine(argc, argv);
9973  if (returnCode == 0)
9974  returnCode = run();
9975  return returnCode;
9976  }
9977 
9978  int run();
9979 
9980  clara::Parser const& cli() const;
9981  void cli( clara::Parser const& newParser );
9982  ConfigData& configData();
9983  Config& config();
9984  private:
9985  int runInternal();
9986 
9987  clara::Parser m_cli;
9988  ConfigData m_configData;
9989  std::shared_ptr<Config> m_config;
9990  bool m_startupExceptions = false;
9991  };
9992 
9993 } // end namespace Catch
9994 
9995 // end catch_session.h
9996 // start catch_version.h
9997 
9998 #include <iosfwd>
9999 
10000 namespace Catch {
10001 
10002  // Versioning information
10003  struct Version {
10004  Version( Version const& ) = delete;
10005  Version& operator=( Version const& ) = delete;
10006  Version( unsigned int _majorVersion,
10007  unsigned int _minorVersion,
10008  unsigned int _patchNumber,
10009  char const * const _branchName,
10010  unsigned int _buildNumber );
10011 
10012  unsigned int const majorVersion;
10013  unsigned int const minorVersion;
10014  unsigned int const patchNumber;
10015 
10016  // buildNumber is only used if branchName is not null
10017  char const * const branchName;
10018  unsigned int const buildNumber;
10019 
10020  friend std::ostream& operator << ( std::ostream& os, Version const& version );
10021  };
10022 
10023  Version const& libraryVersion();
10024 }
10025 
10026 // end catch_version.h
10027 #include <cstdlib>
10028 #include <iomanip>
10029 
10030 namespace Catch {
10031 
10032  namespace {
10033  const int MaxExitCode = 255;
10034 
10035  IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) {
10036  auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config);
10037  CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'");
10038 
10039  return reporter;
10040  }
10041 
10042  IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) {
10043  if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) {
10044  return createReporter(config->getReporterName(), config);
10045  }
10046 
10047  auto multi = std::unique_ptr<ListeningReporter>(new ListeningReporter);
10048 
10049  auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();
10050  for (auto const& listener : listeners) {
10051  multi->addListener(listener->create(Catch::ReporterConfig(config)));
10052  }
10053  multi->addReporter(createReporter(config->getReporterName(), config));
10054  return std::move(multi);
10055  }
10056 
10057  Catch::Totals runTests(std::shared_ptr<Config> const& config) {
10058  // FixMe: Add listeners in order first, then add reporters.
10059 
10060  auto reporter = makeReporter(config);
10061 
10062  RunContext context(config, std::move(reporter));
10063 
10064  Totals totals;
10065 
10066  context.testGroupStarting(config->name(), 1, 1);
10067 
10068  TestSpec testSpec = config->testSpec();
10069 
10070  auto const& allTestCases = getAllTestCasesSorted(*config);
10071  for (auto const& testCase : allTestCases) {
10072  if (!context.aborting() && matchTest(testCase, testSpec, *config))
10073  totals += context.runTest(testCase);
10074  else
10075  context.reporter().skipTest(testCase);
10076  }
10077 
10078  if (config->warnAboutNoTests() && totals.testCases.total() == 0) {
10079  ReusableStringStream testConfig;
10080 
10081  bool first = true;
10082  for (const auto& input : config->getTestsOrTags()) {
10083  if (!first) { testConfig << ' '; }
10084  first = false;
10085  testConfig << input;
10086  }
10087 
10088  context.reporter().noMatchingTestCases(testConfig.str());
10089  totals.error = -1;
10090  }
10091 
10092  context.testGroupEnded(config->name(), totals, 1, 1);
10093  return totals;
10094  }
10095 
10096  void applyFilenamesAsTags(Catch::IConfig const& config) {
10097  auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));
10098  for (auto& testCase : tests) {
10099  auto tags = testCase.tags;
10100 
10101  std::string filename = testCase.lineInfo.file;
10102  auto lastSlash = filename.find_last_of("\\/");
10103  if (lastSlash != std::string::npos) {
10104  filename.erase(0, lastSlash);
10105  filename[0] = '#';
10106  }
10107 
10108  auto lastDot = filename.find_last_of('.');
10109  if (lastDot != std::string::npos) {
10110  filename.erase(lastDot);
10111  }
10112 
10113  tags.push_back(std::move(filename));
10114  setTags(testCase, tags);
10115  }
10116  }
10117 
10118  } // anon namespace
10119 
10120  Session::Session() {
10121  static bool alreadyInstantiated = false;
10122  if( alreadyInstantiated ) {
10123  CATCH_TRY { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
10125  }
10126 
10127  // There cannot be exceptions at startup in no-exception mode.
10128 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
10129  const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
10130  if ( !exceptions.empty() ) {
10131  m_startupExceptions = true;
10132  Colour colourGuard( Colour::Red );
10133  Catch::cerr() << "Errors occurred during startup!" << '\n';
10134  // iterate over all exceptions and notify user
10135  for ( const auto& ex_ptr : exceptions ) {
10136  try {
10137  std::rethrow_exception(ex_ptr);
10138  } catch ( std::exception const& ex ) {
10139  Catch::cerr() << Column( ex.what() ).indent(2) << '\n';
10140  }
10141  }
10142  }
10143 #endif
10144 
10145  alreadyInstantiated = true;
10146  m_cli = makeCommandLineParser( m_configData );
10147  }
10148  Session::~Session() {
10149  Catch::cleanUp();
10150  }
10151 
10152  void Session::showHelp() const {
10153  Catch::cout()
10154  << "\nCatch v" << libraryVersion() << "\n"
10155  << m_cli << std::endl
10156  << "For more detailed usage please see the project docs\n" << std::endl;
10157  }
10158  void Session::libIdentify() {
10159  Catch::cout()
10160  << std::left << std::setw(16) << "description: " << "A Catch test executable\n"
10161  << std::left << std::setw(16) << "category: " << "testframework\n"
10162  << std::left << std::setw(16) << "framework: " << "Catch Test\n"
10163  << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
10164  }
10165 
10166  int Session::applyCommandLine( int argc, char const * const * argv ) {
10167  if( m_startupExceptions )
10168  return 1;
10169 
10170  auto result = m_cli.parse( clara::Args( argc, argv ) );
10171  if( !result ) {
10172  Catch::cerr()
10173  << Colour( Colour::Red )
10174  << "\nError(s) in input:\n"
10175  << Column( result.errorMessage() ).indent( 2 )
10176  << "\n\n";
10177  Catch::cerr() << "Run with -? for usage\n" << std::endl;
10178  return MaxExitCode;
10179  }
10180 
10181  if( m_configData.showHelp )
10182  showHelp();
10183  if( m_configData.libIdentify )
10184  libIdentify();
10185  m_config.reset();
10186  return 0;
10187  }
10188 
10189 #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
10190  int Session::applyCommandLine( int argc, wchar_t const * const * argv ) {
10191 
10192  char **utf8Argv = new char *[ argc ];
10193 
10194  for ( int i = 0; i < argc; ++i ) {
10195  int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL );
10196 
10197  utf8Argv[ i ] = new char[ bufSize ];
10198 
10199  WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL );
10200  }
10201 
10202  int returnCode = applyCommandLine( argc, utf8Argv );
10203 
10204  for ( int i = 0; i < argc; ++i )
10205  delete [] utf8Argv[ i ];
10206 
10207  delete [] utf8Argv;
10208 
10209  return returnCode;
10210  }
10211 #endif
10212 
10213  void Session::useConfigData( ConfigData const& configData ) {
10214  m_configData = configData;
10215  m_config.reset();
10216  }
10217 
10218  int Session::run() {
10219  if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {
10220  Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
10221  static_cast<void>(std::getchar());
10222  }
10223  int exitCode = runInternal();
10224  if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {
10225  Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
10226  static_cast<void>(std::getchar());
10227  }
10228  return exitCode;
10229  }
10230 
10231  clara::Parser const& Session::cli() const {
10232  return m_cli;
10233  }
10234  void Session::cli( clara::Parser const& newParser ) {
10235  m_cli = newParser;
10236  }
10237  ConfigData& Session::configData() {
10238  return m_configData;
10239  }
10240  Config& Session::config() {
10241  if( !m_config )
10242  m_config = std::make_shared<Config>( m_configData );
10243  return *m_config;
10244  }
10245 
10246  int Session::runInternal() {
10247  if( m_startupExceptions )
10248  return 1;
10249 
10250  if (m_configData.showHelp || m_configData.libIdentify) {
10251  return 0;
10252  }
10253 
10254  CATCH_TRY {
10255  config(); // Force config to be constructed
10256 
10257  seedRng( *m_config );
10258 
10259  if( m_configData.filenamesAsTags )
10260  applyFilenamesAsTags( *m_config );
10261 
10262  // Handle list request
10263  if( Option<std::size_t> listed = list( config() ) )
10264  return static_cast<int>( *listed );
10265 
10266  auto totals = runTests( m_config );
10267  // Note that on unices only the lower 8 bits are usually used, clamping
10268  // the return value to 255 prevents false negative when some multiple
10269  // of 256 tests has failed
10270  return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed)));
10271  }
10272 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
10273  catch( std::exception& ex ) {
10274  Catch::cerr() << ex.what() << std::endl;
10275  return MaxExitCode;
10276  }
10277 #endif
10278  }
10279 
10280 } // end namespace Catch
10281 // end catch_session.cpp
10282 // start catch_singletons.cpp
10283 
10284 #include <vector>
10285 
10286 namespace Catch {
10287 
10288  namespace {
10289  static auto getSingletons() -> std::vector<ISingleton*>*& {
10290  static std::vector<ISingleton*>* g_singletons = nullptr;
10291  if( !g_singletons )
10292  g_singletons = new std::vector<ISingleton*>();
10293  return g_singletons;
10294  }
10295  }
10296 
10297  ISingleton::~ISingleton() {}
10298 
10299  void addSingleton(ISingleton* singleton ) {
10300  getSingletons()->push_back( singleton );
10301  }
10302  void cleanupSingletons() {
10303  auto& singletons = getSingletons();
10304  for( auto singleton : *singletons )
10305  delete singleton;
10306  delete singletons;
10307  singletons = nullptr;
10308  }
10309 
10310 } // namespace Catch
10311 // end catch_singletons.cpp
10312 // start catch_startup_exception_registry.cpp
10313 
10314 namespace Catch {
10315 void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
10316  CATCH_TRY {
10317  m_exceptions.push_back(exception);
10318  } CATCH_CATCH_ALL {
10319  // If we run out of memory during start-up there's really not a lot more we can do about it
10320  std::terminate();
10321  }
10322  }
10323 
10324  std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept {
10325  return m_exceptions;
10326  }
10327 
10328 } // end namespace Catch
10329 // end catch_startup_exception_registry.cpp
10330 // start catch_stream.cpp
10331 
10332 #include <cstdio>
10333 #include <iostream>
10334 #include <fstream>
10335 #include <sstream>
10336 #include <vector>
10337 #include <memory>
10338 
10339 namespace Catch {
10340 
10341  Catch::IStream::~IStream() = default;
10342 
10343  namespace detail { namespace {
10344  template<typename WriterF, std::size_t bufferSize=256>
10345  class StreamBufImpl : public std::streambuf {
10346  char data[bufferSize];
10347  WriterF m_writer;
10348 
10349  public:
10350  StreamBufImpl() {
10351  setp( data, data + sizeof(data) );
10352  }
10353 
10354  ~StreamBufImpl() noexcept {
10355  StreamBufImpl::sync();
10356  }
10357 
10358  private:
10359  int overflow( int c ) override {
10360  sync();
10361 
10362  if( c != EOF ) {
10363  if( pbase() == epptr() )
10364  m_writer( std::string( 1, static_cast<char>( c ) ) );
10365  else
10366  sputc( static_cast<char>( c ) );
10367  }
10368  return 0;
10369  }
10370 
10371  int sync() override {
10372  if( pbase() != pptr() ) {
10373  m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
10374  setp( pbase(), epptr() );
10375  }
10376  return 0;
10377  }
10378  };
10379 
10381 
10382  struct OutputDebugWriter {
10383 
10384  void operator()( std::string const&str ) {
10385  writeToDebugConsole( str );
10386  }
10387  };
10388 
10390 
10391  class FileStream : public IStream {
10392  mutable std::ofstream m_ofs;
10393  public:
10394  FileStream( StringRef filename ) {
10395  m_ofs.open( filename.c_str() );
10396  CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << "'" );
10397  }
10398  ~FileStream() override = default;
10399  public: // IStream
10400  std::ostream& stream() const override {
10401  return m_ofs;
10402  }
10403  };
10404 
10406 
10407  class CoutStream : public IStream {
10408  mutable std::ostream m_os;
10409  public:
10410  // Store the streambuf from cout up-front because
10411  // cout may get redirected when running tests
10412  CoutStream() : m_os( Catch::cout().rdbuf() ) {}
10413  ~CoutStream() override = default;
10414 
10415  public: // IStream
10416  std::ostream& stream() const override { return m_os; }
10417  };
10418 
10420 
10421  class DebugOutStream : public IStream {
10422  std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf;
10423  mutable std::ostream m_os;
10424  public:
10425  DebugOutStream()
10426  : m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
10427  m_os( m_streamBuf.get() )
10428  {}
10429 
10430  ~DebugOutStream() override = default;
10431 
10432  public: // IStream
10433  std::ostream& stream() const override { return m_os; }
10434  };
10435 
10436  }} // namespace anon::detail
10437 
10439 
10440  auto makeStream( StringRef const &filename ) -> IStream const* {
10441  if( filename.empty() )
10442  return new detail::CoutStream();
10443  else if( filename[0] == '%' ) {
10444  if( filename == "%debug" )
10445  return new detail::DebugOutStream();
10446  else
10447  CATCH_ERROR( "Unrecognised stream: '" << filename << "'" );
10448  }
10449  else
10450  return new detail::FileStream( filename );
10451  }
10452 
10453  // This class encapsulates the idea of a pool of ostringstreams that can be reused.
10454  struct StringStreams {
10455  std::vector<std::unique_ptr<std::ostringstream>> m_streams;
10456  std::vector<std::size_t> m_unused;
10457  std::ostringstream m_referenceStream; // Used for copy state/ flags from
10458 
10459  auto add() -> std::size_t {
10460  if( m_unused.empty() ) {
10461  m_streams.push_back( std::unique_ptr<std::ostringstream>( new std::ostringstream ) );
10462  return m_streams.size()-1;
10463  }
10464  else {
10465  auto index = m_unused.back();
10466  m_unused.pop_back();
10467  return index;
10468  }
10469  }
10470 
10471  void release( std::size_t index ) {
10472  m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state
10473  m_unused.push_back(index);
10474  }
10475  };
10476 
10478  : m_index( Singleton<StringStreams>::getMutable().add() ),
10479  m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].get() )
10480  {}
10481 
10483  static_cast<std::ostringstream*>( m_oss )->str("");
10484  m_oss->clear();
10485  Singleton<StringStreams>::getMutable().release( m_index );
10486  }
10487 
10488  auto ReusableStringStream::str() const -> std::string {
10489  return static_cast<std::ostringstream*>( m_oss )->str();
10490  }
10491 
10493 
10494 #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
10495  std::ostream& cout() { return std::cout; }
10496  std::ostream& cerr() { return std::cerr; }
10497  std::ostream& clog() { return std::clog; }
10498 #endif
10499 }
10500 // end catch_stream.cpp
10501 // start catch_string_manip.cpp
10502 
10503 #include <algorithm>
10504 #include <ostream>
10505 #include <cstring>
10506 #include <cctype>
10507 
10508 namespace Catch {
10509 
10510  namespace {
10511  char toLowerCh(char c) {
10512  return static_cast<char>( std::tolower( c ) );
10513  }
10514  }
10515 
10516  bool startsWith( std::string const& s, std::string const& prefix ) {
10517  return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
10518  }
10519  bool startsWith( std::string const& s, char prefix ) {
10520  return !s.empty() && s[0] == prefix;
10521  }
10522  bool endsWith( std::string const& s, std::string const& suffix ) {
10523  return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
10524  }
10525  bool endsWith( std::string const& s, char suffix ) {
10526  return !s.empty() && s[s.size()-1] == suffix;
10527  }
10528  bool contains( std::string const& s, std::string const& infix ) {
10529  return s.find( infix ) != std::string::npos;
10530  }
10531  void toLowerInPlace( std::string& s ) {
10532  std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
10533  }
10534  std::string toLower( std::string const& s ) {
10535  std::string lc = s;
10536  toLowerInPlace( lc );
10537  return lc;
10538  }
10539  std::string trim( std::string const& str ) {
10540  static char const* whitespaceChars = "\n\r\t ";
10541  std::string::size_type start = str.find_first_not_of( whitespaceChars );
10542  std::string::size_type end = str.find_last_not_of( whitespaceChars );
10543 
10544  return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
10545  }
10546 
10547  bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
10548  bool replaced = false;
10549  std::size_t i = str.find( replaceThis );
10550  while( i != std::string::npos ) {
10551  replaced = true;
10552  str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
10553  if( i < str.size()-withThis.size() )
10554  i = str.find( replaceThis, i+withThis.size() );
10555  else
10556  i = std::string::npos;
10557  }
10558  return replaced;
10559  }
10560 
10561  pluralise::pluralise( std::size_t count, std::string const& label )
10562  : m_count( count ),
10563  m_label( label )
10564  {}
10565 
10566  std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
10567  os << pluraliser.m_count << ' ' << pluraliser.m_label;
10568  if( pluraliser.m_count != 1 )
10569  os << 's';
10570  return os;
10571  }
10572 
10573 }
10574 // end catch_string_manip.cpp
10575 // start catch_stringref.cpp
10576 
10577 #if defined(__clang__)
10578 # pragma clang diagnostic push
10579 # pragma clang diagnostic ignored "-Wexit-time-destructors"
10580 #endif
10581 
10582 #include <ostream>
10583 #include <cstring>
10584 #include <cstdint>
10585 
10586 namespace {
10587  const uint32_t byte_2_lead = 0xC0;
10588  const uint32_t byte_3_lead = 0xE0;
10589  const uint32_t byte_4_lead = 0xF0;
10590 }
10591 
10592 namespace Catch {
10593  StringRef::StringRef( char const* rawChars ) noexcept
10594  : StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) )
10595  {}
10596 
10597  StringRef::operator std::string() const {
10598  return std::string( m_start, m_size );
10599  }
10600 
10601  void StringRef::swap( StringRef& other ) noexcept {
10602  std::swap( m_start, other.m_start );
10603  std::swap( m_size, other.m_size );
10604  std::swap( m_data, other.m_data );
10605  }
10606 
10607  auto StringRef::c_str() const -> char const* {
10608  if( isSubstring() )
10609  const_cast<StringRef*>( this )->takeOwnership();
10610  return m_start;
10611  }
10612  auto StringRef::currentData() const noexcept -> char const* {
10613  return m_start;
10614  }
10615 
10616  auto StringRef::isOwned() const noexcept -> bool {
10617  return m_data != nullptr;
10618  }
10619  auto StringRef::isSubstring() const noexcept -> bool {
10620  return m_start[m_size] != '\0';
10621  }
10622 
10623  void StringRef::takeOwnership() {
10624  if( !isOwned() ) {
10625  m_data = new char[m_size+1];
10626  memcpy( m_data, m_start, m_size );
10627  m_data[m_size] = '\0';
10628  m_start = m_data;
10629  }
10630  }
10631  auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {
10632  if( start < m_size )
10633  return StringRef( m_start+start, size );
10634  else
10635  return StringRef();
10636  }
10637  auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool {
10638  return
10639  size() == other.size() &&
10640  (std::strncmp( m_start, other.m_start, size() ) == 0);
10641  }
10642  auto StringRef::operator != ( StringRef const& other ) const noexcept -> bool {
10643  return !operator==( other );
10644  }
10645 
10646  auto StringRef::operator[](size_type index) const noexcept -> char {
10647  return m_start[index];
10648  }
10649 
10650  auto StringRef::numberOfCharacters() const noexcept -> size_type {
10651  size_type noChars = m_size;
10652  // Make adjustments for uft encodings
10653  for( size_type i=0; i < m_size; ++i ) {
10654  char c = m_start[i];
10655  if( ( c & byte_2_lead ) == byte_2_lead ) {
10656  noChars--;
10657  if (( c & byte_3_lead ) == byte_3_lead )
10658  noChars--;
10659  if( ( c & byte_4_lead ) == byte_4_lead )
10660  noChars--;
10661  }
10662  }
10663  return noChars;
10664  }
10665 
10666  auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string {
10667  std::string str;
10668  str.reserve( lhs.size() + rhs.size() );
10669  str += lhs;
10670  str += rhs;
10671  return str;
10672  }
10673  auto operator + ( StringRef const& lhs, const char* rhs ) -> std::string {
10674  return std::string( lhs ) + std::string( rhs );
10675  }
10676  auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string {
10677  return std::string( lhs ) + std::string( rhs );
10678  }
10679 
10680  auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {
10681  return os.write(str.currentData(), str.size());
10682  }
10683 
10684  auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& {
10685  lhs.append(rhs.currentData(), rhs.size());
10686  return lhs;
10687  }
10688 
10689 } // namespace Catch
10690 
10691 #if defined(__clang__)
10692 # pragma clang diagnostic pop
10693 #endif
10694 // end catch_stringref.cpp
10695 // start catch_tag_alias.cpp
10696 
10697 namespace Catch {
10698  TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {}
10699 }
10700 // end catch_tag_alias.cpp
10701 // start catch_tag_alias_autoregistrar.cpp
10702 
10703 namespace Catch {
10704 
10705  RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {
10706  CATCH_TRY {
10707  getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
10708  } CATCH_CATCH_ALL {
10709  // Do not throw when constructing global objects, instead register the exception to be processed later
10711  }
10712  }
10713 
10714 }
10715 // end catch_tag_alias_autoregistrar.cpp
10716 // start catch_tag_alias_registry.cpp
10717 
10718 #include <sstream>
10719 
10720 namespace Catch {
10721 
10722  TagAliasRegistry::~TagAliasRegistry() {}
10723 
10724  TagAlias const* TagAliasRegistry::find( std::string const& alias ) const {
10725  auto it = m_registry.find( alias );
10726  if( it != m_registry.end() )
10727  return &(it->second);
10728  else
10729  return nullptr;
10730  }
10731 
10732  std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
10733  std::string expandedTestSpec = unexpandedTestSpec;
10734  for( auto const& registryKvp : m_registry ) {
10735  std::size_t pos = expandedTestSpec.find( registryKvp.first );
10736  if( pos != std::string::npos ) {
10737  expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
10738  registryKvp.second.tag +
10739  expandedTestSpec.substr( pos + registryKvp.first.size() );
10740  }
10741  }
10742  return expandedTestSpec;
10743  }
10744 
10745  void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) {
10746  CATCH_ENFORCE( startsWith(alias, "[@") && endsWith(alias, ']'),
10747  "error: tag alias, '" << alias << "' is not of the form [@alias name].\n" << lineInfo );
10748 
10749  CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,
10750  "error: tag alias, '" << alias << "' already registered.\n"
10751  << "\tFirst seen at: " << find(alias)->lineInfo << "\n"
10752  << "\tRedefined at: " << lineInfo );
10753  }
10754 
10755  ITagAliasRegistry::~ITagAliasRegistry() {}
10756 
10757  ITagAliasRegistry const& ITagAliasRegistry::get() {
10759  }
10760 
10761 } // end namespace Catch
10762 // end catch_tag_alias_registry.cpp
10763 // start catch_test_case_info.cpp
10764 
10765 #include <cctype>
10766 #include <exception>
10767 #include <algorithm>
10768 #include <sstream>
10769 
10770 namespace Catch {
10771 
10772  namespace {
10773  TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
10774  if( startsWith( tag, '.' ) ||
10775  tag == "!hide" )
10776  return TestCaseInfo::IsHidden;
10777  else if( tag == "!throws" )
10778  return TestCaseInfo::Throws;
10779  else if( tag == "!shouldfail" )
10780  return TestCaseInfo::ShouldFail;
10781  else if( tag == "!mayfail" )
10782  return TestCaseInfo::MayFail;
10783  else if( tag == "!nonportable" )
10785  else if( tag == "!benchmark" )
10787  else
10788  return TestCaseInfo::None;
10789  }
10790  bool isReservedTag( std::string const& tag ) {
10791  return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) );
10792  }
10793  void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
10794  CATCH_ENFORCE( !isReservedTag(tag),
10795  "Tag name: [" << tag << "] is not allowed.\n"
10796  << "Tag names starting with non alpha-numeric characters are reserved\n"
10797  << _lineInfo );
10798  }
10799  }
10800 
10801  TestCase makeTestCase( ITestInvoker* _testCase,
10802  std::string const& _className,
10803  NameAndTags const& nameAndTags,
10804  SourceLineInfo const& _lineInfo )
10805  {
10806  bool isHidden = false;
10807 
10808  // Parse out tags
10809  std::vector<std::string> tags;
10810  std::string desc, tag;
10811  bool inTag = false;
10812  std::string _descOrTags = nameAndTags.tags;
10813  for (char c : _descOrTags) {
10814  if( !inTag ) {
10815  if( c == '[' )
10816  inTag = true;
10817  else
10818  desc += c;
10819  }
10820  else {
10821  if( c == ']' ) {
10822  TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
10823  if( ( prop & TestCaseInfo::IsHidden ) != 0 )
10824  isHidden = true;
10825  else if( prop == TestCaseInfo::None )
10826  enforceNotReservedTag( tag, _lineInfo );
10827 
10828  tags.push_back( tag );
10829  tag.clear();
10830  inTag = false;
10831  }
10832  else
10833  tag += c;
10834  }
10835  }
10836  if( isHidden ) {
10837  tags.push_back( "." );
10838  }
10839 
10840  TestCaseInfo info( nameAndTags.name, _className, desc, tags, _lineInfo );
10841  return TestCase( _testCase, std::move(info) );
10842  }
10843 
10844  void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ) {
10845  std::sort(begin(tags), end(tags));
10846  tags.erase(std::unique(begin(tags), end(tags)), end(tags));
10847  testCaseInfo.lcaseTags.clear();
10848 
10849  for( auto const& tag : tags ) {
10850  std::string lcaseTag = toLower( tag );
10851  testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
10852  testCaseInfo.lcaseTags.push_back( lcaseTag );
10853  }
10854  testCaseInfo.tags = std::move(tags);
10855  }
10856 
10857  TestCaseInfo::TestCaseInfo( std::string const& _name,
10858  std::string const& _className,
10859  std::string const& _description,
10860  std::vector<std::string> const& _tags,
10861  SourceLineInfo const& _lineInfo )
10862  : name( _name ),
10863  className( _className ),
10864  description( _description ),
10865  lineInfo( _lineInfo ),
10866  properties( None )
10867  {
10868  setTags( *this, _tags );
10869  }
10870 
10871  bool TestCaseInfo::isHidden() const {
10872  return ( properties & IsHidden ) != 0;
10873  }
10874  bool TestCaseInfo::throws() const {
10875  return ( properties & Throws ) != 0;
10876  }
10877  bool TestCaseInfo::okToFail() const {
10878  return ( properties & (ShouldFail | MayFail ) ) != 0;
10879  }
10880  bool TestCaseInfo::expectedToFail() const {
10881  return ( properties & (ShouldFail ) ) != 0;
10882  }
10883 
10884  std::string TestCaseInfo::tagsAsString() const {
10885  std::string ret;
10886  // '[' and ']' per tag
10887  std::size_t full_size = 2 * tags.size();
10888  for (const auto& tag : tags) {
10889  full_size += tag.size();
10890  }
10891  ret.reserve(full_size);
10892  for (const auto& tag : tags) {
10893  ret.push_back('[');
10894  ret.append(tag);
10895  ret.push_back(']');
10896  }
10897 
10898  return ret;
10899  }
10900 
10901  TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( std::move(info) ), test( testCase ) {}
10902 
10903  TestCase TestCase::withName( std::string const& _newName ) const {
10904  TestCase other( *this );
10905  other.name = _newName;
10906  return other;
10907  }
10908 
10909  void TestCase::invoke() const {
10910  test->invoke();
10911  }
10912 
10913  bool TestCase::operator == ( TestCase const& other ) const {
10914  return test.get() == other.test.get() &&
10915  name == other.name &&
10916  className == other.className;
10917  }
10918 
10919  bool TestCase::operator < ( TestCase const& other ) const {
10920  return name < other.name;
10921  }
10922 
10924  {
10925  return *this;
10926  }
10927 
10928 } // end namespace Catch
10929 // end catch_test_case_info.cpp
10930 // start catch_test_case_registry_impl.cpp
10931 
10932 #include <sstream>
10933 
10934 namespace Catch {
10935 
10936  std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
10937 
10938  std::vector<TestCase> sorted = unsortedTestCases;
10939 
10940  switch( config.runOrder() ) {
10941  case RunTests::InLexicographicalOrder:
10942  std::sort( sorted.begin(), sorted.end() );
10943  break;
10944  case RunTests::InRandomOrder:
10945  seedRng( config );
10946  std::shuffle( sorted.begin(), sorted.end(), rng() );
10947  break;
10948  case RunTests::InDeclarationOrder:
10949  // already in declaration order
10950  break;
10951  }
10952  return sorted;
10953  }
10954  bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
10955  return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
10956  }
10957 
10958  void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
10959  std::set<TestCase> seenFunctions;
10960  for( auto const& function : functions ) {
10961  auto prev = seenFunctions.insert( function );
10962  CATCH_ENFORCE( prev.second,
10963  "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n"
10964  << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
10965  << "\tRedefined at " << function.getTestCaseInfo().lineInfo );
10966  }
10967  }
10968 
10969  std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
10970  std::vector<TestCase> filtered;
10971  filtered.reserve( testCases.size() );
10972  for( auto const& testCase : testCases )
10973  if( matchTest( testCase, testSpec, config ) )
10974  filtered.push_back( testCase );
10975  return filtered;
10976  }
10977  std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
10979  }
10980 
10981  void TestRegistry::registerTest( TestCase const& testCase ) {
10982  std::string name = testCase.getTestCaseInfo().name;
10983  if( name.empty() ) {
10985  rss << "Anonymous test case " << ++m_unnamedCount;
10986  return registerTest( testCase.withName( rss.str() ) );
10987  }
10988  m_functions.push_back( testCase );
10989  }
10990 
10991  std::vector<TestCase> const& TestRegistry::getAllTests() const {
10992  return m_functions;
10993  }
10994  std::vector<TestCase> const& TestRegistry::getAllTestsSorted( IConfig const& config ) const {
10995  if( m_sortedFunctions.empty() )
10996  enforceNoDuplicateTestCases( m_functions );
10997 
10998  if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
10999  m_sortedFunctions = sortTests( config, m_functions );
11000  m_currentSortOrder = config.runOrder();
11001  }
11002  return m_sortedFunctions;
11003  }
11004 
11006  TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {}
11007 
11008  void TestInvokerAsFunction::invoke() const {
11009  m_testAsFunction();
11010  }
11011 
11012  std::string extractClassName( StringRef const& classOrQualifiedMethodName ) {
11013  std::string className = classOrQualifiedMethodName;
11014  if( startsWith( className, '&' ) )
11015  {
11016  std::size_t lastColons = className.rfind( "::" );
11017  std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
11018  if( penultimateColons == std::string::npos )
11019  penultimateColons = 1;
11020  className = className.substr( penultimateColons, lastColons-penultimateColons );
11021  }
11022  return className;
11023  }
11024 
11025 } // end namespace Catch
11026 // end catch_test_case_registry_impl.cpp
11027 // start catch_test_case_tracker.cpp
11028 
11029 #include <algorithm>
11030 #include <cassert>
11031 #include <stdexcept>
11032 #include <memory>
11033 #include <sstream>
11034 
11035 #if defined(__clang__)
11036 # pragma clang diagnostic push
11037 # pragma clang diagnostic ignored "-Wexit-time-destructors"
11038 #endif
11039 
11040 namespace Catch {
11041 namespace TestCaseTracking {
11042 
11043  NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location )
11044  : name( _name ),
11045  location( _location )
11046  {}
11047 
11048  ITracker::~ITracker() = default;
11049 
11050  TrackerContext& TrackerContext::instance() {
11051  static TrackerContext s_instance;
11052  return s_instance;
11053  }
11054 
11055  ITracker& TrackerContext::startRun() {
11056  m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr );
11057  m_currentTracker = nullptr;
11058  m_runState = Executing;
11059  return *m_rootTracker;
11060  }
11061 
11062  void TrackerContext::endRun() {
11063  m_rootTracker.reset();
11064  m_currentTracker = nullptr;
11065  m_runState = NotStarted;
11066  }
11067 
11068  void TrackerContext::startCycle() {
11069  m_currentTracker = m_rootTracker.get();
11070  m_runState = Executing;
11071  }
11072  void TrackerContext::completeCycle() {
11073  m_runState = CompletedCycle;
11074  }
11075 
11076  bool TrackerContext::completedCycle() const {
11077  return m_runState == CompletedCycle;
11078  }
11079  ITracker& TrackerContext::currentTracker() {
11080  return *m_currentTracker;
11081  }
11082  void TrackerContext::setCurrentTracker( ITracker* tracker ) {
11083  m_currentTracker = tracker;
11084  }
11085 
11086  TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
11087  : m_nameAndLocation( nameAndLocation ),
11088  m_ctx( ctx ),
11089  m_parent( parent )
11090  {}
11091 
11092  NameAndLocation const& TrackerBase::nameAndLocation() const {
11093  return m_nameAndLocation;
11094  }
11095  bool TrackerBase::isComplete() const {
11096  return m_runState == CompletedSuccessfully || m_runState == Failed;
11097  }
11098  bool TrackerBase::isSuccessfullyCompleted() const {
11099  return m_runState == CompletedSuccessfully;
11100  }
11101  bool TrackerBase::isOpen() const {
11102  return m_runState != NotStarted && !isComplete();
11103  }
11104  bool TrackerBase::hasChildren() const {
11105  return !m_children.empty();
11106  }
11107 
11108  void TrackerBase::addChild( ITrackerPtr const& child ) {
11109  m_children.push_back( child );
11110  }
11111 
11112  ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) {
11113  auto it = std::find_if( m_children.begin(), m_children.end(),
11114  [&nameAndLocation]( ITrackerPtr const& tracker ){
11115  return
11116  tracker->nameAndLocation().location == nameAndLocation.location &&
11117  tracker->nameAndLocation().name == nameAndLocation.name;
11118  } );
11119  return( it != m_children.end() )
11120  ? *it
11121  : nullptr;
11122  }
11123  ITracker& TrackerBase::parent() {
11124  assert( m_parent ); // Should always be non-null except for root
11125  return *m_parent;
11126  }
11127 
11128  void TrackerBase::openChild() {
11129  if( m_runState != ExecutingChildren ) {
11130  m_runState = ExecutingChildren;
11131  if( m_parent )
11132  m_parent->openChild();
11133  }
11134  }
11135 
11136  bool TrackerBase::isSectionTracker() const { return false; }
11137  bool TrackerBase::isIndexTracker() const { return false; }
11138 
11139  void TrackerBase::open() {
11140  m_runState = Executing;
11141  moveToThis();
11142  if( m_parent )
11143  m_parent->openChild();
11144  }
11145 
11146  void TrackerBase::close() {
11147 
11148  // Close any still open children (e.g. generators)
11149  while( &m_ctx.currentTracker() != this )
11150  m_ctx.currentTracker().close();
11151 
11152  switch( m_runState ) {
11153  case NeedsAnotherRun:
11154  break;
11155 
11156  case Executing:
11157  m_runState = CompletedSuccessfully;
11158  break;
11159  case ExecutingChildren:
11160  if( m_children.empty() || m_children.back()->isComplete() )
11161  m_runState = CompletedSuccessfully;
11162  break;
11163 
11164  case NotStarted:
11165  case CompletedSuccessfully:
11166  case Failed:
11167  CATCH_INTERNAL_ERROR( "Illogical state: " << m_runState );
11168 
11169  default:
11170  CATCH_INTERNAL_ERROR( "Unknown state: " << m_runState );
11171  }
11172  moveToParent();
11173  m_ctx.completeCycle();
11174  }
11175  void TrackerBase::fail() {
11176  m_runState = Failed;
11177  if( m_parent )
11178  m_parent->markAsNeedingAnotherRun();
11179  moveToParent();
11180  m_ctx.completeCycle();
11181  }
11182  void TrackerBase::markAsNeedingAnotherRun() {
11183  m_runState = NeedsAnotherRun;
11184  }
11185 
11186  void TrackerBase::moveToParent() {
11187  assert( m_parent );
11188  m_ctx.setCurrentTracker( m_parent );
11189  }
11190  void TrackerBase::moveToThis() {
11191  m_ctx.setCurrentTracker( this );
11192  }
11193 
11194  SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
11195  : TrackerBase( nameAndLocation, ctx, parent )
11196  {
11197  if( parent ) {
11198  while( !parent->isSectionTracker() )
11199  parent = &parent->parent();
11200 
11201  SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );
11202  addNextFilters( parentSection.m_filters );
11203  }
11204  }
11205 
11206  bool SectionTracker::isSectionTracker() const { return true; }
11207 
11208  SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {
11209  std::shared_ptr<SectionTracker> section;
11210 
11211  ITracker& currentTracker = ctx.currentTracker();
11212  if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
11213  assert( childTracker );
11214  assert( childTracker->isSectionTracker() );
11215  section = std::static_pointer_cast<SectionTracker>( childTracker );
11216  }
11217  else {
11218  section = std::make_shared<SectionTracker>( nameAndLocation, ctx, &currentTracker );
11219  currentTracker.addChild( section );
11220  }
11221  if( !ctx.completedCycle() )
11222  section->tryOpen();
11223  return *section;
11224  }
11225 
11226  void SectionTracker::tryOpen() {
11227  if( !isComplete() && (m_filters.empty() || m_filters[0].empty() || m_filters[0] == m_nameAndLocation.name ) )
11228  open();
11229  }
11230 
11231  void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) {
11232  if( !filters.empty() ) {
11233  m_filters.push_back(""); // Root - should never be consulted
11234  m_filters.push_back(""); // Test Case - not a section filter
11235  m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
11236  }
11237  }
11238  void SectionTracker::addNextFilters( std::vector<std::string> const& filters ) {
11239  if( filters.size() > 1 )
11240  m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() );
11241  }
11242 
11243  IndexTracker::IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size )
11244  : TrackerBase( nameAndLocation, ctx, parent ),
11245  m_size( size )
11246  {}
11247 
11248  bool IndexTracker::isIndexTracker() const { return true; }
11249 
11250  IndexTracker& IndexTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size ) {
11251  std::shared_ptr<IndexTracker> tracker;
11252 
11253  ITracker& currentTracker = ctx.currentTracker();
11254  if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
11255  assert( childTracker );
11256  assert( childTracker->isIndexTracker() );
11257  tracker = std::static_pointer_cast<IndexTracker>( childTracker );
11258  }
11259  else {
11260  tracker = std::make_shared<IndexTracker>( nameAndLocation, ctx, &currentTracker, size );
11261  currentTracker.addChild( tracker );
11262  }
11263 
11264  if( !ctx.completedCycle() && !tracker->isComplete() ) {
11265  if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
11266  tracker->moveNext();
11267  tracker->open();
11268  }
11269 
11270  return *tracker;
11271  }
11272 
11273  int IndexTracker::index() const { return m_index; }
11274 
11275  void IndexTracker::moveNext() {
11276  m_index++;
11277  m_children.clear();
11278  }
11279 
11280  void IndexTracker::close() {
11281  TrackerBase::close();
11282  if( m_runState == CompletedSuccessfully && m_index < m_size-1 )
11283  m_runState = Executing;
11284  }
11285 
11286 } // namespace TestCaseTracking
11287 
11288 using TestCaseTracking::ITracker;
11289 using TestCaseTracking::TrackerContext;
11290 using TestCaseTracking::SectionTracker;
11291 using TestCaseTracking::IndexTracker;
11292 
11293 } // namespace Catch
11294 
11295 #if defined(__clang__)
11296 # pragma clang diagnostic pop
11297 #endif
11298 // end catch_test_case_tracker.cpp
11299 // start catch_test_registry.cpp
11300 
11301 namespace Catch {
11302 
11303  auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker* {
11304  return new(std::nothrow) TestInvokerAsFunction( testAsFunction );
11305  }
11306 
11307  NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {}
11308 
11309  AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept {
11310  CATCH_TRY {
11312  .registerTest(
11313  makeTestCase(
11314  invoker,
11315  extractClassName( classOrMethod ),
11316  nameAndTags,
11317  lineInfo));
11318  } CATCH_CATCH_ALL {
11319  // Do not throw when constructing global objects, instead register the exception to be processed later
11321  }
11322  }
11323 
11324  AutoReg::~AutoReg() = default;
11325 }
11326 // end catch_test_registry.cpp
11327 // start catch_test_spec.cpp
11328 
11329 #include <algorithm>
11330 #include <string>
11331 #include <vector>
11332 #include <memory>
11333 
11334 namespace Catch {
11335 
11336  TestSpec::Pattern::~Pattern() = default;
11337  TestSpec::NamePattern::~NamePattern() = default;
11338  TestSpec::TagPattern::~TagPattern() = default;
11339  TestSpec::ExcludedPattern::~ExcludedPattern() = default;
11340 
11341  TestSpec::NamePattern::NamePattern( std::string const& name )
11342  : m_wildcardPattern( toLower( name ), CaseSensitive::No )
11343  {}
11344  bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const {
11345  return m_wildcardPattern.matches( toLower( testCase.name ) );
11346  }
11347 
11348  TestSpec::TagPattern::TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
11349  bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const {
11350  return std::find(begin(testCase.lcaseTags),
11351  end(testCase.lcaseTags),
11352  m_tag) != end(testCase.lcaseTags);
11353  }
11354 
11355  TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
11356  bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
11357 
11358  bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const {
11359  // All patterns in a filter must match for the filter to be a match
11360  for( auto const& pattern : m_patterns ) {
11361  if( !pattern->matches( testCase ) )
11362  return false;
11363  }
11364  return true;
11365  }
11366 
11367  bool TestSpec::hasFilters() const {
11368  return !m_filters.empty();
11369  }
11370  bool TestSpec::matches( TestCaseInfo const& testCase ) const {
11371  // A TestSpec matches if any filter matches
11372  for( auto const& filter : m_filters )
11373  if( filter.matches( testCase ) )
11374  return true;
11375  return false;
11376  }
11377 }
11378 // end catch_test_spec.cpp
11379 // start catch_test_spec_parser.cpp
11380 
11381 namespace Catch {
11382 
11383  TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
11384 
11385  TestSpecParser& TestSpecParser::parse( std::string const& arg ) {
11386  m_mode = None;
11387  m_exclusion = false;
11388  m_start = std::string::npos;
11389  m_arg = m_tagAliases->expandAliases( arg );
11390  m_escapeChars.clear();
11391  for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
11392  visitChar( m_arg[m_pos] );
11393  if( m_mode == Name )
11394  addPattern<TestSpec::NamePattern>();
11395  return *this;
11396  }
11397  TestSpec TestSpecParser::testSpec() {
11398  addFilter();
11399  return m_testSpec;
11400  }
11401 
11402  void TestSpecParser::visitChar( char c ) {
11403  if( m_mode == None ) {
11404  switch( c ) {
11405  case ' ': return;
11406  case '~': m_exclusion = true; return;
11407  case '[': return startNewMode( Tag, ++m_pos );
11408  case '"': return startNewMode( QuotedName, ++m_pos );
11409  case '\\': return escape();
11410  default: startNewMode( Name, m_pos ); break;
11411  }
11412  }
11413  if( m_mode == Name ) {
11414  if( c == ',' ) {
11415  addPattern<TestSpec::NamePattern>();
11416  addFilter();
11417  }
11418  else if( c == '[' ) {
11419  if( subString() == "exclude:" )
11420  m_exclusion = true;
11421  else
11422  addPattern<TestSpec::NamePattern>();
11423  startNewMode( Tag, ++m_pos );
11424  }
11425  else if( c == '\\' )
11426  escape();
11427  }
11428  else if( m_mode == EscapedName )
11429  m_mode = Name;
11430  else if( m_mode == QuotedName && c == '"' )
11431  addPattern<TestSpec::NamePattern>();
11432  else if( m_mode == Tag && c == ']' )
11433  addPattern<TestSpec::TagPattern>();
11434  }
11435  void TestSpecParser::startNewMode( Mode mode, std::size_t start ) {
11436  m_mode = mode;
11437  m_start = start;
11438  }
11439  void TestSpecParser::escape() {
11440  if( m_mode == None )
11441  m_start = m_pos;
11442  m_mode = EscapedName;
11443  m_escapeChars.push_back( m_pos );
11444  }
11445  std::string TestSpecParser::subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
11446 
11447  void TestSpecParser::addFilter() {
11448  if( !m_currentFilter.m_patterns.empty() ) {
11449  m_testSpec.m_filters.push_back( m_currentFilter );
11450  m_currentFilter = TestSpec::Filter();
11451  }
11452  }
11453 
11454  TestSpec parseTestSpec( std::string const& arg ) {
11455  return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
11456  }
11457 
11458 } // namespace Catch
11459 // end catch_test_spec_parser.cpp
11460 // start catch_timer.cpp
11461 
11462 #include <chrono>
11463 
11464 static const uint64_t nanosecondsInSecond = 1000000000;
11465 
11466 namespace Catch {
11467 
11468  auto getCurrentNanosecondsSinceEpoch() -> uint64_t {
11469  return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
11470  }
11471 
11472  namespace {
11473  auto estimateClockResolution() -> uint64_t {
11474  uint64_t sum = 0;
11475  static const uint64_t iterations = 1000000;
11476 
11477  auto startTime = getCurrentNanosecondsSinceEpoch();
11478 
11479  for( std::size_t i = 0; i < iterations; ++i ) {
11480 
11481  uint64_t ticks;
11482  uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
11483  do {
11485  } while( ticks == baseTicks );
11486 
11487  auto delta = ticks - baseTicks;
11488  sum += delta;
11489 
11490  // If we have been calibrating for over 3 seconds -- the clock
11491  // is terrible and we should move on.
11492  // TBD: How to signal that the measured resolution is probably wrong?
11493  if (ticks > startTime + 3 * nanosecondsInSecond) {
11494  return sum / i;
11495  }
11496  }
11497 
11498  // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
11499  // - and potentially do more iterations if there's a high variance.
11500  return sum/iterations;
11501  }
11502  }
11503  auto getEstimatedClockResolution() -> uint64_t {
11504  static auto s_resolution = estimateClockResolution();
11505  return s_resolution;
11506  }
11507 
11508  void Timer::start() {
11509  m_nanoseconds = getCurrentNanosecondsSinceEpoch();
11510  }
11511  auto Timer::getElapsedNanoseconds() const -> uint64_t {
11512  return getCurrentNanosecondsSinceEpoch() - m_nanoseconds;
11513  }
11514  auto Timer::getElapsedMicroseconds() const -> uint64_t {
11515  return getElapsedNanoseconds()/1000;
11516  }
11517  auto Timer::getElapsedMilliseconds() const -> unsigned int {
11518  return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
11519  }
11520  auto Timer::getElapsedSeconds() const -> double {
11521  return getElapsedMicroseconds()/1000000.0;
11522  }
11523 
11524 } // namespace Catch
11525 // end catch_timer.cpp
11526 // start catch_tostring.cpp
11527 
11528 #if defined(__clang__)
11529 # pragma clang diagnostic push
11530 # pragma clang diagnostic ignored "-Wexit-time-destructors"
11531 # pragma clang diagnostic ignored "-Wglobal-constructors"
11532 #endif
11533 
11534 // Enable specific decls locally
11535 #if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
11536 #define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
11537 #endif
11538 
11539 #include <cmath>
11540 #include <iomanip>
11541 
11542 namespace Catch {
11543 
11544 namespace Detail {
11545 
11546  const std::string unprintableString = "{?}";
11547 
11548  namespace {
11549  const int hexThreshold = 255;
11550 
11551  struct Endianness {
11552  enum Arch { Big, Little };
11553 
11554  static Arch which() {
11555  union _{
11556  int asInt;
11557  char asChar[sizeof (int)];
11558  } u;
11559 
11560  u.asInt = 1;
11561  return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
11562  }
11563  };
11564  }
11565 
11566  std::string rawMemoryToString( const void *object, std::size_t size ) {
11567  // Reverse order for little endian architectures
11568  int i = 0, end = static_cast<int>( size ), inc = 1;
11569  if( Endianness::which() == Endianness::Little ) {
11570  i = end-1;
11571  end = inc = -1;
11572  }
11573 
11574  unsigned char const *bytes = static_cast<unsigned char const *>(object);
11576  rss << "0x" << std::setfill('0') << std::hex;
11577  for( ; i != end; i += inc )
11578  rss << std::setw(2) << static_cast<unsigned>(bytes[i]);
11579  return rss.str();
11580  }
11581 }
11582 
11583 template<typename T>
11584 std::string fpToString( T value, int precision ) {
11585  if (std::isnan(value)) {
11586  return "nan";
11587  }
11588 
11590  rss << std::setprecision( precision )
11591  << std::fixed
11592  << value;
11593  std::string d = rss.str();
11594  std::size_t i = d.find_last_not_of( '0' );
11595  if( i != std::string::npos && i != d.size()-1 ) {
11596  if( d[i] == '.' )
11597  i++;
11598  d = d.substr( 0, i+1 );
11599  }
11600  return d;
11601 }
11602 
11604 //
11605 // Out-of-line defs for full specialization of StringMaker
11606 //
11608 
11609 std::string StringMaker<std::string>::convert(const std::string& str) {
11610  if (!getCurrentContext().getConfig()->showInvisibles()) {
11611  return '"' + str + '"';
11612  }
11613 
11614  std::string s("\"");
11615  for (char c : str) {
11616  switch (c) {
11617  case '\n':
11618  s.append("\\n");
11619  break;
11620  case '\t':
11621  s.append("\\t");
11622  break;
11623  default:
11624  s.push_back(c);
11625  break;
11626  }
11627  }
11628  s.append("\"");
11629  return s;
11630 }
11631 
11632 #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
11633 std::string StringMaker<std::string_view>::convert(std::string_view str) {
11634  return ::Catch::Detail::stringify(std::string{ str });
11635 }
11636 #endif
11637 
11638 std::string StringMaker<char const*>::convert(char const* str) {
11639  if (str) {
11640  return ::Catch::Detail::stringify(std::string{ str });
11641  } else {
11642  return{ "{null string}" };
11643  }
11644 }
11645 std::string StringMaker<char*>::convert(char* str) {
11646  if (str) {
11647  return ::Catch::Detail::stringify(std::string{ str });
11648  } else {
11649  return{ "{null string}" };
11650  }
11651 }
11652 
11653 #ifdef CATCH_CONFIG_WCHAR
11654 std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
11655  std::string s;
11656  s.reserve(wstr.size());
11657  for (auto c : wstr) {
11658  s += (c <= 0xff) ? static_cast<char>(c) : '?';
11659  }
11661 }
11662 
11663 # ifdef CATCH_CONFIG_CPP17_STRING_VIEW
11664 std::string StringMaker<std::wstring_view>::convert(std::wstring_view str) {
11665  return StringMaker<std::wstring>::convert(std::wstring(str));
11666 }
11667 # endif
11668 
11669 std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {
11670  if (str) {
11671  return ::Catch::Detail::stringify(std::wstring{ str });
11672  } else {
11673  return{ "{null string}" };
11674  }
11675 }
11676 std::string StringMaker<wchar_t *>::convert(wchar_t * str) {
11677  if (str) {
11678  return ::Catch::Detail::stringify(std::wstring{ str });
11679  } else {
11680  return{ "{null string}" };
11681  }
11682 }
11683 #endif
11684 
11685 std::string StringMaker<int>::convert(int value) {
11686  return ::Catch::Detail::stringify(static_cast<long long>(value));
11687 }
11688 std::string StringMaker<long>::convert(long value) {
11689  return ::Catch::Detail::stringify(static_cast<long long>(value));
11690 }
11691 std::string StringMaker<long long>::convert(long long value) {
11693  rss << value;
11694  if (value > Detail::hexThreshold) {
11695  rss << " (0x" << std::hex << value << ')';
11696  }
11697  return rss.str();
11698 }
11699 
11700 std::string StringMaker<unsigned int>::convert(unsigned int value) {
11701  return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
11702 }
11703 std::string StringMaker<unsigned long>::convert(unsigned long value) {
11704  return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
11705 }
11706 std::string StringMaker<unsigned long long>::convert(unsigned long long value) {
11708  rss << value;
11709  if (value > Detail::hexThreshold) {
11710  rss << " (0x" << std::hex << value << ')';
11711  }
11712  return rss.str();
11713 }
11714 
11715 std::string StringMaker<bool>::convert(bool b) {
11716  return b ? "true" : "false";
11717 }
11718 
11719 std::string StringMaker<signed char>::convert(signed char value) {
11720  if (value == '\r') {
11721  return "'\\r'";
11722  } else if (value == '\f') {
11723  return "'\\f'";
11724  } else if (value == '\n') {
11725  return "'\\n'";
11726  } else if (value == '\t') {
11727  return "'\\t'";
11728  } else if ('\0' <= value && value < ' ') {
11729  return ::Catch::Detail::stringify(static_cast<unsigned int>(value));
11730  } else {
11731  char chstr[] = "' '";
11732  chstr[1] = value;
11733  return chstr;
11734  }
11735 }
11736 std::string StringMaker<char>::convert(char c) {
11737  return ::Catch::Detail::stringify(static_cast<signed char>(c));
11738 }
11739 std::string StringMaker<unsigned char>::convert(unsigned char c) {
11740  return ::Catch::Detail::stringify(static_cast<char>(c));
11741 }
11742 
11743 std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) {
11744  return "nullptr";
11745 }
11746 
11747 std::string StringMaker<float>::convert(float value) {
11748  return fpToString(value, 5) + 'f';
11749 }
11750 std::string StringMaker<double>::convert(double value) {
11751  return fpToString(value, 10);
11752 }
11753 
11754 std::string ratio_string<std::atto>::symbol() { return "a"; }
11755 std::string ratio_string<std::femto>::symbol() { return "f"; }
11756 std::string ratio_string<std::pico>::symbol() { return "p"; }
11757 std::string ratio_string<std::nano>::symbol() { return "n"; }
11758 std::string ratio_string<std::micro>::symbol() { return "u"; }
11759 std::string ratio_string<std::milli>::symbol() { return "m"; }
11760 
11761 } // end namespace Catch
11762 
11763 #if defined(__clang__)
11764 # pragma clang diagnostic pop
11765 #endif
11766 
11767 // end catch_tostring.cpp
11768 // start catch_totals.cpp
11769 
11770 namespace Catch {
11771 
11772  Counts Counts::operator - ( Counts const& other ) const {
11773  Counts diff;
11774  diff.passed = passed - other.passed;
11775  diff.failed = failed - other.failed;
11776  diff.failedButOk = failedButOk - other.failedButOk;
11777  return diff;
11778  }
11779 
11780  Counts& Counts::operator += ( Counts const& other ) {
11781  passed += other.passed;
11782  failed += other.failed;
11783  failedButOk += other.failedButOk;
11784  return *this;
11785  }
11786 
11787  std::size_t Counts::total() const {
11788  return passed + failed + failedButOk;
11789  }
11790  bool Counts::allPassed() const {
11791  return failed == 0 && failedButOk == 0;
11792  }
11793  bool Counts::allOk() const {
11794  return failed == 0;
11795  }
11796 
11797  Totals Totals::operator - ( Totals const& other ) const {
11798  Totals diff;
11799  diff.assertions = assertions - other.assertions;
11800  diff.testCases = testCases - other.testCases;
11801  return diff;
11802  }
11803 
11804  Totals& Totals::operator += ( Totals const& other ) {
11805  assertions += other.assertions;
11806  testCases += other.testCases;
11807  return *this;
11808  }
11809 
11810  Totals Totals::delta( Totals const& prevTotals ) const {
11811  Totals diff = *this - prevTotals;
11812  if( diff.assertions.failed > 0 )
11813  ++diff.testCases.failed;
11814  else if( diff.assertions.failedButOk > 0 )
11815  ++diff.testCases.failedButOk;
11816  else
11817  ++diff.testCases.passed;
11818  return diff;
11819  }
11820 
11821 }
11822 // end catch_totals.cpp
11823 // start catch_uncaught_exceptions.cpp
11824 
11825 #include <exception>
11826 
11827 namespace Catch {
11828  bool uncaught_exceptions() {
11829 #if defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
11830  return std::uncaught_exceptions() > 0;
11831 #else
11832  return std::uncaught_exception();
11833 #endif
11834  }
11835 } // end namespace Catch
11836 // end catch_uncaught_exceptions.cpp
11837 // start catch_version.cpp
11838 
11839 #include <ostream>
11840 
11841 namespace Catch {
11842 
11843  Version::Version
11844  ( unsigned int _majorVersion,
11845  unsigned int _minorVersion,
11846  unsigned int _patchNumber,
11847  char const * const _branchName,
11848  unsigned int _buildNumber )
11849  : majorVersion( _majorVersion ),
11850  minorVersion( _minorVersion ),
11851  patchNumber( _patchNumber ),
11852  branchName( _branchName ),
11853  buildNumber( _buildNumber )
11854  {}
11855 
11856  std::ostream& operator << ( std::ostream& os, Version const& version ) {
11857  os << version.majorVersion << '.'
11858  << version.minorVersion << '.'
11859  << version.patchNumber;
11860  // branchName is never null -> 0th char is \0 if it is empty
11861  if (version.branchName[0]) {
11862  os << '-' << version.branchName
11863  << '.' << version.buildNumber;
11864  }
11865  return os;
11866  }
11867 
11868  Version const& libraryVersion() {
11869  static Version version( 2, 4, 2, "", 0 );
11870  return version;
11871  }
11872 
11873 }
11874 // end catch_version.cpp
11875 // start catch_wildcard_pattern.cpp
11876 
11877 #include <sstream>
11878 
11879 namespace Catch {
11880 
11881  WildcardPattern::WildcardPattern( std::string const& pattern,
11882  CaseSensitive::Choice caseSensitivity )
11883  : m_caseSensitivity( caseSensitivity ),
11884  m_pattern( adjustCase( pattern ) )
11885  {
11886  if( startsWith( m_pattern, '*' ) ) {
11887  m_pattern = m_pattern.substr( 1 );
11888  m_wildcard = WildcardAtStart;
11889  }
11890  if( endsWith( m_pattern, '*' ) ) {
11891  m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
11892  m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
11893  }
11894  }
11895 
11896  bool WildcardPattern::matches( std::string const& str ) const {
11897  switch( m_wildcard ) {
11898  case NoWildcard:
11899  return m_pattern == adjustCase( str );
11900  case WildcardAtStart:
11901  return endsWith( adjustCase( str ), m_pattern );
11902  case WildcardAtEnd:
11903  return startsWith( adjustCase( str ), m_pattern );
11904  case WildcardAtBothEnds:
11905  return contains( adjustCase( str ), m_pattern );
11906  default:
11907  CATCH_INTERNAL_ERROR( "Unknown enum" );
11908  }
11909  }
11910 
11911  std::string WildcardPattern::adjustCase( std::string const& str ) const {
11912  return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;
11913  }
11914 }
11915 // end catch_wildcard_pattern.cpp
11916 // start catch_xmlwriter.cpp
11917 
11918 #include <iomanip>
11919 
11920 using uchar = unsigned char;
11921 
11922 namespace Catch {
11923 
11924 namespace {
11925 
11926  size_t trailingBytes(unsigned char c) {
11927  if ((c & 0xE0) == 0xC0) {
11928  return 2;
11929  }
11930  if ((c & 0xF0) == 0xE0) {
11931  return 3;
11932  }
11933  if ((c & 0xF8) == 0xF0) {
11934  return 4;
11935  }
11936  CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
11937  }
11938 
11939  uint32_t headerValue(unsigned char c) {
11940  if ((c & 0xE0) == 0xC0) {
11941  return c & 0x1F;
11942  }
11943  if ((c & 0xF0) == 0xE0) {
11944  return c & 0x0F;
11945  }
11946  if ((c & 0xF8) == 0xF0) {
11947  return c & 0x07;
11948  }
11949  CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
11950  }
11951 
11952  void hexEscapeChar(std::ostream& os, unsigned char c) {
11953  os << "\\x"
11954  << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
11955  << static_cast<int>(c);
11956  }
11957 
11958 } // anonymous namespace
11959 
11960  XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )
11961  : m_str( str ),
11962  m_forWhat( forWhat )
11963  {}
11964 
11965  void XmlEncode::encodeTo( std::ostream& os ) const {
11966  // Apostrophe escaping not necessary if we always use " to write attributes
11967  // (see: http://www.w3.org/TR/xml/#syntax)
11968 
11969  for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
11970  uchar c = m_str[idx];
11971  switch (c) {
11972  case '<': os << "&lt;"; break;
11973  case '&': os << "&amp;"; break;
11974 
11975  case '>':
11976  // See: http://www.w3.org/TR/xml/#syntax
11977  if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
11978  os << "&gt;";
11979  else
11980  os << c;
11981  break;
11982 
11983  case '\"':
11984  if (m_forWhat == ForAttributes)
11985  os << "&quot;";
11986  else
11987  os << c;
11988  break;
11989 
11990  default:
11991  // Check for control characters and invalid utf-8
11992 
11993  // Escape control characters in standard ascii
11994  // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
11995  if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
11996  hexEscapeChar(os, c);
11997  break;
11998  }
11999 
12000  // Plain ASCII: Write it to stream
12001  if (c < 0x7F) {
12002  os << c;
12003  break;
12004  }
12005 
12006  // UTF-8 territory
12007  // Check if the encoding is valid and if it is not, hex escape bytes.
12008  // Important: We do not check the exact decoded values for validity, only the encoding format
12009  // First check that this bytes is a valid lead byte:
12010  // This means that it is not encoded as 1111 1XXX
12011  // Or as 10XX XXXX
12012  if (c < 0xC0 ||
12013  c >= 0xF8) {
12014  hexEscapeChar(os, c);
12015  break;
12016  }
12017 
12018  auto encBytes = trailingBytes(c);
12019  // Are there enough bytes left to avoid accessing out-of-bounds memory?
12020  if (idx + encBytes - 1 >= m_str.size()) {
12021  hexEscapeChar(os, c);
12022  break;
12023  }
12024  // The header is valid, check data
12025  // The next encBytes bytes must together be a valid utf-8
12026  // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)
12027  bool valid = true;
12028  uint32_t value = headerValue(c);
12029  for (std::size_t n = 1; n < encBytes; ++n) {
12030  uchar nc = m_str[idx + n];
12031  valid &= ((nc & 0xC0) == 0x80);
12032  value = (value << 6) | (nc & 0x3F);
12033  }
12034 
12035  if (
12036  // Wrong bit pattern of following bytes
12037  (!valid) ||
12038  // Overlong encodings
12039  (value < 0x80) ||
12040  (0x80 <= value && value < 0x800 && encBytes > 2) ||
12041  (0x800 < value && value < 0x10000 && encBytes > 3) ||
12042  // Encoded value out of range
12043  (value >= 0x110000)
12044  ) {
12045  hexEscapeChar(os, c);
12046  break;
12047  }
12048 
12049  // If we got here, this is in fact a valid(ish) utf-8 sequence
12050  for (std::size_t n = 0; n < encBytes; ++n) {
12051  os << m_str[idx + n];
12052  }
12053  idx += encBytes - 1;
12054  break;
12055  }
12056  }
12057  }
12058 
12059  std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
12060  xmlEncode.encodeTo( os );
12061  return os;
12062  }
12063 
12064  XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer )
12065  : m_writer( writer )
12066  {}
12067 
12068  XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept
12069  : m_writer( other.m_writer ){
12070  other.m_writer = nullptr;
12071  }
12072  XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept {
12073  if ( m_writer ) {
12074  m_writer->endElement();
12075  }
12076  m_writer = other.m_writer;
12077  other.m_writer = nullptr;
12078  return *this;
12079  }
12080 
12081  XmlWriter::ScopedElement::~ScopedElement() {
12082  if( m_writer )
12083  m_writer->endElement();
12084  }
12085 
12086  XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, bool indent ) {
12087  m_writer->writeText( text, indent );
12088  return *this;
12089  }
12090 
12091  XmlWriter::XmlWriter( std::ostream& os ) : m_os( os )
12092  {
12093  writeDeclaration();
12094  }
12095 
12096  XmlWriter::~XmlWriter() {
12097  while( !m_tags.empty() )
12098  endElement();
12099  }
12100 
12101  XmlWriter& XmlWriter::startElement( std::string const& name ) {
12102  ensureTagClosed();
12103  newlineIfNecessary();
12104  m_os << m_indent << '<' << name;
12105  m_tags.push_back( name );
12106  m_indent += " ";
12107  m_tagIsOpen = true;
12108  return *this;
12109  }
12110 
12111  XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name ) {
12112  ScopedElement scoped( this );
12113  startElement( name );
12114  return scoped;
12115  }
12116 
12117  XmlWriter& XmlWriter::endElement() {
12118  newlineIfNecessary();
12119  m_indent = m_indent.substr( 0, m_indent.size()-2 );
12120  if( m_tagIsOpen ) {
12121  m_os << "/>";
12122  m_tagIsOpen = false;
12123  }
12124  else {
12125  m_os << m_indent << "</" << m_tags.back() << ">";
12126  }
12127  m_os << std::endl;
12128  m_tags.pop_back();
12129  return *this;
12130  }
12131 
12132  XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) {
12133  if( !name.empty() && !attribute.empty() )
12134  m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
12135  return *this;
12136  }
12137 
12138  XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) {
12139  m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
12140  return *this;
12141  }
12142 
12143  XmlWriter& XmlWriter::writeText( std::string const& text, bool indent ) {
12144  if( !text.empty() ){
12145  bool tagWasOpen = m_tagIsOpen;
12146  ensureTagClosed();
12147  if( tagWasOpen && indent )
12148  m_os << m_indent;
12149  m_os << XmlEncode( text );
12150  m_needsNewline = true;
12151  }
12152  return *this;
12153  }
12154 
12155  XmlWriter& XmlWriter::writeComment( std::string const& text ) {
12156  ensureTagClosed();
12157  m_os << m_indent << "<!--" << text << "-->";
12158  m_needsNewline = true;
12159  return *this;
12160  }
12161 
12162  void XmlWriter::writeStylesheetRef( std::string const& url ) {
12163  m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
12164  }
12165 
12166  XmlWriter& XmlWriter::writeBlankLine() {
12167  ensureTagClosed();
12168  m_os << '\n';
12169  return *this;
12170  }
12171 
12172  void XmlWriter::ensureTagClosed() {
12173  if( m_tagIsOpen ) {
12174  m_os << ">" << std::endl;
12175  m_tagIsOpen = false;
12176  }
12177  }
12178 
12179  void XmlWriter::writeDeclaration() {
12180  m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
12181  }
12182 
12183  void XmlWriter::newlineIfNecessary() {
12184  if( m_needsNewline ) {
12185  m_os << std::endl;
12186  m_needsNewline = false;
12187  }
12188  }
12189 }
12190 // end catch_xmlwriter.cpp
12191 // start catch_reporter_bases.cpp
12192 
12193 #include <cstring>
12194 #include <cfloat>
12195 #include <cstdio>
12196 #include <cassert>
12197 #include <memory>
12198 
12199 namespace Catch {
12200  void prepareExpandedExpression(AssertionResult& result) {
12201  result.getExpandedExpression();
12202  }
12203 
12204  // Because formatting using c++ streams is stateful, drop down to C is required
12205  // Alternatively we could use stringstream, but its performance is... not good.
12206  std::string getFormattedDuration( double duration ) {
12207  // Max exponent + 1 is required to represent the whole part
12208  // + 1 for decimal point
12209  // + 3 for the 3 decimal places
12210  // + 1 for null terminator
12211  const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
12212  char buffer[maxDoubleSize];
12213 
12214  // Save previous errno, to prevent sprintf from overwriting it
12215  ErrnoGuard guard;
12216 #ifdef _MSC_VER
12217  sprintf_s(buffer, "%.3f", duration);
12218 #else
12219  sprintf(buffer, "%.3f", duration);
12220 #endif
12221  return std::string(buffer);
12222  }
12223 
12224  TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)
12225  :StreamingReporterBase(_config) {}
12226 
12227  void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}
12228 
12229  bool TestEventListenerBase::assertionEnded(AssertionStats const &) {
12230  return false;
12231  }
12232 
12233 } // end namespace Catch
12234 // end catch_reporter_bases.cpp
12235 // start catch_reporter_compact.cpp
12236 
12237 namespace {
12238 
12239 #ifdef CATCH_PLATFORM_MAC
12240  const char* failedString() { return "FAILED"; }
12241  const char* passedString() { return "PASSED"; }
12242 #else
12243  const char* failedString() { return "failed"; }
12244  const char* passedString() { return "passed"; }
12245 #endif
12246 
12247  // Colour::LightGrey
12248  Catch::Colour::Code dimColour() { return Catch::Colour::FileName; }
12249 
12250  std::string bothOrAll( std::size_t count ) {
12251  return count == 1 ? std::string() :
12252  count == 2 ? "both " : "all " ;
12253  }
12254 
12255 } // anon namespace
12256 
12257 namespace Catch {
12258 namespace {
12259 // Colour, message variants:
12260 // - white: No tests ran.
12261 // - red: Failed [both/all] N test cases, failed [both/all] M assertions.
12262 // - white: Passed [both/all] N test cases (no assertions).
12263 // - red: Failed N tests cases, failed M assertions.
12264 // - green: Passed [both/all] N tests cases with M assertions.
12265 void printTotals(std::ostream& out, const Totals& totals) {
12266  if (totals.testCases.total() == 0) {
12267  out << "No tests ran.";
12268  } else if (totals.testCases.failed == totals.testCases.total()) {
12269  Colour colour(Colour::ResultError);
12270  const std::string qualify_assertions_failed =
12271  totals.assertions.failed == totals.assertions.total() ?
12272  bothOrAll(totals.assertions.failed) : std::string();
12273  out <<
12274  "Failed " << bothOrAll(totals.testCases.failed)
12275  << pluralise(totals.testCases.failed, "test case") << ", "
12276  "failed " << qualify_assertions_failed <<
12277  pluralise(totals.assertions.failed, "assertion") << '.';
12278  } else if (totals.assertions.total() == 0) {
12279  out <<
12280  "Passed " << bothOrAll(totals.testCases.total())
12281  << pluralise(totals.testCases.total(), "test case")
12282  << " (no assertions).";
12283  } else if (totals.assertions.failed) {
12284  Colour colour(Colour::ResultError);
12285  out <<
12286  "Failed " << pluralise(totals.testCases.failed, "test case") << ", "
12287  "failed " << pluralise(totals.assertions.failed, "assertion") << '.';
12288  } else {
12289  Colour colour(Colour::ResultSuccess);
12290  out <<
12291  "Passed " << bothOrAll(totals.testCases.passed)
12292  << pluralise(totals.testCases.passed, "test case") <<
12293  " with " << pluralise(totals.assertions.passed, "assertion") << '.';
12294  }
12295 }
12296 
12297 // Implementation of CompactReporter formatting
12298 class AssertionPrinter {
12299 public:
12300  AssertionPrinter& operator= (AssertionPrinter const&) = delete;
12301  AssertionPrinter(AssertionPrinter const&) = delete;
12302  AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
12303  : stream(_stream)
12304  , result(_stats.assertionResult)
12305  , messages(_stats.infoMessages)
12306  , itMessage(_stats.infoMessages.begin())
12307  , printInfoMessages(_printInfoMessages) {}
12308 
12309  void print() {
12310  printSourceInfo();
12311 
12312  itMessage = messages.begin();
12313 
12314  switch (result.getResultType()) {
12315  case ResultWas::Ok:
12316  printResultType(Colour::ResultSuccess, passedString());
12317  printOriginalExpression();
12318  printReconstructedExpression();
12319  if (!result.hasExpression())
12320  printRemainingMessages(Colour::None);
12321  else
12322  printRemainingMessages();
12323  break;
12325  if (result.isOk())
12326  printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok"));
12327  else
12328  printResultType(Colour::Error, failedString());
12329  printOriginalExpression();
12330  printReconstructedExpression();
12331  printRemainingMessages();
12332  break;
12334  printResultType(Colour::Error, failedString());
12335  printIssue("unexpected exception with message:");
12336  printMessage();
12337  printExpressionWas();
12338  printRemainingMessages();
12339  break;
12341  printResultType(Colour::Error, failedString());
12342  printIssue("fatal error condition with message:");
12343  printMessage();
12344  printExpressionWas();
12345  printRemainingMessages();
12346  break;
12348  printResultType(Colour::Error, failedString());
12349  printIssue("expected exception, got none");
12350  printExpressionWas();
12351  printRemainingMessages();
12352  break;
12353  case ResultWas::Info:
12354  printResultType(Colour::None, "info");
12355  printMessage();
12356  printRemainingMessages();
12357  break;
12358  case ResultWas::Warning:
12359  printResultType(Colour::None, "warning");
12360  printMessage();
12361  printRemainingMessages();
12362  break;
12364  printResultType(Colour::Error, failedString());
12365  printIssue("explicitly");
12366  printRemainingMessages(Colour::None);
12367  break;
12368  // These cases are here to prevent compiler warnings
12369  case ResultWas::Unknown:
12370  case ResultWas::FailureBit:
12371  case ResultWas::Exception:
12372  printResultType(Colour::Error, "** internal error **");
12373  break;
12374  }
12375  }
12376 
12377 private:
12378  void printSourceInfo() const {
12379  Colour colourGuard(Colour::FileName);
12380  stream << result.getSourceInfo() << ':';
12381  }
12382 
12383  void printResultType(Colour::Code colour, std::string const& passOrFail) const {
12384  if (!passOrFail.empty()) {
12385  {
12386  Colour colourGuard(colour);
12387  stream << ' ' << passOrFail;
12388  }
12389  stream << ':';
12390  }
12391  }
12392 
12393  void printIssue(std::string const& issue) const {
12394  stream << ' ' << issue;
12395  }
12396 
12397  void printExpressionWas() {
12398  if (result.hasExpression()) {
12399  stream << ';';
12400  {
12401  Colour colour(dimColour());
12402  stream << " expression was:";
12403  }
12404  printOriginalExpression();
12405  }
12406  }
12407 
12408  void printOriginalExpression() const {
12409  if (result.hasExpression()) {
12410  stream << ' ' << result.getExpression();
12411  }
12412  }
12413 
12414  void printReconstructedExpression() const {
12415  if (result.hasExpandedExpression()) {
12416  {
12417  Colour colour(dimColour());
12418  stream << " for: ";
12419  }
12420  stream << result.getExpandedExpression();
12421  }
12422  }
12423 
12424  void printMessage() {
12425  if (itMessage != messages.end()) {
12426  stream << " '" << itMessage->message << '\'';
12427  ++itMessage;
12428  }
12429  }
12430 
12431  void printRemainingMessages(Colour::Code colour = dimColour()) {
12432  if (itMessage == messages.end())
12433  return;
12434 
12435  // using messages.end() directly yields (or auto) compilation error:
12436  std::vector<MessageInfo>::const_iterator itEnd = messages.end();
12437  const std::size_t N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
12438 
12439  {
12440  Colour colourGuard(colour);
12441  stream << " with " << pluralise(N, "message") << ':';
12442  }
12443 
12444  for (; itMessage != itEnd; ) {
12445  // If this assertion is a warning ignore any INFO messages
12446  if (printInfoMessages || itMessage->type != ResultWas::Info) {
12447  stream << " '" << itMessage->message << '\'';
12448  if (++itMessage != itEnd) {
12449  Colour colourGuard(dimColour());
12450  stream << " and";
12451  }
12452  }
12453  }
12454  }
12455 
12456 private:
12457  std::ostream& stream;
12458  AssertionResult const& result;
12459  std::vector<MessageInfo> messages;
12460  std::vector<MessageInfo>::const_iterator itMessage;
12461  bool printInfoMessages;
12462 };
12463 
12464 } // anon namespace
12465 
12466  std::string CompactReporter::getDescription() {
12467  return "Reports test results on a single line, suitable for IDEs";
12468  }
12469 
12470  ReporterPreferences CompactReporter::getPreferences() const {
12471  return m_reporterPrefs;
12472  }
12473 
12474  void CompactReporter::noMatchingTestCases( std::string const& spec ) {
12475  stream << "No test cases matched '" << spec << '\'' << std::endl;
12476  }
12477 
12478  void CompactReporter::assertionStarting( AssertionInfo const& ) {}
12479 
12480  bool CompactReporter::assertionEnded( AssertionStats const& _assertionStats ) {
12481  AssertionResult const& result = _assertionStats.assertionResult;
12482 
12483  bool printInfoMessages = true;
12484 
12485  // Drop out if result was successful and we're not printing those
12486  if( !m_config->includeSuccessfulResults() && result.isOk() ) {
12487  if( result.getResultType() != ResultWas::Warning )
12488  return false;
12489  printInfoMessages = false;
12490  }
12491 
12492  AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
12493  printer.print();
12494 
12495  stream << std::endl;
12496  return true;
12497  }
12498 
12499  void CompactReporter::sectionEnded(SectionStats const& _sectionStats) {
12500  if (m_config->showDurations() == ShowDurations::Always) {
12501  stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
12502  }
12503  }
12504 
12505  void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) {
12506  printTotals( stream, _testRunStats.totals );
12507  stream << '\n' << std::endl;
12508  StreamingReporterBase::testRunEnded( _testRunStats );
12509  }
12510 
12511  CompactReporter::~CompactReporter() {}
12512 
12513  CATCH_REGISTER_REPORTER( "compact", CompactReporter )
12514 
12515 } // end namespace Catch
12516 // end catch_reporter_compact.cpp
12517 // start catch_reporter_console.cpp
12518 
12519 #include <cfloat>
12520 #include <cstdio>
12521 
12522 #if defined(_MSC_VER)
12523 #pragma warning(push)
12524 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
12525  // Note that 4062 (not all labels are handled
12526  // and default is missing) is enabled
12527 #endif
12528 
12529 namespace Catch {
12530 
12531 namespace {
12532 
12533 // Formatter impl for ConsoleReporter
12534 class ConsoleAssertionPrinter {
12535 public:
12536  ConsoleAssertionPrinter& operator= (ConsoleAssertionPrinter const&) = delete;
12537  ConsoleAssertionPrinter(ConsoleAssertionPrinter const&) = delete;
12538  ConsoleAssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)
12539  : stream(_stream),
12540  stats(_stats),
12541  result(_stats.assertionResult),
12542  colour(Colour::None),
12543  message(result.getMessage()),
12544  messages(_stats.infoMessages),
12545  printInfoMessages(_printInfoMessages) {
12546  switch (result.getResultType()) {
12547  case ResultWas::Ok:
12548  colour = Colour::Success;
12549  passOrFail = "PASSED";
12550  //if( result.hasMessage() )
12551  if (_stats.infoMessages.size() == 1)
12552  messageLabel = "with message";
12553  if (_stats.infoMessages.size() > 1)
12554  messageLabel = "with messages";
12555  break;
12557  if (result.isOk()) {
12558  colour = Colour::Success;
12559  passOrFail = "FAILED - but was ok";
12560  } else {
12561  colour = Colour::Error;
12562  passOrFail = "FAILED";
12563  }
12564  if (_stats.infoMessages.size() == 1)
12565  messageLabel = "with message";
12566  if (_stats.infoMessages.size() > 1)
12567  messageLabel = "with messages";
12568  break;
12570  colour = Colour::Error;
12571  passOrFail = "FAILED";
12572  messageLabel = "due to unexpected exception with ";
12573  if (_stats.infoMessages.size() == 1)
12574  messageLabel += "message";
12575  if (_stats.infoMessages.size() > 1)
12576  messageLabel += "messages";
12577  break;
12579  colour = Colour::Error;
12580  passOrFail = "FAILED";
12581  messageLabel = "due to a fatal error condition";
12582  break;
12584  colour = Colour::Error;
12585  passOrFail = "FAILED";
12586  messageLabel = "because no exception was thrown where one was expected";
12587  break;
12588  case ResultWas::Info:
12589  messageLabel = "info";
12590  break;
12591  case ResultWas::Warning:
12592  messageLabel = "warning";
12593  break;
12595  passOrFail = "FAILED";
12596  colour = Colour::Error;
12597  if (_stats.infoMessages.size() == 1)
12598  messageLabel = "explicitly with message";
12599  if (_stats.infoMessages.size() > 1)
12600  messageLabel = "explicitly with messages";
12601  break;
12602  // These cases are here to prevent compiler warnings
12603  case ResultWas::Unknown:
12604  case ResultWas::FailureBit:
12605  case ResultWas::Exception:
12606  passOrFail = "** internal error **";
12607  colour = Colour::Error;
12608  break;
12609  }
12610  }
12611 
12612  void print() const {
12613  printSourceInfo();
12614  if (stats.totals.assertions.total() > 0) {
12615  if (result.isOk())
12616  stream << '\n';
12617  printResultType();
12618  printOriginalExpression();
12619  printReconstructedExpression();
12620  } else {
12621  stream << '\n';
12622  }
12623  printMessage();
12624  }
12625 
12626 private:
12627  void printResultType() const {
12628  if (!passOrFail.empty()) {
12629  Colour colourGuard(colour);
12630  stream << passOrFail << ":\n";
12631  }
12632  }
12633  void printOriginalExpression() const {
12634  if (result.hasExpression()) {
12635  Colour colourGuard(Colour::OriginalExpression);
12636  stream << " ";
12637  stream << result.getExpressionInMacro();
12638  stream << '\n';
12639  }
12640  }
12641  void printReconstructedExpression() const {
12642  if (result.hasExpandedExpression()) {
12643  stream << "with expansion:\n";
12644  Colour colourGuard(Colour::ReconstructedExpression);
12645  stream << Column(result.getExpandedExpression()).indent(2) << '\n';
12646  }
12647  }
12648  void printMessage() const {
12649  if (!messageLabel.empty())
12650  stream << messageLabel << ':' << '\n';
12651  for (auto const& msg : messages) {
12652  // If this assertion is a warning ignore any INFO messages
12653  if (printInfoMessages || msg.type != ResultWas::Info)
12654  stream << Column(msg.message).indent(2) << '\n';
12655  }
12656  }
12657  void printSourceInfo() const {
12658  Colour colourGuard(Colour::FileName);
12659  stream << result.getSourceInfo() << ": ";
12660  }
12661 
12662  std::ostream& stream;
12663  AssertionStats const& stats;
12664  AssertionResult const& result;
12665  Colour::Code colour;
12666  std::string passOrFail;
12667  std::string messageLabel;
12668  std::string message;
12669  std::vector<MessageInfo> messages;
12670  bool printInfoMessages;
12671 };
12672 
12673 std::size_t makeRatio(std::size_t number, std::size_t total) {
12674  std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0;
12675  return (ratio == 0 && number > 0) ? 1 : ratio;
12676 }
12677 
12678 std::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k) {
12679  if (i > j && i > k)
12680  return i;
12681  else if (j > k)
12682  return j;
12683  else
12684  return k;
12685 }
12686 
12687 struct ColumnInfo {
12688  enum Justification { Left, Right };
12689  std::string name;
12690  int width;
12691  Justification justification;
12692 };
12693 struct ColumnBreak {};
12694 struct RowBreak {};
12695 
12696 class Duration {
12697  enum class Unit {
12698  Auto,
12699  Nanoseconds,
12700  Microseconds,
12701  Milliseconds,
12702  Seconds,
12703  Minutes
12704  };
12705  static const uint64_t s_nanosecondsInAMicrosecond = 1000;
12706  static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond;
12707  static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;
12708  static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;
12709 
12710  uint64_t m_inNanoseconds;
12711  Unit m_units;
12712 
12713 public:
12714  explicit Duration(uint64_t inNanoseconds, Unit units = Unit::Auto)
12715  : m_inNanoseconds(inNanoseconds),
12716  m_units(units) {
12717  if (m_units == Unit::Auto) {
12718  if (m_inNanoseconds < s_nanosecondsInAMicrosecond)
12719  m_units = Unit::Nanoseconds;
12720  else if (m_inNanoseconds < s_nanosecondsInAMillisecond)
12721  m_units = Unit::Microseconds;
12722  else if (m_inNanoseconds < s_nanosecondsInASecond)
12723  m_units = Unit::Milliseconds;
12724  else if (m_inNanoseconds < s_nanosecondsInAMinute)
12725  m_units = Unit::Seconds;
12726  else
12727  m_units = Unit::Minutes;
12728  }
12729 
12730  }
12731 
12732  auto value() const -> double {
12733  switch (m_units) {
12734  case Unit::Microseconds:
12735  return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond);
12736  case Unit::Milliseconds:
12737  return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond);
12738  case Unit::Seconds:
12739  return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond);
12740  case Unit::Minutes:
12741  return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute);
12742  default:
12743  return static_cast<double>(m_inNanoseconds);
12744  }
12745  }
12746  auto unitsAsString() const -> std::string {
12747  switch (m_units) {
12748  case Unit::Nanoseconds:
12749  return "ns";
12750  case Unit::Microseconds:
12751  return "µs";
12752  case Unit::Milliseconds:
12753  return "ms";
12754  case Unit::Seconds:
12755  return "s";
12756  case Unit::Minutes:
12757  return "m";
12758  default:
12759  return "** internal error **";
12760  }
12761 
12762  }
12763  friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& {
12764  return os << duration.value() << " " << duration.unitsAsString();
12765  }
12766 };
12767 } // end anon namespace
12768 
12769 class TablePrinter {
12770  std::ostream& m_os;
12771  std::vector<ColumnInfo> m_columnInfos;
12772  std::ostringstream m_oss;
12773  int m_currentColumn = -1;
12774  bool m_isOpen = false;
12775 
12776 public:
12777  TablePrinter( std::ostream& os, std::vector<ColumnInfo> columnInfos )
12778  : m_os( os ),
12779  m_columnInfos( std::move( columnInfos ) ) {}
12780 
12781  auto columnInfos() const -> std::vector<ColumnInfo> const& {
12782  return m_columnInfos;
12783  }
12784 
12785  void open() {
12786  if (!m_isOpen) {
12787  m_isOpen = true;
12788  *this << RowBreak();
12789  for (auto const& info : m_columnInfos)
12790  *this << info.name << ColumnBreak();
12791  *this << RowBreak();
12792  m_os << Catch::getLineOfChars<'-'>() << "\n";
12793  }
12794  }
12795  void close() {
12796  if (m_isOpen) {
12797  *this << RowBreak();
12798  m_os << std::endl;
12799  m_isOpen = false;
12800  }
12801  }
12802 
12803  template<typename T>
12804  friend TablePrinter& operator << (TablePrinter& tp, T const& value) {
12805  tp.m_oss << value;
12806  return tp;
12807  }
12808 
12809  friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) {
12810  auto colStr = tp.m_oss.str();
12811  // This takes account of utf8 encodings
12812  auto strSize = Catch::StringRef(colStr).numberOfCharacters();
12813  tp.m_oss.str("");
12814  tp.open();
12815  if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) {
12816  tp.m_currentColumn = -1;
12817  tp.m_os << "\n";
12818  }
12819  tp.m_currentColumn++;
12820 
12821  auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
12822  auto padding = (strSize + 2 < static_cast<std::size_t>(colInfo.width))
12823  ? std::string(colInfo.width - (strSize + 2), ' ')
12824  : std::string();
12825  if (colInfo.justification == ColumnInfo::Left)
12826  tp.m_os << colStr << padding << " ";
12827  else
12828  tp.m_os << padding << colStr << " ";
12829  return tp;
12830  }
12831 
12832  friend TablePrinter& operator << (TablePrinter& tp, RowBreak) {
12833  if (tp.m_currentColumn > 0) {
12834  tp.m_os << "\n";
12835  tp.m_currentColumn = -1;
12836  }
12837  return tp;
12838  }
12839 };
12840 
12841 ConsoleReporter::ConsoleReporter(ReporterConfig const& config)
12842  : StreamingReporterBase(config),
12843  m_tablePrinter(new TablePrinter(config.stream(),
12844  {
12845  { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 32, ColumnInfo::Left },
12846  { "iters", 8, ColumnInfo::Right },
12847  { "elapsed ns", 14, ColumnInfo::Right },
12848  { "average", 14, ColumnInfo::Right }
12849  })) {}
12850 ConsoleReporter::~ConsoleReporter() = default;
12851 
12852 std::string ConsoleReporter::getDescription() {
12853  return "Reports test results as plain lines of text";
12854 }
12855 
12856 void ConsoleReporter::noMatchingTestCases(std::string const& spec) {
12857  stream << "No test cases matched '" << spec << '\'' << std::endl;
12858 }
12859 
12860 void ConsoleReporter::assertionStarting(AssertionInfo const&) {}
12861 
12862 bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {
12863  AssertionResult const& result = _assertionStats.assertionResult;
12864 
12865  bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
12866 
12867  // Drop out if result was successful but we're not printing them.
12868  if (!includeResults && result.getResultType() != ResultWas::Warning)
12869  return false;
12870 
12871  lazyPrint();
12872 
12873  ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults);
12874  printer.print();
12875  stream << std::endl;
12876  return true;
12877 }
12878 
12879 void ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) {
12880  m_headerPrinted = false;
12881  StreamingReporterBase::sectionStarting(_sectionInfo);
12882 }
12883 void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) {
12884  m_tablePrinter->close();
12885  if (_sectionStats.missingAssertions) {
12886  lazyPrint();
12887  Colour colour(Colour::ResultError);
12888  if (m_sectionStack.size() > 1)
12889  stream << "\nNo assertions in section";
12890  else
12891  stream << "\nNo assertions in test case";
12892  stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
12893  }
12894  if (m_config->showDurations() == ShowDurations::Always) {
12895  stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
12896  }
12897  if (m_headerPrinted) {
12898  m_headerPrinted = false;
12899  }
12900  StreamingReporterBase::sectionEnded(_sectionStats);
12901 }
12902 
12903 void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {
12904  lazyPrintWithoutClosingBenchmarkTable();
12905 
12906  auto nameCol = Column( info.name ).width( static_cast<std::size_t>( m_tablePrinter->columnInfos()[0].width - 2 ) );
12907 
12908  bool firstLine = true;
12909  for (auto line : nameCol) {
12910  if (!firstLine)
12911  (*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();
12912  else
12913  firstLine = false;
12914 
12915  (*m_tablePrinter) << line << ColumnBreak();
12916  }
12917 }
12918 void ConsoleReporter::benchmarkEnded(BenchmarkStats const& stats) {
12919  Duration average(stats.elapsedTimeInNanoseconds / stats.iterations);
12920  (*m_tablePrinter)
12921  << stats.iterations << ColumnBreak()
12922  << stats.elapsedTimeInNanoseconds << ColumnBreak()
12923  << average << ColumnBreak();
12924 }
12925 
12926 void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {
12927  m_tablePrinter->close();
12928  StreamingReporterBase::testCaseEnded(_testCaseStats);
12929  m_headerPrinted = false;
12930 }
12931 void ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats) {
12932  if (currentGroupInfo.used) {
12933  printSummaryDivider();
12934  stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
12935  printTotals(_testGroupStats.totals);
12936  stream << '\n' << std::endl;
12937  }
12938  StreamingReporterBase::testGroupEnded(_testGroupStats);
12939 }
12940 void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
12941  printTotalsDivider(_testRunStats.totals);
12942  printTotals(_testRunStats.totals);
12943  stream << std::endl;
12944  StreamingReporterBase::testRunEnded(_testRunStats);
12945 }
12946 
12947 void ConsoleReporter::lazyPrint() {
12948 
12949  m_tablePrinter->close();
12950  lazyPrintWithoutClosingBenchmarkTable();
12951 }
12952 
12953 void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() {
12954 
12955  if (!currentTestRunInfo.used)
12956  lazyPrintRunInfo();
12957  if (!currentGroupInfo.used)
12958  lazyPrintGroupInfo();
12959 
12960  if (!m_headerPrinted) {
12961  printTestCaseAndSectionHeader();
12962  m_headerPrinted = true;
12963  }
12964 }
12965 void ConsoleReporter::lazyPrintRunInfo() {
12966  stream << '\n' << getLineOfChars<'~'>() << '\n';
12967  Colour colour(Colour::SecondaryText);
12968  stream << currentTestRunInfo->name
12969  << " is a Catch v" << libraryVersion() << " host application.\n"
12970  << "Run with -? for options\n\n";
12971 
12972  if (m_config->rngSeed() != 0)
12973  stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
12974 
12975  currentTestRunInfo.used = true;
12976 }
12977 void ConsoleReporter::lazyPrintGroupInfo() {
12978  if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) {
12979  printClosedHeader("Group: " + currentGroupInfo->name);
12980  currentGroupInfo.used = true;
12981  }
12982 }
12983 void ConsoleReporter::printTestCaseAndSectionHeader() {
12984  assert(!m_sectionStack.empty());
12985  printOpenHeader(currentTestCaseInfo->name);
12986 
12987  if (m_sectionStack.size() > 1) {
12988  Colour colourGuard(Colour::Headers);
12989 
12990  auto
12991  it = m_sectionStack.begin() + 1, // Skip first section (test case)
12992  itEnd = m_sectionStack.end();
12993  for (; it != itEnd; ++it)
12994  printHeaderString(it->name, 2);
12995  }
12996 
12997  SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
12998 
12999  if (!lineInfo.empty()) {
13000  stream << getLineOfChars<'-'>() << '\n';
13001  Colour colourGuard(Colour::FileName);
13002  stream << lineInfo << '\n';
13003  }
13004  stream << getLineOfChars<'.'>() << '\n' << std::endl;
13005 }
13006 
13007 void ConsoleReporter::printClosedHeader(std::string const& _name) {
13008  printOpenHeader(_name);
13009  stream << getLineOfChars<'.'>() << '\n';
13010 }
13011 void ConsoleReporter::printOpenHeader(std::string const& _name) {
13012  stream << getLineOfChars<'-'>() << '\n';
13013  {
13014  Colour colourGuard(Colour::Headers);
13015  printHeaderString(_name);
13016  }
13017 }
13018 
13019 // if string has a : in first line will set indent to follow it on
13020 // subsequent lines
13021 void ConsoleReporter::printHeaderString(std::string const& _string, std::size_t indent) {
13022  std::size_t i = _string.find(": ");
13023  if (i != std::string::npos)
13024  i += 2;
13025  else
13026  i = 0;
13027  stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n';
13028 }
13029 
13030 struct SummaryColumn {
13031 
13032  SummaryColumn( std::string _label, Colour::Code _colour )
13033  : label( std::move( _label ) ),
13034  colour( _colour ) {}
13035  SummaryColumn addRow( std::size_t count ) {
13037  rss << count;
13038  std::string row = rss.str();
13039  for (auto& oldRow : rows) {
13040  while (oldRow.size() < row.size())
13041  oldRow = ' ' + oldRow;
13042  while (oldRow.size() > row.size())
13043  row = ' ' + row;
13044  }
13045  rows.push_back(row);
13046  return *this;
13047  }
13048 
13049  std::string label;
13050  Colour::Code colour;
13051  std::vector<std::string> rows;
13052 
13053 };
13054 
13055 void ConsoleReporter::printTotals( Totals const& totals ) {
13056  if (totals.testCases.total() == 0) {
13057  stream << Colour(Colour::Warning) << "No tests ran\n";
13058  } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) {
13059  stream << Colour(Colour::ResultSuccess) << "All tests passed";
13060  stream << " ("
13061  << pluralise(totals.assertions.passed, "assertion") << " in "
13062  << pluralise(totals.testCases.passed, "test case") << ')'
13063  << '\n';
13064  } else {
13065 
13066  std::vector<SummaryColumn> columns;
13067  columns.push_back(SummaryColumn("", Colour::None)
13068  .addRow(totals.testCases.total())
13069  .addRow(totals.assertions.total()));
13070  columns.push_back(SummaryColumn("passed", Colour::Success)
13071  .addRow(totals.testCases.passed)
13072  .addRow(totals.assertions.passed));
13073  columns.push_back(SummaryColumn("failed", Colour::ResultError)
13074  .addRow(totals.testCases.failed)
13075  .addRow(totals.assertions.failed));
13076  columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure)
13077  .addRow(totals.testCases.failedButOk)
13078  .addRow(totals.assertions.failedButOk));
13079 
13080  printSummaryRow("test cases", columns, 0);
13081  printSummaryRow("assertions", columns, 1);
13082  }
13083 }
13084 void ConsoleReporter::printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row) {
13085  for (auto col : cols) {
13086  std::string value = col.rows[row];
13087  if (col.label.empty()) {
13088  stream << label << ": ";
13089  if (value != "0")
13090  stream << value;
13091  else
13092  stream << Colour(Colour::Warning) << "- none -";
13093  } else if (value != "0") {
13094  stream << Colour(Colour::LightGrey) << " | ";
13095  stream << Colour(col.colour)
13096  << value << ' ' << col.label;
13097  }
13098  }
13099  stream << '\n';
13100 }
13101 
13102 void ConsoleReporter::printTotalsDivider(Totals const& totals) {
13103  if (totals.testCases.total() > 0) {
13104  std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());
13105  std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());
13106  std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());
13107  while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
13108  findMax(failedRatio, failedButOkRatio, passedRatio)++;
13109  while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)
13110  findMax(failedRatio, failedButOkRatio, passedRatio)--;
13111 
13112  stream << Colour(Colour::Error) << std::string(failedRatio, '=');
13113  stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '=');
13114  if (totals.testCases.allPassed())
13115  stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '=');
13116  else
13117  stream << Colour(Colour::Success) << std::string(passedRatio, '=');
13118  } else {
13119  stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '=');
13120  }
13121  stream << '\n';
13122 }
13123 void ConsoleReporter::printSummaryDivider() {
13124  stream << getLineOfChars<'-'>() << '\n';
13125 }
13126 
13127 CATCH_REGISTER_REPORTER("console", ConsoleReporter)
13128 
13129 } // end namespace Catch
13130 
13131 #if defined(_MSC_VER)
13132 #pragma warning(pop)
13133 #endif
13134 // end catch_reporter_console.cpp
13135 // start catch_reporter_junit.cpp
13136 
13137 #include <cassert>
13138 #include <sstream>
13139 #include <ctime>
13140 #include <algorithm>
13141 
13142 namespace Catch {
13143 
13144  namespace {
13145  std::string getCurrentTimestamp() {
13146  // Beware, this is not reentrant because of backward compatibility issues
13147  // Also, UTC only, again because of backward compatibility (%z is C++11)
13148  time_t rawtime;
13149  std::time(&rawtime);
13150  auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
13151 
13152 #ifdef _MSC_VER
13153  std::tm timeInfo = {};
13154  gmtime_s(&timeInfo, &rawtime);
13155 #else
13156  std::tm* timeInfo;
13157  timeInfo = std::gmtime(&rawtime);
13158 #endif
13159 
13160  char timeStamp[timeStampSize];
13161  const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
13162 
13163 #ifdef _MSC_VER
13164  std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
13165 #else
13166  std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
13167 #endif
13168  return std::string(timeStamp);
13169  }
13170 
13171  std::string fileNameTag(const std::vector<std::string> &tags) {
13172  auto it = std::find_if(begin(tags),
13173  end(tags),
13174  [] (std::string const& tag) {return tag.front() == '#'; });
13175  if (it != tags.end())
13176  return it->substr(1);
13177  return std::string();
13178  }
13179  } // anonymous namespace
13180 
13181  JunitReporter::JunitReporter( ReporterConfig const& _config )
13182  : CumulativeReporterBase( _config ),
13183  xml( _config.stream() )
13184  {
13185  m_reporterPrefs.shouldRedirectStdOut = true;
13186  m_reporterPrefs.shouldReportAllAssertions = true;
13187  }
13188 
13189  JunitReporter::~JunitReporter() {}
13190 
13191  std::string JunitReporter::getDescription() {
13192  return "Reports test results in an XML format that looks like Ant's junitreport target";
13193  }
13194 
13195  void JunitReporter::noMatchingTestCases( std::string const& /*spec*/ ) {}
13196 
13197  void JunitReporter::testRunStarting( TestRunInfo const& runInfo ) {
13198  CumulativeReporterBase::testRunStarting( runInfo );
13199  xml.startElement( "testsuites" );
13200  }
13201 
13202  void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) {
13203  suiteTimer.start();
13204  stdOutForSuite.clear();
13205  stdErrForSuite.clear();
13206  unexpectedExceptions = 0;
13207  CumulativeReporterBase::testGroupStarting( groupInfo );
13208  }
13209 
13210  void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) {
13211  m_okToFail = testCaseInfo.okToFail();
13212  }
13213 
13214  bool JunitReporter::assertionEnded( AssertionStats const& assertionStats ) {
13215  if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
13216  unexpectedExceptions++;
13217  return CumulativeReporterBase::assertionEnded( assertionStats );
13218  }
13219 
13220  void JunitReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
13221  stdOutForSuite += testCaseStats.stdOut;
13222  stdErrForSuite += testCaseStats.stdErr;
13223  CumulativeReporterBase::testCaseEnded( testCaseStats );
13224  }
13225 
13226  void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
13227  double suiteTime = suiteTimer.getElapsedSeconds();
13228  CumulativeReporterBase::testGroupEnded( testGroupStats );
13229  writeGroup( *m_testGroups.back(), suiteTime );
13230  }
13231 
13232  void JunitReporter::testRunEndedCumulative() {
13233  xml.endElement();
13234  }
13235 
13236  void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
13237  XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
13238  TestGroupStats const& stats = groupNode.value;
13239  xml.writeAttribute( "name", stats.groupInfo.name );
13240  xml.writeAttribute( "errors", unexpectedExceptions );
13241  xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
13242  xml.writeAttribute( "tests", stats.totals.assertions.total() );
13243  xml.writeAttribute( "hostname", "tbd" ); // !TBD
13244  if( m_config->showDurations() == ShowDurations::Never )
13245  xml.writeAttribute( "time", "" );
13246  else
13247  xml.writeAttribute( "time", suiteTime );
13248  xml.writeAttribute( "timestamp", getCurrentTimestamp() );
13249 
13250  // Write test cases
13251  for( auto const& child : groupNode.children )
13252  writeTestCase( *child );
13253 
13254  xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), false );
13255  xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), false );
13256  }
13257 
13258  void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) {
13259  TestCaseStats const& stats = testCaseNode.value;
13260 
13261  // All test cases have exactly one section - which represents the
13262  // test case itself. That section may have 0-n nested sections
13263  assert( testCaseNode.children.size() == 1 );
13264  SectionNode const& rootSection = *testCaseNode.children.front();
13265 
13266  std::string className = stats.testInfo.className;
13267 
13268  if( className.empty() ) {
13269  className = fileNameTag(stats.testInfo.tags);
13270  if ( className.empty() )
13271  className = "global";
13272  }
13273 
13274  if ( !m_config->name().empty() )
13275  className = m_config->name() + "." + className;
13276 
13277  writeSection( className, "", rootSection );
13278  }
13279 
13280  void JunitReporter::writeSection( std::string const& className,
13281  std::string const& rootName,
13282  SectionNode const& sectionNode ) {
13283  std::string name = trim( sectionNode.stats.sectionInfo.name );
13284  if( !rootName.empty() )
13285  name = rootName + '/' + name;
13286 
13287  if( !sectionNode.assertions.empty() ||
13288  !sectionNode.stdOut.empty() ||
13289  !sectionNode.stdErr.empty() ) {
13290  XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
13291  if( className.empty() ) {
13292  xml.writeAttribute( "classname", name );
13293  xml.writeAttribute( "name", "root" );
13294  }
13295  else {
13296  xml.writeAttribute( "classname", className );
13297  xml.writeAttribute( "name", name );
13298  }
13299  xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) );
13300 
13301  writeAssertions( sectionNode );
13302 
13303  if( !sectionNode.stdOut.empty() )
13304  xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
13305  if( !sectionNode.stdErr.empty() )
13306  xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
13307  }
13308  for( auto const& childNode : sectionNode.childSections )
13309  if( className.empty() )
13310  writeSection( name, "", *childNode );
13311  else
13312  writeSection( className, name, *childNode );
13313  }
13314 
13315  void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {
13316  for( auto const& assertion : sectionNode.assertions )
13317  writeAssertion( assertion );
13318  }
13319 
13320  void JunitReporter::writeAssertion( AssertionStats const& stats ) {
13321  AssertionResult const& result = stats.assertionResult;
13322  if( !result.isOk() ) {
13323  std::string elementName;
13324  switch( result.getResultType() ) {
13327  elementName = "error";
13328  break;
13330  elementName = "failure";
13331  break;
13333  elementName = "failure";
13334  break;
13336  elementName = "failure";
13337  break;
13338 
13339  // We should never see these here:
13340  case ResultWas::Info:
13341  case ResultWas::Warning:
13342  case ResultWas::Ok:
13343  case ResultWas::Unknown:
13344  case ResultWas::FailureBit:
13345  case ResultWas::Exception:
13346  elementName = "internalError";
13347  break;
13348  }
13349 
13350  XmlWriter::ScopedElement e = xml.scopedElement( elementName );
13351 
13352  xml.writeAttribute( "message", result.getExpandedExpression() );
13353  xml.writeAttribute( "type", result.getTestMacroName() );
13354 
13356  if( !result.getMessage().empty() )
13357  rss << result.getMessage() << '\n';
13358  for( auto const& msg : stats.infoMessages )
13359  if( msg.type == ResultWas::Info )
13360  rss << msg.message << '\n';
13361 
13362  rss << "at " << result.getSourceInfo();
13363  xml.writeText( rss.str(), false );
13364  }
13365  }
13366 
13367  CATCH_REGISTER_REPORTER( "junit", JunitReporter )
13368 
13369 } // end namespace Catch
13370 // end catch_reporter_junit.cpp
13371 // start catch_reporter_listening.cpp
13372 
13373 #include <cassert>
13374 
13375 namespace Catch {
13376 
13377  ListeningReporter::ListeningReporter() {
13378  // We will assume that listeners will always want all assertions
13379  m_preferences.shouldReportAllAssertions = true;
13380  }
13381 
13382  void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) {
13383  m_listeners.push_back( std::move( listener ) );
13384  }
13385 
13386  void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {
13387  assert(!m_reporter && "Listening reporter can wrap only 1 real reporter");
13388  m_reporter = std::move( reporter );
13389  m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;
13390  }
13391 
13392  ReporterPreferences ListeningReporter::getPreferences() const {
13393  return m_preferences;
13394  }
13395 
13396  std::set<Verbosity> ListeningReporter::getSupportedVerbosities() {
13397  return std::set<Verbosity>{ };
13398  }
13399 
13400  void ListeningReporter::noMatchingTestCases( std::string const& spec ) {
13401  for ( auto const& listener : m_listeners ) {
13402  listener->noMatchingTestCases( spec );
13403  }
13404  m_reporter->noMatchingTestCases( spec );
13405  }
13406 
13407  void ListeningReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {
13408  for ( auto const& listener : m_listeners ) {
13409  listener->benchmarkStarting( benchmarkInfo );
13410  }
13411  m_reporter->benchmarkStarting( benchmarkInfo );
13412  }
13413  void ListeningReporter::benchmarkEnded( BenchmarkStats const& benchmarkStats ) {
13414  for ( auto const& listener : m_listeners ) {
13415  listener->benchmarkEnded( benchmarkStats );
13416  }
13417  m_reporter->benchmarkEnded( benchmarkStats );
13418  }
13419 
13420  void ListeningReporter::testRunStarting( TestRunInfo const& testRunInfo ) {
13421  for ( auto const& listener : m_listeners ) {
13422  listener->testRunStarting( testRunInfo );
13423  }
13424  m_reporter->testRunStarting( testRunInfo );
13425  }
13426 
13427  void ListeningReporter::testGroupStarting( GroupInfo const& groupInfo ) {
13428  for ( auto const& listener : m_listeners ) {
13429  listener->testGroupStarting( groupInfo );
13430  }
13431  m_reporter->testGroupStarting( groupInfo );
13432  }
13433 
13434  void ListeningReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
13435  for ( auto const& listener : m_listeners ) {
13436  listener->testCaseStarting( testInfo );
13437  }
13438  m_reporter->testCaseStarting( testInfo );
13439  }
13440 
13441  void ListeningReporter::sectionStarting( SectionInfo const& sectionInfo ) {
13442  for ( auto const& listener : m_listeners ) {
13443  listener->sectionStarting( sectionInfo );
13444  }
13445  m_reporter->sectionStarting( sectionInfo );
13446  }
13447 
13448  void ListeningReporter::assertionStarting( AssertionInfo const& assertionInfo ) {
13449  for ( auto const& listener : m_listeners ) {
13450  listener->assertionStarting( assertionInfo );
13451  }
13452  m_reporter->assertionStarting( assertionInfo );
13453  }
13454 
13455  // The return value indicates if the messages buffer should be cleared:
13456  bool ListeningReporter::assertionEnded( AssertionStats const& assertionStats ) {
13457  for( auto const& listener : m_listeners ) {
13458  static_cast<void>( listener->assertionEnded( assertionStats ) );
13459  }
13460  return m_reporter->assertionEnded( assertionStats );
13461  }
13462 
13463  void ListeningReporter::sectionEnded( SectionStats const& sectionStats ) {
13464  for ( auto const& listener : m_listeners ) {
13465  listener->sectionEnded( sectionStats );
13466  }
13467  m_reporter->sectionEnded( sectionStats );
13468  }
13469 
13470  void ListeningReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
13471  for ( auto const& listener : m_listeners ) {
13472  listener->testCaseEnded( testCaseStats );
13473  }
13474  m_reporter->testCaseEnded( testCaseStats );
13475  }
13476 
13477  void ListeningReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
13478  for ( auto const& listener : m_listeners ) {
13479  listener->testGroupEnded( testGroupStats );
13480  }
13481  m_reporter->testGroupEnded( testGroupStats );
13482  }
13483 
13484  void ListeningReporter::testRunEnded( TestRunStats const& testRunStats ) {
13485  for ( auto const& listener : m_listeners ) {
13486  listener->testRunEnded( testRunStats );
13487  }
13488  m_reporter->testRunEnded( testRunStats );
13489  }
13490 
13491  void ListeningReporter::skipTest( TestCaseInfo const& testInfo ) {
13492  for ( auto const& listener : m_listeners ) {
13493  listener->skipTest( testInfo );
13494  }
13495  m_reporter->skipTest( testInfo );
13496  }
13497 
13498  bool ListeningReporter::isMulti() const {
13499  return true;
13500  }
13501 
13502 } // end namespace Catch
13503 // end catch_reporter_listening.cpp
13504 // start catch_reporter_xml.cpp
13505 
13506 #if defined(_MSC_VER)
13507 #pragma warning(push)
13508 #pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
13509  // Note that 4062 (not all labels are handled
13510  // and default is missing) is enabled
13511 #endif
13512 
13513 namespace Catch {
13514  XmlReporter::XmlReporter( ReporterConfig const& _config )
13515  : StreamingReporterBase( _config ),
13516  m_xml(_config.stream())
13517  {
13518  m_reporterPrefs.shouldRedirectStdOut = true;
13519  m_reporterPrefs.shouldReportAllAssertions = true;
13520  }
13521 
13522  XmlReporter::~XmlReporter() = default;
13523 
13524  std::string XmlReporter::getDescription() {
13525  return "Reports test results as an XML document";
13526  }
13527 
13528  std::string XmlReporter::getStylesheetRef() const {
13529  return std::string();
13530  }
13531 
13532  void XmlReporter::writeSourceInfo( SourceLineInfo const& sourceInfo ) {
13533  m_xml
13534  .writeAttribute( "filename", sourceInfo.file )
13535  .writeAttribute( "line", sourceInfo.line );
13536  }
13537 
13538  void XmlReporter::noMatchingTestCases( std::string const& s ) {
13539  StreamingReporterBase::noMatchingTestCases( s );
13540  }
13541 
13542  void XmlReporter::testRunStarting( TestRunInfo const& testInfo ) {
13543  StreamingReporterBase::testRunStarting( testInfo );
13544  std::string stylesheetRef = getStylesheetRef();
13545  if( !stylesheetRef.empty() )
13546  m_xml.writeStylesheetRef( stylesheetRef );
13547  m_xml.startElement( "Catch" );
13548  if( !m_config->name().empty() )
13549  m_xml.writeAttribute( "name", m_config->name() );
13550  if( m_config->rngSeed() != 0 )
13551  m_xml.scopedElement( "Randomness" )
13552  .writeAttribute( "seed", m_config->rngSeed() );
13553  }
13554 
13555  void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) {
13556  StreamingReporterBase::testGroupStarting( groupInfo );
13557  m_xml.startElement( "Group" )
13558  .writeAttribute( "name", groupInfo.name );
13559  }
13560 
13561  void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
13562  StreamingReporterBase::testCaseStarting(testInfo);
13563  m_xml.startElement( "TestCase" )
13564  .writeAttribute( "name", trim( testInfo.name ) )
13565  .writeAttribute( "description", testInfo.description )
13566  .writeAttribute( "tags", testInfo.tagsAsString() );
13567 
13568  writeSourceInfo( testInfo.lineInfo );
13569 
13570  if ( m_config->showDurations() == ShowDurations::Always )
13571  m_testCaseTimer.start();
13572  m_xml.ensureTagClosed();
13573  }
13574 
13575  void XmlReporter::sectionStarting( SectionInfo const& sectionInfo ) {
13576  StreamingReporterBase::sectionStarting( sectionInfo );
13577  if( m_sectionDepth++ > 0 ) {
13578  m_xml.startElement( "Section" )
13579  .writeAttribute( "name", trim( sectionInfo.name ) );
13580  writeSourceInfo( sectionInfo.lineInfo );
13581  m_xml.ensureTagClosed();
13582  }
13583  }
13584 
13585  void XmlReporter::assertionStarting( AssertionInfo const& ) { }
13586 
13587  bool XmlReporter::assertionEnded( AssertionStats const& assertionStats ) {
13588 
13589  AssertionResult const& result = assertionStats.assertionResult;
13590 
13591  bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
13592 
13593  if( includeResults || result.getResultType() == ResultWas::Warning ) {
13594  // Print any info messages in <Info> tags.
13595  for( auto const& msg : assertionStats.infoMessages ) {
13596  if( msg.type == ResultWas::Info && includeResults ) {
13597  m_xml.scopedElement( "Info" )
13598  .writeText( msg.message );
13599  } else if ( msg.type == ResultWas::Warning ) {
13600  m_xml.scopedElement( "Warning" )
13601  .writeText( msg.message );
13602  }
13603  }
13604  }
13605 
13606  // Drop out if result was successful but we're not printing them.
13607  if( !includeResults && result.getResultType() != ResultWas::Warning )
13608  return true;
13609 
13610  // Print the expression if there is one.
13611  if( result.hasExpression() ) {
13612  m_xml.startElement( "Expression" )
13613  .writeAttribute( "success", result.succeeded() )
13614  .writeAttribute( "type", result.getTestMacroName() );
13615 
13616  writeSourceInfo( result.getSourceInfo() );
13617 
13618  m_xml.scopedElement( "Original" )
13619  .writeText( result.getExpression() );
13620  m_xml.scopedElement( "Expanded" )
13621  .writeText( result.getExpandedExpression() );
13622  }
13623 
13624  // And... Print a result applicable to each result type.
13625  switch( result.getResultType() ) {
13627  m_xml.startElement( "Exception" );
13628  writeSourceInfo( result.getSourceInfo() );
13629  m_xml.writeText( result.getMessage() );
13630  m_xml.endElement();
13631  break;
13633  m_xml.startElement( "FatalErrorCondition" );
13634  writeSourceInfo( result.getSourceInfo() );
13635  m_xml.writeText( result.getMessage() );
13636  m_xml.endElement();
13637  break;
13638  case ResultWas::Info:
13639  m_xml.scopedElement( "Info" )
13640  .writeText( result.getMessage() );
13641  break;
13642  case ResultWas::Warning:
13643  // Warning will already have been written
13644  break;
13646  m_xml.startElement( "Failure" );
13647  writeSourceInfo( result.getSourceInfo() );
13648  m_xml.writeText( result.getMessage() );
13649  m_xml.endElement();
13650  break;
13651  default:
13652  break;
13653  }
13654 
13655  if( result.hasExpression() )
13656  m_xml.endElement();
13657 
13658  return true;
13659  }
13660 
13661  void XmlReporter::sectionEnded( SectionStats const& sectionStats ) {
13662  StreamingReporterBase::sectionEnded( sectionStats );
13663  if( --m_sectionDepth > 0 ) {
13664  XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
13665  e.writeAttribute( "successes", sectionStats.assertions.passed );
13666  e.writeAttribute( "failures", sectionStats.assertions.failed );
13667  e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
13668 
13669  if ( m_config->showDurations() == ShowDurations::Always )
13670  e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
13671 
13672  m_xml.endElement();
13673  }
13674  }
13675 
13676  void XmlReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
13677  StreamingReporterBase::testCaseEnded( testCaseStats );
13678  XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
13679  e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
13680 
13681  if ( m_config->showDurations() == ShowDurations::Always )
13682  e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
13683 
13684  if( !testCaseStats.stdOut.empty() )
13685  m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false );
13686  if( !testCaseStats.stdErr.empty() )
13687  m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false );
13688 
13689  m_xml.endElement();
13690  }
13691 
13692  void XmlReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
13693  StreamingReporterBase::testGroupEnded( testGroupStats );
13694  // TODO: Check testGroupStats.aborting and act accordingly.
13695  m_xml.scopedElement( "OverallResults" )
13696  .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
13697  .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
13698  .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
13699  m_xml.endElement();
13700  }
13701 
13702  void XmlReporter::testRunEnded( TestRunStats const& testRunStats ) {
13703  StreamingReporterBase::testRunEnded( testRunStats );
13704  m_xml.scopedElement( "OverallResults" )
13705  .writeAttribute( "successes", testRunStats.totals.assertions.passed )
13706  .writeAttribute( "failures", testRunStats.totals.assertions.failed )
13707  .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
13708  m_xml.endElement();
13709  }
13710 
13711  CATCH_REGISTER_REPORTER( "xml", XmlReporter )
13712 
13713 } // end namespace Catch
13714 
13715 #if defined(_MSC_VER)
13716 #pragma warning(pop)
13717 #endif
13718 // end catch_reporter_xml.cpp
13719 
13720 namespace Catch {
13721  LeakDetector leakDetector;
13722 }
13723 
13724 #ifdef __clang__
13725 #pragma clang diagnostic pop
13726 #endif
13727 
13728 // end catch_impl.hpp
13729 #endif
13730 
13731 #ifdef CATCH_CONFIG_MAIN
13732 // start catch_default_main.hpp
13733 
13734 #ifndef __OBJC__
13735 
13736 #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
13737 // Standard C/C++ Win32 Unicode wmain entry point
13738 extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
13739 #else
13740 // Standard C/C++ main entry point
13741 int main (int argc, char * argv[]) {
13742 #endif
13743 
13744  return Catch::Session().run( argc, argv );
13745 }
13746 
13747 #else // __OBJC__
13748 
13749 // Objective-C entry point
13750 int main (int argc, char * const argv[]) {
13751 #if !CATCH_ARC_ENABLED
13752  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
13753 #endif
13754 
13755  Catch::registerTestMethods();
13756  int result = Catch::Session().run( argc, (char**)argv );
13757 
13758 #if !CATCH_ARC_ENABLED
13759  [pool drain];
13760 #endif
13761 
13762  return result;
13763 }
13764 
13765 #endif // __OBJC__
13766 
13767 // end catch_default_main.hpp
13768 #endif
13769 
13770 #if !defined(CATCH_CONFIG_IMPL_ONLY)
13771 
13772 #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
13773 # undef CLARA_CONFIG_MAIN
13774 #endif
13775 
13776 #if !defined(CATCH_CONFIG_DISABLE)
13777 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
13779 #ifdef CATCH_CONFIG_PREFIX_ALL
13780 
13781 #define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
13782 #define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
13783 
13784 #define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", __VA_ARGS__ )
13785 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
13786 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
13787 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
13788 #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
13789 #endif// CATCH_CONFIG_DISABLE_MATCHERS
13790 #define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
13791 
13792 #define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13793 #define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
13794 #define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13795 #define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13796 #define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
13797 
13798 #define CATCH_CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", __VA_ARGS__ )
13799 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
13800 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
13801 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
13802 #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
13803 #endif // CATCH_CONFIG_DISABLE_MATCHERS
13804 #define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13805 
13806 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
13807 #define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
13808 
13809 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
13810 #endif // CATCH_CONFIG_DISABLE_MATCHERS
13811 
13812 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
13813 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
13814 #define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE",__VA_ARGS__ )
13815 
13816 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
13817 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
13818 #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
13819 #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
13820 #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
13821 #define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
13822 #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
13823 #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13824 #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13825 
13826 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
13827 
13828 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
13829 #define CATCH_STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__ , #__VA_ARGS__ ); CATCH_SUCCEED( #__VA_ARGS__ )
13830 #define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ )
13831 #else
13832 #define CATCH_STATIC_REQUIRE( ... ) CATCH_REQUIRE( __VA_ARGS__ )
13833 #define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ )
13834 #endif
13835 
13836 // "BDD-style" convenience wrappers
13837 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
13838 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
13839 #define CATCH_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
13840 #define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
13841 #define CATCH_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
13842 #define CATCH_AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
13843 #define CATCH_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
13844 #define CATCH_AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )
13845 
13846 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
13847 #else
13848 
13849 #define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
13850 #define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
13851 
13852 #define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
13853 #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
13854 #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
13855 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
13856 #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
13857 #endif // CATCH_CONFIG_DISABLE_MATCHERS
13858 #define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )
13859 
13860 #define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13861 #define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
13862 #define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13863 #define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13864 #define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )
13865 
13866 #define CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13867 #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
13868 #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
13869 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
13870 #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
13871 #endif // CATCH_CONFIG_DISABLE_MATCHERS
13872 #define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13873 
13874 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
13875 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
13876 
13877 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
13878 #endif // CATCH_CONFIG_DISABLE_MATCHERS
13879 
13880 #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
13881 #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
13882 #define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ )
13883 
13884 #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
13885 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
13886 #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
13887 #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
13888 #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
13889 #define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
13890 #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
13891 #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13892 #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
13893 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
13894 
13895 #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
13896 #define STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__, #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ )
13897 #define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" )
13898 #else
13899 #define STATIC_REQUIRE( ... ) REQUIRE( __VA_ARGS__ )
13900 #define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ )
13901 #endif
13902 
13903 #endif
13904 
13905 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
13906 
13907 // "BDD-style" convenience wrappers
13908 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
13909 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
13910 
13911 #define GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Given: " << desc )
13912 #define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
13913 #define WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " When: " << desc )
13914 #define AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
13915 #define THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " Then: " << desc )
13916 #define AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( " And: " << desc )
13917 
13918 using Catch::Detail::Approx;
13919 
13920 #else // CATCH_CONFIG_DISABLE
13921 
13923 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
13924 #ifdef CATCH_CONFIG_PREFIX_ALL
13925 
13926 #define CATCH_REQUIRE( ... ) (void)(0)
13927 #define CATCH_REQUIRE_FALSE( ... ) (void)(0)
13928 
13929 #define CATCH_REQUIRE_THROWS( ... ) (void)(0)
13930 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
13931 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
13932 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
13933 #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
13934 #endif// CATCH_CONFIG_DISABLE_MATCHERS
13935 #define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)
13936 
13937 #define CATCH_CHECK( ... ) (void)(0)
13938 #define CATCH_CHECK_FALSE( ... ) (void)(0)
13939 #define CATCH_CHECKED_IF( ... ) if (__VA_ARGS__)
13940 #define CATCH_CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
13941 #define CATCH_CHECK_NOFAIL( ... ) (void)(0)
13942 
13943 #define CATCH_CHECK_THROWS( ... ) (void)(0)
13944 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
13945 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) (void)(0)
13946 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
13947 #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
13948 #endif // CATCH_CONFIG_DISABLE_MATCHERS
13949 #define CATCH_CHECK_NOTHROW( ... ) (void)(0)
13950 
13951 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
13952 #define CATCH_CHECK_THAT( arg, matcher ) (void)(0)
13953 
13954 #define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
13955 #endif // CATCH_CONFIG_DISABLE_MATCHERS
13956 
13957 #define CATCH_INFO( msg ) (void)(0)
13958 #define CATCH_WARN( msg ) (void)(0)
13959 #define CATCH_CAPTURE( msg ) (void)(0)
13960 
13961 #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
13962 #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
13963 #define CATCH_METHOD_AS_TEST_CASE( method, ... )
13964 #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
13965 #define CATCH_SECTION( ... )
13966 #define CATCH_DYNAMIC_SECTION( ... )
13967 #define CATCH_FAIL( ... ) (void)(0)
13968 #define CATCH_FAIL_CHECK( ... ) (void)(0)
13969 #define CATCH_SUCCEED( ... ) (void)(0)
13970 
13971 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
13972 
13973 // "BDD-style" convenience wrappers
13974 #define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
13975 #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 )
13976 #define CATCH_GIVEN( desc )
13977 #define CATCH_AND_GIVEN( desc )
13978 #define CATCH_WHEN( desc )
13979 #define CATCH_AND_WHEN( desc )
13980 #define CATCH_THEN( desc )
13981 #define CATCH_AND_THEN( desc )
13982 
13983 #define CATCH_STATIC_REQUIRE( ... ) (void)(0)
13984 #define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0)
13985 
13986 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
13987 #else
13988 
13989 #define REQUIRE( ... ) (void)(0)
13990 #define REQUIRE_FALSE( ... ) (void)(0)
13991 
13992 #define REQUIRE_THROWS( ... ) (void)(0)
13993 #define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
13994 #define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
13995 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
13996 #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
13997 #endif // CATCH_CONFIG_DISABLE_MATCHERS
13998 #define REQUIRE_NOTHROW( ... ) (void)(0)
13999 
14000 #define CHECK( ... ) (void)(0)
14001 #define CHECK_FALSE( ... ) (void)(0)
14002 #define CHECKED_IF( ... ) if (__VA_ARGS__)
14003 #define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
14004 #define CHECK_NOFAIL( ... ) (void)(0)
14005 
14006 #define CHECK_THROWS( ... ) (void)(0)
14007 #define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
14008 #define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
14009 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14010 #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
14011 #endif // CATCH_CONFIG_DISABLE_MATCHERS
14012 #define CHECK_NOTHROW( ... ) (void)(0)
14013 
14014 #if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
14015 #define CHECK_THAT( arg, matcher ) (void)(0)
14016 
14017 #define REQUIRE_THAT( arg, matcher ) (void)(0)
14018 #endif // CATCH_CONFIG_DISABLE_MATCHERS
14019 
14020 #define INFO( msg ) (void)(0)
14021 #define WARN( msg ) (void)(0)
14022 #define CAPTURE( msg ) (void)(0)
14023 
14024 #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
14025 #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
14026 #define METHOD_AS_TEST_CASE( method, ... )
14027 #define REGISTER_TEST_CASE( Function, ... ) (void)(0)
14028 #define SECTION( ... )
14029 #define DYNAMIC_SECTION( ... )
14030 #define FAIL( ... ) (void)(0)
14031 #define FAIL_CHECK( ... ) (void)(0)
14032 #define SUCCEED( ... ) (void)(0)
14033 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
14034 
14035 #define STATIC_REQUIRE( ... ) (void)(0)
14036 #define STATIC_REQUIRE_FALSE( ... ) (void)(0)
14037 
14038 #endif
14039 
14040 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
14041 
14042 // "BDD-style" convenience wrappers
14043 #define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) )
14044 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
14045 
14046 #define GIVEN( desc )
14047 #define AND_GIVEN( desc )
14048 #define WHEN( desc )
14049 #define AND_WHEN( desc )
14050 #define THEN( desc )
14051 #define AND_THEN( desc )
14052 
14053 using Catch::Detail::Approx;
14054 
14055 #endif
14056 
14057 #endif // ! CATCH_CONFIG_IMPL_ONLY
14058 
14059 // start catch_reenable_warnings.h
14060 
14061 
14062 #ifdef __clang__
14063 # ifdef __ICC // icpc defines the __clang__ macro
14064 # pragma warning(pop)
14065 # else
14066 # pragma clang diagnostic pop
14067 # endif
14068 #elif defined __GNUC__
14069 # pragma GCC diagnostic pop
14070 #endif
14071 
14072 // end catch_reenable_warnings.h
14073 // end catch.hpp
14074 #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
14075 
EqualsMatcher(std::vector< T > const &comparator)
Definition: catch.hpp:2821
static std::string convert(T const (&arr)[SZ])
Definition: catch.hpp:1324
d
bool okToFail() const
virtual void setGenerator(Generators::GeneratorBasePtr &&generator)=0
Error
void handleExpression(ITransientExpression const &expr)
bool matchTest(TestCase const &testCase, TestSpec const &testSpec, IConfig const &config)
virtual void benchmarkEnded(BenchmarkStats const &stats)=0
SourceLineInfo lineInfo
Definition: catch.hpp:1775
std::size_t m_count
Definition: catch.hpp:2412
auto getResult() const -> bool
Definition: catch.hpp:1467
unsigned int sequence
Definition: catch.hpp:1777
Totals & operator+=(Totals const &other)
std::vector< MatcherBase< ArgT > const * > m_matchers
Definition: catch.hpp:2503
std::unique_ptr< T > make_unique(Args &&...args)
Definition: catch.hpp:3053
std::string rawMemoryToString(const T &object)
Definition: catch.hpp:870
MessageInfo m_info
Definition: catch.hpp:1807
std::ostream * m_oss
Definition: catch.hpp:789
virtual ~NonCopyable()
FixedValuesGenerator(std::initializer_list< T > values)
Definition: catch.hpp:3080
CaseSensitive::Choice m_caseSensitivity
Definition: catch.hpp:2719
bool isFalseTest(int flags)
Definition: catch.hpp:735
double epsilon
ExceptionTranslatorRegistrar(std::string(*translateFunction)(T &))
Definition: catch.hpp:2251
TestCase(ITestInvoker *testCase, TestCaseInfo &&info)
std::vector< size_t > randomiseIndices(size_t selectionSize, size_t sourceSize)
bool match(std::vector< T > const &v) const override
Definition: catch.hpp:2772
void populate(U &&valueOrGenerator, Gs...moreGenerators)
Definition: catch.hpp:3213
Counts testCases
Definition: catch.hpp:2012
auto empty() const noexcept-> bool
Definition: catch.hpp:560
bool operator<(TestCase const &other) const
Counts assertions
Definition: catch.hpp:2011
bool allPassed() const
static std::enable_if<!::Catch::Detail::IsStreamInsertable< Fake >::value, std::string >::type convert(const Fake &value)
Definition: catch.hpp:941
#define CATCH_ENFORCE(condition, msg)
Definition: catch.hpp:3037
virtual void registerTest(TestCase const &testInfo)=0
char * m_data
Definition: catch.hpp:501
std::string toString() const
auto operator[](size_type index) const noexcept-> char
void toLowerInPlace(std::string &s)
virtual StartupExceptionRegistry const & getStartupExceptionRegistry() const =0
std::shared_ptr< ITestInvoker > test
Definition: catch.hpp:3344
StringRef tags
Definition: catch.hpp:624
void handleMessage(ResultWas::OfType resultType, StringRef const &message)
std::string name
Definition: catch.hpp:3320
ROSCPP_DECL void start()
void handleExceptionNotThrownAsExpected()
LazyExpression(bool isNegated)
auto c_str() const -> char const *
ResultDisposition::Flags operator|(ResultDisposition::Flags lhs, ResultDisposition::Flags rhs)
TestCase makeTestCase(ITestInvoker *testCase, std::string const &className, NameAndTags const &nameAndTags, SourceLineInfo const &lineInfo)
std::ostream & operator<<(std::ostream &os, SourceLineInfo const &info)
virtual void registerTagAlias(std::string const &alias, std::string const &tag, SourceLineInfo const &lineInfo)=0
virtual auto acquireGeneratorTracker(SourceLineInfo const &lineInfo) -> IGeneratorTracker &=0
bool contains(std::string const &s, std::string const &infix)
StringRef(char const *rawChars, size_type size) noexcept
Definition: catch.hpp:527
bool match(T const &item) const override
Definition: catch.hpp:2644
CaseSensitive::Choice m_caseSensitivity
Definition: catch.hpp:2683
std::string m_name
Definition: catch.hpp:2083
f
unsigned int rngSeed()
PredicateMatcher(std::function< bool(T const &)> const &elem, std::string const &descr)
Definition: catch.hpp:2639
auto makeUnaryExpr() const -> UnaryExpr< LhsT >
Definition: catch.hpp:1583
int main(int argc, char **argv)
SectionInfo m_info
Definition: catch.hpp:2081
bool expectedToFail() const
virtual void registerReporter(std::string const &name, IReporterFactoryPtr const &factory)=0
#define CATCH_TRY
Definition: catch.hpp:337
ros::Time * timeStamp(M &m)
auto compareNotEqual(LhsT const &lhs, RhsT &&rhs) -> bool
Definition: catch.hpp:1534
auto getCurrentNanosecondsSinceEpoch() -> uint64_t
T const & operator+(T const &value, StreamEndStop)
Definition: catch.hpp:417
auto getEstimatedClockResolution() -> uint64_t
SpecialProperties properties
Definition: catch.hpp:3326
bool match(ArgT const &arg) const override
Definition: catch.hpp:2475
std::size_t failedButOk
Definition: catch.hpp:2000
not_this_one end(...)
virtual ~ITestInvoker()
ContainsMatcher(std::vector< T > const &comparator)
Definition: catch.hpp:2791
TestInvokerAsMethod(void(C::*testAsMethod)()) noexcept
Definition: catch.hpp:606
bool match(std::vector< T > const &vec) const override
Definition: catch.hpp:2844
SourceLineInfo(char const *_file, std::size_t _line) noexcept
Definition: catch.hpp:384
virtual void popScopedMessage(MessageInfo const &message)=0
IResultCapture & getResultCapture()
std::string tagsAsString() const
Approx & epsilon(T const &newEpsilon)
Definition: catch.hpp:2348
Capturer(StringRef macroName, SourceLineInfo const &lineInfo, ResultWas::OfType resultType, StringRef names)
std::string m_name
Definition: catch.hpp:2111
std::shared_ptr< ITestInvoker > ITestCasePtr
Definition: catch.hpp:456
std::vector< std::string > lcaseTags
Definition: catch.hpp:3324
XmlRpcServer s
StdString::RegexMatcher Matches(std::string const &regex, CaseSensitive::Choice caseSensitivity=CaseSensitive::Yes)
auto as() -> Generator< T >
Definition: catch.hpp:3182
double durationInSeconds
Definition: catch.hpp:2040
virtual auto hasGenerator() const -> bool=0
SectionInfo(SourceLineInfo const &_lineInfo, std::string const &_name)
#define CATCH_RUNTIME_ERROR(msg)
Definition: catch.hpp:3035
bool replaceInPlace(std::string &str, std::string const &replaceThis, std::string const &withThis)
size_t count(InputIterator first, InputIterator last, T const &item)
Definition: catch.hpp:2747
StringRef(StringRef const &other) noexcept
Definition: catch.hpp:512
std::vector< size_t > m_indices
Definition: catch.hpp:3134
virtual std::vector< TestCase > const & getAllTestsSorted(IConfig const &config) const =0
std::string finalizeDescription(const std::string &desc)
bool allOk() const
bool operator==(SourceLineInfo const &other) const noexcept
Definition: catch.hpp:94
Approx operator()(T const &value)
Definition: catch.hpp:2294
bool operator==(const in6_addr a, const in6_addr b)
static auto getResolution() -> uint64_t
SectionInfo sectionInfo
Definition: catch.hpp:2038
UnaryExpr(LhsT lhs)
Definition: catch.hpp:1515
ROSCPP_DECL bool validate(const std::string &name, std::string &error)
virtual auto getGenerator() const -> Generators::GeneratorBasePtr const &=0
std::vector< std::unique_ptr< IExceptionTranslator const >> ExceptionTranslators
Definition: catch.hpp:2211
Counts m_assertions
Definition: catch.hpp:2084
StringRef(std::string const &stdString) noexcept
Definition: catch.hpp:532
auto size() const -> size_t
Definition: catch.hpp:2995
std::vector< std::string > tags
Definition: catch.hpp:3323
virtual auto getIndex() const -> std::size_t=0
#define CATCH_INTERNAL_ERROR(msg)
Definition: catch.hpp:3031
ExprLhs(LhsT lhs)
Definition: catch.hpp:1548
static std::string convert(signed char const *str)
Definition: catch.hpp:1029
IMutableRegistryHub & getMutableRegistryHub()
Counts & operator+=(Counts const &other)
std::string(*)( exceptionTranslateFunction)
Definition: catch.hpp:2208
Vector::ContainsMatcher< T > Contains(std::vector< T > const &comparator)
Definition: catch.hpp:2887
void formatReconstructedExpression(std::ostream &os, std::string const &lhs, StringRef op, std::string const &rhs)
bool empty() const noexcept
ITransientExpression(bool isBinaryExpression, bool result)
Definition: catch.hpp:1470
ScopedMessage(MessageBuilder const &builder)
std::string stringify(const T &e)
Definition: catch.hpp:955
StdString::EqualsMatcher Equals(std::string const &str, CaseSensitive::Choice caseSensitivity=CaseSensitive::Yes)
std::vector< T > const & m_comparator
Definition: catch.hpp:2815
Generator(size_t size, std::unique_ptr< IGenerator< T >> generator)
Definition: catch.hpp:3116
bool operator==(TestCase const &other) const
std::vector< Generator< T > > m_generators
Definition: catch.hpp:3193
static std::string convert(U *p)
Definition: catch.hpp:1100
virtual void registerStartupException() noexcept=0
virtual void pushScopedMessage(MessageInfo const &message)=0
virtual ~IStream()
auto getElapsedSeconds() const -> double
ROSCONSOLE_DECL void print(FilterBase *filter, void *logger, Level level, const char *file, int line, const char *function, const char *fmt,...) ROSCONSOLE_PRINTF_ATTRIBUTE(7
auto operator+(char const *lhs, StringRef const &rhs) -> std::string
std::string describe() const override
Definition: catch.hpp:2811
ResultDisposition::Flags resultDisposition
Definition: catch.hpp:748
std::vector< TestCase > const & getAllTestCasesSorted(IConfig const &config)
ExceptionTranslator(std::string(*translateFunction)(T &))
Definition: catch.hpp:2229
void streamReconstructedExpression(std::ostream &os) const override
Definition: catch.hpp:1510
bool shouldContinueOnFailure(int flags)
auto str() const -> std::string
std::string operator+() const
bool isJustInfo(int flags)
#define CATCH_ERROR(msg)
Definition: catch.hpp:3033
AutoReg(ITestInvoker *invoker, SourceLineInfo const &lineInfo, StringRef const &classOrMethod, NameAndTags const &nameAndTags) noexcept
not_this_one begin(...)
bool isHidden() const
auto values(std::initializer_list< T > values) -> Generator< T >
Definition: catch.hpp:3173
std::vector< TestCase > filterTests(std::vector< TestCase > const &testCases, TestSpec const &testSpec, IConfig const &config)
AssertionReaction m_reaction
Definition: catch.hpp:1719
AssertionInfo m_assertionInfo
Definition: catch.hpp:1718
bool throws() const
Approx(T const &value)
Definition: catch.hpp:2303
std::string description
Definition: catch.hpp:2033
void handleUnexpectedInflightException()
Floating::WithinAbsMatcher WithinAbs(double target, double margin)
Approx & scale(T const &newScale)
Definition: catch.hpp:2362
ArgT const & m_arg
Definition: catch.hpp:2914
Totals delta(Totals const &prevTotals) const
std::unique_ptr< GeneratorBase > GeneratorBasePtr
Definition: catch.hpp:2997
static std::string convert(R C::*p)
Definition: catch.hpp:1111
std::size_t failed
Definition: catch.hpp:1999
GeneratorRandomiser(Generator< T > &&baseGenerator, size_t numberOfItems)
Definition: catch.hpp:3136
StringRef m_matcherString
Definition: catch.hpp:2916
BinaryExpr(bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs)
Definition: catch.hpp:1498
auto operator!=(StringRef const &other) const noexcept-> bool
void captureValues(size_t index, T &&value)
Definition: catch.hpp:1829
void cleanUp()
std::ostream & cout()
AssertionHandler(StringRef const &macroName, SourceLineInfo const &lineInfo, StringRef capturedExpression, ResultDisposition::Flags resultDisposition)
StringRef capturedExpression
Definition: catch.hpp:747
bool shouldSuppressFailure(int flags)
virtual ~IRegistryHub()
std::shared_ptr< IReporterFactory > IReporterFactoryPtr
Definition: catch.hpp:2166
StdString::EndsWithMatcher EndsWith(std::string const &str, CaseSensitive::Choice caseSensitivity=CaseSensitive::Yes)
std::string describe() const override
Definition: catch.hpp:2648
UnorderedEqualsMatcher(std::vector< T > const &target)
Definition: catch.hpp:2843
auto random(size_t size) -> Generator< T >
Definition: catch.hpp:3168
auto makeTestInvoker(void(*testAsFunction)()) noexcept-> ITestInvoker *
bool isOk(ResultWas::OfType resultType)
ResultWas::OfType type
Definition: catch.hpp:1776
virtual void registerTranslator(const IExceptionTranslator *translator)=0
void setVerbosity(int level)
ReusableStringStream m_stream
Definition: catch.hpp:1793
SourceLineInfo lineInfo
Definition: catch.hpp:3325
StringRef macroName
Definition: catch.hpp:1773
bool operator<(SourceLineInfo const &other) const noexcept
auto size() const noexcept-> size_type
Definition: catch.hpp:563
RangeGenerator(T const &first, T const &last)
Definition: catch.hpp:3093
void handleExceptionThrownAsExpected()
Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff)
virtual std::string translateActiveException() const =0
auto needsMoreIterations() -> bool
auto all< int >() -> Generator< int >
NameAndTags(StringRef const &name_=StringRef(), StringRef const &tags_=StringRef()) noexcept
std::string className
Definition: catch.hpp:3321
std::string m_label
Definition: catch.hpp:2413
std::string trim(std::string const &str)
bool endsWith(std::string const &s, std::string const &suffix)
#define CATCH_INTERNAL_LINEINFO
Definition: catch.hpp:422
static std::string convert(char const *str)
Definition: catch.hpp:1023
StringRef macroName
Definition: catch.hpp:745
std::string describe() const override
Definition: catch.hpp:2874
std::string toLower(std::string const &s)
ROSCPP_DECL bool ok()
char const * file
Definition: catch.hpp:398
std::string translateActiveException()
#define CATCH_CATCH_ALL
Definition: catch.hpp:338
virtual void benchmarkStarting(BenchmarkInfo const &info)=0
Vector::EqualsMatcher< T > Equals(std::vector< T > const &comparator)
Definition: catch.hpp:2897
virtual void streamReconstructedExpression(std::ostream &os) const =0
Info
TestCase withName(std::string const &_newName) const
std::string describe() const override
Definition: catch.hpp:2835
bool equalityComparisonImpl(double other) const
std::enable_if< !std::is_enum< T >::value &&!std::is_base_of< std::exception, T >::value, std::string >::type convertUnstreamable(T const &)
Definition: catch.hpp:893
virtual ITestCaseRegistry const & getTestCaseRegistry() const =0
void captureValues(size_t index, T &&value, Ts &&...values)
Definition: catch.hpp:1834
void handleExpr(ExprLhs< T > const &expr)
Definition: catch.hpp:1736
bool match(ArgT const &arg) const override
Definition: catch.hpp:2544
auto isSubstring() const noexcept-> bool
std::string name
Definition: catch.hpp:2032
std::size_t total() const
auto makeGenerators(U &&val, Gs...moreGenerators) -> Generators< T >
Definition: catch.hpp:3248
StringRef(StringRef &&other) noexcept
Definition: catch.hpp:517
bool match(ArgT const &arg) const override
Definition: catch.hpp:2508
auto operator+=(std::string &lhs, StringRef const &sr) -> std::string &
StringRef m_op
Definition: catch.hpp:1489
RegistrarForTagAliases(char const *alias, char const *tag, SourceLineInfo const &lineInfo)
BenchmarkLooper(StringRef name)
Definition: catch.hpp:2120
MessageBuilder(StringRef const &macroName, SourceLineInfo const &lineInfo, ResultWas::OfType type)
std::ostream & clog()
IResultCapture & m_resultCapture
Definition: catch.hpp:1721
void throw_exception(std::exception const &e)
auto table(std::initializer_list< std::tuple< Ts... >> &&tuples) -> Generator< std::tuple< Ts... >>
Definition: catch.hpp:3187
static unsigned int globalCount
Definition: catch.hpp:1782
StringRef() noexcept
Definition: catch.hpp:508
auto getElapsedNanoseconds() const -> uint64_t
virtual void registerListener(IReporterFactoryPtr const &factory)=0
void streamReconstructedExpression(std::ostream &os) const override
Definition: catch.hpp:2925
std::string translate(ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd) const override
Definition: catch.hpp:2233
TestCaseInfo const & getTestCaseInfo() const
auto getElapsedMicroseconds() const -> uint64_t
SourceLineInfo lineInfo
Definition: catch.hpp:746
auto range(T const &first, T const &last) -> Generator< T >
Definition: catch.hpp:3156
const std::string unprintableString
static std::enable_if<::Catch::Detail::IsStreamInsertable< Fake >::value, std::string >::type convert(const Fake &value)
Definition: catch.hpp:930
virtual void handleIncomplete(AssertionInfo const &info)=0
MatcherT m_matcher
Definition: catch.hpp:2915
std::string rangeToString(std::vector< bool, Allocator > const &v)
Definition: catch.hpp:1300
auto isBinaryExpression() const -> bool
Definition: catch.hpp:1466
MessageInfo(StringRef const &_macroName, SourceLineInfo const &_lineInfo, ResultWas::OfType _type)
auto all() -> Generator< T >
Definition: catch.hpp:3150
char const * m_start
Definition: catch.hpp:498
Section(SectionInfo const &info)
auto substr(size_type start, size_type size) const noexcept-> StringRef
virtual IReporterRegistry const & getReporterRegistry() const =0
void populate(Generator< T > &&generator)
Definition: catch.hpp:3207
std::vector< MatcherBase< ArgT > const * > m_matchers
Definition: catch.hpp:2536
auto acquireGeneratorTracker(SourceLineInfo const &lineInfo) -> IGeneratorTracker &
size_type m_size
Definition: catch.hpp:499
auto operator==(StringRef const &other) const noexcept-> bool
std::unique_ptr< IGenerator< T > > m_generator
Definition: catch.hpp:3112
MessageInfo m_info
Definition: catch.hpp:1815
virtual ~IRunner()
auto makeMatchExpr(ArgT const &arg, MatcherT const &matcher, StringRef const &matcherString) -> MatchExpr< ArgT, MatcherT >
Definition: catch.hpp:2940
void captureValue(size_t index, StringRef value)
std::size_t passed
Definition: catch.hpp:1998
StdString::StartsWithMatcher StartsWith(std::string const &str, CaseSensitive::Choice caseSensitivity=CaseSensitive::Yes)
std::enable_if< std::is_enum< T >::value, std::string >::type convertUnstreamable(T const &value)
Definition: catch.hpp:906
std::size_t line
Definition: catch.hpp:399
Approx & margin(T const &newMargin)
Definition: catch.hpp:2355
std::string convertUnknownEnumToString(E e)
Definition: catch.hpp:960
std::ostream & cerr()
bool operator==(MessageInfo const &other) const
std::string describe() const override
Definition: catch.hpp:2515
std::string describe() const override
Definition: catch.hpp:2781
auto numberOfCharacters() const noexcept-> size_type
std::function< bool(T const &)> m_predicate
Definition: catch.hpp:2635
bool operator<(MessageInfo const &other) const
virtual void sectionEnded(SectionEndInfo const &endInfo)=0
auto size() const -> size_t
Definition: catch.hpp:3121
void handleExceptionMatchExpr(AssertionHandler &handler, std::string const &str, StringRef const &matcherString)
Totals operator-(Totals const &other) const
MatcherBase< ArgT > const & m_underlyingMatcher
Definition: catch.hpp:2551
bool match(std::vector< T > const &v) const override
Definition: catch.hpp:2793
std::vector< T > const & m_comparator
Definition: catch.hpp:2838
virtual IExceptionTranslatorRegistry const & getExceptionTranslatorRegistry() const =0
StringRef name
Definition: catch.hpp:623
bool m_sectionIncluded
Definition: catch.hpp:2085
Counts operator-(Counts const &other) const
void swap(StringRef &other) noexcept
void streamReconstructedExpression(std::ostream &os) const override
Definition: catch.hpp:1492
bool contains(InputIterator first, InputIterator last, T const &item)
Definition: catch.hpp:2757
void invoke() const
auto generate(SourceLineInfo const &lineInfo, L const &generatorExpression) -> decltype(std::declval< decltype(generatorExpression())>()[0])
Definition: catch.hpp:3258
IRegistryHub const & getRegistryHub()
auto value(T const &val) -> Generator< T >
Definition: catch.hpp:3177
Vector::UnorderedEqualsMatcher< T > UnorderedEquals(std::vector< T > const &target)
Definition: catch.hpp:2902
auto operator[](size_t index) const -> T
Definition: catch.hpp:3218
std::size_t size_type
Definition: catch.hpp:493
Generic::PredicateMatcher< T > Predicate(std::function< bool(T const &)> const &predicate, std::string const &description="")
Definition: catch.hpp:2660
Timer m_timer
Definition: catch.hpp:2086
void handleUnexpectedExceptionNotThrown()
std::string description
Definition: catch.hpp:3322
auto compareEqual(LhsT const &lhs, RhsT const &rhs) -> bool
Definition: catch.hpp:1523
SourceLineInfo lineInfo
Definition: catch.hpp:2034
MatchNotOf(MatcherBase< ArgT > const &underlyingMatcher)
Definition: catch.hpp:2542
virtual void sectionEndedEarly(SectionEndInfo const &endInfo)=0
ITransientExpression const * m_transientExpression
Definition: catch.hpp:1700
std::string message
Definition: catch.hpp:1774
std::string describe() const override
Definition: catch.hpp:2548
std::string describe() const override
Definition: catch.hpp:2482
bool match(std::vector< T > const &v) const override
Definition: catch.hpp:2823
MatchExpr(ArgT const &arg, MatcherT const &matcher, StringRef const &matcherString)
Definition: catch.hpp:2918
std::string rangeToString(Range const &range)
Definition: catch.hpp:1294
void invoke() const override
Definition: catch.hpp:608
auto makeStream(StringRef const &filename) -> IStream const *
static std::string convert(unsigned char const *str)
Definition: catch.hpp:1035
auto currentData() const noexcept-> char const *
auto isOwned() const noexcept-> bool
auto allowThrows() const -> bool
TestCaseInfo(std::string const &_name, std::string const &_className, std::string const &_description, std::vector< std::string > const &_tags, SourceLineInfo const &_lineInfo)
virtual ITagAliasRegistry const & getTagAliasRegistry() const =0
~StringRef() noexcept
Definition: catch.hpp:537
#define CATCH_CATCH_ANON(type)
Definition: catch.hpp:339
pluralise(std::size_t count, std::string const &label)
auto get() -> std::ostream &
Definition: catch.hpp:801
std::vector< MessageInfo > m_messages
Definition: catch.hpp:1819
auto operator[](size_t index) const -> T
Definition: catch.hpp:3122
bool startsWith(std::string const &s, std::string const &prefix)
Vector::ContainsElementMatcher< T > VectorContains(T const &comparator)
Definition: catch.hpp:2892
auto getElapsedMilliseconds() const -> unsigned int


catch_ros
Author(s): Max Schwarz
autogenerated on Sat Jun 8 2019 17:59:58