catch.hpp
Go to the documentation of this file.
1 /*
2  * Catch v1.2.1
3  * Generated: 2015-06-30 18:23:27.961086
4  * ----------------------------------------------------------
5  * This file has been merged from multiple headers. Please don't edit it directly
6  * Copyright (c) 2012 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 
14 #define TWOBLUECUBES_CATCH_HPP_INCLUDED
15 
16 #ifdef __clang__
17 # pragma clang system_header
18 #elif defined __GNUC__
19 # pragma GCC system_header
20 #endif
21 
22 // #included from: internal/catch_suppress_warnings.h
23 
24 #define TWOBLUECUBES_CATCH_SUPPRESS_WARNINGS_H_INCLUDED
25 
26 #ifdef __clang__
27 # ifdef __ICC // icpc defines the __clang__ macro
28 # pragma warning(push)
29 # pragma warning(disable: 161 1682)
30 # else // __ICC
31 # pragma clang diagnostic ignored "-Wglobal-constructors"
32 # pragma clang diagnostic ignored "-Wvariadic-macros"
33 # pragma clang diagnostic ignored "-Wc99-extensions"
34 # pragma clang diagnostic ignored "-Wunused-variable"
35 # pragma clang diagnostic push
36 # pragma clang diagnostic ignored "-Wpadded"
37 # pragma clang diagnostic ignored "-Wc++98-compat"
38 # pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
39 # pragma clang diagnostic ignored "-Wswitch-enum"
40 # endif
41 #elif defined __GNUC__
42 # pragma GCC diagnostic ignored "-Wvariadic-macros"
43 # pragma GCC diagnostic ignored "-Wunused-variable"
44 # pragma GCC diagnostic push
45 # pragma GCC diagnostic ignored "-Wpadded"
46 #endif
47 
48 #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
49 # define CATCH_IMPL
50 #endif
51 
52 #ifdef CATCH_IMPL
53 # ifndef CLARA_CONFIG_MAIN
54 # define CLARA_CONFIG_MAIN_NOT_DEFINED
55 # define CLARA_CONFIG_MAIN
56 # endif
57 #endif
58 
59 // #included from: internal/catch_notimplemented_exception.h
60 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED
61 
62 // #included from: catch_common.h
63 #define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
64 
65 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
66 #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
67 #define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
68 
69 #define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
70 #define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
71 
72 #include <sstream>
73 #include <stdexcept>
74 #include <algorithm>
75 
76 // #included from: catch_compiler_capabilities.h
77 #define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
78 
79 // Detect a number of compiler features - mostly C++11/14 conformance - by compiler
80 // The following features are defined:
81 //
82 // CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported?
83 // CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
84 // CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
85 // CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported?
86 // CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported
87 
88 // CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
89 
90 // CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
91 
92 // In general each macro has a _NO_<feature name> form
93 // (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
94 // Many features, at point of detection, define an _INTERNAL_ macro, so they
95 // can be combined, en-mass, with the _NO_ forms later.
96 
97 // All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11
98 
99 #ifdef __clang__
100 
101 # if __has_feature(cxx_nullptr)
102 # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
103 # endif
104 
105 # if __has_feature(cxx_noexcept)
106 # define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
107 # endif
108 
109 #endif // __clang__
110 
112 // Borland
113 #ifdef __BORLANDC__
114 
115 #endif // __BORLANDC__
116 
118 // EDG
119 #ifdef __EDG_VERSION__
120 
121 #endif // __EDG_VERSION__
122 
124 // Digital Mars
125 #ifdef __DMC__
126 
127 #endif // __DMC__
128 
130 // GCC
131 #ifdef __GNUC__
132 
133 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) )
134 # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
135 #endif
136 
137 #endif // __GNUC__
138 
140 // Visual C++
141 #ifdef _MSC_VER
142 
143 #if (_MSC_VER >= 1600)
144 # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
145 #endif
146 
147 #if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
148 #define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
149 #define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
150 #endif
151 
152 #endif // _MSC_VER
153 
154 // Use variadic macros if the compiler supports them
155 #if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
156  ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
157  ( defined __GNUC__ && __GNUC__ >= 3 ) || \
158  ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
159 
160 #define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
161 
162 #endif
163 
165 // C++ language feature support
166 
167 // catch all support for C++11
168 #if (__cplusplus >= 201103L)
169 
170 # define CATCH_CPP11_OR_GREATER
171 
172 # if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR)
173 # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
174 # endif
175 
176 # ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
177 # define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
178 # endif
179 
180 # ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
181 # define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
182 # endif
183 
184 # ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
185 # define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
186 # endif
187 
188 # ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE
189 # define CATCH_INTERNAL_CONFIG_CPP11_TUPLE
190 # endif
191 
192 # ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
193 # define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
194 # endif
195 
196 #endif // __cplusplus >= 201103L
197 
198 // Now set the actual defines based on the above + anything the user has configured
199 #if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11)
200 # define CATCH_CONFIG_CPP11_NULLPTR
201 #endif
202 #if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11)
203 # define CATCH_CONFIG_CPP11_NOEXCEPT
204 #endif
205 #if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11)
206 # define CATCH_CONFIG_CPP11_GENERATED_METHODS
207 #endif
208 #if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11)
209 # define CATCH_CONFIG_CPP11_IS_ENUM
210 #endif
211 #if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11)
212 # define CATCH_CONFIG_CPP11_TUPLE
213 #endif
214 #if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS)
215 #define CATCH_CONFIG_VARIADIC_MACROS
216 #endif
217 
218 // noexcept support:
219 #if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)
220 # define CATCH_NOEXCEPT noexcept
221 # define CATCH_NOEXCEPT_IS(x) noexcept(x)
222 #else
223 # define CATCH_NOEXCEPT throw()
224 # define CATCH_NOEXCEPT_IS(x)
225 #endif
226 
227 namespace Catch {
228 
229  class NonCopyable {
230 #ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
231  NonCopyable( NonCopyable const& ) = delete;
232  NonCopyable( NonCopyable && ) = delete;
233  NonCopyable& operator = ( NonCopyable const& ) = delete;
234  NonCopyable& operator = ( NonCopyable && ) = delete;
235 #else
236  NonCopyable( NonCopyable const& info );
238 #endif
239 
240  protected:
242  virtual ~NonCopyable();
243  };
244 
245  class SafeBool {
246  public:
247  typedef void (SafeBool::*type)() const;
248 
249  static type makeSafe( bool value ) {
250  return value ? &SafeBool::trueValue : 0;
251  }
252  private:
253  void trueValue() const {}
254  };
255 
256  template<typename ContainerT>
257  inline void deleteAll( ContainerT& container ) {
258  typename ContainerT::const_iterator it = container.begin();
259  typename ContainerT::const_iterator itEnd = container.end();
260  for(; it != itEnd; ++it )
261  delete *it;
262  }
263  template<typename AssociativeContainerT>
264  inline void deleteAllValues( AssociativeContainerT& container ) {
265  typename AssociativeContainerT::const_iterator it = container.begin();
266  typename AssociativeContainerT::const_iterator itEnd = container.end();
267  for(; it != itEnd; ++it )
268  delete it->second;
269  }
270 
271  bool startsWith( std::string const& s, std::string const& prefix );
272  bool endsWith( std::string const& s, std::string const& suffix );
273  bool contains( std::string const& s, std::string const& infix );
274  void toLowerInPlace( std::string& s );
275  std::string toLower( std::string const& s );
276  std::string trim( std::string const& str );
277  bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
278 
279  struct pluralise {
280  pluralise( std::size_t count, std::string const& label );
281 
282  friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
283 
284  std::size_t m_count;
286  };
287 
288  struct SourceLineInfo {
289 
290  SourceLineInfo();
291  SourceLineInfo( char const* _file, std::size_t _line );
292  SourceLineInfo( SourceLineInfo const& other );
293 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
294  SourceLineInfo( SourceLineInfo && ) = default;
295  SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
296  SourceLineInfo& operator = ( SourceLineInfo && ) = default;
297 # endif
298  bool empty() const;
299  bool operator == ( SourceLineInfo const& other ) const;
300  bool operator < ( SourceLineInfo const& other ) const;
301 
303  std::size_t line;
304  };
305 
306  std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
307 
308  // This is just here to avoid compiler warnings with macro constants and boolean literals
309  inline bool isTrue( bool value ){ return value; }
310  inline bool alwaysTrue() { return true; }
311  inline bool alwaysFalse() { return false; }
312 
313  void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
314 
315  // Use this in variadic streaming macros to allow
316  // >> +StreamEndStop
317  // as well as
318  // >> stuff +StreamEndStop
319  struct StreamEndStop {
321  return std::string();
322  }
323  };
324  template<typename T>
325  T const& operator + ( T const& value, StreamEndStop ) {
326  return value;
327  }
328 }
329 
330 #define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
331 #define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
332 
333 #include <ostream>
334 
335 namespace Catch {
336 
337  class NotImplementedException : public std::exception
338  {
339  public:
340  NotImplementedException( SourceLineInfo const& lineInfo );
342 
344 
345  virtual const char* what() const CATCH_NOEXCEPT;
346 
347  private:
350  };
351 
352 } // end namespace Catch
353 
355 #define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )
356 
357 // #included from: internal/catch_context.h
358 #define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
359 
360 // #included from: catch_interfaces_generators.h
361 #define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED
362 
363 #include <string>
364 
365 namespace Catch {
366 
367  struct IGeneratorInfo {
368  virtual ~IGeneratorInfo();
369  virtual bool moveNext() = 0;
370  virtual std::size_t getCurrentIndex() const = 0;
371  };
372 
374  virtual ~IGeneratorsForTest();
375 
376  virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0;
377  virtual bool moveNext() = 0;
378  };
379 
381 
382 } // end namespace Catch
383 
384 // #included from: catch_ptr.hpp
385 #define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
386 
387 #ifdef __clang__
388 #pragma clang diagnostic push
389 #pragma clang diagnostic ignored "-Wpadded"
390 #endif
391 
392 namespace Catch {
393 
394  // An intrusive reference counting smart pointer.
395  // T must implement addRef() and release() methods
396  // typically implementing the IShared interface
397  template<typename T>
398  class Ptr {
399  public:
400  Ptr() : m_p( NULL ){}
401  Ptr( T* p ) : m_p( p ){
402  if( m_p )
403  m_p->addRef();
404  }
405  Ptr( Ptr const& other ) : m_p( other.m_p ){
406  if( m_p )
407  m_p->addRef();
408  }
409  ~Ptr(){
410  if( m_p )
411  m_p->release();
412  }
413  void reset() {
414  if( m_p )
415  m_p->release();
416  m_p = NULL;
417  }
418  Ptr& operator = ( T* p ){
419  Ptr temp( p );
420  swap( temp );
421  return *this;
422  }
423  Ptr& operator = ( Ptr const& other ){
424  Ptr temp( other );
425  swap( temp );
426  return *this;
427  }
428  void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
429  T* get() { return m_p; }
430  const T* get() const{ return m_p; }
431  T& operator*() const { return *m_p; }
432  T* operator->() const { return m_p; }
433  bool operator !() const { return m_p == NULL; }
434  operator SafeBool::type() const { return SafeBool::makeSafe( m_p != NULL ); }
435 
436  private:
437  T* m_p;
438  };
439 
440  struct IShared : NonCopyable {
441  virtual ~IShared();
442  virtual void addRef() const = 0;
443  virtual void release() const = 0;
444  };
445 
446  template<typename T = IShared>
447  struct SharedImpl : T {
448 
449  SharedImpl() : m_rc( 0 ){}
450 
451  virtual void addRef() const {
452  ++m_rc;
453  }
454  virtual void release() const {
455  if( --m_rc == 0 )
456  delete this;
457  }
458 
459  mutable unsigned int m_rc;
460  };
461 
462 } // end namespace Catch
463 
464 #ifdef __clang__
465 #pragma clang diagnostic pop
466 #endif
467 
468 #include <memory>
469 #include <vector>
470 #include <stdlib.h>
471 
472 namespace Catch {
473 
474  class TestCase;
475  class Stream;
476  struct IResultCapture;
477  struct IRunner;
478  struct IGeneratorsForTest;
479  struct IConfig;
480 
481  struct IContext
482  {
483  virtual ~IContext();
484 
485  virtual IResultCapture* getResultCapture() = 0;
486  virtual IRunner* getRunner() = 0;
487  virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;
488  virtual bool advanceGeneratorsForCurrentTest() = 0;
489  virtual Ptr<IConfig const> getConfig() const = 0;
490  };
491 
493  {
494  virtual ~IMutableContext();
495  virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
496  virtual void setRunner( IRunner* runner ) = 0;
497  virtual void setConfig( Ptr<IConfig const> const& config ) = 0;
498  };
499 
502  void cleanUpContext();
503  Stream createStream( std::string const& streamName );
504 
505 }
506 
507 // #included from: internal/catch_test_registry.hpp
508 #define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
509 
510 // #included from: catch_interfaces_testcase.h
511 #define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
512 
513 #include <vector>
514 
515 namespace Catch {
516 
517  class TestSpec;
518 
519  struct ITestCase : IShared {
520  virtual void invoke () const = 0;
521  protected:
522  virtual ~ITestCase();
523  };
524 
525  class TestCase;
526  struct IConfig;
527 
529  virtual ~ITestCaseRegistry();
530  virtual std::vector<TestCase> const& getAllTests() const = 0;
531  virtual void getFilteredTests( TestSpec const& testSpec, IConfig const& config, std::vector<TestCase>& matchingTestCases, bool negated = false ) const = 0;
532 
533  };
534 }
535 
536 namespace Catch {
537 
538 template<typename C>
539 class MethodTestCase : public SharedImpl<ITestCase> {
540 
541 public:
542  MethodTestCase( void (C::*method)() ) : m_method( method ) {}
543 
544  virtual void invoke() const {
545  C obj;
546  (obj.*m_method)();
547  }
548 
549 private:
550  virtual ~MethodTestCase() {}
551 
552  void (C::*m_method)();
553 };
554 
555 typedef void(*TestFunction)();
556 
557 struct NameAndDesc {
558  NameAndDesc( const char* _name = "", const char* _description= "" )
559  : name( _name ), description( _description )
560  {}
561 
562  const char* name;
563  const char* description;
564 };
565 
566 struct AutoReg {
567 
568  AutoReg( TestFunction function,
569  SourceLineInfo const& lineInfo,
570  NameAndDesc const& nameAndDesc );
571 
572  template<typename C>
573  AutoReg( void (C::*method)(),
574  char const* className,
575  NameAndDesc const& nameAndDesc,
576  SourceLineInfo const& lineInfo ) {
577  registerTestCase( new MethodTestCase<C>( method ),
578  className,
579  nameAndDesc,
580  lineInfo );
581  }
582 
583  void registerTestCase( ITestCase* testCase,
584  char const* className,
585  NameAndDesc const& nameAndDesc,
586  SourceLineInfo const& lineInfo );
587 
588  ~AutoReg();
589 
590 private:
591  AutoReg( AutoReg const& );
592  void operator= ( AutoReg const& );
593 };
594 
595 } // end namespace Catch
596 
597 #ifdef CATCH_CONFIG_VARIADIC_MACROS
598  #define INTERNAL_CATCH_TESTCASE( ... ) \
600  static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
601  namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
602  static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )()
603 
605  #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
606  namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
607 
609  #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... )\
610  namespace{ \
611  struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
612  void test(); \
613  }; \
614  Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
615  } \
616  void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
617 
618 #else
619  #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
621  static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
622  namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
623  static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )()
624 
626  #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
627  namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
628 
630  #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
631  namespace{ \
632  struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
633  void test(); \
634  }; \
635  Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
636  } \
637  void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
638 
639 #endif
640 
641 // #included from: internal/catch_capture.hpp
642 #define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
643 
644 // #included from: catch_result_builder.h
645 #define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
646 
647 // #included from: catch_result_type.h
648 #define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
649 
650 namespace Catch {
651 
652  // ResultWas::OfType enum
653  struct ResultWas { enum OfType {
654  Unknown = -1,
655  Ok = 0,
656  Info = 1,
657  Warning = 2,
658 
659  FailureBit = 0x10,
660 
661  ExpressionFailed = FailureBit | 1,
662  ExplicitFailure = FailureBit | 2,
663 
664  Exception = 0x100 | FailureBit,
665 
666  ThrewException = Exception | 1,
667  DidntThrowException = Exception | 2,
668 
669  FatalErrorCondition = 0x200 | FailureBit
670 
671  }; };
672 
673  inline bool isOk( ResultWas::OfType resultType ) {
674  return ( resultType & ResultWas::FailureBit ) == 0;
675  }
676  inline bool isJustInfo( int flags ) {
677  return flags == ResultWas::Info;
678  }
679 
680  // ResultDisposition::Flags enum
681  struct ResultDisposition { enum Flags {
682  Normal = 0x01,
683 
684  ContinueOnFailure = 0x02, // Failures fail test, but execution continues
685  FalseTest = 0x04, // Prefix expression with !
686  SuppressFail = 0x08 // Failures are reported but do not fail the test
687  }; };
688 
690  return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
691  }
692 
693  inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
694  inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
695  inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
696 
697 } // end namespace Catch
698 
699 // #included from: catch_assertionresult.h
700 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
701 
702 #include <string>
703 
704 namespace Catch {
705 
707  {
709  AssertionInfo( std::string const& _macroName,
710  SourceLineInfo const& _lineInfo,
711  std::string const& _capturedExpression,
712  ResultDisposition::Flags _resultDisposition );
713 
718  };
719 
721  {
722  AssertionResultData() : resultType( ResultWas::Unknown ) {}
723 
727  };
728 
730  public:
731  AssertionResult();
732  AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
733  ~AssertionResult();
734 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
735  AssertionResult( AssertionResult const& ) = default;
736  AssertionResult( AssertionResult && ) = default;
737  AssertionResult& operator = ( AssertionResult const& ) = default;
739 # endif
740 
741  bool isOk() const;
742  bool succeeded() const;
743  ResultWas::OfType getResultType() const;
744  bool hasExpression() const;
745  bool hasMessage() const;
746  std::string getExpression() const;
747  std::string getExpressionInMacro() const;
748  bool hasExpandedExpression() const;
749  std::string getExpandedExpression() const;
750  std::string getMessage() const;
751  SourceLineInfo getSourceInfo() const;
752  std::string getTestMacroName() const;
753 
754  protected:
757  };
758 
759 } // end namespace Catch
760 
761 namespace Catch {
762 
764 
765  template<typename T> class ExpressionLhs;
766 
767  struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
768 
769  struct CopyableStream {
771  CopyableStream( CopyableStream const& other ) {
772  oss << other.oss.str();
773  }
775  oss.str("");
776  oss << other.oss.str();
777  return *this;
778  }
779  std::ostringstream oss;
780  };
781 
783  public:
784  ResultBuilder( char const* macroName,
785  SourceLineInfo const& lineInfo,
786  char const* capturedExpression,
787  ResultDisposition::Flags resultDisposition );
788 
789  template<typename T>
790  ExpressionLhs<T const&> operator <= ( T const& operand );
791  ExpressionLhs<bool> operator <= ( bool value );
792 
793  template<typename T>
794  ResultBuilder& operator << ( T const& value ) {
795  m_stream.oss << value;
796  return *this;
797  }
798 
799  template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
800  template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
801 
802  ResultBuilder& setResultType( ResultWas::OfType result );
803  ResultBuilder& setResultType( bool result );
804  ResultBuilder& setLhs( std::string const& lhs );
805  ResultBuilder& setRhs( std::string const& rhs );
806  ResultBuilder& setOp( std::string const& op );
807 
808  void endExpression();
809 
810  std::string reconstructExpression() const;
811  AssertionResult build() const;
812 
813  void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
814  void captureResult( ResultWas::OfType resultType );
815  void captureExpression();
816  void react();
817  bool shouldDebugBreak() const;
818  bool allowThrows() const;
819 
820  private:
823  struct ExprComponents {
824  ExprComponents() : testFalse( false ) {}
825  bool testFalse;
826  std::string lhs, rhs, op;
827  } m_exprComponents;
829 
832  };
833 
834 } // namespace Catch
835 
836 // Include after due to circular dependency:
837 // #included from: catch_expression_lhs.hpp
838 #define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
839 
840 // #included from: catch_evaluate.hpp
841 #define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
842 
843 #ifdef _MSC_VER
844 #pragma warning(push)
845 #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
846 #endif
847 
848 #include <cstddef>
849 
850 namespace Catch {
851 namespace Internal {
852 
853  enum Operator {
860  };
861 
862  template<Operator Op> struct OperatorTraits { static const char* getName(){ return "*error*"; } };
863  template<> struct OperatorTraits<IsEqualTo> { static const char* getName(){ return "=="; } };
864  template<> struct OperatorTraits<IsNotEqualTo> { static const char* getName(){ return "!="; } };
865  template<> struct OperatorTraits<IsLessThan> { static const char* getName(){ return "<"; } };
866  template<> struct OperatorTraits<IsGreaterThan> { static const char* getName(){ return ">"; } };
867  template<> struct OperatorTraits<IsLessThanOrEqualTo> { static const char* getName(){ return "<="; } };
868  template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
869 
870  template<typename T>
871  inline T& opCast(T const& t) { return const_cast<T&>(t); }
872 
873 // nullptr_t support based on pull request #154 from Konstantin Baumann
874 #ifdef CATCH_CONFIG_CPP11_NULLPTR
875  inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
876 #endif // CATCH_CONFIG_CPP11_NULLPTR
877 
878  // So the compare overloads can be operator agnostic we convey the operator as a template
879  // enum, which is used to specialise an Evaluator for doing the comparison.
880  template<typename T1, typename T2, Operator Op>
881  class Evaluator{};
882 
883  template<typename T1, typename T2>
884  struct Evaluator<T1, T2, IsEqualTo> {
885  static bool evaluate( T1 const& lhs, T2 const& rhs) {
886  return opCast( lhs ) == opCast( rhs );
887  }
888  };
889  template<typename T1, typename T2>
890  struct Evaluator<T1, T2, IsNotEqualTo> {
891  static bool evaluate( T1 const& lhs, T2 const& rhs ) {
892  return opCast( lhs ) != opCast( rhs );
893  }
894  };
895  template<typename T1, typename T2>
896  struct Evaluator<T1, T2, IsLessThan> {
897  static bool evaluate( T1 const& lhs, T2 const& rhs ) {
898  return opCast( lhs ) < opCast( rhs );
899  }
900  };
901  template<typename T1, typename T2>
902  struct Evaluator<T1, T2, IsGreaterThan> {
903  static bool evaluate( T1 const& lhs, T2 const& rhs ) {
904  return opCast( lhs ) > opCast( rhs );
905  }
906  };
907  template<typename T1, typename T2>
909  static bool evaluate( T1 const& lhs, T2 const& rhs ) {
910  return opCast( lhs ) >= opCast( rhs );
911  }
912  };
913  template<typename T1, typename T2>
914  struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
915  static bool evaluate( T1 const& lhs, T2 const& rhs ) {
916  return opCast( lhs ) <= opCast( rhs );
917  }
918  };
919 
920  template<Operator Op, typename T1, typename T2>
921  bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
922  return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
923  }
924 
925  // This level of indirection allows us to specialise for integer types
926  // to avoid signed/ unsigned warnings
927 
928  // "base" overload
929  template<Operator Op, typename T1, typename T2>
930  bool compare( T1 const& lhs, T2 const& rhs ) {
931  return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
932  }
933 
934  // unsigned X to int
935  template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
936  return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
937  }
938  template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
939  return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
940  }
941  template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
942  return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
943  }
944 
945  // unsigned X to long
946  template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
947  return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
948  }
949  template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
950  return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
951  }
952  template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
953  return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
954  }
955 
956  // int to unsigned X
957  template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
958  return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
959  }
960  template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
961  return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
962  }
963  template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
964  return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
965  }
966 
967  // long to unsigned X
968  template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
969  return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
970  }
971  template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
972  return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
973  }
974  template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
975  return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
976  }
977 
978  // pointer to long (when comparing against NULL)
979  template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
980  return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
981  }
982  template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
983  return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
984  }
985 
986  // pointer to int (when comparing against NULL)
987  template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
988  return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
989  }
990  template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
991  return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
992  }
993 
994 #ifdef CATCH_CONFIG_CPP11_NULLPTR
995  // pointer to nullptr_t (when comparing against nullptr)
996  template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
997  return Evaluator<T*, T*, Op>::evaluate( NULL, rhs );
998  }
999  template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
1000  return Evaluator<T*, T*, Op>::evaluate( lhs, NULL );
1001  }
1002 #endif // CATCH_CONFIG_CPP11_NULLPTR
1003 
1004 } // end of namespace Internal
1005 } // end of namespace Catch
1006 
1007 #ifdef _MSC_VER
1008 #pragma warning(pop)
1009 #endif
1010 
1011 // #included from: catch_tostring.h
1012 #define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED
1013 
1014 #include <sstream>
1015 #include <iomanip>
1016 #include <limits>
1017 #include <vector>
1018 #include <cstddef>
1019 
1020 #ifdef __OBJC__
1021 // #included from: catch_objc_arc.hpp
1022 #define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED
1023 
1024 #import <Foundation/Foundation.h>
1025 
1026 #ifdef __has_feature
1027 #define CATCH_ARC_ENABLED __has_feature(objc_arc)
1028 #else
1029 #define CATCH_ARC_ENABLED 0
1030 #endif
1031 
1032 void arcSafeRelease( NSObject* obj );
1033 id performOptionalSelector( id obj, SEL sel );
1034 
1035 #if !CATCH_ARC_ENABLED
1036 inline void arcSafeRelease( NSObject* obj ) {
1037  [obj release];
1038 }
1039 inline id performOptionalSelector( id obj, SEL sel ) {
1040  if( [obj respondsToSelector: sel] )
1041  return [obj performSelector: sel];
1042  return nil;
1043 }
1044 #define CATCH_UNSAFE_UNRETAINED
1045 #define CATCH_ARC_STRONG
1046 #else
1047 inline void arcSafeRelease( NSObject* ){}
1048 inline id performOptionalSelector( id obj, SEL sel ) {
1049 #ifdef __clang__
1050 #pragma clang diagnostic push
1051 #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
1052 #endif
1053  if( [obj respondsToSelector: sel] )
1054  return [obj performSelector: sel];
1055 #ifdef __clang__
1056 #pragma clang diagnostic pop
1057 #endif
1058  return nil;
1059 }
1060 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
1061 #define CATCH_ARC_STRONG __strong
1062 #endif
1063 
1064 #endif
1065 
1066 #ifdef CATCH_CONFIG_CPP11_TUPLE
1067 #include <tuple>
1068 #endif
1069 
1070 #ifdef CATCH_CONFIG_CPP11_IS_ENUM
1071 #include <type_traits>
1072 #endif
1073 
1074 namespace Catch {
1075 
1076 // Why we're here.
1077 template<typename T>
1078 std::string toString( T const& value );
1079 
1080 // Built in overloads
1081 
1083 std::string toString( std::wstring const& value );
1084 std::string toString( const char* const value );
1085 std::string toString( char* const value );
1086 std::string toString( const wchar_t* const value );
1087 std::string toString( wchar_t* const value );
1088 std::string toString( int value );
1089 std::string toString( unsigned long value );
1090 std::string toString( unsigned int value );
1091 std::string toString( const double value );
1092 std::string toString( const float value );
1093 std::string toString( bool value );
1094 std::string toString( char value );
1095 std::string toString( signed char value );
1096 std::string toString( unsigned char value );
1097 
1098 #ifdef CATCH_CONFIG_CPP11_NULLPTR
1099 std::string toString( std::nullptr_t );
1100 #endif
1101 
1102 #ifdef __OBJC__
1103  std::string toString( NSString const * const& nsstring );
1104  std::string toString( NSString * CATCH_ARC_STRONG const& nsstring );
1105  std::string toString( NSObject* const& nsObject );
1106 #endif
1107 
1108 namespace Detail {
1109 
1111 
1112  struct BorgType {
1113  template<typename T> BorgType( T const& );
1114  };
1115 
1116  struct TrueType { char sizer[1]; };
1117  struct FalseType { char sizer[2]; };
1118 
1119  TrueType& testStreamable( std::ostream& );
1121 
1122  FalseType operator<<( std::ostream const&, BorgType const& );
1123 
1124  template<typename T>
1126  static std::ostream &s;
1127  static T const&t;
1128  enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
1129  };
1130 
1131 #if defined(CATCH_CONFIG_CPP11_IS_ENUM)
1132  template<typename T,
1133  bool IsEnum = std::is_enum<T>::value
1134  >
1135  struct EnumStringMaker
1136  {
1137  static std::string convert( T const& ) { return unprintableString; }
1138  };
1139 
1140  template<typename T>
1141  struct EnumStringMaker<T,true>
1142  {
1143  static std::string convert( T const& v )
1144  {
1146  static_cast<typename std::underlying_type<T>::type>(v)
1147  );
1148  }
1149  };
1150 #endif
1151  template<bool C>
1153 #if defined(CATCH_CONFIG_CPP11_IS_ENUM)
1154  template<typename T>
1155  static std::string convert( T const& v )
1156  {
1157  return EnumStringMaker<T>::convert( v );
1158  }
1159 #else
1160  template<typename T>
1161  static std::string convert( T const& ) { return unprintableString; }
1162 #endif
1163  };
1164 
1165  template<>
1166  struct StringMakerBase<true> {
1167  template<typename T>
1168  static std::string convert( T const& _value ) {
1169  std::ostringstream oss;
1170  oss << _value;
1171  return oss.str();
1172  }
1173  };
1174 
1175  std::string rawMemoryToString( const void *object, std::size_t size );
1176 
1177  template<typename T>
1178  inline std::string rawMemoryToString( const T& object ) {
1179  return rawMemoryToString( &object, sizeof(object) );
1180  }
1181 
1182 } // end namespace Detail
1183 
1184 template<typename T>
1185 struct StringMaker :
1186  Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};
1187 
1188 template<typename T>
1189 struct StringMaker<T*> {
1190  template<typename U>
1191  static std::string convert( U* p ) {
1192  if( !p )
1193  return INTERNAL_CATCH_STRINGIFY( NULL );
1194  else
1195  return Detail::rawMemoryToString( p );
1196  }
1197 };
1198 
1199 template<typename R, typename C>
1200 struct StringMaker<R C::*> {
1201  static std::string convert( R C::* p ) {
1202  if( !p )
1203  return INTERNAL_CATCH_STRINGIFY( NULL );
1204  else
1205  return Detail::rawMemoryToString( p );
1206  }
1207 };
1208 
1209 namespace Detail {
1210  template<typename InputIterator>
1211  std::string rangeToString( InputIterator first, InputIterator last );
1212 }
1213 
1214 //template<typename T, typename Allocator>
1215 //struct StringMaker<std::vector<T, Allocator> > {
1216 // static std::string convert( std::vector<T,Allocator> const& v ) {
1217 // return Detail::rangeToString( v.begin(), v.end() );
1218 // }
1219 //};
1220 
1221 template<typename T, typename Allocator>
1222 std::string toString( std::vector<T,Allocator> const& v ) {
1223  return Detail::rangeToString( v.begin(), v.end() );
1224 }
1225 
1226 #ifdef CATCH_CONFIG_CPP11_TUPLE
1227 
1228 // toString for tuples
1229 namespace TupleDetail {
1230  template<
1231  typename Tuple,
1232  std::size_t N = 0,
1234  >
1235  struct ElementPrinter {
1236  static void print( const Tuple& tuple, std::ostream& os )
1237  {
1238  os << ( N ? ", " : " " )
1239  << Catch::toString(std::get<N>(tuple));
1240  ElementPrinter<Tuple,N+1>::print(tuple,os);
1241  }
1242  };
1243 
1244  template<
1245  typename Tuple,
1246  std::size_t N
1247  >
1248  struct ElementPrinter<Tuple,N,false> {
1249  static void print( const Tuple&, std::ostream& ) {}
1250  };
1251 
1252 }
1253 
1254 template<typename ...Types>
1255 struct StringMaker<std::tuple<Types...>> {
1256 
1257  static std::string convert( const std::tuple<Types...>& tuple )
1258  {
1259  std::ostringstream os;
1260  os << '{';
1261  TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os );
1262  os << " }";
1263  return os.str();
1264  }
1265 };
1266 #endif // CATCH_CONFIG_CPP11_TUPLE
1267 
1268 namespace Detail {
1269  template<typename T>
1271  return StringMaker<T>::convert( value );
1272  }
1273 } // end namespace Detail
1274 
1282 template<typename T>
1284  return StringMaker<T>::convert( value );
1285 }
1286 
1287  namespace Detail {
1288  template<typename InputIterator>
1289  std::string rangeToString( InputIterator first, InputIterator last ) {
1290  std::ostringstream oss;
1291  oss << "{ ";
1292  if( first != last ) {
1293  oss << Catch::toString( *first );
1294  for( ++first ; first != last ; ++first )
1295  oss << ", " << Catch::toString( *first );
1296  }
1297  oss << " }";
1298  return oss.str();
1299  }
1300 }
1301 
1302 } // end namespace Catch
1303 
1304 namespace Catch {
1305 
1306 // Wraps the LHS of an expression and captures the operator and RHS (if any) -
1307 // wrapping them all in a ResultBuilder object
1308 template<typename T>
1309 class ExpressionLhs {
1311 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
1312  ExpressionLhs& operator = ( ExpressionLhs && ) = delete;
1313 # endif
1314 
1315 public:
1316  ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {}
1317 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
1318  ExpressionLhs( ExpressionLhs const& ) = default;
1319  ExpressionLhs( ExpressionLhs && ) = default;
1320 # endif
1321 
1322  template<typename RhsT>
1323  ResultBuilder& operator == ( RhsT const& rhs ) {
1324  return captureExpression<Internal::IsEqualTo>( rhs );
1325  }
1326 
1327  template<typename RhsT>
1328  ResultBuilder& operator != ( RhsT const& rhs ) {
1329  return captureExpression<Internal::IsNotEqualTo>( rhs );
1330  }
1331 
1332  template<typename RhsT>
1333  ResultBuilder& operator < ( RhsT const& rhs ) {
1334  return captureExpression<Internal::IsLessThan>( rhs );
1335  }
1336 
1337  template<typename RhsT>
1338  ResultBuilder& operator > ( RhsT const& rhs ) {
1339  return captureExpression<Internal::IsGreaterThan>( rhs );
1340  }
1341 
1342  template<typename RhsT>
1343  ResultBuilder& operator <= ( RhsT const& rhs ) {
1344  return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
1345  }
1346 
1347  template<typename RhsT>
1348  ResultBuilder& operator >= ( RhsT const& rhs ) {
1349  return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
1350  }
1351 
1353  return captureExpression<Internal::IsEqualTo>( rhs );
1354  }
1355 
1356  ResultBuilder& operator != ( bool rhs ) {
1357  return captureExpression<Internal::IsNotEqualTo>( rhs );
1358  }
1359 
1360  void endExpression() {
1361  bool value = m_lhs ? true : false;
1362  m_rb
1363  .setLhs( Catch::toString( value ) )
1364  .setResultType( value )
1365  .endExpression();
1366  }
1367 
1368  // Only simple binary expressions are allowed on the LHS.
1369  // If more complex compositions are required then place the sub expression in parentheses
1370  template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& );
1371  template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& );
1372  template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& );
1373  template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& );
1374  template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
1375  template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
1376 
1377 private:
1378  template<Internal::Operator Op, typename RhsT>
1379  ResultBuilder& captureExpression( RhsT const& rhs ) {
1380  return m_rb
1381  .setResultType( Internal::compare<Op>( m_lhs, rhs ) )
1382  .setLhs( Catch::toString( m_lhs ) )
1383  .setRhs( Catch::toString( rhs ) )
1385  }
1386 
1387 private:
1390 };
1391 
1392 } // end namespace Catch
1393 
1394 
1395 namespace Catch {
1396 
1397  template<typename T>
1399  return ExpressionLhs<T const&>( *this, operand );
1400  }
1401 
1403  return ExpressionLhs<bool>( *this, value );
1404  }
1405 
1406 } // namespace Catch
1407 
1408 // #included from: catch_message.h
1409 #define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
1410 
1411 #include <string>
1412 
1413 namespace Catch {
1414 
1415  struct MessageInfo {
1416  MessageInfo( std::string const& _macroName,
1417  SourceLineInfo const& _lineInfo,
1418  ResultWas::OfType _type );
1419 
1424  unsigned int sequence;
1425 
1426  bool operator == ( MessageInfo const& other ) const {
1427  return sequence == other.sequence;
1428  }
1429  bool operator < ( MessageInfo const& other ) const {
1430  return sequence < other.sequence;
1431  }
1432  private:
1433  static unsigned int globalCount;
1434  };
1435 
1437  MessageBuilder( std::string const& macroName,
1438  SourceLineInfo const& lineInfo,
1440  : m_info( macroName, lineInfo, type )
1441  {}
1442 
1443  template<typename T>
1445  m_stream << value;
1446  return *this;
1447  }
1448 
1450  std::ostringstream m_stream;
1451  };
1452 
1454  public:
1455  ScopedMessage( MessageBuilder const& builder );
1456  ScopedMessage( ScopedMessage const& other );
1457  ~ScopedMessage();
1458 
1460  };
1461 
1462 } // end namespace Catch
1463 
1464 // #included from: catch_interfaces_capture.h
1465 #define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
1466 
1467 #include <string>
1468 
1469 namespace Catch {
1470 
1471  class TestCase;
1472  class AssertionResult;
1473  struct AssertionInfo;
1474  struct SectionInfo;
1475  struct MessageInfo;
1476  class ScopedMessageBuilder;
1477  struct Counts;
1478 
1480 
1481  virtual ~IResultCapture();
1482 
1483  virtual void assertionEnded( AssertionResult const& result ) = 0;
1484  virtual bool sectionStarted( SectionInfo const& sectionInfo,
1485  Counts& assertions ) = 0;
1486  virtual void sectionEnded( SectionInfo const& name, Counts const& assertions, double _durationInSeconds ) = 0;
1487  virtual void pushScopedMessage( MessageInfo const& message ) = 0;
1488  virtual void popScopedMessage( MessageInfo const& message ) = 0;
1489 
1490  virtual std::string getCurrentTestName() const = 0;
1491  virtual const AssertionResult* getLastResult() const = 0;
1492 
1493  virtual void handleFatalErrorCondition( std::string const& message ) = 0;
1494  };
1495 
1497 }
1498 
1499 // #included from: catch_debugger.h
1500 #define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
1501 
1502 // #included from: catch_platform.h
1503 #define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
1504 
1505 #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
1506 #define CATCH_PLATFORM_MAC
1507 #elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
1508 #define CATCH_PLATFORM_IPHONE
1509 #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
1510 #define CATCH_PLATFORM_WINDOWS
1511 #endif
1512 
1513 #include <string>
1514 
1515 namespace Catch{
1516 
1517  bool isDebuggerActive();
1518  void writeToDebugConsole( std::string const& text );
1519 }
1520 
1521 #ifdef CATCH_PLATFORM_MAC
1522 
1523  // The following code snippet based on:
1524  // http://cocoawithlove.com/2008/03/break-into-debugger.html
1525  #ifdef DEBUG
1526  #if defined(__ppc64__) || defined(__ppc__)
1527  #define CATCH_BREAK_INTO_DEBUGGER() \
1528  if( Catch::isDebuggerActive() ) { \
1529  __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
1530  : : : "memory","r0","r3","r4" ); \
1531  }
1532  #else
1533  #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );}
1534  #endif
1535  #endif
1536 
1537 #elif defined(_MSC_VER)
1538  #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); }
1539 #elif defined(__MINGW32__)
1540  extern "C" __declspec(dllimport) void __stdcall DebugBreak();
1541  #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); }
1542 #endif
1543 
1544 #ifndef CATCH_BREAK_INTO_DEBUGGER
1545 #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
1546 #endif
1547 
1548 // #included from: catch_interfaces_runner.h
1549 #define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
1550 
1551 namespace Catch {
1552  class TestCase;
1553 
1554  struct IRunner {
1555  virtual ~IRunner();
1556  virtual bool aborting() const = 0;
1557  };
1558 }
1559 
1561 // In the event of a failure works out if the debugger needs to be invoked
1562 // and/or an exception thrown and takes appropriate action.
1563 // This needs to be done as a macro so the debugger will stop in the user
1564 // source code rather than in Catch library code
1565 #define INTERNAL_CATCH_REACT( resultBuilder ) \
1566  if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
1567  resultBuilder.react();
1568 
1570 #define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \
1571  do { \
1572  Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
1573  try { \
1574  ( __catchResult <= expr ).endExpression(); \
1575  } \
1576  catch( ... ) { \
1577  __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \
1578  } \
1579  INTERNAL_CATCH_REACT( __catchResult ) \
1580  } while( Catch::isTrue( false && (expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
1581 
1583 #define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
1584  INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
1585  if( Catch::getResultCapture().getLastResult()->succeeded() )
1586 
1588 #define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \
1589  INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
1590  if( !Catch::getResultCapture().getLastResult()->succeeded() )
1591 
1593 #define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \
1594  do { \
1595  Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
1596  try { \
1597  expr; \
1598  __catchResult.captureResult( Catch::ResultWas::Ok ); \
1599  } \
1600  catch( ... ) { \
1601  __catchResult.useActiveException( resultDisposition ); \
1602  } \
1603  INTERNAL_CATCH_REACT( __catchResult ) \
1604  } while( Catch::alwaysFalse() )
1605 
1607 #define INTERNAL_CATCH_THROWS( expr, resultDisposition, macroName ) \
1608  do { \
1609  Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
1610  if( __catchResult.allowThrows() ) \
1611  try { \
1612  expr; \
1613  __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
1614  } \
1615  catch( ... ) { \
1616  __catchResult.captureResult( Catch::ResultWas::Ok ); \
1617  } \
1618  else \
1619  __catchResult.captureResult( Catch::ResultWas::Ok ); \
1620  INTERNAL_CATCH_REACT( __catchResult ) \
1621  } while( Catch::alwaysFalse() )
1622 
1624 #define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \
1625  do { \
1626  Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
1627  if( __catchResult.allowThrows() ) \
1628  try { \
1629  expr; \
1630  __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
1631  } \
1632  catch( exceptionType ) { \
1633  __catchResult.captureResult( Catch::ResultWas::Ok ); \
1634  } \
1635  catch( ... ) { \
1636  __catchResult.useActiveException( resultDisposition ); \
1637  } \
1638  else \
1639  __catchResult.captureResult( Catch::ResultWas::Ok ); \
1640  INTERNAL_CATCH_REACT( __catchResult ) \
1641  } while( Catch::alwaysFalse() )
1642 
1644 #ifdef CATCH_CONFIG_VARIADIC_MACROS
1645  #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \
1646  do { \
1647  Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
1648  __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \
1649  __catchResult.captureResult( messageType ); \
1650  INTERNAL_CATCH_REACT( __catchResult ) \
1651  } while( Catch::alwaysFalse() )
1652 #else
1653  #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \
1654  do { \
1655  Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
1656  __catchResult << log + ::Catch::StreamEndStop(); \
1657  __catchResult.captureResult( messageType ); \
1658  INTERNAL_CATCH_REACT( __catchResult ) \
1659  } while( Catch::alwaysFalse() )
1660 #endif
1661 
1663 #define INTERNAL_CATCH_INFO( log, macroName ) \
1664  Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
1665 
1667 #define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \
1668  do { \
1669  Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg " " #matcher, resultDisposition ); \
1670  try { \
1671  std::string matcherAsString = ::Catch::Matchers::matcher.toString(); \
1672  __catchResult \
1673  .setLhs( Catch::toString( arg ) ) \
1674  .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \
1675  .setOp( "matches" ) \
1676  .setResultType( ::Catch::Matchers::matcher.match( arg ) ); \
1677  __catchResult.captureExpression(); \
1678  } catch( ... ) { \
1679  __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
1680  } \
1681  INTERNAL_CATCH_REACT( __catchResult ) \
1682  } while( Catch::alwaysFalse() )
1683 
1684 // #included from: internal/catch_section.h
1685 #define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
1686 
1687 // #included from: catch_section_info.h
1688 #define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
1689 
1690 namespace Catch {
1691 
1692  struct SectionInfo {
1693  SectionInfo
1694  ( SourceLineInfo const& _lineInfo,
1695  std::string const& _name,
1696  std::string const& _description = std::string() );
1697 
1701  };
1702 
1703 } // end namespace Catch
1704 
1705 // #included from: catch_totals.hpp
1706 #define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED
1707 
1708 #include <cstddef>
1709 
1710 namespace Catch {
1711 
1712  struct Counts {
1713  Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {}
1714 
1715  Counts operator - ( Counts const& other ) const {
1716  Counts diff;
1717  diff.passed = passed - other.passed;
1718  diff.failed = failed - other.failed;
1719  diff.failedButOk = failedButOk - other.failedButOk;
1720  return diff;
1721  }
1722  Counts& operator += ( Counts const& other ) {
1723  passed += other.passed;
1724  failed += other.failed;
1725  failedButOk += other.failedButOk;
1726  return *this;
1727  }
1728 
1729  std::size_t total() const {
1730  return passed + failed + failedButOk;
1731  }
1732  bool allPassed() const {
1733  return failed == 0 && failedButOk == 0;
1734  }
1735  bool allOk() const {
1736  return failed == 0;
1737  }
1738 
1739  std::size_t passed;
1740  std::size_t failed;
1741  std::size_t failedButOk;
1742  };
1743 
1744  struct Totals {
1745 
1746  Totals operator - ( Totals const& other ) const {
1747  Totals diff;
1748  diff.assertions = assertions - other.assertions;
1749  diff.testCases = testCases - other.testCases;
1750  return diff;
1751  }
1752 
1753  Totals delta( Totals const& prevTotals ) const {
1754  Totals diff = *this - prevTotals;
1755  if( diff.assertions.failed > 0 )
1756  ++diff.testCases.failed;
1757  else if( diff.assertions.failedButOk > 0 )
1758  ++diff.testCases.failedButOk;
1759  else
1760  ++diff.testCases.passed;
1761  return diff;
1762  }
1763 
1764  Totals& operator += ( Totals const& other ) {
1765  assertions += other.assertions;
1766  testCases += other.testCases;
1767  return *this;
1768  }
1769 
1772  };
1773 }
1774 
1775 // #included from: catch_timer.h
1776 #define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED
1777 
1778 #ifdef CATCH_PLATFORM_WINDOWS
1779 typedef unsigned long long uint64_t;
1780 #else
1781 #include <stdint.h>
1782 #endif
1783 
1784 namespace Catch {
1785 
1786  class Timer {
1787  public:
1788  Timer() : m_ticks( 0 ) {}
1789  void start();
1790  unsigned int getElapsedMicroseconds() const;
1791  unsigned int getElapsedMilliseconds() const;
1792  double getElapsedSeconds() const;
1793 
1794  private:
1795  uint64_t m_ticks;
1796  };
1797 
1798 } // namespace Catch
1799 
1800 #include <string>
1801 
1802 namespace Catch {
1803 
1805  public:
1806  Section( SectionInfo const& info );
1807  ~Section();
1808 
1809  // This indicates whether the section should be executed or not
1810  operator bool() const;
1811 
1812  private:
1814 
1819  };
1820 
1821 } // end namespace Catch
1822 
1823 #ifdef CATCH_CONFIG_VARIADIC_MACROS
1824  #define INTERNAL_CATCH_SECTION( ... ) \
1825  if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
1826 #else
1827  #define INTERNAL_CATCH_SECTION( name, desc ) \
1828  if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) )
1829 #endif
1830 
1831 // #included from: internal/catch_generators.hpp
1832 #define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
1833 
1834 #include <iterator>
1835 #include <vector>
1836 #include <string>
1837 #include <stdlib.h>
1838 
1839 namespace Catch {
1840 
1841 template<typename T>
1842 struct IGenerator {
1843  virtual ~IGenerator() {}
1844  virtual T getValue( std::size_t index ) const = 0;
1845  virtual std::size_t size () const = 0;
1846 };
1847 
1848 template<typename T>
1849 class BetweenGenerator : public IGenerator<T> {
1850 public:
1851  BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){}
1852 
1853  virtual T getValue( std::size_t index ) const {
1854  return m_from+static_cast<int>( index );
1855  }
1856 
1857  virtual std::size_t size() const {
1858  return static_cast<std::size_t>( 1+m_to-m_from );
1859  }
1860 
1861 private:
1862 
1864  T m_to;
1865 };
1866 
1867 template<typename T>
1868 class ValuesGenerator : public IGenerator<T> {
1869 public:
1871 
1872  void add( T value ) {
1873  m_values.push_back( value );
1874  }
1875 
1876  virtual T getValue( std::size_t index ) const {
1877  return m_values[index];
1878  }
1879 
1880  virtual std::size_t size() const {
1881  return m_values.size();
1882  }
1883 
1884 private:
1885  std::vector<T> m_values;
1886 };
1887 
1888 template<typename T>
1890 public:
1891  CompositeGenerator() : m_totalSize( 0 ) {}
1892 
1893  // *** Move semantics, similar to auto_ptr ***
1895  : m_fileInfo( other.m_fileInfo ),
1896  m_totalSize( 0 )
1897  {
1898  move( other );
1899  }
1900 
1901  CompositeGenerator& setFileInfo( const char* fileInfo ) {
1902  m_fileInfo = fileInfo;
1903  return *this;
1904  }
1905 
1907  deleteAll( m_composed );
1908  }
1909 
1910  operator T () const {
1911  size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );
1912 
1913  typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
1914  typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
1915  for( size_t index = 0; it != itEnd; ++it )
1916  {
1917  const IGenerator<T>* generator = *it;
1918  if( overallIndex >= index && overallIndex < index + generator->size() )
1919  {
1920  return generator->getValue( overallIndex-index );
1921  }
1922  index += generator->size();
1923  }
1924  CATCH_INTERNAL_ERROR( "Indexed past end of generated range" );
1925  return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so
1926  }
1927 
1928  void add( const IGenerator<T>* generator ) {
1929  m_totalSize += generator->size();
1930  m_composed.push_back( generator );
1931  }
1932 
1934  move( other );
1935  return *this;
1936  }
1937 
1939  ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
1940  valuesGen->add( value );
1941  add( valuesGen );
1942  return *this;
1943  }
1944 
1945 private:
1946 
1947  void move( CompositeGenerator& other ) {
1948  std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );
1949  m_totalSize += other.m_totalSize;
1950  other.m_composed.clear();
1951  }
1952 
1953  std::vector<const IGenerator<T>*> m_composed;
1955  size_t m_totalSize;
1956 };
1957 
1958 namespace Generators
1959 {
1960  template<typename T>
1961  CompositeGenerator<T> between( T from, T to ) {
1962  CompositeGenerator<T> generators;
1963  generators.add( new BetweenGenerator<T>( from, to ) );
1964  return generators;
1965  }
1966 
1967  template<typename T>
1968  CompositeGenerator<T> values( T val1, T val2 ) {
1969  CompositeGenerator<T> generators;
1970  ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
1971  valuesGen->add( val1 );
1972  valuesGen->add( val2 );
1973  generators.add( valuesGen );
1974  return generators;
1975  }
1976 
1977  template<typename T>
1978  CompositeGenerator<T> values( T val1, T val2, T val3 ){
1979  CompositeGenerator<T> generators;
1980  ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
1981  valuesGen->add( val1 );
1982  valuesGen->add( val2 );
1983  valuesGen->add( val3 );
1984  generators.add( valuesGen );
1985  return generators;
1986  }
1987 
1988  template<typename T>
1989  CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) {
1990  CompositeGenerator<T> generators;
1991  ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
1992  valuesGen->add( val1 );
1993  valuesGen->add( val2 );
1994  valuesGen->add( val3 );
1995  valuesGen->add( val4 );
1996  generators.add( valuesGen );
1997  return generators;
1998  }
1999 
2000 } // end namespace Generators
2001 
2002 using namespace Generators;
2003 
2004 } // end namespace Catch
2005 
2006 #define INTERNAL_CATCH_LINESTR2( line ) #line
2007 #define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )
2008 
2009 #define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" )
2010 
2011 // #included from: internal/catch_interfaces_exception.h
2012 #define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
2013 
2014 #include <string>
2015 // #included from: catch_interfaces_registry_hub.h
2016 #define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
2017 
2018 #include <string>
2019 
2020 namespace Catch {
2021 
2022  class TestCase;
2023  struct ITestCaseRegistry;
2024  struct IExceptionTranslatorRegistry;
2025  struct IExceptionTranslator;
2026  struct IReporterRegistry;
2027  struct IReporterFactory;
2028 
2029  struct IRegistryHub {
2030  virtual ~IRegistryHub();
2031 
2032  virtual IReporterRegistry const& getReporterRegistry() const = 0;
2033  virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
2034  virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
2035  };
2036 
2038  virtual ~IMutableRegistryHub();
2039  virtual void registerReporter( std::string const& name, IReporterFactory* factory ) = 0;
2040  virtual void registerTest( TestCase const& testInfo ) = 0;
2041  virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
2042  };
2043 
2046  void cleanUp();
2048 
2049 }
2050 
2051 
2052 namespace Catch {
2053 
2055 
2057  virtual ~IExceptionTranslator();
2058  virtual std::string translate() const = 0;
2059  };
2060 
2062  virtual ~IExceptionTranslatorRegistry();
2063 
2064  virtual std::string translateActiveException() const = 0;
2065  };
2066 
2068  template<typename T>
2070  public:
2071 
2072  ExceptionTranslator( std::string(*translateFunction)( T& ) )
2073  : m_translateFunction( translateFunction )
2074  {}
2075 
2076  virtual std::string translate() const {
2077  try {
2078  throw;
2079  }
2080  catch( T& ex ) {
2081  return m_translateFunction( ex );
2082  }
2083  }
2084 
2085  protected:
2086  std::string(*m_translateFunction)( T& );
2087  };
2088 
2089  public:
2090  template<typename T>
2091  ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
2093  ( new ExceptionTranslator<T>( translateFunction ) );
2094  }
2095  };
2096 }
2097 
2099 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) \
2100  static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ); \
2101  namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ) ); }\
2102  static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature )
2103 
2104 // #included from: internal/catch_approx.hpp
2105 #define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
2106 
2107 #include <cmath>
2108 #include <limits>
2109 
2110 namespace Catch {
2111 namespace Detail {
2112 
2113  class Approx {
2114  public:
2115  explicit Approx ( double value )
2116  : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
2117  m_scale( 1.0 ),
2118  m_value( value )
2119  {}
2120 
2121  Approx( Approx const& other )
2122  : m_epsilon( other.m_epsilon ),
2123  m_scale( other.m_scale ),
2124  m_value( other.m_value )
2125  {}
2126 
2127  static Approx custom() {
2128  return Approx( 0 );
2129  }
2130 
2132  Approx approx( value );
2133  approx.epsilon( m_epsilon );
2134  approx.scale( m_scale );
2135  return approx;
2136  }
2137 
2138  friend bool operator == ( double lhs, Approx const& rhs ) {
2139  // Thanks to Richard Harris for his help refining this formula
2140  return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );
2141  }
2142 
2143  friend bool operator == ( Approx const& lhs, double rhs ) {
2144  return operator==( rhs, lhs );
2145  }
2146 
2147  friend bool operator != ( double lhs, Approx const& rhs ) {
2148  return !operator==( lhs, rhs );
2149  }
2150 
2151  friend bool operator != ( Approx const& lhs, double rhs ) {
2152  return !operator==( rhs, lhs );
2153  }
2154 
2155  Approx& epsilon( double newEpsilon ) {
2156  m_epsilon = newEpsilon;
2157  return *this;
2158  }
2159 
2160  Approx& scale( double newScale ) {
2161  m_scale = newScale;
2162  return *this;
2163  }
2164 
2166  std::ostringstream oss;
2167  oss << "Approx( " << Catch::toString( m_value ) << " )";
2168  return oss.str();
2169  }
2170 
2171  private:
2172  double m_epsilon;
2173  double m_scale;
2174  double m_value;
2175  };
2176 }
2177 
2178 template<>
2179 inline std::string toString<Detail::Approx>( Detail::Approx const& value ) {
2180  return value.toString();
2181 }
2182 
2183 } // end namespace Catch
2184 
2185 // #included from: internal/catch_matchers.hpp
2186 #define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
2187 
2188 namespace Catch {
2189 namespace Matchers {
2190  namespace Impl {
2191 
2192  template<typename ExpressionT>
2193  struct Matcher : SharedImpl<IShared>
2194  {
2195  typedef ExpressionT ExpressionType;
2196 
2197  virtual ~Matcher() {}
2198  virtual Ptr<Matcher> clone() const = 0;
2199  virtual bool match( ExpressionT const& expr ) const = 0;
2200  virtual std::string toString() const = 0;
2201  };
2202 
2203  template<typename DerivedT, typename ExpressionT>
2204  struct MatcherImpl : Matcher<ExpressionT> {
2205 
2206  virtual Ptr<Matcher<ExpressionT> > clone() const {
2207  return Ptr<Matcher<ExpressionT> >( new DerivedT( static_cast<DerivedT const&>( *this ) ) );
2208  }
2209  };
2210 
2211  namespace Generic {
2212 
2213  template<typename ExpressionT>
2214  class AllOf : public MatcherImpl<AllOf<ExpressionT>, ExpressionT> {
2215  public:
2216 
2217  AllOf() {}
2218  AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {}
2219 
2220  AllOf& add( Matcher<ExpressionT> const& matcher ) {
2221  m_matchers.push_back( matcher.clone() );
2222  return *this;
2223  }
2224  virtual bool match( ExpressionT const& expr ) const
2225  {
2226  for( std::size_t i = 0; i < m_matchers.size(); ++i )
2227  if( !m_matchers[i]->match( expr ) )
2228  return false;
2229  return true;
2230  }
2231  virtual std::string toString() const {
2232  std::ostringstream oss;
2233  oss << "( ";
2234  for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
2235  if( i != 0 )
2236  oss << " and ";
2237  oss << m_matchers[i]->toString();
2238  }
2239  oss << " )";
2240  return oss.str();
2241  }
2242 
2243  private:
2244  std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
2245  };
2246 
2247  template<typename ExpressionT>
2248  class AnyOf : public MatcherImpl<AnyOf<ExpressionT>, ExpressionT> {
2249  public:
2250 
2251  AnyOf() {}
2252  AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {}
2253 
2254  AnyOf& add( Matcher<ExpressionT> const& matcher ) {
2255  m_matchers.push_back( matcher.clone() );
2256  return *this;
2257  }
2258  virtual bool match( ExpressionT const& expr ) const
2259  {
2260  for( std::size_t i = 0; i < m_matchers.size(); ++i )
2261  if( m_matchers[i]->match( expr ) )
2262  return true;
2263  return false;
2264  }
2265  virtual std::string toString() const {
2266  std::ostringstream oss;
2267  oss << "( ";
2268  for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
2269  if( i != 0 )
2270  oss << " or ";
2271  oss << m_matchers[i]->toString();
2272  }
2273  oss << " )";
2274  return oss.str();
2275  }
2276 
2277  private:
2278  std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
2279  };
2280 
2281  }
2282 
2283  namespace StdString {
2284 
2285  inline std::string makeString( std::string const& str ) { return str; }
2286  inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); }
2287 
2288  struct Equals : MatcherImpl<Equals, std::string> {
2289  Equals( std::string const& str ) : m_str( str ){}
2290  Equals( Equals const& other ) : m_str( other.m_str ){}
2291 
2292  virtual ~Equals();
2293 
2294  virtual bool match( std::string const& expr ) const {
2295  return m_str == expr;
2296  }
2297  virtual std::string toString() const {
2298  return "equals: \"" + m_str + "\"";
2299  }
2300 
2302  };
2303 
2304  struct Contains : MatcherImpl<Contains, std::string> {
2305  Contains( std::string const& substr ) : m_substr( substr ){}
2306  Contains( Contains const& other ) : m_substr( other.m_substr ){}
2307 
2308  virtual ~Contains();
2309 
2310  virtual bool match( std::string const& expr ) const {
2311  return expr.find( m_substr ) != std::string::npos;
2312  }
2313  virtual std::string toString() const {
2314  return "contains: \"" + m_substr + "\"";
2315  }
2316 
2318  };
2319 
2320  struct StartsWith : MatcherImpl<StartsWith, std::string> {
2321  StartsWith( std::string const& substr ) : m_substr( substr ){}
2322  StartsWith( StartsWith const& other ) : m_substr( other.m_substr ){}
2323 
2324  virtual ~StartsWith();
2325 
2326  virtual bool match( std::string const& expr ) const {
2327  return expr.find( m_substr ) == 0;
2328  }
2329  virtual std::string toString() const {
2330  return "starts with: \"" + m_substr + "\"";
2331  }
2332 
2334  };
2335 
2336  struct EndsWith : MatcherImpl<EndsWith, std::string> {
2337  EndsWith( std::string const& substr ) : m_substr( substr ){}
2338  EndsWith( EndsWith const& other ) : m_substr( other.m_substr ){}
2339 
2340  virtual ~EndsWith();
2341 
2342  virtual bool match( std::string const& expr ) const {
2343  return expr.find( m_substr ) == expr.size() - m_substr.size();
2344  }
2345  virtual std::string toString() const {
2346  return "ends with: \"" + m_substr + "\"";
2347  }
2348 
2350  };
2351  } // namespace StdString
2352  } // namespace Impl
2353 
2354  // The following functions create the actual matcher objects.
2355  // This allows the types to be inferred
2356  template<typename ExpressionT>
2358  Impl::Matcher<ExpressionT> const& m2 ) {
2359  return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 );
2360  }
2361  template<typename ExpressionT>
2363  Impl::Matcher<ExpressionT> const& m2,
2364  Impl::Matcher<ExpressionT> const& m3 ) {
2365  return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
2366  }
2367  template<typename ExpressionT>
2369  Impl::Matcher<ExpressionT> const& m2 ) {
2370  return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 );
2371  }
2372  template<typename ExpressionT>
2374  Impl::Matcher<ExpressionT> const& m2,
2375  Impl::Matcher<ExpressionT> const& m3 ) {
2376  return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
2377  }
2378 
2380  return Impl::StdString::Equals( str );
2381  }
2382  inline Impl::StdString::Equals Equals( const char* str ) {
2384  }
2386  return Impl::StdString::Contains( substr );
2387  }
2388  inline Impl::StdString::Contains Contains( const char* substr ) {
2390  }
2392  return Impl::StdString::StartsWith( substr );
2393  }
2394  inline Impl::StdString::StartsWith StartsWith( const char* substr ) {
2396  }
2398  return Impl::StdString::EndsWith( substr );
2399  }
2400  inline Impl::StdString::EndsWith EndsWith( const char* substr ) {
2402  }
2403 
2404 } // namespace Matchers
2405 
2406 using namespace Matchers;
2407 
2408 } // namespace Catch
2409 
2410 // #included from: internal/catch_interfaces_tag_alias_registry.h
2411 #define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED
2412 
2413 // #included from: catch_tag_alias.h
2414 #define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED
2415 
2416 #include <string>
2417 
2418 namespace Catch {
2419 
2420  struct TagAlias {
2421  TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
2422 
2425  };
2426 
2428  RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
2429  };
2430 
2431 } // end namespace Catch
2432 
2433 #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }
2434 // #included from: catch_option.hpp
2435 #define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
2436 
2437 namespace Catch {
2438 
2439  // An optional type
2440  template<typename T>
2441  class Option {
2442  public:
2443  Option() : nullableValue( NULL ) {}
2444  Option( T const& _value )
2445  : nullableValue( new( storage ) T( _value ) )
2446  {}
2447  Option( Option const& _other )
2448  : nullableValue( _other ? new( storage ) T( *_other ) : NULL )
2449  {}
2450 
2452  reset();
2453  }
2454 
2455  Option& operator= ( Option const& _other ) {
2456  if( &_other != this ) {
2457  reset();
2458  if( _other )
2459  nullableValue = new( storage ) T( *_other );
2460  }
2461  return *this;
2462  }
2463  Option& operator = ( T const& _value ) {
2464  reset();
2465  nullableValue = new( storage ) T( _value );
2466  return *this;
2467  }
2468 
2469  void reset() {
2470  if( nullableValue )
2471  nullableValue->~T();
2472  nullableValue = NULL;
2473  }
2474 
2475  T& operator*() { return *nullableValue; }
2476  T const& operator*() const { return *nullableValue; }
2477  T* operator->() { return nullableValue; }
2478  const T* operator->() const { return nullableValue; }
2479 
2480  T valueOr( T const& defaultValue ) const {
2481  return nullableValue ? *nullableValue : defaultValue;
2482  }
2483 
2484  bool some() const { return nullableValue != NULL; }
2485  bool none() const { return nullableValue == NULL; }
2486 
2487  bool operator !() const { return nullableValue == NULL; }
2488  operator SafeBool::type() const {
2489  return SafeBool::makeSafe( some() );
2490  }
2491 
2492  private:
2494  char storage[sizeof(T)];
2495  };
2496 
2497 } // end namespace Catch
2498 
2499 namespace Catch {
2500 
2502  virtual ~ITagAliasRegistry();
2503  virtual Option<TagAlias> find( std::string const& alias ) const = 0;
2504  virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
2505 
2506  static ITagAliasRegistry const& get();
2507  };
2508 
2509 } // end namespace Catch
2510 
2511 // These files are included here so the single_include script doesn't put them
2512 // in the conditionally compiled sections
2513 // #included from: internal/catch_test_case_info.h
2514 #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED
2515 
2516 #include <string>
2517 #include <set>
2518 
2519 #ifdef __clang__
2520 #pragma clang diagnostic push
2521 #pragma clang diagnostic ignored "-Wpadded"
2522 #endif
2523 
2524 namespace Catch {
2525 
2526  struct ITestCase;
2527 
2528  struct TestCaseInfo {
2530  None = 0,
2531  IsHidden = 1 << 1,
2532  ShouldFail = 1 << 2,
2533  MayFail = 1 << 3,
2534  Throws = 1 << 4
2535  };
2536 
2537  TestCaseInfo( std::string const& _name,
2538  std::string const& _className,
2539  std::string const& _description,
2540  std::set<std::string> const& _tags,
2541  SourceLineInfo const& _lineInfo );
2542 
2543  TestCaseInfo( TestCaseInfo const& other );
2544 
2545  bool isHidden() const;
2546  bool throws() const;
2547  bool okToFail() const;
2548  bool expectedToFail() const;
2549 
2553  std::set<std::string> tags;
2554  std::set<std::string> lcaseTags;
2558  };
2559 
2560  class TestCase : public TestCaseInfo {
2561  public:
2562 
2563  TestCase( ITestCase* testCase, TestCaseInfo const& info );
2564  TestCase( TestCase const& other );
2565 
2566  TestCase withName( std::string const& _newName ) const;
2567 
2568  void invoke() const;
2569 
2570  TestCaseInfo const& getTestCaseInfo() const;
2571 
2572  void swap( TestCase& other );
2573  bool operator == ( TestCase const& other ) const;
2574  bool operator < ( TestCase const& other ) const;
2575  TestCase& operator = ( TestCase const& other );
2576 
2577  private:
2579  };
2580 
2581  TestCase makeTestCase( ITestCase* testCase,
2582  std::string const& className,
2583  std::string const& name,
2584  std::string const& description,
2585  SourceLineInfo const& lineInfo );
2586 }
2587 
2588 #ifdef __clang__
2589 #pragma clang diagnostic pop
2590 #endif
2591 
2592 
2593 #ifdef __OBJC__
2594 // #included from: internal/catch_objc.hpp
2595 #define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
2596 
2597 #import <objc/runtime.h>
2598 
2599 #include <string>
2600 
2601 // NB. Any general catch headers included here must be included
2602 // in catch.hpp first to make sure they are included by the single
2603 // header for non obj-usage
2604 
2606 // This protocol is really only here for (self) documenting purposes, since
2607 // all its methods are optional.
2608 @protocol OcFixture
2609 
2610 @optional
2611 
2612 -(void) setUp;
2613 -(void) tearDown;
2614 
2615 @end
2616 
2617 namespace Catch {
2618 
2619  class OcMethod : public SharedImpl<ITestCase> {
2620 
2621  public:
2622  OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
2623 
2624  virtual void invoke() const {
2625  id obj = [[m_cls alloc] init];
2626 
2627  performOptionalSelector( obj, @selector(setUp) );
2628  performOptionalSelector( obj, m_sel );
2629  performOptionalSelector( obj, @selector(tearDown) );
2630 
2631  arcSafeRelease( obj );
2632  }
2633  private:
2634  virtual ~OcMethod() {}
2635 
2636  Class m_cls;
2637  SEL m_sel;
2638  };
2639 
2640  namespace Detail{
2641 
2642  inline std::string getAnnotation( Class cls,
2643  std::string const& annotationName,
2644  std::string const& testCaseName ) {
2645  NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
2646  SEL sel = NSSelectorFromString( selStr );
2647  arcSafeRelease( selStr );
2648  id value = performOptionalSelector( cls, sel );
2649  if( value )
2650  return [(NSString*)value UTF8String];
2651  return "";
2652  }
2653  }
2654 
2655  inline size_t registerTestMethods() {
2656  size_t noTestMethods = 0;
2657  int noClasses = objc_getClassList( NULL, 0 );
2658 
2659  Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
2660  objc_getClassList( classes, noClasses );
2661 
2662  for( int c = 0; c < noClasses; c++ ) {
2663  Class cls = classes[c];
2664  {
2665  u_int count;
2666  Method* methods = class_copyMethodList( cls, &count );
2667  for( u_int m = 0; m < count ; m++ ) {
2668  SEL selector = method_getName(methods[m]);
2669  std::string methodName = sel_getName(selector);
2670  if( startsWith( methodName, "Catch_TestCase_" ) ) {
2671  std::string testCaseName = methodName.substr( 15 );
2672  std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
2673  std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
2674  const char* className = class_getName( cls );
2675 
2676  getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) );
2677  noTestMethods++;
2678  }
2679  }
2680  free(methods);
2681  }
2682  }
2683  return noTestMethods;
2684  }
2685 
2686  namespace Matchers {
2687  namespace Impl {
2688  namespace NSStringMatchers {
2689 
2690  template<typename MatcherT>
2691  struct StringHolder : MatcherImpl<MatcherT, NSString*>{
2692  StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
2693  StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
2694  StringHolder() {
2695  arcSafeRelease( m_substr );
2696  }
2697 
2698  NSString* m_substr;
2699  };
2700 
2701  struct Equals : StringHolder<Equals> {
2702  Equals( NSString* substr ) : StringHolder( substr ){}
2703 
2704  virtual bool match( ExpressionType const& str ) const {
2705  return (str != nil || m_substr == nil ) &&
2706  [str isEqualToString:m_substr];
2707  }
2708 
2709  virtual std::string toString() const {
2710  return "equals string: " + Catch::toString( m_substr );
2711  }
2712  };
2713 
2714  struct Contains : StringHolder<Contains> {
2715  Contains( NSString* substr ) : StringHolder( substr ){}
2716 
2717  virtual bool match( ExpressionType const& str ) const {
2718  return (str != nil || m_substr == nil ) &&
2719  [str rangeOfString:m_substr].location != NSNotFound;
2720  }
2721 
2722  virtual std::string toString() const {
2723  return "contains string: " + Catch::toString( m_substr );
2724  }
2725  };
2726 
2727  struct StartsWith : StringHolder<StartsWith> {
2728  StartsWith( NSString* substr ) : StringHolder( substr ){}
2729 
2730  virtual bool match( ExpressionType const& str ) const {
2731  return (str != nil || m_substr == nil ) &&
2732  [str rangeOfString:m_substr].location == 0;
2733  }
2734 
2735  virtual std::string toString() const {
2736  return "starts with: " + Catch::toString( m_substr );
2737  }
2738  };
2739  struct EndsWith : StringHolder<EndsWith> {
2740  EndsWith( NSString* substr ) : StringHolder( substr ){}
2741 
2742  virtual bool match( ExpressionType const& str ) const {
2743  return (str != nil || m_substr == nil ) &&
2744  [str rangeOfString:m_substr].location == [str length] - [m_substr length];
2745  }
2746 
2747  virtual std::string toString() const {
2748  return "ends with: " + Catch::toString( m_substr );
2749  }
2750  };
2751 
2752  } // namespace NSStringMatchers
2753  } // namespace Impl
2754 
2756  Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
2757 
2759  Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
2760 
2762  StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
2763 
2765  EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
2766 
2767  } // namespace Matchers
2768 
2769  using namespace Matchers;
2770 
2771 } // namespace Catch
2772 
2774 #define OC_TEST_CASE( name, desc )\
2775 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
2776 {\
2777 return @ name; \
2778 }\
2779 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
2780 { \
2781 return @ desc; \
2782 } \
2783 -(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
2784 
2785 #endif
2786 
2787 #ifdef CATCH_IMPL
2788 // #included from: internal/catch_impl.hpp
2789 #define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED
2790 
2791 // Collect all the implementation files together here
2792 // These are the equivalent of what would usually be cpp files
2793 
2794 #ifdef __clang__
2795 #pragma clang diagnostic push
2796 #pragma clang diagnostic ignored "-Wweak-vtables"
2797 #endif
2798 
2799 // #included from: ../catch_runner.hpp
2800 #define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
2801 
2802 // #included from: internal/catch_commandline.hpp
2803 #define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
2804 
2805 // #included from: catch_config.hpp
2806 #define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
2807 
2808 // #included from: catch_test_spec_parser.hpp
2809 #define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
2810 
2811 #ifdef __clang__
2812 #pragma clang diagnostic push
2813 #pragma clang diagnostic ignored "-Wpadded"
2814 #endif
2815 
2816 // #included from: catch_test_spec.hpp
2817 #define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
2818 
2819 #ifdef __clang__
2820 #pragma clang diagnostic push
2821 #pragma clang diagnostic ignored "-Wpadded"
2822 #endif
2823 
2824 #include <string>
2825 #include <vector>
2826 
2827 namespace Catch {
2828 
2829  class TestSpec {
2830  struct Pattern : SharedImpl<> {
2831  virtual ~Pattern();
2832  virtual bool matches( TestCaseInfo const& testCase ) const = 0;
2833  };
2834  class NamePattern : public Pattern {
2835  enum WildcardPosition {
2836  NoWildcard = 0,
2837  WildcardAtStart = 1,
2838  WildcardAtEnd = 2,
2839  WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
2840  };
2841 
2842  public:
2843  NamePattern( std::string const& name ) : m_name( toLower( name ) ), m_wildcard( NoWildcard ) {
2844  if( startsWith( m_name, "*" ) ) {
2845  m_name = m_name.substr( 1 );
2846  m_wildcard = WildcardAtStart;
2847  }
2848  if( endsWith( m_name, "*" ) ) {
2849  m_name = m_name.substr( 0, m_name.size()-1 );
2850  m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
2851  }
2852  }
2853  virtual ~NamePattern();
2854  virtual bool matches( TestCaseInfo const& testCase ) const {
2855  switch( m_wildcard ) {
2856  case NoWildcard:
2857  return m_name == toLower( testCase.name );
2858  case WildcardAtStart:
2859  return endsWith( toLower( testCase.name ), m_name );
2860  case WildcardAtEnd:
2861  return startsWith( toLower( testCase.name ), m_name );
2862  case WildcardAtBothEnds:
2863  return contains( toLower( testCase.name ), m_name );
2864  }
2865 
2866 #ifdef __clang__
2867 #pragma clang diagnostic push
2868 #pragma clang diagnostic ignored "-Wunreachable-code"
2869 #endif
2870  throw std::logic_error( "Unknown enum" );
2871 #ifdef __clang__
2872 #pragma clang diagnostic pop
2873 #endif
2874  }
2875  private:
2876  std::string m_name;
2877  WildcardPosition m_wildcard;
2878  };
2879  class TagPattern : public Pattern {
2880  public:
2881  TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
2882  virtual ~TagPattern();
2883  virtual bool matches( TestCaseInfo const& testCase ) const {
2884  return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end();
2885  }
2886  private:
2887  std::string m_tag;
2888  };
2889  class ExcludedPattern : public Pattern {
2890  public:
2891  ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
2892  virtual ~ExcludedPattern();
2893  virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
2894  private:
2895  Ptr<Pattern> m_underlyingPattern;
2896  };
2897 
2898  struct Filter {
2899  std::vector<Ptr<Pattern> > m_patterns;
2900 
2901  bool matches( TestCaseInfo const& testCase ) const {
2902  // All patterns in a filter must match for the filter to be a match
2903  for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it )
2904  if( !(*it)->matches( testCase ) )
2905  return false;
2906  return true;
2907  }
2908  };
2909 
2910  public:
2911  bool hasFilters() const {
2912  return !m_filters.empty();
2913  }
2914  bool matches( TestCaseInfo const& testCase ) const {
2915  // A TestSpec matches if any filter matches
2916  for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it )
2917  if( it->matches( testCase ) )
2918  return true;
2919  return false;
2920  }
2921 
2922  private:
2923  std::vector<Filter> m_filters;
2924 
2925  friend class TestSpecParser;
2926  };
2927 }
2928 
2929 #ifdef __clang__
2930 #pragma clang diagnostic pop
2931 #endif
2932 
2933 namespace Catch {
2934 
2935  class TestSpecParser {
2936  enum Mode{ None, Name, QuotedName, Tag };
2937  Mode m_mode;
2938  bool m_exclusion;
2939  std::size_t m_start, m_pos;
2940  std::string m_arg;
2941  TestSpec::Filter m_currentFilter;
2942  TestSpec m_testSpec;
2943  ITagAliasRegistry const* m_tagAliases;
2944 
2945  public:
2946  TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
2947 
2948  TestSpecParser& parse( std::string const& arg ) {
2949  m_mode = None;
2950  m_exclusion = false;
2951  m_start = std::string::npos;
2952  m_arg = m_tagAliases->expandAliases( arg );
2953  for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
2954  visitChar( m_arg[m_pos] );
2955  if( m_mode == Name )
2956  addPattern<TestSpec::NamePattern>();
2957  return *this;
2958  }
2959  TestSpec testSpec() {
2960  addFilter();
2961  return m_testSpec;
2962  }
2963  private:
2964  void visitChar( char c ) {
2965  if( m_mode == None ) {
2966  switch( c ) {
2967  case ' ': return;
2968  case '~': m_exclusion = true; return;
2969  case '[': return startNewMode( Tag, ++m_pos );
2970  case '"': return startNewMode( QuotedName, ++m_pos );
2971  default: startNewMode( Name, m_pos ); break;
2972  }
2973  }
2974  if( m_mode == Name ) {
2975  if( c == ',' ) {
2976  addPattern<TestSpec::NamePattern>();
2977  addFilter();
2978  }
2979  else if( c == '[' ) {
2980  if( subString() == "exclude:" )
2981  m_exclusion = true;
2982  else
2983  addPattern<TestSpec::NamePattern>();
2984  startNewMode( Tag, ++m_pos );
2985  }
2986  }
2987  else if( m_mode == QuotedName && c == '"' )
2988  addPattern<TestSpec::NamePattern>();
2989  else if( m_mode == Tag && c == ']' )
2990  addPattern<TestSpec::TagPattern>();
2991  }
2992  void startNewMode( Mode mode, std::size_t start ) {
2993  m_mode = mode;
2994  m_start = start;
2995  }
2996  std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
2997  template<typename T>
2998  void addPattern() {
2999  std::string token = subString();
3000  if( startsWith( token, "exclude:" ) ) {
3001  m_exclusion = true;
3002  token = token.substr( 8 );
3003  }
3004  if( !token.empty() ) {
3005  Ptr<TestSpec::Pattern> pattern = new T( token );
3006  if( m_exclusion )
3007  pattern = new TestSpec::ExcludedPattern( pattern );
3008  m_currentFilter.m_patterns.push_back( pattern );
3009  }
3010  m_exclusion = false;
3011  m_mode = None;
3012  }
3013  void addFilter() {
3014  if( !m_currentFilter.m_patterns.empty() ) {
3015  m_testSpec.m_filters.push_back( m_currentFilter );
3016  m_currentFilter = TestSpec::Filter();
3017  }
3018  }
3019  };
3020  inline TestSpec parseTestSpec( std::string const& arg ) {
3021  return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
3022  }
3023 
3024 } // namespace Catch
3025 
3026 #ifdef __clang__
3027 #pragma clang diagnostic pop
3028 #endif
3029 
3030 // #included from: catch_interfaces_config.h
3031 #define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
3032 
3033 #include <iostream>
3034 #include <string>
3035 #include <vector>
3036 
3037 namespace Catch {
3038 
3039  struct Verbosity { enum Level {
3040  NoOutput = 0,
3041  Quiet,
3042  Normal
3043  }; };
3044 
3045  struct WarnAbout { enum What {
3046  Nothing = 0x00,
3047  NoAssertions = 0x01
3048  }; };
3049 
3050  struct ShowDurations { enum OrNot {
3051  DefaultForReporter,
3052  Always,
3053  Never
3054  }; };
3055  struct RunTests { enum InWhatOrder {
3056  InDeclarationOrder,
3057  InLexicographicalOrder,
3058  InRandomOrder
3059  }; };
3060 
3061  class TestSpec;
3062 
3063  struct IConfig : IShared {
3064 
3065  virtual ~IConfig();
3066 
3067  virtual bool allowThrows() const = 0;
3068  virtual std::ostream& stream() const = 0;
3069  virtual std::string name() const = 0;
3070  virtual bool includeSuccessfulResults() const = 0;
3071  virtual bool shouldDebugBreak() const = 0;
3072  virtual bool warnAboutMissingAssertions() const = 0;
3073  virtual int abortAfter() const = 0;
3074  virtual bool showInvisibles() const = 0;
3075  virtual ShowDurations::OrNot showDurations() const = 0;
3076  virtual TestSpec const& testSpec() const = 0;
3077  virtual RunTests::InWhatOrder runOrder() const = 0;
3078  virtual unsigned int rngSeed() const = 0;
3079  virtual bool forceColour() const = 0;
3080  };
3081 }
3082 
3083 // #included from: catch_stream.h
3084 #define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
3085 
3086 #include <streambuf>
3087 
3088 #ifdef __clang__
3089 #pragma clang diagnostic ignored "-Wpadded"
3090 #endif
3091 
3092 namespace Catch {
3093 
3094  class Stream {
3095  public:
3096  Stream();
3097  Stream( std::streambuf* _streamBuf, bool _isOwned );
3098  void release();
3099 
3100  std::streambuf* streamBuf;
3101 
3102  private:
3103  bool isOwned;
3104  };
3105 
3106  std::ostream& cout();
3107  std::ostream& cerr();
3108 }
3109 
3110 #include <memory>
3111 #include <vector>
3112 #include <string>
3113 #include <iostream>
3114 #include <ctime>
3115 
3116 #ifndef CATCH_CONFIG_CONSOLE_WIDTH
3117 #define CATCH_CONFIG_CONSOLE_WIDTH 80
3118 #endif
3119 
3120 namespace Catch {
3121 
3122  struct ConfigData {
3123 
3124  ConfigData()
3125  : listTests( false ),
3126  listTags( false ),
3127  listReporters( false ),
3128  listTestNamesOnly( false ),
3129  showSuccessfulTests( false ),
3130  shouldDebugBreak( false ),
3131  noThrow( false ),
3132  showHelp( false ),
3133  showInvisibles( false ),
3134  forceColour( false ),
3135  abortAfter( -1 ),
3136  rngSeed( 0 ),
3137  verbosity( Verbosity::Normal ),
3138  warnings( WarnAbout::Nothing ),
3139  showDurations( ShowDurations::DefaultForReporter ),
3140  runOrder( RunTests::InDeclarationOrder )
3141  {}
3142 
3143  bool listTests;
3144  bool listTags;
3145  bool listReporters;
3146  bool listTestNamesOnly;
3147 
3148  bool showSuccessfulTests;
3149  bool shouldDebugBreak;
3150  bool noThrow;
3151  bool showHelp;
3152  bool showInvisibles;
3153  bool forceColour;
3154 
3155  int abortAfter;
3156  unsigned int rngSeed;
3157 
3158  Verbosity::Level verbosity;
3159  WarnAbout::What warnings;
3160  ShowDurations::OrNot showDurations;
3161  RunTests::InWhatOrder runOrder;
3162 
3163  std::string reporterName;
3164  std::string outputFilename;
3165  std::string name;
3166  std::string processName;
3167 
3168  std::vector<std::string> testsOrTags;
3169  };
3170 
3171  class Config : public SharedImpl<IConfig> {
3172  private:
3173  Config( Config const& other );
3174  Config& operator = ( Config const& other );
3175  virtual void dummy();
3176  public:
3177 
3178  Config()
3179  : m_os( Catch::cout().rdbuf() )
3180  {}
3181 
3182  Config( ConfigData const& data )
3183  : m_data( data ),
3184  m_os( Catch::cout().rdbuf() )
3185  {
3186  if( !data.testsOrTags.empty() ) {
3187  TestSpecParser parser( ITagAliasRegistry::get() );
3188  for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )
3189  parser.parse( data.testsOrTags[i] );
3190  m_testSpec = parser.testSpec();
3191  }
3192  }
3193 
3194  virtual ~Config() {
3195  m_os.rdbuf( Catch::cout().rdbuf() );
3196  m_stream.release();
3197  }
3198 
3199  void setFilename( std::string const& filename ) {
3200  m_data.outputFilename = filename;
3201  }
3202 
3203  std::string const& getFilename() const {
3204  return m_data.outputFilename ;
3205  }
3206 
3207  bool listTests() const { return m_data.listTests; }
3208  bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }
3209  bool listTags() const { return m_data.listTags; }
3210  bool listReporters() const { return m_data.listReporters; }
3211 
3212  std::string getProcessName() const { return m_data.processName; }
3213 
3214  bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }
3215 
3216  void setStreamBuf( std::streambuf* buf ) {
3217  m_os.rdbuf( buf ? buf : Catch::cout().rdbuf() );
3218  }
3219 
3220  void useStream( std::string const& streamName ) {
3221  Stream stream = createStream( streamName );
3222  setStreamBuf( stream.streamBuf );
3223  m_stream.release();
3224  m_stream = stream;
3225  }
3226 
3227  std::string getReporterName() const { return m_data.reporterName; }
3228 
3229  int abortAfter() const { return m_data.abortAfter; }
3230 
3231  TestSpec const& testSpec() const { return m_testSpec; }
3232 
3233  bool showHelp() const { return m_data.showHelp; }
3234  bool showInvisibles() const { return m_data.showInvisibles; }
3235 
3236  // IConfig interface
3237  virtual bool allowThrows() const { return !m_data.noThrow; }
3238  virtual std::ostream& stream() const { return m_os; }
3239  virtual std::string name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
3240  virtual bool includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
3241  virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
3242  virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }
3243  virtual RunTests::InWhatOrder runOrder() const { return m_data.runOrder; }
3244  virtual unsigned int rngSeed() const { return m_data.rngSeed; }
3245  virtual bool forceColour() const { return m_data.forceColour; }
3246 
3247  private:
3248  ConfigData m_data;
3249 
3250  Stream m_stream;
3251  mutable std::ostream m_os;
3252  TestSpec m_testSpec;
3253  };
3254 
3255 } // end namespace Catch
3256 
3257 // #included from: catch_clara.h
3258 #define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED
3259 
3260 // Use Catch's value for console width (store Clara's off to the side, if present)
3261 #ifdef CLARA_CONFIG_CONSOLE_WIDTH
3262 #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH
3263 #undef CLARA_CONFIG_CONSOLE_WIDTH
3264 #endif
3265 #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
3266 
3267 // Declare Clara inside the Catch namespace
3268 #define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {
3269 // #included from: ../external/clara.h
3270 
3271 // Only use header guard if we are not using an outer namespace
3272 #if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
3273 
3274 #ifndef STITCH_CLARA_OPEN_NAMESPACE
3275 #define TWOBLUECUBES_CLARA_H_INCLUDED
3276 #define STITCH_CLARA_OPEN_NAMESPACE
3277 #define STITCH_CLARA_CLOSE_NAMESPACE
3278 #else
3279 #define STITCH_CLARA_CLOSE_NAMESPACE }
3280 #endif
3281 
3282 #define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE
3283 
3284 // ----------- #included from tbc_text_format.h -----------
3285 
3286 // Only use header guard if we are not using an outer namespace
3287 #if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE)
3288 #ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
3289 #define TBC_TEXT_FORMAT_H_INCLUDED
3290 #endif
3291 
3292 #include <string>
3293 #include <vector>
3294 #include <sstream>
3295 
3296 // Use optional outer namespace
3297 #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
3298 namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
3299 #endif
3300 
3301 namespace Tbc {
3302 
3303 #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
3304  const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
3305 #else
3306  const unsigned int consoleWidth = 80;
3307 #endif
3308 
3309  struct TextAttributes {
3310  TextAttributes()
3311  : initialIndent( std::string::npos ),
3312  indent( 0 ),
3313  width( consoleWidth-1 ),
3314  tabChar( '\t' )
3315  {}
3316 
3317  TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
3318  TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
3319  TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
3320  TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; }
3321 
3322  std::size_t initialIndent; // indent of first line, or npos
3323  std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos
3324  std::size_t width; // maximum width of text, including indent. Longer text will wrap
3325  char tabChar; // If this char is seen the indent is changed to current pos
3326  };
3327 
3328  class Text {
3329  public:
3330  Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
3331  : attr( _attr )
3332  {
3333  std::string wrappableChars = " [({.,/|\\-";
3334  std::size_t indent = _attr.initialIndent != std::string::npos
3335  ? _attr.initialIndent
3336  : _attr.indent;
3337  std::string remainder = _str;
3338 
3339  while( !remainder.empty() ) {
3340  if( lines.size() >= 1000 ) {
3341  lines.push_back( "... message truncated due to excessive size" );
3342  return;
3343  }
3344  std::size_t tabPos = std::string::npos;
3345  std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
3346  std::size_t pos = remainder.find_first_of( '\n' );
3347  if( pos <= width ) {
3348  width = pos;
3349  }
3350  pos = remainder.find_last_of( _attr.tabChar, width );
3351  if( pos != std::string::npos ) {
3352  tabPos = pos;
3353  if( remainder[width] == '\n' )
3354  width--;
3355  remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
3356  }
3357 
3358  if( width == remainder.size() ) {
3359  spliceLine( indent, remainder, width );
3360  }
3361  else if( remainder[width] == '\n' ) {
3362  spliceLine( indent, remainder, width );
3363  if( width <= 1 || remainder.size() != 1 )
3364  remainder = remainder.substr( 1 );
3365  indent = _attr.indent;
3366  }
3367  else {
3368  pos = remainder.find_last_of( wrappableChars, width );
3369  if( pos != std::string::npos && pos > 0 ) {
3370  spliceLine( indent, remainder, pos );
3371  if( remainder[0] == ' ' )
3372  remainder = remainder.substr( 1 );
3373  }
3374  else {
3375  spliceLine( indent, remainder, width-1 );
3376  lines.back() += "-";
3377  }
3378  if( lines.size() == 1 )
3379  indent = _attr.indent;
3380  if( tabPos != std::string::npos )
3381  indent += tabPos;
3382  }
3383  }
3384  }
3385 
3386  void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
3387  lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
3388  _remainder = _remainder.substr( _pos );
3389  }
3390 
3391  typedef std::vector<std::string>::const_iterator const_iterator;
3392 
3393  const_iterator begin() const { return lines.begin(); }
3394  const_iterator end() const { return lines.end(); }
3395  std::string const& last() const { return lines.back(); }
3396  std::size_t size() const { return lines.size(); }
3397  std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
3398  std::string toString() const {
3399  std::ostringstream oss;
3400  oss << *this;
3401  return oss.str();
3402  }
3403 
3404  inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
3405  for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
3406  it != itEnd; ++it ) {
3407  if( it != _text.begin() )
3408  _stream << "\n";
3409  _stream << *it;
3410  }
3411  return _stream;
3412  }
3413 
3414  private:
3415  std::string str;
3416  TextAttributes attr;
3417  std::vector<std::string> lines;
3418  };
3419 
3420 } // end namespace Tbc
3421 
3422 #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
3423 } // end outer namespace
3424 #endif
3425 
3426 #endif // TBC_TEXT_FORMAT_H_INCLUDED
3427 
3428 // ----------- end of #include from tbc_text_format.h -----------
3429 // ........... back in /Users/philnash/Dev/OSS/Clara/srcs/clara.h
3430 
3431 #undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE
3432 
3433 #include <map>
3434 #include <algorithm>
3435 #include <stdexcept>
3436 #include <memory>
3437 
3438 // Use optional outer namespace
3439 #ifdef STITCH_CLARA_OPEN_NAMESPACE
3440 STITCH_CLARA_OPEN_NAMESPACE
3441 #endif
3442 
3443 namespace Clara {
3444 
3445  struct UnpositionalTag {};
3446 
3447  extern UnpositionalTag _;
3448 
3449 #ifdef CLARA_CONFIG_MAIN
3450  UnpositionalTag _;
3451 #endif
3452 
3453  namespace Detail {
3454 
3455 #ifdef CLARA_CONSOLE_WIDTH
3456  const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
3457 #else
3458  const unsigned int consoleWidth = 80;
3459 #endif
3460 
3461  using namespace Tbc;
3462 
3463  inline bool startsWith( std::string const& str, std::string const& prefix ) {
3464  return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;
3465  }
3466 
3467  template<typename T> struct RemoveConstRef{ typedef T type; };
3468  template<typename T> struct RemoveConstRef<T&>{ typedef T type; };
3469  template<typename T> struct RemoveConstRef<T const&>{ typedef T type; };
3470  template<typename T> struct RemoveConstRef<T const>{ typedef T type; };
3471 
3472  template<typename T> struct IsBool { static const bool value = false; };
3473  template<> struct IsBool<bool> { static const bool value = true; };
3474 
3475  template<typename T>
3476  void convertInto( std::string const& _source, T& _dest ) {
3477  std::stringstream ss;
3478  ss << _source;
3479  ss >> _dest;
3480  if( ss.fail() )
3481  throw std::runtime_error( "Unable to convert " + _source + " to destination type" );
3482  }
3483  inline void convertInto( std::string const& _source, std::string& _dest ) {
3484  _dest = _source;
3485  }
3486  inline void convertInto( std::string const& _source, bool& _dest ) {
3487  std::string sourceLC = _source;
3488  std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), ::tolower );
3489  if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" )
3490  _dest = true;
3491  else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" )
3492  _dest = false;
3493  else
3494  throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" );
3495  }
3496  inline void convertInto( bool _source, bool& _dest ) {
3497  _dest = _source;
3498  }
3499  template<typename T>
3500  inline void convertInto( bool, T& ) {
3501  throw std::runtime_error( "Invalid conversion" );
3502  }
3503 
3504  template<typename ConfigT>
3505  struct IArgFunction {
3506  virtual ~IArgFunction() {}
3507 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
3508  IArgFunction() = default;
3509  IArgFunction( IArgFunction const& ) = default;
3510 # endif
3511  virtual void set( ConfigT& config, std::string const& value ) const = 0;
3512  virtual void setFlag( ConfigT& config ) const = 0;
3513  virtual bool takesArg() const = 0;
3514  virtual IArgFunction* clone() const = 0;
3515  };
3516 
3517  template<typename ConfigT>
3518  class BoundArgFunction {
3519  public:
3520  BoundArgFunction() : functionObj( NULL ) {}
3521  BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
3522  BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : NULL ) {}
3523  BoundArgFunction& operator = ( BoundArgFunction const& other ) {
3524  IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : NULL;
3525  delete functionObj;
3526  functionObj = newFunctionObj;
3527  return *this;
3528  }
3529  ~BoundArgFunction() { delete functionObj; }
3530 
3531  void set( ConfigT& config, std::string const& value ) const {
3532  functionObj->set( config, value );
3533  }
3534  void setFlag( ConfigT& config ) const {
3535  functionObj->setFlag( config );
3536  }
3537  bool takesArg() const { return functionObj->takesArg(); }
3538 
3539  bool isSet() const {
3540  return functionObj != NULL;
3541  }
3542  private:
3543  IArgFunction<ConfigT>* functionObj;
3544  };
3545 
3546  template<typename C>
3547  struct NullBinder : IArgFunction<C>{
3548  virtual void set( C&, std::string const& ) const {}
3549  virtual void setFlag( C& ) const {}
3550  virtual bool takesArg() const { return true; }
3551  virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }
3552  };
3553 
3554  template<typename C, typename M>
3555  struct BoundDataMember : IArgFunction<C>{
3556  BoundDataMember( M C::* _member ) : member( _member ) {}
3557  virtual void set( C& p, std::string const& stringValue ) const {
3558  convertInto( stringValue, p.*member );
3559  }
3560  virtual void setFlag( C& p ) const {
3561  convertInto( true, p.*member );
3562  }
3563  virtual bool takesArg() const { return !IsBool<M>::value; }
3564  virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }
3565  M C::* member;
3566  };
3567  template<typename C, typename M>
3568  struct BoundUnaryMethod : IArgFunction<C>{
3569  BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {}
3570  virtual void set( C& p, std::string const& stringValue ) const {
3571  typename RemoveConstRef<M>::type value;
3572  convertInto( stringValue, value );
3573  (p.*member)( value );
3574  }
3575  virtual void setFlag( C& p ) const {
3576  typename RemoveConstRef<M>::type value;
3577  convertInto( true, value );
3578  (p.*member)( value );
3579  }
3580  virtual bool takesArg() const { return !IsBool<M>::value; }
3581  virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }
3582  void (C::*member)( M );
3583  };
3584  template<typename C>
3585  struct BoundNullaryMethod : IArgFunction<C>{
3586  BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {}
3587  virtual void set( C& p, std::string const& stringValue ) const {
3588  bool value;
3589  convertInto( stringValue, value );
3590  if( value )
3591  (p.*member)();
3592  }
3593  virtual void setFlag( C& p ) const {
3594  (p.*member)();
3595  }
3596  virtual bool takesArg() const { return false; }
3597  virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }
3598  void (C::*member)();
3599  };
3600 
3601  template<typename C>
3602  struct BoundUnaryFunction : IArgFunction<C>{
3603  BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {}
3604  virtual void set( C& obj, std::string const& stringValue ) const {
3605  bool value;
3606  convertInto( stringValue, value );
3607  if( value )
3608  function( obj );
3609  }
3610  virtual void setFlag( C& p ) const {
3611  function( p );
3612  }
3613  virtual bool takesArg() const { return false; }
3614  virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }
3615  void (*function)( C& );
3616  };
3617 
3618  template<typename C, typename T>
3619  struct BoundBinaryFunction : IArgFunction<C>{
3620  BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {}
3621  virtual void set( C& obj, std::string const& stringValue ) const {
3622  typename RemoveConstRef<T>::type value;
3623  convertInto( stringValue, value );
3624  function( obj, value );
3625  }
3626  virtual void setFlag( C& obj ) const {
3627  typename RemoveConstRef<T>::type value;
3628  convertInto( true, value );
3629  function( obj, value );
3630  }
3631  virtual bool takesArg() const { return !IsBool<T>::value; }
3632  virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }
3633  void (*function)( C&, T );
3634  };
3635 
3636  } // namespace Detail
3637 
3638  struct Parser {
3639  Parser() : separators( " \t=:" ) {}
3640 
3641  struct Token {
3642  enum Type { Positional, ShortOpt, LongOpt };
3643  Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {}
3644  Type type;
3645  std::string data;
3646  };
3647 
3648  void parseIntoTokens( int argc, char const * const * argv, std::vector<Parser::Token>& tokens ) const {
3649  const std::string doubleDash = "--";
3650  for( int i = 1; i < argc && argv[i] != doubleDash; ++i )
3651  parseIntoTokens( argv[i] , tokens);
3652  }
3653  void parseIntoTokens( std::string arg, std::vector<Parser::Token>& tokens ) const {
3654  while( !arg.empty() ) {
3655  Parser::Token token( Parser::Token::Positional, arg );
3656  arg = "";
3657  if( token.data[0] == '-' ) {
3658  if( token.data.size() > 1 && token.data[1] == '-' ) {
3659  token = Parser::Token( Parser::Token::LongOpt, token.data.substr( 2 ) );
3660  }
3661  else {
3662  token = Parser::Token( Parser::Token::ShortOpt, token.data.substr( 1 ) );
3663  if( token.data.size() > 1 && separators.find( token.data[1] ) == std::string::npos ) {
3664  arg = "-" + token.data.substr( 1 );
3665  token.data = token.data.substr( 0, 1 );
3666  }
3667  }
3668  }
3669  if( token.type != Parser::Token::Positional ) {
3670  std::size_t pos = token.data.find_first_of( separators );
3671  if( pos != std::string::npos ) {
3672  arg = token.data.substr( pos+1 );
3673  token.data = token.data.substr( 0, pos );
3674  }
3675  }
3676  tokens.push_back( token );
3677  }
3678  }
3679  std::string separators;
3680  };
3681 
3682  template<typename ConfigT>
3683  struct CommonArgProperties {
3684  CommonArgProperties() {}
3685  CommonArgProperties( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ) {}
3686 
3687  Detail::BoundArgFunction<ConfigT> boundField;
3688  std::string description;
3689  std::string detail;
3690  std::string placeholder; // Only value if boundField takes an arg
3691 
3692  bool takesArg() const {
3693  return !placeholder.empty();
3694  }
3695  void validate() const {
3696  if( !boundField.isSet() )
3697  throw std::logic_error( "option not bound" );
3698  }
3699  };
3700  struct OptionArgProperties {
3701  std::vector<std::string> shortNames;
3702  std::string longName;
3703 
3704  bool hasShortName( std::string const& shortName ) const {
3705  return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end();
3706  }
3707  bool hasLongName( std::string const& _longName ) const {
3708  return _longName == longName;
3709  }
3710  };
3711  struct PositionalArgProperties {
3712  PositionalArgProperties() : position( -1 ) {}
3713  int position; // -1 means non-positional (floating)
3714 
3715  bool isFixedPositional() const {
3716  return position != -1;
3717  }
3718  };
3719 
3720  template<typename ConfigT>
3721  class CommandLine {
3722 
3723  struct Arg : CommonArgProperties<ConfigT>, OptionArgProperties, PositionalArgProperties {
3724  Arg() {}
3725  Arg( Detail::BoundArgFunction<ConfigT> const& _boundField ) : CommonArgProperties<ConfigT>( _boundField ) {}
3726 
3727  using CommonArgProperties<ConfigT>::placeholder; // !TBD
3728 
3729  std::string dbgName() const {
3730  if( !longName.empty() )
3731  return "--" + longName;
3732  if( !shortNames.empty() )
3733  return "-" + shortNames[0];
3734  return "positional args";
3735  }
3736  std::string commands() const {
3737  std::ostringstream oss;
3738  bool first = true;
3739  std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();
3740  for(; it != itEnd; ++it ) {
3741  if( first )
3742  first = false;
3743  else
3744  oss << ", ";
3745  oss << "-" << *it;
3746  }
3747  if( !longName.empty() ) {
3748  if( !first )
3749  oss << ", ";
3750  oss << "--" << longName;
3751  }
3752  if( !placeholder.empty() )
3753  oss << " <" << placeholder << ">";
3754  return oss.str();
3755  }
3756  };
3757 
3758  // NOTE: std::auto_ptr is deprecated in c++11/c++0x
3759 #if defined(__cplusplus) && __cplusplus > 199711L
3760  typedef std::unique_ptr<Arg> ArgAutoPtr;
3761 #else
3762  typedef std::auto_ptr<Arg> ArgAutoPtr;
3763 #endif
3764 
3765  friend void addOptName( Arg& arg, std::string const& optName )
3766  {
3767  if( optName.empty() )
3768  return;
3769  if( Detail::startsWith( optName, "--" ) ) {
3770  if( !arg.longName.empty() )
3771  throw std::logic_error( "Only one long opt may be specified. '"
3772  + arg.longName
3773  + "' already specified, now attempting to add '"
3774  + optName + "'" );
3775  arg.longName = optName.substr( 2 );
3776  }
3777  else if( Detail::startsWith( optName, "-" ) )
3778  arg.shortNames.push_back( optName.substr( 1 ) );
3779  else
3780  throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" );
3781  }
3782  friend void setPositionalArg( Arg& arg, int position )
3783  {
3784  arg.position = position;
3785  }
3786 
3787  class ArgBuilder {
3788  public:
3789  ArgBuilder( Arg* arg ) : m_arg( arg ) {}
3790 
3791  // Bind a non-boolean data member (requires placeholder string)
3792  template<typename C, typename M>
3793  void bind( M C::* field, std::string const& placeholder ) {
3794  m_arg->boundField = new Detail::BoundDataMember<C,M>( field );
3795  m_arg->placeholder = placeholder;
3796  }
3797  // Bind a boolean data member (no placeholder required)
3798  template<typename C>
3799  void bind( bool C::* field ) {
3800  m_arg->boundField = new Detail::BoundDataMember<C,bool>( field );
3801  }
3802 
3803  // Bind a method taking a single, non-boolean argument (requires a placeholder string)
3804  template<typename C, typename M>
3805  void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) {
3806  m_arg->boundField = new Detail::BoundUnaryMethod<C,M>( unaryMethod );
3807  m_arg->placeholder = placeholder;
3808  }
3809 
3810  // Bind a method taking a single, boolean argument (no placeholder string required)
3811  template<typename C>
3812  void bind( void (C::* unaryMethod)( bool ) ) {
3813  m_arg->boundField = new Detail::BoundUnaryMethod<C,bool>( unaryMethod );
3814  }
3815 
3816  // Bind a method that takes no arguments (will be called if opt is present)
3817  template<typename C>
3818  void bind( void (C::* nullaryMethod)() ) {
3819  m_arg->boundField = new Detail::BoundNullaryMethod<C>( nullaryMethod );
3820  }
3821 
3822  // Bind a free function taking a single argument - the object to operate on (no placeholder string required)
3823  template<typename C>
3824  void bind( void (* unaryFunction)( C& ) ) {
3825  m_arg->boundField = new Detail::BoundUnaryFunction<C>( unaryFunction );
3826  }
3827 
3828  // Bind a free function taking a single argument - the object to operate on (requires a placeholder string)
3829  template<typename C, typename T>
3830  void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) {
3831  m_arg->boundField = new Detail::BoundBinaryFunction<C, T>( binaryFunction );
3832  m_arg->placeholder = placeholder;
3833  }
3834 
3835  ArgBuilder& describe( std::string const& description ) {
3836  m_arg->description = description;
3837  return *this;
3838  }
3839  ArgBuilder& detail( std::string const& detail ) {
3840  m_arg->detail = detail;
3841  return *this;
3842  }
3843 
3844  protected:
3845  Arg* m_arg;
3846  };
3847 
3848  class OptBuilder : public ArgBuilder {
3849  public:
3850  OptBuilder( Arg* arg ) : ArgBuilder( arg ) {}
3851  OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {}
3852 
3853  OptBuilder& operator[]( std::string const& optName ) {
3854  addOptName( *ArgBuilder::m_arg, optName );
3855  return *this;
3856  }
3857  };
3858 
3859  public:
3860 
3861  CommandLine()
3862  : m_boundProcessName( new Detail::NullBinder<ConfigT>() ),
3863  m_highestSpecifiedArgPosition( 0 ),
3864  m_throwOnUnrecognisedTokens( false )
3865  {}
3866  CommandLine( CommandLine const& other )
3867  : m_boundProcessName( other.m_boundProcessName ),
3868  m_options ( other.m_options ),
3869  m_positionalArgs( other.m_positionalArgs ),
3870  m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ),
3871  m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens )
3872  {
3873  if( other.m_floatingArg.get() )
3874  m_floatingArg.reset( new Arg( *other.m_floatingArg ) );
3875  }
3876 
3877  CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) {
3878  m_throwOnUnrecognisedTokens = shouldThrow;
3879  return *this;
3880  }
3881 
3882  OptBuilder operator[]( std::string const& optName ) {
3883  m_options.push_back( Arg() );
3884  addOptName( m_options.back(), optName );
3885  OptBuilder builder( &m_options.back() );
3886  return builder;
3887  }
3888 
3889  ArgBuilder operator[]( int position ) {
3890  m_positionalArgs.insert( std::make_pair( position, Arg() ) );
3891  if( position > m_highestSpecifiedArgPosition )
3892  m_highestSpecifiedArgPosition = position;
3893  setPositionalArg( m_positionalArgs[position], position );
3894  ArgBuilder builder( &m_positionalArgs[position] );
3895  return builder;
3896  }
3897 
3898  // Invoke this with the _ instance
3899  ArgBuilder operator[]( UnpositionalTag ) {
3900  if( m_floatingArg.get() )
3901  throw std::logic_error( "Only one unpositional argument can be added" );
3902  m_floatingArg.reset( new Arg() );
3903  ArgBuilder builder( m_floatingArg.get() );
3904  return builder;
3905  }
3906 
3907  template<typename C, typename M>
3908  void bindProcessName( M C::* field ) {
3909  m_boundProcessName = new Detail::BoundDataMember<C,M>( field );
3910  }
3911  template<typename C, typename M>
3912  void bindProcessName( void (C::*_unaryMethod)( M ) ) {
3913  m_boundProcessName = new Detail::BoundUnaryMethod<C,M>( _unaryMethod );
3914  }
3915 
3916  void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const {
3917  typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;
3918  std::size_t maxWidth = 0;
3919  for( it = itBegin; it != itEnd; ++it )
3920  maxWidth = (std::max)( maxWidth, it->commands().size() );
3921 
3922  for( it = itBegin; it != itEnd; ++it ) {
3923  Detail::Text usage( it->commands(), Detail::TextAttributes()
3924  .setWidth( maxWidth+indent )
3925  .setIndent( indent ) );
3926  Detail::Text desc( it->description, Detail::TextAttributes()
3927  .setWidth( width - maxWidth - 3 ) );
3928 
3929  for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) {
3930  std::string usageCol = i < usage.size() ? usage[i] : "";
3931  os << usageCol;
3932 
3933  if( i < desc.size() && !desc[i].empty() )
3934  os << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' )
3935  << desc[i];
3936  os << "\n";
3937  }
3938  }
3939  }
3940  std::string optUsage() const {
3941  std::ostringstream oss;
3942  optUsage( oss );
3943  return oss.str();
3944  }
3945 
3946  void argSynopsis( std::ostream& os ) const {
3947  for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {
3948  if( i > 1 )
3949  os << " ";
3950  typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
3951  if( it != m_positionalArgs.end() )
3952  os << "<" << it->second.placeholder << ">";
3953  else if( m_floatingArg.get() )
3954  os << "<" << m_floatingArg->placeholder << ">";
3955  else
3956  throw std::logic_error( "non consecutive positional arguments with no floating args" );
3957  }
3958  // !TBD No indication of mandatory args
3959  if( m_floatingArg.get() ) {
3960  if( m_highestSpecifiedArgPosition > 1 )
3961  os << " ";
3962  os << "[<" << m_floatingArg->placeholder << "> ...]";
3963  }
3964  }
3965  std::string argSynopsis() const {
3966  std::ostringstream oss;
3967  argSynopsis( oss );
3968  return oss.str();
3969  }
3970 
3971  void usage( std::ostream& os, std::string const& procName ) const {
3972  validate();
3973  os << "usage:\n " << procName << " ";
3974  argSynopsis( os );
3975  if( !m_options.empty() ) {
3976  os << " [options]\n\nwhere options are: \n";
3977  optUsage( os, 2 );
3978  }
3979  os << "\n";
3980  }
3981  std::string usage( std::string const& procName ) const {
3982  std::ostringstream oss;
3983  usage( oss, procName );
3984  return oss.str();
3985  }
3986 
3987  ConfigT parse( int argc, char const * const * argv ) const {
3988  ConfigT config;
3989  parseInto( argc, argv, config );
3990  return config;
3991  }
3992 
3993  std::vector<Parser::Token> parseInto( int argc, char const * const * argv, ConfigT& config ) const {
3994  std::string processName = argv[0];
3995  std::size_t lastSlash = processName.find_last_of( "/\\" );
3996  if( lastSlash != std::string::npos )
3997  processName = processName.substr( lastSlash+1 );
3998  m_boundProcessName.set( config, processName );
3999  std::vector<Parser::Token> tokens;
4000  Parser parser;
4001  parser.parseIntoTokens( argc, argv, tokens );
4002  return populate( tokens, config );
4003  }
4004 
4005  std::vector<Parser::Token> populate( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
4006  validate();
4007  std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config );
4008  unusedTokens = populateFixedArgs( unusedTokens, config );
4009  unusedTokens = populateFloatingArgs( unusedTokens, config );
4010  return unusedTokens;
4011  }
4012 
4013  std::vector<Parser::Token> populateOptions( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
4014  std::vector<Parser::Token> unusedTokens;
4015  std::vector<std::string> errors;
4016  for( std::size_t i = 0; i < tokens.size(); ++i ) {
4017  Parser::Token const& token = tokens[i];
4018  typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();
4019  for(; it != itEnd; ++it ) {
4020  Arg const& arg = *it;
4021 
4022  try {
4023  if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||
4024  ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {
4025  if( arg.takesArg() ) {
4026  if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional )
4027  errors.push_back( "Expected argument to option: " + token.data );
4028  else
4029  arg.boundField.set( config, tokens[++i].data );
4030  }
4031  else {
4032  arg.boundField.setFlag( config );
4033  }
4034  break;
4035  }
4036  }
4037  catch( std::exception& ex ) {
4038  errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" );
4039  }
4040  }
4041  if( it == itEnd ) {
4042  if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens )
4043  unusedTokens.push_back( token );
4044  else if( errors.empty() && m_throwOnUnrecognisedTokens )
4045  errors.push_back( "unrecognised option: " + token.data );
4046  }
4047  }
4048  if( !errors.empty() ) {
4049  std::ostringstream oss;
4050  for( std::vector<std::string>::const_iterator it = errors.begin(), itEnd = errors.end();
4051  it != itEnd;
4052  ++it ) {
4053  if( it != errors.begin() )
4054  oss << "\n";
4055  oss << *it;
4056  }
4057  throw std::runtime_error( oss.str() );
4058  }
4059  return unusedTokens;
4060  }
4061  std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
4062  std::vector<Parser::Token> unusedTokens;
4063  int position = 1;
4064  for( std::size_t i = 0; i < tokens.size(); ++i ) {
4065  Parser::Token const& token = tokens[i];
4066  typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );
4067  if( it != m_positionalArgs.end() )
4068  it->second.boundField.set( config, token.data );
4069  else
4070  unusedTokens.push_back( token );
4071  if( token.type == Parser::Token::Positional )
4072  position++;
4073  }
4074  return unusedTokens;
4075  }
4076  std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
4077  if( !m_floatingArg.get() )
4078  return tokens;
4079  std::vector<Parser::Token> unusedTokens;
4080  for( std::size_t i = 0; i < tokens.size(); ++i ) {
4081  Parser::Token const& token = tokens[i];
4082  if( token.type == Parser::Token::Positional )
4083  m_floatingArg->boundField.set( config, token.data );
4084  else
4085  unusedTokens.push_back( token );
4086  }
4087  return unusedTokens;
4088  }
4089 
4090  void validate() const
4091  {
4092  if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() )
4093  throw std::logic_error( "No options or arguments specified" );
4094 
4095  for( typename std::vector<Arg>::const_iterator it = m_options.begin(),
4096  itEnd = m_options.end();
4097  it != itEnd; ++it )
4098  it->validate();
4099  }
4100 
4101  private:
4102  Detail::BoundArgFunction<ConfigT> m_boundProcessName;
4103  std::vector<Arg> m_options;
4104  std::map<int, Arg> m_positionalArgs;
4105  ArgAutoPtr m_floatingArg;
4106  int m_highestSpecifiedArgPosition;
4107  bool m_throwOnUnrecognisedTokens;
4108  };
4109 
4110 } // end namespace Clara
4111 
4112 STITCH_CLARA_CLOSE_NAMESPACE
4113 #undef STITCH_CLARA_OPEN_NAMESPACE
4114 #undef STITCH_CLARA_CLOSE_NAMESPACE
4115 
4116 #endif // TWOBLUECUBES_CLARA_H_INCLUDED
4117 #undef STITCH_CLARA_OPEN_NAMESPACE
4118 
4119 // Restore Clara's value for console width, if present
4120 #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
4121 #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
4122 #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
4123 #endif
4124 
4125 #include <fstream>
4126 
4127 namespace Catch {
4128 
4129  inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }
4130  inline void abortAfterX( ConfigData& config, int x ) {
4131  if( x < 1 )
4132  throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" );
4133  config.abortAfter = x;
4134  }
4135  inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
4136 
4137  inline void addWarning( ConfigData& config, std::string const& _warning ) {
4138  if( _warning == "NoAssertions" )
4139  config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );
4140  else
4141  throw std::runtime_error( "Unrecognised warning: '" + _warning + "'" );
4142  }
4143  inline void setOrder( ConfigData& config, std::string const& order ) {
4144  if( startsWith( "declared", order ) )
4145  config.runOrder = RunTests::InDeclarationOrder;
4146  else if( startsWith( "lexical", order ) )
4147  config.runOrder = RunTests::InLexicographicalOrder;
4148  else if( startsWith( "random", order ) )
4149  config.runOrder = RunTests::InRandomOrder;
4150  else
4151  throw std::runtime_error( "Unrecognised ordering: '" + order + "'" );
4152  }
4153  inline void setRngSeed( ConfigData& config, std::string const& seed ) {
4154  if( seed == "time" ) {
4155  config.rngSeed = static_cast<unsigned int>( std::time(0) );
4156  }
4157  else {
4158  std::stringstream ss;
4159  ss << seed;
4160  ss >> config.rngSeed;
4161  if( ss.fail() )
4162  throw std::runtime_error( "Argment to --rng-seed should be the word 'time' or a number" );
4163  }
4164  }
4165  inline void setVerbosity( ConfigData& config, int level ) {
4166  // !TBD: accept strings?
4167  config.verbosity = static_cast<Verbosity::Level>( level );
4168  }
4169  inline void setShowDurations( ConfigData& config, bool _showDurations ) {
4170  config.showDurations = _showDurations
4171  ? ShowDurations::Always
4172  : ShowDurations::Never;
4173  }
4174  inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {
4175  std::ifstream f( _filename.c_str() );
4176  if( !f.is_open() )
4177  throw std::domain_error( "Unable to load input file: " + _filename );
4178 
4179  std::string line;
4180  while( std::getline( f, line ) ) {
4181  line = trim(line);
4182  if( !line.empty() && !startsWith( line, "#" ) )
4183  addTestOrTags( config, "\"" + line + "\"," );
4184  }
4185  }
4186 
4187  inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
4188 
4189  using namespace Clara;
4190  CommandLine<ConfigData> cli;
4191 
4192  cli.bindProcessName( &ConfigData::processName );
4193 
4194  cli["-?"]["-h"]["--help"]
4195  .describe( "display usage information" )
4196  .bind( &ConfigData::showHelp );
4197 
4198  cli["-l"]["--list-tests"]
4199  .describe( "list all/matching test cases" )
4200  .bind( &ConfigData::listTests );
4201 
4202  cli["-t"]["--list-tags"]
4203  .describe( "list all/matching tags" )
4204  .bind( &ConfigData::listTags );
4205 
4206  cli["-s"]["--success"]
4207  .describe( "include successful tests in output" )
4208  .bind( &ConfigData::showSuccessfulTests );
4209 
4210  cli["-b"]["--break"]
4211  .describe( "break into debugger on failure" )
4212  .bind( &ConfigData::shouldDebugBreak );
4213 
4214  cli["-e"]["--nothrow"]
4215  .describe( "skip exception tests" )
4216  .bind( &ConfigData::noThrow );
4217 
4218  cli["-i"]["--invisibles"]
4219  .describe( "show invisibles (tabs, newlines)" )
4220  .bind( &ConfigData::showInvisibles );
4221 
4222  cli["-o"]["--out"]
4223  .describe( "output filename" )
4224  .bind( &ConfigData::outputFilename, "filename" );
4225 
4226  cli["-r"]["--reporter"]
4227 // .placeholder( "name[:filename]" )
4228  .describe( "reporter to use (defaults to console)" )
4229  .bind( &ConfigData::reporterName, "name" );
4230 
4231  cli["-n"]["--name"]
4232  .describe( "suite name" )
4233  .bind( &ConfigData::name, "name" );
4234 
4235  cli["-a"]["--abort"]
4236  .describe( "abort at first failure" )
4237  .bind( &abortAfterFirst );
4238 
4239  cli["-x"]["--abortx"]
4240  .describe( "abort after x failures" )
4241  .bind( &abortAfterX, "no. failures" );
4242 
4243  cli["-w"]["--warn"]
4244  .describe( "enable warnings" )
4245  .bind( &addWarning, "warning name" );
4246 
4247 // - needs updating if reinstated
4248 // cli.into( &setVerbosity )
4249 // .describe( "level of verbosity (0=no output)" )
4250 // .shortOpt( "v")
4251 // .longOpt( "verbosity" )
4252 // .placeholder( "level" );
4253 
4254  cli[_]
4255  .describe( "which test or tests to use" )
4256  .bind( &addTestOrTags, "test name, pattern or tags" );
4257 
4258  cli["-d"]["--durations"]
4259  .describe( "show test durations" )
4260  .bind( &setShowDurations, "yes/no" );
4261 
4262  cli["-f"]["--input-file"]
4263  .describe( "load test names to run from a file" )
4264  .bind( &loadTestNamesFromFile, "filename" );
4265 
4266  // Less common commands which don't have a short form
4267  cli["--list-test-names-only"]
4268  .describe( "list all/matching test cases names only" )
4269  .bind( &ConfigData::listTestNamesOnly );
4270 
4271  cli["--list-reporters"]
4272  .describe( "list all reporters" )
4273  .bind( &ConfigData::listReporters );
4274 
4275  cli["--order"]
4276  .describe( "test case order (defaults to decl)" )
4277  .bind( &setOrder, "decl|lex|rand" );
4278 
4279  cli["--rng-seed"]
4280  .describe( "set a specific seed for random numbers" )
4281  .bind( &setRngSeed, "'time'|number" );
4282 
4283  cli["--force-colour"]
4284  .describe( "force colourised output" )
4285  .bind( &ConfigData::forceColour );
4286 
4287  return cli;
4288  }
4289 
4290 } // end namespace Catch
4291 
4292 // #included from: internal/catch_list.hpp
4293 #define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED
4294 
4295 // #included from: catch_text.h
4296 #define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED
4297 
4298 #define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
4299 
4300 #define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch
4301 // #included from: ../external/tbc_text_format.h
4302 // Only use header guard if we are not using an outer namespace
4303 #ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
4304 # ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
4305 # ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
4306 # define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
4307 # endif
4308 # else
4309 # define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
4310 # endif
4311 #endif
4312 #ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
4313 #include <string>
4314 #include <vector>
4315 #include <sstream>
4316 
4317 // Use optional outer namespace
4318 #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
4319 namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
4320 #endif
4321 
4322 namespace Tbc {
4323 
4324 #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
4325  const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
4326 #else
4327  const unsigned int consoleWidth = 80;
4328 #endif
4329 
4330  struct TextAttributes {
4331  TextAttributes()
4332  : initialIndent( std::string::npos ),
4333  indent( 0 ),
4334  width( consoleWidth-1 ),
4335  tabChar( '\t' )
4336  {}
4337 
4338  TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
4339  TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
4340  TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
4341  TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; }
4342 
4343  std::size_t initialIndent; // indent of first line, or npos
4344  std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos
4345  std::size_t width; // maximum width of text, including indent. Longer text will wrap
4346  char tabChar; // If this char is seen the indent is changed to current pos
4347  };
4348 
4349  class Text {
4350  public:
4351  Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
4352  : attr( _attr )
4353  {
4354  std::string wrappableChars = " [({.,/|\\-";
4355  std::size_t indent = _attr.initialIndent != std::string::npos
4356  ? _attr.initialIndent
4357  : _attr.indent;
4358  std::string remainder = _str;
4359 
4360  while( !remainder.empty() ) {
4361  if( lines.size() >= 1000 ) {
4362  lines.push_back( "... message truncated due to excessive size" );
4363  return;
4364  }
4365  std::size_t tabPos = std::string::npos;
4366  std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
4367  std::size_t pos = remainder.find_first_of( '\n' );
4368  if( pos <= width ) {
4369  width = pos;
4370  }
4371  pos = remainder.find_last_of( _attr.tabChar, width );
4372  if( pos != std::string::npos ) {
4373  tabPos = pos;
4374  if( remainder[width] == '\n' )
4375  width--;
4376  remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
4377  }
4378 
4379  if( width == remainder.size() ) {
4380  spliceLine( indent, remainder, width );
4381  }
4382  else if( remainder[width] == '\n' ) {
4383  spliceLine( indent, remainder, width );
4384  if( width <= 1 || remainder.size() != 1 )
4385  remainder = remainder.substr( 1 );
4386  indent = _attr.indent;
4387  }
4388  else {
4389  pos = remainder.find_last_of( wrappableChars, width );
4390  if( pos != std::string::npos && pos > 0 ) {
4391  spliceLine( indent, remainder, pos );
4392  if( remainder[0] == ' ' )
4393  remainder = remainder.substr( 1 );
4394  }
4395  else {
4396  spliceLine( indent, remainder, width-1 );
4397  lines.back() += "-";
4398  }
4399  if( lines.size() == 1 )
4400  indent = _attr.indent;
4401  if( tabPos != std::string::npos )
4402  indent += tabPos;
4403  }
4404  }
4405  }
4406 
4407  void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
4408  lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
4409  _remainder = _remainder.substr( _pos );
4410  }
4411 
4412  typedef std::vector<std::string>::const_iterator const_iterator;
4413 
4414  const_iterator begin() const { return lines.begin(); }
4415  const_iterator end() const { return lines.end(); }
4416  std::string const& last() const { return lines.back(); }
4417  std::size_t size() const { return lines.size(); }
4418  std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
4419  std::string toString() const {
4420  std::ostringstream oss;
4421  oss << *this;
4422  return oss.str();
4423  }
4424 
4425  inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
4426  for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
4427  it != itEnd; ++it ) {
4428  if( it != _text.begin() )
4429  _stream << "\n";
4430  _stream << *it;
4431  }
4432  return _stream;
4433  }
4434 
4435  private:
4436  std::string str;
4437  TextAttributes attr;
4438  std::vector<std::string> lines;
4439  };
4440 
4441 } // end namespace Tbc
4442 
4443 #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
4444 } // end outer namespace
4445 #endif
4446 
4447 #endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
4448 #undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
4449 
4450 namespace Catch {
4451  using Tbc::Text;
4452  using Tbc::TextAttributes;
4453 }
4454 
4455 // #included from: catch_console_colour.hpp
4456 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED
4457 
4458 namespace Catch {
4459 
4460  struct Colour {
4461  enum Code {
4462  None = 0,
4463 
4464  White,
4465  Red,
4466  Green,
4467  Blue,
4468  Cyan,
4469  Yellow,
4470  Grey,
4471 
4472  Bright = 0x10,
4473 
4474  BrightRed = Bright | Red,
4475  BrightGreen = Bright | Green,
4476  LightGrey = Bright | Grey,
4477  BrightWhite = Bright | White,
4478 
4479  // By intention
4480  FileName = LightGrey,
4481  Warning = Yellow,
4482  ResultError = BrightRed,
4483  ResultSuccess = BrightGreen,
4484  ResultExpectedFailure = Warning,
4485 
4486  Error = BrightRed,
4487  Success = Green,
4488 
4489  OriginalExpression = Cyan,
4490  ReconstructedExpression = Yellow,
4491 
4492  SecondaryText = LightGrey,
4493  Headers = White
4494  };
4495 
4496  // Use constructed object for RAII guard
4497  Colour( Code _colourCode );
4498  Colour( Colour const& other );
4499  ~Colour();
4500 
4501  // Use static method for one-shot changes
4502  static void use( Code _colourCode );
4503 
4504  private:
4505  bool m_moved;
4506  };
4507 
4508  inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; }
4509 
4510 } // end namespace Catch
4511 
4512 // #included from: catch_interfaces_reporter.h
4513 #define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
4514 
4515 #include <string>
4516 #include <ostream>
4517 #include <map>
4518 #include <assert.h>
4519 
4520 namespace Catch
4521 {
4522  struct ReporterConfig {
4523  explicit ReporterConfig( Ptr<IConfig> const& _fullConfig )
4524  : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
4525 
4526  ReporterConfig( Ptr<IConfig> const& _fullConfig, std::ostream& _stream )
4527  : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
4528 
4529  std::ostream& stream() const { return *m_stream; }
4530  Ptr<IConfig> fullConfig() const { return m_fullConfig; }
4531 
4532  private:
4533  std::ostream* m_stream;
4534  Ptr<IConfig> m_fullConfig;
4535  };
4536 
4537  struct ReporterPreferences {
4538  ReporterPreferences()
4539  : shouldRedirectStdOut( false )
4540  {}
4541 
4542  bool shouldRedirectStdOut;
4543  };
4544 
4545  template<typename T>
4546  struct LazyStat : Option<T> {
4547  LazyStat() : used( false ) {}
4548  LazyStat& operator=( T const& _value ) {
4549  Option<T>::operator=( _value );
4550  used = false;
4551  return *this;
4552  }
4553  void reset() {
4554  Option<T>::reset();
4555  used = false;
4556  }
4557  bool used;
4558  };
4559 
4560  struct TestRunInfo {
4561  TestRunInfo( std::string const& _name ) : name( _name ) {}
4562  std::string name;
4563  };
4564  struct GroupInfo {
4565  GroupInfo( std::string const& _name,
4566  std::size_t _groupIndex,
4567  std::size_t _groupsCount )
4568  : name( _name ),
4569  groupIndex( _groupIndex ),
4570  groupsCounts( _groupsCount )
4571  {}
4572 
4573  std::string name;
4574  std::size_t groupIndex;
4575  std::size_t groupsCounts;
4576  };
4577 
4578  struct AssertionStats {
4579  AssertionStats( AssertionResult const& _assertionResult,
4580  std::vector<MessageInfo> const& _infoMessages,
4581  Totals const& _totals )
4582  : assertionResult( _assertionResult ),
4583  infoMessages( _infoMessages ),
4584  totals( _totals )
4585  {
4586  if( assertionResult.hasMessage() ) {
4587  // Copy message into messages list.
4588  // !TBD This should have been done earlier, somewhere
4589  MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
4590  builder << assertionResult.getMessage();
4591  builder.m_info.message = builder.m_stream.str();
4592 
4593  infoMessages.push_back( builder.m_info );
4594  }
4595  }
4596  virtual ~AssertionStats();
4597 
4598 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
4599  AssertionStats( AssertionStats const& ) = default;
4600  AssertionStats( AssertionStats && ) = default;
4601  AssertionStats& operator = ( AssertionStats const& ) = default;
4602  AssertionStats& operator = ( AssertionStats && ) = default;
4603 # endif
4604 
4605  AssertionResult assertionResult;
4606  std::vector<MessageInfo> infoMessages;
4607  Totals totals;
4608  };
4609 
4610  struct SectionStats {
4611  SectionStats( SectionInfo const& _sectionInfo,
4612  Counts const& _assertions,
4613  double _durationInSeconds,
4614  bool _missingAssertions )
4615  : sectionInfo( _sectionInfo ),
4616  assertions( _assertions ),
4617  durationInSeconds( _durationInSeconds ),
4618  missingAssertions( _missingAssertions )
4619  {}
4620  virtual ~SectionStats();
4621 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
4622  SectionStats( SectionStats const& ) = default;
4623  SectionStats( SectionStats && ) = default;
4624  SectionStats& operator = ( SectionStats const& ) = default;
4625  SectionStats& operator = ( SectionStats && ) = default;
4626 # endif
4627 
4628  SectionInfo sectionInfo;
4629  Counts assertions;
4630  double durationInSeconds;
4631  bool missingAssertions;
4632  };
4633 
4634  struct TestCaseStats {
4635  TestCaseStats( TestCaseInfo const& _testInfo,
4636  Totals const& _totals,
4637  std::string const& _stdOut,
4638  std::string const& _stdErr,
4639  bool _aborting )
4640  : testInfo( _testInfo ),
4641  totals( _totals ),
4642  stdOut( _stdOut ),
4643  stdErr( _stdErr ),
4644  aborting( _aborting )
4645  {}
4646  virtual ~TestCaseStats();
4647 
4648 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
4649  TestCaseStats( TestCaseStats const& ) = default;
4650  TestCaseStats( TestCaseStats && ) = default;
4651  TestCaseStats& operator = ( TestCaseStats const& ) = default;
4652  TestCaseStats& operator = ( TestCaseStats && ) = default;
4653 # endif
4654 
4655  TestCaseInfo testInfo;
4656  Totals totals;
4657  std::string stdOut;
4658  std::string stdErr;
4659  bool aborting;
4660  };
4661 
4662  struct TestGroupStats {
4663  TestGroupStats( GroupInfo const& _groupInfo,
4664  Totals const& _totals,
4665  bool _aborting )
4666  : groupInfo( _groupInfo ),
4667  totals( _totals ),
4668  aborting( _aborting )
4669  {}
4670  TestGroupStats( GroupInfo const& _groupInfo )
4671  : groupInfo( _groupInfo ),
4672  aborting( false )
4673  {}
4674  virtual ~TestGroupStats();
4675 
4676 # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
4677  TestGroupStats( TestGroupStats const& ) = default;
4678  TestGroupStats( TestGroupStats && ) = default;
4679  TestGroupStats& operator = ( TestGroupStats const& ) = default;
4680  TestGroupStats& operator = ( TestGroupStats && ) = default;
4681 # endif
4682 
4683  GroupInfo groupInfo;
4684  Totals totals;
4685  bool aborting;
4686  };
4687 
4688  struct TestRunStats {
4689  TestRunStats( TestRunInfo const& _runInfo,
4690  Totals const& _totals,
4691  bool _aborting )
4692  : runInfo( _runInfo ),
4693  totals( _totals ),
4694  aborting( _aborting )
4695  {}
4696  virtual ~TestRunStats();
4697 
4698 # ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS
4699  TestRunStats( TestRunStats const& _other )
4700  : runInfo( _other.runInfo ),
4701  totals( _other.totals ),
4702  aborting( _other.aborting )
4703  {}
4704 # else
4705  TestRunStats( TestRunStats const& ) = default;
4706  TestRunStats( TestRunStats && ) = default;
4707  TestRunStats& operator = ( TestRunStats const& ) = default;
4708  TestRunStats& operator = ( TestRunStats && ) = default;
4709 # endif
4710 
4711  TestRunInfo runInfo;
4712  Totals totals;
4713  bool aborting;
4714  };
4715 
4716  struct IStreamingReporter : IShared {
4717  virtual ~IStreamingReporter();
4718 
4719  // Implementing class must also provide the following static method:
4720  // static std::string getDescription();
4721 
4722  virtual ReporterPreferences getPreferences() const = 0;
4723 
4724  virtual void noMatchingTestCases( std::string const& spec ) = 0;
4725 
4726  virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
4727  virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
4728 
4729  virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
4730  virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
4731 
4732  virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
4733 
4734  // The return value indicates if the messages buffer should be cleared:
4735  virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
4736  virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
4737  virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
4738  virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
4739  virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
4740 
4741  virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
4742  };
4743 
4744  struct IReporterFactory {
4745  virtual ~IReporterFactory();
4746  virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0;
4747  virtual std::string getDescription() const = 0;
4748  };
4749 
4750  struct IReporterRegistry {
4751  typedef std::map<std::string, IReporterFactory*> FactoryMap;
4752 
4753  virtual ~IReporterRegistry();
4754  virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig> const& config ) const = 0;
4755  virtual FactoryMap const& getFactories() const = 0;
4756  };
4757 
4758 }
4759 
4760 #include <limits>
4761 #include <algorithm>
4762 
4763 namespace Catch {
4764 
4765  inline std::size_t listTests( Config const& config ) {
4766 
4767  TestSpec testSpec = config.testSpec();
4768  if( config.testSpec().hasFilters() )
4769  Catch::cout() << "Matching test cases:\n";
4770  else {
4771  Catch::cout() << "All available test cases:\n";
4772  testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
4773  }
4774 
4775  std::size_t matchedTests = 0;
4776  TextAttributes nameAttr, tagsAttr;
4777  nameAttr.setInitialIndent( 2 ).setIndent( 4 );
4778  tagsAttr.setIndent( 6 );
4779 
4780  std::vector<TestCase> matchedTestCases;
4781  getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases );
4782  for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
4783  it != itEnd;
4784  ++it ) {
4785  matchedTests++;
4786  TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
4787  Colour::Code colour = testCaseInfo.isHidden()
4788  ? Colour::SecondaryText
4789  : Colour::None;
4790  Colour colourGuard( colour );
4791 
4792  Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl;
4793  if( !testCaseInfo.tags.empty() )
4794  Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl;
4795  }
4796 
4797  if( !config.testSpec().hasFilters() )
4798  Catch::cout() << pluralise( matchedTests, "test case" ) << "\n" << std::endl;
4799  else
4800  Catch::cout() << pluralise( matchedTests, "matching test case" ) << "\n" << std::endl;
4801  return matchedTests;
4802  }
4803 
4804  inline std::size_t listTestsNamesOnly( Config const& config ) {
4805  TestSpec testSpec = config.testSpec();
4806  if( !config.testSpec().hasFilters() )
4807  testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
4808  std::size_t matchedTests = 0;
4809  std::vector<TestCase> matchedTestCases;
4810  getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases );
4811  for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
4812  it != itEnd;
4813  ++it ) {
4814  matchedTests++;
4815  TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
4816  Catch::cout() << testCaseInfo.name << std::endl;
4817  }
4818  return matchedTests;
4819  }
4820 
4821  struct TagInfo {
4822  TagInfo() : count ( 0 ) {}
4823  void add( std::string const& spelling ) {
4824  ++count;
4825  spellings.insert( spelling );
4826  }
4827  std::string all() const {
4828  std::string out;
4829  for( std::set<std::string>::const_iterator it = spellings.begin(), itEnd = spellings.end();
4830  it != itEnd;
4831  ++it )
4832  out += "[" + *it + "]";
4833  return out;
4834  }
4835  std::set<std::string> spellings;
4836  std::size_t count;
4837  };
4838 
4839  inline std::size_t listTags( Config const& config ) {
4840  TestSpec testSpec = config.testSpec();
4841  if( config.testSpec().hasFilters() )
4842  Catch::cout() << "Tags for matching test cases:\n";
4843  else {
4844  Catch::cout() << "All available tags:\n";
4845  testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
4846  }
4847 
4848  std::map<std::string, TagInfo> tagCounts;
4849 
4850  std::vector<TestCase> matchedTestCases;
4851  getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases );
4852  for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
4853  it != itEnd;
4854  ++it ) {
4855  for( std::set<std::string>::const_iterator tagIt = it->getTestCaseInfo().tags.begin(),
4856  tagItEnd = it->getTestCaseInfo().tags.end();
4857  tagIt != tagItEnd;
4858  ++tagIt ) {
4859  std::string tagName = *tagIt;
4860  std::string lcaseTagName = toLower( tagName );
4861  std::map<std::string, TagInfo>::iterator countIt = tagCounts.find( lcaseTagName );
4862  if( countIt == tagCounts.end() )
4863  countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
4864  countIt->second.add( tagName );
4865  }
4866  }
4867 
4868  for( std::map<std::string, TagInfo>::const_iterator countIt = tagCounts.begin(),
4869  countItEnd = tagCounts.end();
4870  countIt != countItEnd;
4871  ++countIt ) {
4872  std::ostringstream oss;
4873  oss << " " << std::setw(2) << countIt->second.count << " ";
4874  Text wrapper( countIt->second.all(), TextAttributes()
4875  .setInitialIndent( 0 )
4876  .setIndent( oss.str().size() )
4877  .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) );
4878  Catch::cout() << oss.str() << wrapper << "\n";
4879  }
4880  Catch::cout() << pluralise( tagCounts.size(), "tag" ) << "\n" << std::endl;
4881  return tagCounts.size();
4882  }
4883 
4884  inline std::size_t listReporters( Config const& /*config*/ ) {
4885  Catch::cout() << "Available reporters:\n";
4886  IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
4887  IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;
4888  std::size_t maxNameLen = 0;
4889  for(it = itBegin; it != itEnd; ++it )
4890  maxNameLen = (std::max)( maxNameLen, it->first.size() );
4891 
4892  for(it = itBegin; it != itEnd; ++it ) {
4893  Text wrapper( it->second->getDescription(), TextAttributes()
4894  .setInitialIndent( 0 )
4895  .setIndent( 7+maxNameLen )
4896  .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );
4897  Catch::cout() << " "
4898  << it->first
4899  << ":"
4900  << std::string( maxNameLen - it->first.size() + 2, ' ' )
4901  << wrapper << "\n";
4902  }
4903  Catch::cout() << std::endl;
4904  return factories.size();
4905  }
4906 
4907  inline Option<std::size_t> list( Config const& config ) {
4908  Option<std::size_t> listedCount;
4909  if( config.listTests() )
4910  listedCount = listedCount.valueOr(0) + listTests( config );
4911  if( config.listTestNamesOnly() )
4912  listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
4913  if( config.listTags() )
4914  listedCount = listedCount.valueOr(0) + listTags( config );
4915  if( config.listReporters() )
4916  listedCount = listedCount.valueOr(0) + listReporters( config );
4917  return listedCount;
4918  }
4919 
4920 } // end namespace Catch
4921 
4922 // #included from: internal/catch_runner_impl.hpp
4923 #define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
4924 
4925 // #included from: catch_test_case_tracker.hpp
4926 #define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
4927 
4928 #include <map>
4929 #include <string>
4930 #include <assert.h>
4931 
4932 namespace Catch {
4933 namespace SectionTracking {
4934 
4935  class TrackedSection {
4936 
4937  typedef std::map<std::string, TrackedSection> TrackedSections;
4938 
4939  public:
4940  enum RunState {
4941  NotStarted,
4942  Executing,
4943  ExecutingChildren,
4944  Completed
4945  };
4946 
4947  TrackedSection( std::string const& name, TrackedSection* parent )
4948  : m_name( name ), m_runState( NotStarted ), m_parent( parent )
4949  {}
4950 
4951  RunState runState() const { return m_runState; }
4952 
4953  TrackedSection* findChild( std::string const& childName );
4954  TrackedSection* acquireChild( std::string const& childName );
4955 
4956  void enter() {
4957  if( m_runState == NotStarted )
4958  m_runState = Executing;
4959  }
4960  void leave();
4961 
4962  TrackedSection* getParent() {
4963  return m_parent;
4964  }
4965  bool hasChildren() const {
4966  return !m_children.empty();
4967  }
4968 
4969  private:
4970  std::string m_name;
4971  RunState m_runState;
4972  TrackedSections m_children;
4973  TrackedSection* m_parent;
4974  };
4975 
4976  inline TrackedSection* TrackedSection::findChild( std::string const& childName ) {
4977  TrackedSections::iterator it = m_children.find( childName );
4978  return it != m_children.end()
4979  ? &it->second
4980  : NULL;
4981  }
4982  inline TrackedSection* TrackedSection::acquireChild( std::string const& childName ) {
4983  if( TrackedSection* child = findChild( childName ) )
4984  return child;
4985  m_children.insert( std::make_pair( childName, TrackedSection( childName, this ) ) );
4986  return findChild( childName );
4987  }
4988  inline void TrackedSection::leave() {
4989  for( TrackedSections::const_iterator it = m_children.begin(), itEnd = m_children.end();
4990  it != itEnd;
4991  ++it )
4992  if( it->second.runState() != Completed ) {
4993  m_runState = ExecutingChildren;
4994  return;
4995  }
4996  m_runState = Completed;
4997  }
4998 
4999  class TestCaseTracker {
5000  public:
5001  TestCaseTracker( std::string const& testCaseName )
5002  : m_testCase( testCaseName, NULL ),
5003  m_currentSection( &m_testCase ),
5004  m_completedASectionThisRun( false )
5005  {}
5006 
5007  bool enterSection( std::string const& name ) {
5008  TrackedSection* child = m_currentSection->acquireChild( name );
5009  if( m_completedASectionThisRun || child->runState() == TrackedSection::Completed )
5010  return false;
5011 
5012  m_currentSection = child;
5013  m_currentSection->enter();
5014  return true;
5015  }
5016  void leaveSection() {
5017  m_currentSection->leave();
5018  m_currentSection = m_currentSection->getParent();
5019  assert( m_currentSection != NULL );
5020  m_completedASectionThisRun = true;
5021  }
5022 
5023  bool currentSectionHasChildren() const {
5024  return m_currentSection->hasChildren();
5025  }
5026  bool isCompleted() const {
5027  return m_testCase.runState() == TrackedSection::Completed;
5028  }
5029 
5030  class Guard {
5031  public:
5032  Guard( TestCaseTracker& tracker ) : m_tracker( tracker ) {
5033  m_tracker.enterTestCase();
5034  }
5035  ~Guard() {
5036  m_tracker.leaveTestCase();
5037  }
5038  private:
5039  Guard( Guard const& );
5040  void operator = ( Guard const& );
5041  TestCaseTracker& m_tracker;
5042  };
5043 
5044  private:
5045  void enterTestCase() {
5046  m_currentSection = &m_testCase;
5047  m_completedASectionThisRun = false;
5048  m_testCase.enter();
5049  }
5050  void leaveTestCase() {
5051  m_testCase.leave();
5052  }
5053 
5054  TrackedSection m_testCase;
5055  TrackedSection* m_currentSection;
5056  bool m_completedASectionThisRun;
5057  };
5058 
5059 } // namespace SectionTracking
5060 
5061 using SectionTracking::TestCaseTracker;
5062 
5063 } // namespace Catch
5064 
5065 // #included from: catch_fatal_condition.hpp
5066 #define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
5067 
5068 namespace Catch {
5069 
5070  // Report the error condition then exit the process
5071  inline void fatal( std::string const& message, int exitCode ) {
5072  IContext& context = Catch::getCurrentContext();
5073  IResultCapture* resultCapture = context.getResultCapture();
5074  resultCapture->handleFatalErrorCondition( message );
5075 
5076  if( Catch::alwaysTrue() ) // avoids "no return" warnings
5077  exit( exitCode );
5078  }
5079 
5080 } // namespace Catch
5081 
5082 #if defined ( CATCH_PLATFORM_WINDOWS )
5083 
5084 namespace Catch {
5085 
5086  struct FatalConditionHandler {
5087  void reset() {}
5088  };
5089 
5090 } // namespace Catch
5091 
5092 #else // Not Windows - assumed to be POSIX compatible
5093 
5094 #include <signal.h>
5095 
5096 namespace Catch {
5097 
5098  struct SignalDefs { int id; const char* name; };
5099  extern SignalDefs signalDefs[];
5100  SignalDefs signalDefs[] = {
5101  { SIGINT, "SIGINT - Terminal interrupt signal" },
5102  { SIGILL, "SIGILL - Illegal instruction signal" },
5103  { SIGFPE, "SIGFPE - Floating point error signal" },
5104  { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
5105  { SIGTERM, "SIGTERM - Termination request signal" },
5106  { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
5107  };
5108 
5109  struct FatalConditionHandler {
5110 
5111  static void handleSignal( int sig ) {
5112  for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
5113  if( sig == signalDefs[i].id )
5114  fatal( signalDefs[i].name, -sig );
5115  fatal( "<unknown signal>", -sig );
5116  }
5117 
5118  FatalConditionHandler() : m_isSet( true ) {
5119  for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
5120  signal( signalDefs[i].id, handleSignal );
5121  }
5122  ~FatalConditionHandler() {
5123  reset();
5124  }
5125  void reset() {
5126  if( m_isSet ) {
5127  for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
5128  signal( signalDefs[i].id, SIG_DFL );
5129  m_isSet = false;
5130  }
5131  }
5132 
5133  bool m_isSet;
5134  };
5135 
5136 } // namespace Catch
5137 
5138 #endif // not Windows
5139 
5140 #include <set>
5141 #include <string>
5142 
5143 namespace Catch {
5144 
5145  class StreamRedirect {
5146 
5147  public:
5148  StreamRedirect( std::ostream& stream, std::string& targetString )
5149  : m_stream( stream ),
5150  m_prevBuf( stream.rdbuf() ),
5151  m_targetString( targetString )
5152  {
5153  stream.rdbuf( m_oss.rdbuf() );
5154  }
5155 
5156  ~StreamRedirect() {
5157  m_targetString += m_oss.str();
5158  m_stream.rdbuf( m_prevBuf );
5159  }
5160 
5161  private:
5162  std::ostream& m_stream;
5163  std::streambuf* m_prevBuf;
5164  std::ostringstream m_oss;
5165  std::string& m_targetString;
5166  };
5167 
5169 
5170  class RunContext : public IResultCapture, public IRunner {
5171 
5172  RunContext( RunContext const& );
5173  void operator =( RunContext const& );
5174 
5175  public:
5176 
5177  explicit RunContext( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> const& reporter )
5178  : m_runInfo( config->name() ),
5179  m_context( getCurrentMutableContext() ),
5180  m_activeTestCase( NULL ),
5181  m_config( config ),
5182  m_reporter( reporter ),
5183  m_prevRunner( m_context.getRunner() ),
5184  m_prevResultCapture( m_context.getResultCapture() ),
5185  m_prevConfig( m_context.getConfig() )
5186  {
5187  m_context.setRunner( this );
5188  m_context.setConfig( m_config );
5189  m_context.setResultCapture( this );
5190  m_reporter->testRunStarting( m_runInfo );
5191  }
5192 
5193  virtual ~RunContext() {
5194  m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );
5195  m_context.setRunner( m_prevRunner );
5196  m_context.setConfig( NULL );
5197  m_context.setResultCapture( m_prevResultCapture );
5198  m_context.setConfig( m_prevConfig );
5199  }
5200 
5201  void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
5202  m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) );
5203  }
5204  void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) {
5205  m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );
5206  }
5207 
5208  Totals runTest( TestCase const& testCase ) {
5209  Totals prevTotals = m_totals;
5210 
5211  std::string redirectedCout;
5212  std::string redirectedCerr;
5213 
5214  TestCaseInfo testInfo = testCase.getTestCaseInfo();
5215 
5216  m_reporter->testCaseStarting( testInfo );
5217 
5218  m_activeTestCase = &testCase;
5219  m_testCaseTracker = TestCaseTracker( testInfo.name );
5220 
5221  do {
5222  do {
5223  runCurrentTest( redirectedCout, redirectedCerr );
5224  }
5225  while( !m_testCaseTracker->isCompleted() && !aborting() );
5226  }
5227  while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
5228 
5229  Totals deltaTotals = m_totals.delta( prevTotals );
5230  m_totals.testCases += deltaTotals.testCases;
5231  m_reporter->testCaseEnded( TestCaseStats( testInfo,
5232  deltaTotals,
5233  redirectedCout,
5234  redirectedCerr,
5235  aborting() ) );
5236 
5237  m_activeTestCase = NULL;
5238  m_testCaseTracker.reset();
5239 
5240  return deltaTotals;
5241  }
5242 
5243  Ptr<IConfig const> config() const {
5244  return m_config;
5245  }
5246 
5247  private: // IResultCapture
5248 
5249  virtual void assertionEnded( AssertionResult const& result ) {
5250  if( result.getResultType() == ResultWas::Ok ) {
5251  m_totals.assertions.passed++;
5252  }
5253  else if( !result.isOk() ) {
5254  m_totals.assertions.failed++;
5255  }
5256 
5257  if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) )
5258  m_messages.clear();
5259 
5260  // Reset working state
5261  m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
5262  m_lastResult = result;
5263  }
5264 
5265  virtual bool sectionStarted (
5266  SectionInfo const& sectionInfo,
5267  Counts& assertions
5268  )
5269  {
5270  std::ostringstream oss;
5271  oss << sectionInfo.name << "@" << sectionInfo.lineInfo;
5272 
5273  if( !m_testCaseTracker->enterSection( oss.str() ) )
5274  return false;
5275 
5276  m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
5277 
5278  m_reporter->sectionStarting( sectionInfo );
5279 
5280  assertions = m_totals.assertions;
5281 
5282  return true;
5283  }
5284  bool testForMissingAssertions( Counts& assertions ) {
5285  if( assertions.total() != 0 ||
5286  !m_config->warnAboutMissingAssertions() ||
5287  m_testCaseTracker->currentSectionHasChildren() )
5288  return false;
5289  m_totals.assertions.failed++;
5290  assertions.failed++;
5291  return true;
5292  }
5293 
5294  virtual void sectionEnded( SectionInfo const& info, Counts const& prevAssertions, double _durationInSeconds ) {
5295  if( std::uncaught_exception() ) {
5296  m_unfinishedSections.push_back( UnfinishedSections( info, prevAssertions, _durationInSeconds ) );
5297  return;
5298  }
5299 
5300  Counts assertions = m_totals.assertions - prevAssertions;
5301  bool missingAssertions = testForMissingAssertions( assertions );
5302 
5303  m_testCaseTracker->leaveSection();
5304 
5305  m_reporter->sectionEnded( SectionStats( info, assertions, _durationInSeconds, missingAssertions ) );
5306  m_messages.clear();
5307  }
5308 
5309  virtual void pushScopedMessage( MessageInfo const& message ) {
5310  m_messages.push_back( message );
5311  }
5312 
5313  virtual void popScopedMessage( MessageInfo const& message ) {
5314  m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() );
5315  }
5316 
5317  virtual std::string getCurrentTestName() const {
5318  return m_activeTestCase
5319  ? m_activeTestCase->getTestCaseInfo().name
5320  : "";
5321  }
5322 
5323  virtual const AssertionResult* getLastResult() const {
5324  return &m_lastResult;
5325  }
5326 
5327  virtual void handleFatalErrorCondition( std::string const& message ) {
5328  ResultBuilder resultBuilder = makeUnexpectedResultBuilder();
5330  resultBuilder << message;
5331  resultBuilder.captureExpression();
5332 
5333  handleUnfinishedSections();
5334 
5335  // Recreate section for test case (as we will lose the one that was in scope)
5336  TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
5337  SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
5338 
5339  Counts assertions;
5340  assertions.failed = 1;
5341  SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false );
5342  m_reporter->sectionEnded( testCaseSectionStats );
5343 
5344  TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo();
5345 
5346  Totals deltaTotals;
5347  deltaTotals.testCases.failed = 1;
5348  m_reporter->testCaseEnded( TestCaseStats( testInfo,
5349  deltaTotals,
5350  "",
5351  "",
5352  false ) );
5353  m_totals.testCases.failed++;
5354  testGroupEnded( "", m_totals, 1, 1 );
5355  m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) );
5356  }
5357 
5358  public:
5359  // !TBD We need to do this another way!
5360  bool aborting() const {
5361  return m_totals.assertions.failed == static_cast<std::size_t>( m_config->abortAfter() );
5362  }
5363 
5364  private:
5365 
5366  void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
5367  TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
5368  SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
5369  m_reporter->sectionStarting( testCaseSection );
5370  Counts prevAssertions = m_totals.assertions;
5371  double duration = 0;
5372  try {
5373  m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
5374  TestCaseTracker::Guard guard( *m_testCaseTracker );
5375 
5376  Timer timer;
5377  timer.start();
5378  if( m_reporter->getPreferences().shouldRedirectStdOut ) {
5379  StreamRedirect coutRedir( Catch::cout(), redirectedCout );
5380  StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr );
5381  invokeActiveTestCase();
5382  }
5383  else {
5384  invokeActiveTestCase();
5385  }
5386  duration = timer.getElapsedSeconds();
5387  }
5388  catch( TestFailureException& ) {
5389  // This just means the test was aborted due to failure
5390  }
5391  catch(...) {
5392  makeUnexpectedResultBuilder().useActiveException();
5393  }
5394  handleUnfinishedSections();
5395  m_messages.clear();
5396 
5397  Counts assertions = m_totals.assertions - prevAssertions;
5398  bool missingAssertions = testForMissingAssertions( assertions );
5399 
5400  if( testCaseInfo.okToFail() ) {
5401  std::swap( assertions.failedButOk, assertions.failed );
5402  m_totals.assertions.failed -= assertions.failedButOk;
5403  m_totals.assertions.failedButOk += assertions.failedButOk;
5404  }
5405 
5406  SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );
5407  m_reporter->sectionEnded( testCaseSectionStats );
5408  }
5409 
5410  void invokeActiveTestCase() {
5411  FatalConditionHandler fatalConditionHandler; // Handle signals
5412  m_activeTestCase->invoke();
5413  fatalConditionHandler.reset();
5414  }
5415 
5416  private:
5417 
5418  ResultBuilder makeUnexpectedResultBuilder() const {
5419  return ResultBuilder( m_lastAssertionInfo.macroName.c_str(),
5420  m_lastAssertionInfo.lineInfo,
5421  m_lastAssertionInfo.capturedExpression.c_str(),
5422  m_lastAssertionInfo.resultDisposition );
5423  }
5424 
5425  void handleUnfinishedSections() {
5426  // If sections ended prematurely due to an exception we stored their
5427  // infos here so we can tear them down outside the unwind process.
5428  for( std::vector<UnfinishedSections>::const_reverse_iterator it = m_unfinishedSections.rbegin(),
5429  itEnd = m_unfinishedSections.rend();
5430  it != itEnd;
5431  ++it )
5432  sectionEnded( it->info, it->prevAssertions, it->durationInSeconds );
5433  m_unfinishedSections.clear();
5434  }
5435 
5436  struct UnfinishedSections {
5437  UnfinishedSections( SectionInfo const& _info, Counts const& _prevAssertions, double _durationInSeconds )
5438  : info( _info ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
5439  {}
5440 
5441  SectionInfo info;
5442  Counts prevAssertions;
5443  double durationInSeconds;
5444  };
5445 
5446  TestRunInfo m_runInfo;
5447  IMutableContext& m_context;
5448  TestCase const* m_activeTestCase;
5449  Option<TestCaseTracker> m_testCaseTracker;
5450  AssertionResult m_lastResult;
5451 
5452  Ptr<IConfig const> m_config;
5453  Totals m_totals;
5454  Ptr<IStreamingReporter> m_reporter;
5455  std::vector<MessageInfo> m_messages;
5456  IRunner* m_prevRunner;
5457  IResultCapture* m_prevResultCapture;
5458  Ptr<IConfig const> m_prevConfig;
5459  AssertionInfo m_lastAssertionInfo;
5460  std::vector<UnfinishedSections> m_unfinishedSections;
5461  };
5462 
5465  return *capture;
5466  else
5467  throw std::logic_error( "No result capture instance" );
5468  }
5469 
5470 } // end namespace Catch
5471 
5472 // #included from: internal/catch_version.h
5473 #define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED
5474 
5475 namespace Catch {
5476 
5477  // Versioning information
5478  struct Version {
5479  Version( unsigned int _majorVersion,
5480  unsigned int _minorVersion,
5481  unsigned int _patchNumber,
5482  std::string const& _branchName,
5483  unsigned int _buildNumber );
5484 
5485  unsigned int const majorVersion;
5486  unsigned int const minorVersion;
5487  unsigned int const patchNumber;
5488 
5489  // buildNumber is only used if branchName is not null
5490  std::string const branchName;
5491  unsigned int const buildNumber;
5492 
5493  friend std::ostream& operator << ( std::ostream& os, Version const& version );
5494 
5495  private:
5496  void operator=( Version const& );
5497  };
5498 
5499  extern Version libraryVersion;
5500 }
5501 
5502 #include <fstream>
5503 #include <stdlib.h>
5504 #include <limits>
5505 
5506 namespace Catch {
5507 
5508  class Runner {
5509 
5510  public:
5511  Runner( Ptr<Config> const& config )
5512  : m_config( config )
5513  {
5514  openStream();
5515  makeReporter();
5516  }
5517 
5518  Totals runTests() {
5519 
5520  RunContext context( m_config.get(), m_reporter );
5521 
5522  Totals totals;
5523 
5524  context.testGroupStarting( "all tests", 1, 1 ); // deprecated?
5525 
5526  TestSpec testSpec = m_config->testSpec();
5527  if( !testSpec.hasFilters() )
5528  testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests
5529 
5530  std::vector<TestCase> testCases;
5531  getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, *m_config, testCases );
5532 
5533  int testsRunForGroup = 0;
5534  for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end();
5535  it != itEnd;
5536  ++it ) {
5537  testsRunForGroup++;
5538  if( m_testsAlreadyRun.find( *it ) == m_testsAlreadyRun.end() ) {
5539 
5540  if( context.aborting() )
5541  break;
5542 
5543  totals += context.runTest( *it );
5544  m_testsAlreadyRun.insert( *it );
5545  }
5546  }
5547  std::vector<TestCase> skippedTestCases;
5548  getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, *m_config, skippedTestCases, true );
5549 
5550  for( std::vector<TestCase>::const_iterator it = skippedTestCases.begin(), itEnd = skippedTestCases.end();
5551  it != itEnd;
5552  ++it )
5553  m_reporter->skipTest( *it );
5554 
5555  context.testGroupEnded( "all tests", totals, 1, 1 );
5556  return totals;
5557  }
5558 
5559  private:
5560  void openStream() {
5561  // Open output file, if specified
5562  if( !m_config->getFilename().empty() ) {
5563  m_ofs.open( m_config->getFilename().c_str() );
5564  if( m_ofs.fail() ) {
5565  std::ostringstream oss;
5566  oss << "Unable to open file: '" << m_config->getFilename() << "'";
5567  throw std::domain_error( oss.str() );
5568  }
5569  m_config->setStreamBuf( m_ofs.rdbuf() );
5570  }
5571  }
5572  void makeReporter() {
5573  std::string reporterName = m_config->getReporterName().empty()
5574  ? "console"
5575  : m_config->getReporterName();
5576 
5577  m_reporter = getRegistryHub().getReporterRegistry().create( reporterName, m_config.get() );
5578  if( !m_reporter ) {
5579  std::ostringstream oss;
5580  oss << "No reporter registered with name: '" << reporterName << "'";
5581  throw std::domain_error( oss.str() );
5582  }
5583  }
5584 
5585  private:
5586  Ptr<Config> m_config;
5587  std::ofstream m_ofs;
5588  Ptr<IStreamingReporter> m_reporter;
5589  std::set<TestCase> m_testsAlreadyRun;
5590  };
5591 
5592  class Session : NonCopyable {
5593  static bool alreadyInstantiated;
5594 
5595  public:
5596 
5597  struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; };
5598 
5599  Session()
5600  : m_cli( makeCommandLineParser() ) {
5601  if( alreadyInstantiated ) {
5602  std::string msg = "Only one instance of Catch::Session can ever be used";
5603  Catch::cerr() << msg << std::endl;
5604  throw std::logic_error( msg );
5605  }
5606  alreadyInstantiated = true;
5607  }
5608  ~Session() {
5609  Catch::cleanUp();
5610  }
5611 
5612  void showHelp( std::string const& processName ) {
5613  Catch::cout() << "\nCatch v" << libraryVersion << "\n";
5614 
5615  m_cli.usage( Catch::cout(), processName );
5616  Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
5617  }
5618 
5619  int applyCommandLine( int argc, char* const argv[], OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
5620  try {
5621  m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
5622  m_unusedTokens = m_cli.parseInto( argc, argv, m_configData );
5623  if( m_configData.showHelp )
5624  showHelp( m_configData.processName );
5625  m_config.reset();
5626  }
5627  catch( std::exception& ex ) {
5628  {
5629  Colour colourGuard( Colour::Red );
5630  Catch::cerr()
5631  << "\nError(s) in input:\n"
5632  << Text( ex.what(), TextAttributes().setIndent(2) )
5633  << "\n\n";
5634  }
5635  m_cli.usage( Catch::cout(), m_configData.processName );
5636  return (std::numeric_limits<int>::max)();
5637  }
5638  return 0;
5639  }
5640 
5641  void useConfigData( ConfigData const& _configData ) {
5642  m_configData = _configData;
5643  m_config.reset();
5644  }
5645 
5646  int run( int argc, char* const argv[] ) {
5647 
5648  int returnCode = applyCommandLine( argc, argv );
5649  if( returnCode == 0 )
5650  returnCode = run();
5651  return returnCode;
5652  }
5653 
5654  int run() {
5655  if( m_configData.showHelp )
5656  return 0;
5657 
5658  try
5659  {
5660  config(); // Force config to be constructed
5661 
5662  std::srand( m_configData.rngSeed );
5663 
5664  Runner runner( m_config );
5665 
5666  // Handle list request
5667  if( Option<std::size_t> listed = list( config() ) )
5668  return static_cast<int>( *listed );
5669 
5670  return static_cast<int>( runner.runTests().assertions.failed );
5671  }
5672  catch( std::exception& ex ) {
5673  Catch::cerr() << ex.what() << std::endl;
5674  return (std::numeric_limits<int>::max)();
5675  }
5676  }
5677 
5678  Clara::CommandLine<ConfigData> const& cli() const {
5679  return m_cli;
5680  }
5681  std::vector<Clara::Parser::Token> const& unusedTokens() const {
5682  return m_unusedTokens;
5683  }
5684  ConfigData& configData() {
5685  return m_configData;
5686  }
5687  Config& config() {
5688  if( !m_config )
5689  m_config = new Config( m_configData );
5690  return *m_config;
5691  }
5692 
5693  private:
5694  Clara::CommandLine<ConfigData> m_cli;
5695  std::vector<Clara::Parser::Token> m_unusedTokens;
5696  ConfigData m_configData;
5697  Ptr<Config> m_config;
5698  };
5699 
5700  bool Session::alreadyInstantiated = false;
5701 
5702 } // end namespace Catch
5703 
5704 // #included from: catch_registry_hub.hpp
5705 #define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED
5706 
5707 // #included from: catch_test_case_registry_impl.hpp
5708 #define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
5709 
5710 #include <vector>
5711 #include <set>
5712 #include <sstream>
5713 #include <iostream>
5714 #include <algorithm>
5715 
5716 namespace Catch {
5717 
5718  class TestRegistry : public ITestCaseRegistry {
5719  struct LexSort {
5720  bool operator() (TestCase i,TestCase j) const { return (i<j);}
5721  };
5722  struct RandomNumberGenerator {
5723  int operator()( int n ) const { return std::rand() % n; }
5724  };
5725 
5726  public:
5727  TestRegistry() : m_unnamedCount( 0 ) {}
5728  virtual ~TestRegistry();
5729 
5730  virtual void registerTest( TestCase const& testCase ) {
5731  std::string name = testCase.getTestCaseInfo().name;
5732  if( name == "" ) {
5733  std::ostringstream oss;
5734  oss << "Anonymous test case " << ++m_unnamedCount;
5735  return registerTest( testCase.withName( oss.str() ) );
5736  }
5737 
5738  if( m_functions.find( testCase ) == m_functions.end() ) {
5739  m_functions.insert( testCase );
5740  m_functionsInOrder.push_back( testCase );
5741  if( !testCase.isHidden() )
5742  m_nonHiddenFunctions.push_back( testCase );
5743  }
5744  else {
5745  TestCase const& prev = *m_functions.find( testCase );
5746  {
5747  Colour colourGuard( Colour::Red );
5748  Catch::cerr() << "error: TEST_CASE( \"" << name << "\" ) already defined.\n"
5749  << "\tFirst seen at " << prev.getTestCaseInfo().lineInfo << "\n"
5750  << "\tRedefined at " << testCase.getTestCaseInfo().lineInfo << std::endl;
5751  }
5752  exit(1);
5753  }
5754  }
5755 
5756  virtual std::vector<TestCase> const& getAllTests() const {
5757  return m_functionsInOrder;
5758  }
5759 
5760  virtual std::vector<TestCase> const& getAllNonHiddenTests() const {
5761  return m_nonHiddenFunctions;
5762  }
5763 
5764  virtual void getFilteredTests( TestSpec const& testSpec, IConfig const& config, std::vector<TestCase>& matchingTestCases, bool negated = false ) const {
5765 
5766  for( std::vector<TestCase>::const_iterator it = m_functionsInOrder.begin(),
5767  itEnd = m_functionsInOrder.end();
5768  it != itEnd;
5769  ++it ) {
5770  bool includeTest = testSpec.matches( *it ) && ( config.allowThrows() || !it->throws() );
5771  if( includeTest != negated )
5772  matchingTestCases.push_back( *it );
5773  }
5774  sortTests( config, matchingTestCases );
5775  }
5776 
5777  private:
5778 
5779  static void sortTests( IConfig const& config, std::vector<TestCase>& matchingTestCases ) {
5780 
5781  switch( config.runOrder() ) {
5782  case RunTests::InLexicographicalOrder:
5783  std::sort( matchingTestCases.begin(), matchingTestCases.end(), LexSort() );
5784  break;
5785  case RunTests::InRandomOrder:
5786  {
5787  RandomNumberGenerator rng;
5788  std::random_shuffle( matchingTestCases.begin(), matchingTestCases.end(), rng );
5789  }
5790  break;
5791  case RunTests::InDeclarationOrder:
5792  // already in declaration order
5793  break;
5794  }
5795  }
5796  std::set<TestCase> m_functions;
5797  std::vector<TestCase> m_functionsInOrder;
5798  std::vector<TestCase> m_nonHiddenFunctions;
5799  size_t m_unnamedCount;
5800  };
5801 
5803 
5804  class FreeFunctionTestCase : public SharedImpl<ITestCase> {
5805  public:
5806 
5807  FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}
5808 
5809  virtual void invoke() const {
5810  m_fun();
5811  }
5812 
5813  private:
5814  virtual ~FreeFunctionTestCase();
5815 
5816  TestFunction m_fun;
5817  };
5818 
5819  inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) {
5820  std::string className = classOrQualifiedMethodName;
5821  if( startsWith( className, "&" ) )
5822  {
5823  std::size_t lastColons = className.rfind( "::" );
5824  std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
5825  if( penultimateColons == std::string::npos )
5826  penultimateColons = 1;
5827  className = className.substr( penultimateColons, lastColons-penultimateColons );
5828  }
5829  return className;
5830  }
5831 
5833 
5834  AutoReg::AutoReg( TestFunction function,
5835  SourceLineInfo const& lineInfo,
5836  NameAndDesc const& nameAndDesc ) {
5837  registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
5838  }
5839 
5840  AutoReg::~AutoReg() {}
5841 
5842  void AutoReg::registerTestCase( ITestCase* testCase,
5843  char const* classOrQualifiedMethodName,
5844  NameAndDesc const& nameAndDesc,
5845  SourceLineInfo const& lineInfo ) {
5846 
5848  ( makeTestCase( testCase,
5849  extractClassName( classOrQualifiedMethodName ),
5850  nameAndDesc.name,
5851  nameAndDesc.description,
5852  lineInfo ) );
5853  }
5854 
5855 } // end namespace Catch
5856 
5857 // #included from: catch_reporter_registry.hpp
5858 #define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED
5859 
5860 #include <map>
5861 
5862 namespace Catch {
5863 
5864  class ReporterRegistry : public IReporterRegistry {
5865 
5866  public:
5867 
5868  virtual ~ReporterRegistry() {
5869  deleteAllValues( m_factories );
5870  }
5871 
5872  virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig> const& config ) const {
5873  FactoryMap::const_iterator it = m_factories.find( name );
5874  if( it == m_factories.end() )
5875  return NULL;
5876  return it->second->create( ReporterConfig( config ) );
5877  }
5878 
5879  void registerReporter( std::string const& name, IReporterFactory* factory ) {
5880  m_factories.insert( std::make_pair( name, factory ) );
5881  }
5882 
5883  FactoryMap const& getFactories() const {
5884  return m_factories;
5885  }
5886 
5887  private:
5888  FactoryMap m_factories;
5889  };
5890 }
5891 
5892 // #included from: catch_exception_translator_registry.hpp
5893 #define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
5894 
5895 #ifdef __OBJC__
5896 #import "Foundation/Foundation.h"
5897 #endif
5898 
5899 namespace Catch {
5900 
5901  class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
5902  public:
5903  ~ExceptionTranslatorRegistry() {
5904  deleteAll( m_translators );
5905  }
5906 
5907  virtual void registerTranslator( const IExceptionTranslator* translator ) {
5908  m_translators.push_back( translator );
5909  }
5910 
5911  virtual std::string translateActiveException() const {
5912  try {
5913 #ifdef __OBJC__
5914  // In Objective-C try objective-c exceptions first
5915  @try {
5916  throw;
5917  }
5918  @catch (NSException *exception) {
5919  return Catch::toString( [exception description] );
5920  }
5921 #else
5922  throw;
5923 #endif
5924  }
5925  catch( TestFailureException& ) {
5926  throw;
5927  }
5928  catch( std::exception& ex ) {
5929  return ex.what();
5930  }
5931  catch( std::string& msg ) {
5932  return msg;
5933  }
5934  catch( const char* msg ) {
5935  return msg;
5936  }
5937  catch(...) {
5938  return tryTranslators( m_translators.begin() );
5939  }
5940  }
5941 
5942  std::string tryTranslators( std::vector<const IExceptionTranslator*>::const_iterator it ) const {
5943  if( it == m_translators.end() )
5944  return "Unknown exception";
5945 
5946  try {
5947  return (*it)->translate();
5948  }
5949  catch(...) {
5950  return tryTranslators( it+1 );
5951  }
5952  }
5953 
5954  private:
5955  std::vector<const IExceptionTranslator*> m_translators;
5956  };
5957 }
5958 
5959 namespace Catch {
5960 
5961  namespace {
5962 
5963  class RegistryHub : public IRegistryHub, public IMutableRegistryHub {
5964 
5965  RegistryHub( RegistryHub const& );
5966  void operator=( RegistryHub const& );
5967 
5968  public: // IRegistryHub
5969  RegistryHub() {
5970  }
5971  virtual IReporterRegistry const& getReporterRegistry() const {
5972  return m_reporterRegistry;
5973  }
5974  virtual ITestCaseRegistry const& getTestCaseRegistry() const {
5975  return m_testCaseRegistry;
5976  }
5977  virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() {
5978  return m_exceptionTranslatorRegistry;
5979  }
5980 
5981  public: // IMutableRegistryHub
5982  virtual void registerReporter( std::string const& name, IReporterFactory* factory ) {
5983  m_reporterRegistry.registerReporter( name, factory );
5984  }
5985  virtual void registerTest( TestCase const& testInfo ) {
5986  m_testCaseRegistry.registerTest( testInfo );
5987  }
5988  virtual void registerTranslator( const IExceptionTranslator* translator ) {
5989  m_exceptionTranslatorRegistry.registerTranslator( translator );
5990  }
5991 
5992  private:
5993  TestRegistry m_testCaseRegistry;
5994  ReporterRegistry m_reporterRegistry;
5995  ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
5996  };
5997 
5998  // Single, global, instance
5999  inline RegistryHub*& getTheRegistryHub() {
6000  static RegistryHub* theRegistryHub = NULL;
6001  if( !theRegistryHub )
6002  theRegistryHub = new RegistryHub();
6003  return theRegistryHub;
6004  }
6005  }
6006 
6008  return *getTheRegistryHub();
6009  }
6011  return *getTheRegistryHub();
6012  }
6013  void cleanUp() {
6014  delete getTheRegistryHub();
6015  getTheRegistryHub() = NULL;
6016  cleanUpContext();
6017  }
6020  }
6021 
6022 } // end namespace Catch
6023 
6024 // #included from: catch_notimplemented_exception.hpp
6025 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED
6026 
6027 #include <ostream>
6028 
6029 namespace Catch {
6030 
6032  : m_lineInfo( lineInfo ) {
6033  std::ostringstream oss;
6034  oss << lineInfo << ": function ";
6035  oss << "not implemented";
6036  m_what = oss.str();
6037  }
6038 
6039  const char* NotImplementedException::what() const CATCH_NOEXCEPT {
6040  return m_what.c_str();
6041  }
6042 
6043 } // end namespace Catch
6044 
6045 // #included from: catch_context_impl.hpp
6046 #define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
6047 
6048 // #included from: catch_stream.hpp
6049 #define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
6050 
6051 // #included from: catch_streambuf.h
6052 #define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED
6053 
6054 #include <streambuf>
6055 
6056 namespace Catch {
6057 
6058  class StreamBufBase : public std::streambuf {
6059  public:
6060  virtual ~StreamBufBase() CATCH_NOEXCEPT;
6061  };
6062 }
6063 
6064 #include <stdexcept>
6065 #include <cstdio>
6066 #include <iostream>
6067 
6068 namespace Catch {
6069 
6070  template<typename WriterF, size_t bufferSize=256>
6071  class StreamBufImpl : public StreamBufBase {
6072  char data[bufferSize];
6073  WriterF m_writer;
6074 
6075  public:
6076  StreamBufImpl() {
6077  setp( data, data + sizeof(data) );
6078  }
6079 
6080  ~StreamBufImpl() CATCH_NOEXCEPT {
6081  sync();
6082  }
6083 
6084  private:
6085  int overflow( int c ) {
6086  sync();
6087 
6088  if( c != EOF ) {
6089  if( pbase() == epptr() )
6090  m_writer( std::string( 1, static_cast<char>( c ) ) );
6091  else
6092  sputc( static_cast<char>( c ) );
6093  }
6094  return 0;
6095  }
6096 
6097  int sync() {
6098  if( pbase() != pptr() ) {
6099  m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
6100  setp( pbase(), epptr() );
6101  }
6102  return 0;
6103  }
6104  };
6105 
6107 
6108  struct OutputDebugWriter {
6109 
6110  void operator()( std::string const&str ) {
6111  writeToDebugConsole( str );
6112  }
6113  };
6114 
6115  Stream::Stream()
6116  : streamBuf( NULL ), isOwned( false )
6117  {}
6118 
6119  Stream::Stream( std::streambuf* _streamBuf, bool _isOwned )
6120  : streamBuf( _streamBuf ), isOwned( _isOwned )
6121  {}
6122 
6123  void Stream::release() {
6124  if( isOwned ) {
6125  delete streamBuf;
6126  streamBuf = NULL;
6127  isOwned = false;
6128  }
6129  }
6130 
6131 #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement this functions
6132  std::ostream& cout() {
6133  return std::cout;
6134  }
6135  std::ostream& cerr() {
6136  return std::cerr;
6137  }
6138 #endif
6139 }
6140 
6141 namespace Catch {
6142 
6143  class Context : public IMutableContext {
6144 
6145  Context() : m_config( NULL ), m_runner( NULL ), m_resultCapture( NULL ) {}
6146  Context( Context const& );
6147  void operator=( Context const& );
6148 
6149  public: // IContext
6150  virtual IResultCapture* getResultCapture() {
6151  return m_resultCapture;
6152  }
6153  virtual IRunner* getRunner() {
6154  return m_runner;
6155  }
6156  virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) {
6157  return getGeneratorsForCurrentTest()
6158  .getGeneratorInfo( fileInfo, totalSize )
6159  .getCurrentIndex();
6160  }
6161  virtual bool advanceGeneratorsForCurrentTest() {
6162  IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
6163  return generators && generators->moveNext();
6164  }
6165 
6166  virtual Ptr<IConfig const> getConfig() const {
6167  return m_config;
6168  }
6169 
6170  public: // IMutableContext
6171  virtual void setResultCapture( IResultCapture* resultCapture ) {
6172  m_resultCapture = resultCapture;
6173  }
6174  virtual void setRunner( IRunner* runner ) {
6175  m_runner = runner;
6176  }
6177  virtual void setConfig( Ptr<IConfig const> const& config ) {
6178  m_config = config;
6179  }
6180 
6182 
6183  private:
6184  IGeneratorsForTest* findGeneratorsForCurrentTest() {
6186 
6187  std::map<std::string, IGeneratorsForTest*>::const_iterator it =
6188  m_generatorsByTestName.find( testName );
6189  return it != m_generatorsByTestName.end()
6190  ? it->second
6191  : NULL;
6192  }
6193 
6194  IGeneratorsForTest& getGeneratorsForCurrentTest() {
6195  IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
6196  if( !generators ) {
6198  generators = createGeneratorsForTest();
6199  m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
6200  }
6201  return *generators;
6202  }
6203 
6204  private:
6205  Ptr<IConfig const> m_config;
6206  IRunner* m_runner;
6207  IResultCapture* m_resultCapture;
6208  std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
6209  };
6210 
6211  namespace {
6212  Context* currentContext = NULL;
6213  }
6215  if( !currentContext )
6216  currentContext = new Context();
6217  return *currentContext;
6218  }
6220  return getCurrentMutableContext();
6221  }
6222 
6223  Stream createStream( std::string const& streamName ) {
6224  if( streamName == "stdout" ) return Stream( Catch::cout().rdbuf(), false );
6225  if( streamName == "stderr" ) return Stream( Catch::cerr().rdbuf(), false );
6226  if( streamName == "debug" ) return Stream( new StreamBufImpl<OutputDebugWriter>, true );
6227 
6228  throw std::domain_error( "Unknown stream: " + streamName );
6229  }
6230 
6231  void cleanUpContext() {
6232  delete currentContext;
6233  currentContext = NULL;
6234  }
6235 }
6236 
6237 // #included from: catch_console_colour_impl.hpp
6238 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
6239 
6240 namespace Catch {
6241  namespace {
6242 
6243  struct IColourImpl {
6244  virtual ~IColourImpl() {}
6245  virtual void use( Colour::Code _colourCode ) = 0;
6246  };
6247 
6248  struct NoColourImpl : IColourImpl {
6249  void use( Colour::Code ) {}
6250 
6251  static IColourImpl* instance() {
6252  static NoColourImpl s_instance;
6253  return &s_instance;
6254  }
6255  };
6256 
6257  } // anon namespace
6258 } // namespace Catch
6259 
6260 #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
6261 # ifdef CATCH_PLATFORM_WINDOWS
6262 # define CATCH_CONFIG_COLOUR_WINDOWS
6263 # else
6264 # define CATCH_CONFIG_COLOUR_ANSI
6265 # endif
6266 #endif
6267 
6268 #if defined ( CATCH_CONFIG_COLOUR_WINDOWS )
6269 
6270 #ifndef NOMINMAX
6271 #define NOMINMAX
6272 #endif
6273 
6274 #ifdef __AFXDLL
6275 #include <AfxWin.h>
6276 #else
6277 #include <windows.h>
6278 #endif
6279 
6280 namespace Catch {
6281 namespace {
6282 
6283  class Win32ColourImpl : public IColourImpl {
6284  public:
6285  Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
6286  {
6287  CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
6288  GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
6289  originalAttributes = csbiInfo.wAttributes;
6290  }
6291 
6292  virtual void use( Colour::Code _colourCode ) {
6293  switch( _colourCode ) {
6294  case Colour::None: return setTextAttribute( originalAttributes );
6295  case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
6296  case Colour::Red: return setTextAttribute( FOREGROUND_RED );
6297  case Colour::Green: return setTextAttribute( FOREGROUND_GREEN );
6298  case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE );
6299  case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
6300  case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
6301  case Colour::Grey: return setTextAttribute( 0 );
6302 
6303  case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY );
6304  case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
6305  case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
6306  case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
6307 
6308  case Colour::Bright: throw std::logic_error( "not a colour" );
6309  }
6310  }
6311 
6312  private:
6313  void setTextAttribute( WORD _textAttribute ) {
6314  SetConsoleTextAttribute( stdoutHandle, _textAttribute );
6315  }
6316  HANDLE stdoutHandle;
6317  WORD originalAttributes;
6318  };
6319 
6320  IColourImpl* platformColourInstance() {
6321  static Win32ColourImpl s_instance;
6322  return &s_instance;
6323  }
6324 
6325 } // end anon namespace
6326 } // end namespace Catch
6327 
6328 #elif defined( CATCH_CONFIG_COLOUR_ANSI )
6329 
6330 #include <unistd.h>
6331 
6332 namespace Catch {
6333 namespace {
6334 
6335  // use POSIX/ ANSI console terminal codes
6336  // Thanks to Adam Strzelecki for original contribution
6337  // (http://github.com/nanoant)
6338  // https://github.com/philsquared/Catch/pull/131
6339  class PosixColourImpl : public IColourImpl {
6340  public:
6341  virtual void use( Colour::Code _colourCode ) {
6342  switch( _colourCode ) {
6343  case Colour::None:
6344  case Colour::White: return setColour( "[0m" );
6345  case Colour::Red: return setColour( "[0;31m" );
6346  case Colour::Green: return setColour( "[0;32m" );
6347  case Colour::Blue: return setColour( "[0:34m" );
6348  case Colour::Cyan: return setColour( "[0;36m" );
6349  case Colour::Yellow: return setColour( "[0;33m" );
6350  case Colour::Grey: return setColour( "[1;30m" );
6351 
6352  case Colour::LightGrey: return setColour( "[0;37m" );
6353  case Colour::BrightRed: return setColour( "[1;31m" );
6354  case Colour::BrightGreen: return setColour( "[1;32m" );
6355  case Colour::BrightWhite: return setColour( "[1;37m" );
6356 
6357  case Colour::Bright: throw std::logic_error( "not a colour" );
6358  }
6359  }
6360  static IColourImpl* instance() {
6361  static PosixColourImpl s_instance;
6362  return &s_instance;
6363  }
6364 
6365  private:
6366  void setColour( const char* _escapeCode ) {
6367  Catch::cout() << '\033' << _escapeCode;
6368  }
6369  };
6370 
6371  IColourImpl* platformColourInstance() {
6373  return (config && config->forceColour()) || isatty(STDOUT_FILENO)
6374  ? PosixColourImpl::instance()
6375  : NoColourImpl::instance();
6376  }
6377 
6378 } // end anon namespace
6379 } // end namespace Catch
6380 
6381 #else // not Windows or ANSI
6382 
6383 namespace Catch {
6384 
6385  static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
6386 
6387 } // end namespace Catch
6388 
6389 #endif // Windows/ ANSI/ None
6390 
6391 namespace Catch {
6392 
6393  Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); }
6394  Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast<Colour&>( _other ).m_moved = true; }
6395  Colour::~Colour(){ if( !m_moved ) use( None ); }
6396 
6397  void Colour::use( Code _colourCode ) {
6398  static IColourImpl* impl = isDebuggerActive()
6399  ? NoColourImpl::instance()
6400  : platformColourInstance();
6401  impl->use( _colourCode );
6402  }
6403 
6404 } // end namespace Catch
6405 
6406 // #included from: catch_generators_impl.hpp
6407 #define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED
6408 
6409 #include <vector>
6410 #include <string>
6411 #include <map>
6412 
6413 namespace Catch {
6414 
6415  struct GeneratorInfo : IGeneratorInfo {
6416 
6417  GeneratorInfo( std::size_t size )
6418  : m_size( size ),
6419  m_currentIndex( 0 )
6420  {}
6421 
6422  bool moveNext() {
6423  if( ++m_currentIndex == m_size ) {
6424  m_currentIndex = 0;
6425  return false;
6426  }
6427  return true;
6428  }
6429 
6430  std::size_t getCurrentIndex() const {
6431  return m_currentIndex;
6432  }
6433 
6434  std::size_t m_size;
6435  std::size_t m_currentIndex;
6436  };
6437 
6439 
6440  class GeneratorsForTest : public IGeneratorsForTest {
6441 
6442  public:
6443  ~GeneratorsForTest() {
6444  deleteAll( m_generatorsInOrder );
6445  }
6446 
6447  IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) {
6448  std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );
6449  if( it == m_generatorsByName.end() ) {
6450  IGeneratorInfo* info = new GeneratorInfo( size );
6451  m_generatorsByName.insert( std::make_pair( fileInfo, info ) );
6452  m_generatorsInOrder.push_back( info );
6453  return *info;
6454  }
6455  return *it->second;
6456  }
6457 
6458  bool moveNext() {
6459  std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
6460  std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();
6461  for(; it != itEnd; ++it ) {
6462  if( (*it)->moveNext() )
6463  return true;
6464  }
6465  return false;
6466  }
6467 
6468  private:
6469  std::map<std::string, IGeneratorInfo*> m_generatorsByName;
6470  std::vector<IGeneratorInfo*> m_generatorsInOrder;
6471  };
6472 
6474  {
6475  return new GeneratorsForTest();
6476  }
6477 
6478 } // end namespace Catch
6479 
6480 // #included from: catch_assertionresult.hpp
6481 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED
6482 
6483 namespace Catch {
6484 
6485  AssertionInfo::AssertionInfo( std::string const& _macroName,
6486  SourceLineInfo const& _lineInfo,
6487  std::string const& _capturedExpression,
6488  ResultDisposition::Flags _resultDisposition )
6489  : macroName( _macroName ),
6490  lineInfo( _lineInfo ),
6491  capturedExpression( _capturedExpression ),
6492  resultDisposition( _resultDisposition )
6493  {}
6494 
6496 
6498  : m_info( info ),
6499  m_resultData( data )
6500  {}
6501 
6503 
6504  // Result was a success
6505  bool AssertionResult::succeeded() const {
6506  return Catch::isOk( m_resultData.resultType );
6507  }
6508 
6509  // Result was a success, or failure is suppressed
6510  bool AssertionResult::isOk() const {
6511  return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
6512  }
6513 
6515  return m_resultData.resultType;
6516  }
6517 
6518  bool AssertionResult::hasExpression() const {
6519  return !m_info.capturedExpression.empty();
6520  }
6521 
6522  bool AssertionResult::hasMessage() const {
6523  return !m_resultData.message.empty();
6524  }
6525 
6527  if( isFalseTest( m_info.resultDisposition ) )
6528  return "!" + m_info.capturedExpression;
6529  else
6530  return m_info.capturedExpression;
6531  }
6533  if( m_info.macroName.empty() )
6534  return m_info.capturedExpression;
6535  else
6536  return m_info.macroName + "( " + m_info.capturedExpression + " )";
6537  }
6538 
6540  return hasExpression() && getExpandedExpression() != getExpression();
6541  }
6542 
6544  return m_resultData.reconstructedExpression;
6545  }
6546 
6548  return m_resultData.message;
6549  }
6551  return m_info.lineInfo;
6552  }
6553 
6555  return m_info.macroName;
6556  }
6557 
6558 } // end namespace Catch
6559 
6560 // #included from: catch_test_case_info.hpp
6561 #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED
6562 
6563 namespace Catch {
6564 
6565  inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
6566  if( startsWith( tag, "." ) ||
6567  tag == "hide" ||
6568  tag == "!hide" )
6569  return TestCaseInfo::IsHidden;
6570  else if( tag == "!throws" )
6571  return TestCaseInfo::Throws;
6572  else if( tag == "!shouldfail" )
6573  return TestCaseInfo::ShouldFail;
6574  else if( tag == "!mayfail" )
6575  return TestCaseInfo::MayFail;
6576  else
6577  return TestCaseInfo::None;
6578  }
6579  inline bool isReservedTag( std::string const& tag ) {
6580  return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !isalnum( tag[0] );
6581  }
6582  inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
6583  if( isReservedTag( tag ) ) {
6584  {
6585  Colour colourGuard( Colour::Red );
6586  Catch::cerr()
6587  << "Tag name [" << tag << "] not allowed.\n"
6588  << "Tag names starting with non alpha-numeric characters are reserved\n";
6589  }
6590  {
6591  Colour colourGuard( Colour::FileName );
6592  Catch::cerr() << _lineInfo << std::endl;
6593  }
6594  exit(1);
6595  }
6596  }
6597 
6598  TestCase makeTestCase( ITestCase* _testCase,
6599  std::string const& _className,
6600  std::string const& _name,
6601  std::string const& _descOrTags,
6602  SourceLineInfo const& _lineInfo )
6603  {
6604  bool isHidden( startsWith( _name, "./" ) ); // Legacy support
6605 
6606  // Parse out tags
6607  std::set<std::string> tags;
6608  std::string desc, tag;
6609  bool inTag = false;
6610  for( std::size_t i = 0; i < _descOrTags.size(); ++i ) {
6611  char c = _descOrTags[i];
6612  if( !inTag ) {
6613  if( c == '[' )
6614  inTag = true;
6615  else
6616  desc += c;
6617  }
6618  else {
6619  if( c == ']' ) {
6620  TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
6621  if( prop == TestCaseInfo::IsHidden )
6622  isHidden = true;
6623  else if( prop == TestCaseInfo::None )
6624  enforceNotReservedTag( tag, _lineInfo );
6625 
6626  tags.insert( tag );
6627  tag.clear();
6628  inTag = false;
6629  }
6630  else
6631  tag += c;
6632  }
6633  }
6634  if( isHidden ) {
6635  tags.insert( "hide" );
6636  tags.insert( "." );
6637  }
6638 
6639  TestCaseInfo info( _name, _className, desc, tags, _lineInfo );
6640  return TestCase( _testCase, info );
6641  }
6642 
6644  std::string const& _className,
6645  std::string const& _description,
6646  std::set<std::string> const& _tags,
6647  SourceLineInfo const& _lineInfo )
6648  : name( _name ),
6649  className( _className ),
6650  description( _description ),
6651  tags( _tags ),
6652  lineInfo( _lineInfo ),
6653  properties( None )
6654  {
6655  std::ostringstream oss;
6656  for( std::set<std::string>::const_iterator it = _tags.begin(), itEnd = _tags.end(); it != itEnd; ++it ) {
6657  oss << "[" << *it << "]";
6658  std::string lcaseTag = toLower( *it );
6659  properties = static_cast<SpecialProperties>( properties | parseSpecialTag( lcaseTag ) );
6660  lcaseTags.insert( lcaseTag );
6661  }
6662  tagsAsString = oss.str();
6663  }
6664 
6666  : name( other.name ),
6667  className( other.className ),
6668  description( other.description ),
6669  tags( other.tags ),
6670  lcaseTags( other.lcaseTags ),
6671  tagsAsString( other.tagsAsString ),
6672  lineInfo( other.lineInfo ),
6673  properties( other.properties )
6674  {}
6675 
6676  bool TestCaseInfo::isHidden() const {
6677  return ( properties & IsHidden ) != 0;
6678  }
6679  bool TestCaseInfo::throws() const {
6680  return ( properties & Throws ) != 0;
6681  }
6682  bool TestCaseInfo::okToFail() const {
6683  return ( properties & (ShouldFail | MayFail ) ) != 0;
6684  }
6685  bool TestCaseInfo::expectedToFail() const {
6686  return ( properties & (ShouldFail ) ) != 0;
6687  }
6688 
6689  TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}
6690 
6691  TestCase::TestCase( TestCase const& other )
6692  : TestCaseInfo( other ),
6693  test( other.test )
6694  {}
6695 
6696  TestCase TestCase::withName( std::string const& _newName ) const {
6697  TestCase other( *this );
6698  other.name = _newName;
6699  return other;
6700  }
6701 
6702  void TestCase::swap( TestCase& other ) {
6703  test.swap( other.test );
6704  name.swap( other.name );
6705  className.swap( other.className );
6706  description.swap( other.description );
6707  tags.swap( other.tags );
6708  lcaseTags.swap( other.lcaseTags );
6709  tagsAsString.swap( other.tagsAsString );
6710  std::swap( TestCaseInfo::properties, static_cast<TestCaseInfo&>( other ).properties );
6711  std::swap( lineInfo, other.lineInfo );
6712  }
6713 
6714  void TestCase::invoke() const {
6715  test->invoke();
6716  }
6717 
6718  bool TestCase::operator == ( TestCase const& other ) const {
6719  return test.get() == other.test.get() &&
6720  name == other.name &&
6721  className == other.className;
6722  }
6723 
6724  bool TestCase::operator < ( TestCase const& other ) const {
6725  return name < other.name;
6726  }
6727  TestCase& TestCase::operator = ( TestCase const& other ) {
6728  TestCase temp( other );
6729  swap( temp );
6730  return *this;
6731  }
6732 
6734  {
6735  return *this;
6736  }
6737 
6738 } // end namespace Catch
6739 
6740 // #included from: catch_version.hpp
6741 #define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED
6742 
6743 namespace Catch {
6744 
6745  Version::Version
6746  ( unsigned int _majorVersion,
6747  unsigned int _minorVersion,
6748  unsigned int _patchNumber,
6749  std::string const& _branchName,
6750  unsigned int _buildNumber )
6751  : majorVersion( _majorVersion ),
6752  minorVersion( _minorVersion ),
6753  patchNumber( _patchNumber ),
6754  branchName( _branchName ),
6755  buildNumber( _buildNumber )
6756  {}
6757 
6758  std::ostream& operator << ( std::ostream& os, Version const& version ) {
6759  os << version.majorVersion << "."
6760  << version.minorVersion << "."
6761  << version.patchNumber;
6762 
6763  if( !version.branchName.empty() ) {
6764  os << "-" << version.branchName
6765  << "." << version.buildNumber;
6766  }
6767  return os;
6768  }
6769 
6770  Version libraryVersion( 1, 2, 1, "", 0 );
6771 
6772 }
6773 
6774 // #included from: catch_message.hpp
6775 #define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED
6776 
6777 namespace Catch {
6778 
6779  MessageInfo::MessageInfo( std::string const& _macroName,
6780  SourceLineInfo const& _lineInfo,
6781  ResultWas::OfType _type )
6782  : macroName( _macroName ),
6783  lineInfo( _lineInfo ),
6784  type( _type ),
6785  sequence( ++globalCount )
6786  {}
6787 
6788  // This may need protecting if threading support is added
6789  unsigned int MessageInfo::globalCount = 0;
6790 
6792 
6794  : m_info( builder.m_info )
6795  {
6796  m_info.message = builder.m_stream.str();
6797  getResultCapture().pushScopedMessage( m_info );
6798  }
6800  : m_info( other.m_info )
6801  {}
6802 
6804  getResultCapture().popScopedMessage( m_info );
6805  }
6806 
6807 } // end namespace Catch
6808 
6809 // #included from: catch_legacy_reporter_adapter.hpp
6810 #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED
6811 
6812 // #included from: catch_legacy_reporter_adapter.h
6813 #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED
6814 
6815 namespace Catch
6816 {
6817  // Deprecated
6818  struct IReporter : IShared {
6819  virtual ~IReporter();
6820 
6821  virtual bool shouldRedirectStdout() const = 0;
6822 
6823  virtual void StartTesting() = 0;
6824  virtual void EndTesting( Totals const& totals ) = 0;
6825  virtual void StartGroup( std::string const& groupName ) = 0;
6826  virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0;
6827  virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0;
6828  virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0;
6829  virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0;
6830  virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0;
6831  virtual void NoAssertionsInSection( std::string const& sectionName ) = 0;
6832  virtual void NoAssertionsInTestCase( std::string const& testName ) = 0;
6833  virtual void Aborted() = 0;
6834  virtual void Result( AssertionResult const& result ) = 0;
6835  };
6836 
6837  class LegacyReporterAdapter : public SharedImpl<IStreamingReporter>
6838  {
6839  public:
6840  LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter );
6841  virtual ~LegacyReporterAdapter();
6842 
6843  virtual ReporterPreferences getPreferences() const;
6844  virtual void noMatchingTestCases( std::string const& );
6845  virtual void testRunStarting( TestRunInfo const& );
6846  virtual void testGroupStarting( GroupInfo const& groupInfo );
6847  virtual void testCaseStarting( TestCaseInfo const& testInfo );
6848  virtual void sectionStarting( SectionInfo const& sectionInfo );
6849  virtual void assertionStarting( AssertionInfo const& );
6850  virtual bool assertionEnded( AssertionStats const& assertionStats );
6851  virtual void sectionEnded( SectionStats const& sectionStats );
6852  virtual void testCaseEnded( TestCaseStats const& testCaseStats );
6853  virtual void testGroupEnded( TestGroupStats const& testGroupStats );
6854  virtual void testRunEnded( TestRunStats const& testRunStats );
6855  virtual void skipTest( TestCaseInfo const& );
6856 
6857  private:
6858  Ptr<IReporter> m_legacyReporter;
6859  };
6860 }
6861 
6862 namespace Catch
6863 {
6864  LegacyReporterAdapter::LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter )
6865  : m_legacyReporter( legacyReporter )
6866  {}
6867  LegacyReporterAdapter::~LegacyReporterAdapter() {}
6868 
6869  ReporterPreferences LegacyReporterAdapter::getPreferences() const {
6870  ReporterPreferences prefs;
6871  prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout();
6872  return prefs;
6873  }
6874 
6875  void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {}
6876  void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) {
6877  m_legacyReporter->StartTesting();
6878  }
6879  void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) {
6880  m_legacyReporter->StartGroup( groupInfo.name );
6881  }
6882  void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) {
6883  m_legacyReporter->StartTestCase( testInfo );
6884  }
6885  void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) {
6886  m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description );
6887  }
6888  void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) {
6889  // Not on legacy interface
6890  }
6891 
6892  bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) {
6893  if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
6894  for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
6895  it != itEnd;
6896  ++it ) {
6897  if( it->type == ResultWas::Info ) {
6898  ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal );
6899  rb << it->message;
6901  AssertionResult result = rb.build();
6902  m_legacyReporter->Result( result );
6903  }
6904  }
6905  }
6906  m_legacyReporter->Result( assertionStats.assertionResult );
6907  return true;
6908  }
6909  void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) {
6910  if( sectionStats.missingAssertions )
6911  m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name );
6912  m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions );
6913  }
6914  void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) {
6915  m_legacyReporter->EndTestCase
6916  ( testCaseStats.testInfo,
6917  testCaseStats.totals,
6918  testCaseStats.stdOut,
6919  testCaseStats.stdErr );
6920  }
6921  void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) {
6922  if( testGroupStats.aborting )
6923  m_legacyReporter->Aborted();
6924  m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals );
6925  }
6926  void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) {
6927  m_legacyReporter->EndTesting( testRunStats.totals );
6928  }
6929  void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) {
6930  }
6931 }
6932 
6933 // #included from: catch_timer.hpp
6934 
6935 #ifdef __clang__
6936 #pragma clang diagnostic push
6937 #pragma clang diagnostic ignored "-Wc++11-long-long"
6938 #endif
6939 
6940 #ifdef CATCH_PLATFORM_WINDOWS
6941 #include <windows.h>
6942 #else
6943 #include <sys/time.h>
6944 #endif
6945 
6946 namespace Catch {
6947 
6948  namespace {
6949 #ifdef CATCH_PLATFORM_WINDOWS
6950  uint64_t getCurrentTicks() {
6951  static uint64_t hz=0, hzo=0;
6952  if (!hz) {
6953  QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>( &hz ) );
6954  QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &hzo ) );
6955  }
6956  uint64_t t;
6957  QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &t ) );
6958  return ((t-hzo)*1000000)/hz;
6959  }
6960 #else
6961  uint64_t getCurrentTicks() {
6962  timeval t;
6963  gettimeofday(&t,NULL);
6964  return static_cast<uint64_t>( t.tv_sec ) * 1000000ull + static_cast<uint64_t>( t.tv_usec );
6965  }
6966 #endif
6967  }
6968 
6969  void Timer::start() {
6970  m_ticks = getCurrentTicks();
6971  }
6972  unsigned int Timer::getElapsedMicroseconds() const {
6973  return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
6974  }
6975  unsigned int Timer::getElapsedMilliseconds() const {
6976  return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
6977  }
6978  double Timer::getElapsedSeconds() const {
6979  return getElapsedMicroseconds()/1000000.0;
6980  }
6981 
6982 } // namespace Catch
6983 
6984 #ifdef __clang__
6985 #pragma clang diagnostic pop
6986 #endif
6987 // #included from: catch_common.hpp
6988 #define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED
6989 
6990 namespace Catch {
6991 
6992  bool startsWith( std::string const& s, std::string const& prefix ) {
6993  return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
6994  }
6995  bool endsWith( std::string const& s, std::string const& suffix ) {
6996  return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
6997  }
6998  bool contains( std::string const& s, std::string const& infix ) {
6999  return s.find( infix ) != std::string::npos;
7000  }
7001  void toLowerInPlace( std::string& s ) {
7002  std::transform( s.begin(), s.end(), s.begin(), ::tolower );
7003  }
7004  std::string toLower( std::string const& s ) {
7005  std::string lc = s;
7006  toLowerInPlace( lc );
7007  return lc;
7008  }
7009  std::string trim( std::string const& str ) {
7010  static char const* whitespaceChars = "\n\r\t ";
7011  std::string::size_type start = str.find_first_not_of( whitespaceChars );
7012  std::string::size_type end = str.find_last_not_of( whitespaceChars );
7013 
7014  return start != std::string::npos ? str.substr( start, 1+end-start ) : "";
7015  }
7016 
7017  bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
7018  bool replaced = false;
7019  std::size_t i = str.find( replaceThis );
7020  while( i != std::string::npos ) {
7021  replaced = true;
7022  str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
7023  if( i < str.size()-withThis.size() )
7024  i = str.find( replaceThis, i+withThis.size() );
7025  else
7026  i = std::string::npos;
7027  }
7028  return replaced;
7029  }
7030 
7031  pluralise::pluralise( std::size_t count, std::string const& label )
7032  : m_count( count ),
7033  m_label( label )
7034  {}
7035 
7036  std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
7037  os << pluraliser.m_count << " " << pluraliser.m_label;
7038  if( pluraliser.m_count != 1 )
7039  os << "s";
7040  return os;
7041  }
7042 
7043  SourceLineInfo::SourceLineInfo() : line( 0 ){}
7044  SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )
7045  : file( _file ),
7046  line( _line )
7047  {}
7049  : file( other.file ),
7050  line( other.line )
7051  {}
7052  bool SourceLineInfo::empty() const {
7053  return file.empty();
7054  }
7055  bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {
7056  return line == other.line && file == other.file;
7057  }
7058  bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const {
7059  return line < other.line || ( line == other.line && file < other.file );
7060  }
7061 
7062  std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
7063 #ifndef __GNUG__
7064  os << info.file << "(" << info.line << ")";
7065 #else
7066  os << info.file << ":" << info.line;
7067 #endif
7068  return os;
7069  }
7070 
7071  void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
7072  std::ostringstream oss;
7073  oss << locationInfo << ": Internal Catch error: '" << message << "'";
7074  if( alwaysTrue() )
7075  throw std::logic_error( oss.str() );
7076  }
7077 }
7078 
7079 // #included from: catch_section.hpp
7080 #define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
7081 
7082 namespace Catch {
7083 
7085  ( SourceLineInfo const& _lineInfo,
7086  std::string const& _name,
7087  std::string const& _description )
7088  : name( _name ),
7089  description( _description ),
7090  lineInfo( _lineInfo )
7091  {}
7092 
7093  Section::Section( SectionInfo const& info )
7094  : m_info( info ),
7095  m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
7096  {
7097  m_timer.start();
7098  }
7099 
7100  Section::~Section() {
7101  if( m_sectionIncluded )
7102  getResultCapture().sectionEnded( m_info, m_assertions, m_timer.getElapsedSeconds() );
7103  }
7104 
7105  // This indicates whether the section should be executed or not
7106  Section::operator bool() const {
7107  return m_sectionIncluded;
7108  }
7109 
7110 } // end namespace Catch
7111 
7112 // #included from: catch_debugger.hpp
7113 #define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
7114 
7115 #include <iostream>
7116 
7117 #ifdef CATCH_PLATFORM_MAC
7118 
7119  #include <assert.h>
7120  #include <stdbool.h>
7121  #include <sys/types.h>
7122  #include <unistd.h>
7123  #include <sys/sysctl.h>
7124 
7125  namespace Catch{
7126 
7127  // The following function is taken directly from the following technical note:
7128  // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
7129 
7130  // Returns true if the current process is being debugged (either
7131  // running under the debugger or has a debugger attached post facto).
7132  bool isDebuggerActive(){
7133 
7134  int mib[4];
7135  struct kinfo_proc info;
7136  size_t size;
7137 
7138  // Initialize the flags so that, if sysctl fails for some bizarre
7139  // reason, we get a predictable result.
7140 
7141  info.kp_proc.p_flag = 0;
7142 
7143  // Initialize mib, which tells sysctl the info we want, in this case
7144  // we're looking for information about a specific process ID.
7145 
7146  mib[0] = CTL_KERN;
7147  mib[1] = KERN_PROC;
7148  mib[2] = KERN_PROC_PID;
7149  mib[3] = getpid();
7150 
7151  // Call sysctl.
7152 
7153  size = sizeof(info);
7154  if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0) != 0 ) {
7155  Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
7156  return false;
7157  }
7158 
7159  // We're being debugged if the P_TRACED flag is set.
7160 
7161  return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
7162  }
7163  } // namespace Catch
7164 
7165 #elif defined(_MSC_VER)
7166  extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
7167  namespace Catch {
7168  bool isDebuggerActive() {
7169  return IsDebuggerPresent() != 0;
7170  }
7171  }
7172 #elif defined(__MINGW32__)
7173  extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
7174  namespace Catch {
7175  bool isDebuggerActive() {
7176  return IsDebuggerPresent() != 0;
7177  }
7178  }
7179 #else
7180  namespace Catch {
7181  inline bool isDebuggerActive() { return false; }
7182  }
7183 #endif // Platform
7184 
7185 #ifdef CATCH_PLATFORM_WINDOWS
7186  extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* );
7187  namespace Catch {
7188  void writeToDebugConsole( std::string const& text ) {
7189  ::OutputDebugStringA( text.c_str() );
7190  }
7191  }
7192 #else
7193  namespace Catch {
7194  void writeToDebugConsole( std::string const& text ) {
7195  // !TBD: Need a version for Mac/ XCode and other IDEs
7196  Catch::cout() << text;
7197  }
7198  }
7199 #endif // Platform
7200 
7201 // #included from: catch_tostring.hpp
7202 #define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED
7203 
7204 namespace Catch {
7205 
7206 namespace Detail {
7207 
7209 
7210  namespace {
7211  struct Endianness {
7212  enum Arch { Big, Little };
7213 
7214  static Arch which() {
7215  union _{
7216  int asInt;
7217  char asChar[sizeof (int)];
7218  } u;
7219 
7220  u.asInt = 1;
7221  return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
7222  }
7223  };
7224  }
7225 
7226  std::string rawMemoryToString( const void *object, std::size_t size )
7227  {
7228  // Reverse order for little endian architectures
7229  int i = 0, end = static_cast<int>( size ), inc = 1;
7230  if( Endianness::which() == Endianness::Little ) {
7231  i = end-1;
7232  end = inc = -1;
7233  }
7234 
7235  unsigned char const *bytes = static_cast<unsigned char const *>(object);
7236  std::ostringstream os;
7237  os << "0x" << std::setfill('0') << std::hex;
7238  for( ; i != end; i += inc )
7239  os << std::setw(2) << static_cast<unsigned>(bytes[i]);
7240  return os.str();
7241  }
7242 }
7243 
7244 std::string toString( std::string const& value ) {
7245  std::string s = value;
7246  if( getCurrentContext().getConfig()->showInvisibles() ) {
7247  for(size_t i = 0; i < s.size(); ++i ) {
7248  std::string subs;
7249  switch( s[i] ) {
7250  case '\n': subs = "\\n"; break;
7251  case '\t': subs = "\\t"; break;
7252  default: break;
7253  }
7254  if( !subs.empty() ) {
7255  s = s.substr( 0, i ) + subs + s.substr( i+1 );
7256  ++i;
7257  }
7258  }
7259  }
7260  return "\"" + s + "\"";
7261 }
7262 std::string toString( std::wstring const& value ) {
7263 
7264  std::string s;
7265  s.reserve( value.size() );
7266  for(size_t i = 0; i < value.size(); ++i )
7267  s += value[i] <= 0xff ? static_cast<char>( value[i] ) : '?';
7268  return Catch::toString( s );
7269 }
7270 
7271 std::string toString( const char* const value ) {
7272  return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" );
7273 }
7274 
7275 std::string toString( char* const value ) {
7276  return Catch::toString( static_cast<const char*>( value ) );
7277 }
7278 
7279 std::string toString( const wchar_t* const value )
7280 {
7281  return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" );
7282 }
7283 
7284 std::string toString( wchar_t* const value )
7285 {
7286  return Catch::toString( static_cast<const wchar_t*>( value ) );
7287 }
7288 
7289 std::string toString( int value ) {
7290  std::ostringstream oss;
7291  oss << value;
7292  if( value >= 255 )
7293  oss << " (0x" << std::hex << value << ")";
7294  return oss.str();
7295 }
7296 
7297 std::string toString( unsigned long value ) {
7298  std::ostringstream oss;
7299  oss << value;
7300  if( value >= 255 )
7301  oss << " (0x" << std::hex << value << ")";
7302  return oss.str();
7303 }
7304 
7305 std::string toString( unsigned int value ) {
7306  return Catch::toString( static_cast<unsigned long>( value ) );
7307 }
7308 
7309 template<typename T>
7310 std::string fpToString( T value, int precision ) {
7311  std::ostringstream oss;
7312  oss << std::setprecision( precision )
7313  << std::fixed
7314  << value;
7315  std::string d = oss.str();
7316  std::size_t i = d.find_last_not_of( '0' );
7317  if( i != std::string::npos && i != d.size()-1 ) {
7318  if( d[i] == '.' )
7319  i++;
7320  d = d.substr( 0, i+1 );
7321  }
7322  return d;
7323 }
7324 
7325 std::string toString( const double value ) {
7326  return fpToString( value, 10 );
7327 }
7328 std::string toString( const float value ) {
7329  return fpToString( value, 5 ) + "f";
7330 }
7331 
7332 std::string toString( bool value ) {
7333  return value ? "true" : "false";
7334 }
7335 
7336 std::string toString( char value ) {
7337  return value < ' '
7338  ? toString( static_cast<unsigned int>( value ) )
7339  : Detail::makeString( value );
7340 }
7341 
7342 std::string toString( signed char value ) {
7343  return toString( static_cast<char>( value ) );
7344 }
7345 
7346 std::string toString( unsigned char value ) {
7347  return toString( static_cast<char>( value ) );
7348 }
7349 
7350 #ifdef CATCH_CONFIG_CPP11_NULLPTR
7351 std::string toString( std::nullptr_t ) {
7352  return "nullptr";
7353 }
7354 #endif
7355 
7356 #ifdef __OBJC__
7357  std::string toString( NSString const * const& nsstring ) {
7358  if( !nsstring )
7359  return "nil";
7360  return "@" + toString([nsstring UTF8String]);
7361  }
7362  std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) {
7363  if( !nsstring )
7364  return "nil";
7365  return "@" + toString([nsstring UTF8String]);
7366  }
7367  std::string toString( NSObject* const& nsObject ) {
7368  return toString( [nsObject description] );
7369  }
7370 #endif
7371 
7372 } // end namespace Catch
7373 
7374 // #included from: catch_result_builder.hpp
7375 #define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED
7376 
7377 namespace Catch {
7378 
7379  ResultBuilder::ResultBuilder( char const* macroName,
7380  SourceLineInfo const& lineInfo,
7381  char const* capturedExpression,
7382  ResultDisposition::Flags resultDisposition )
7383  : m_assertionInfo( macroName, lineInfo, capturedExpression, resultDisposition ),
7384  m_shouldDebugBreak( false ),
7385  m_shouldThrow( false )
7386  {}
7387 
7389  m_data.resultType = result;
7390  return *this;
7391  }
7393  m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;
7394  return *this;
7395  }
7397  m_exprComponents.lhs = lhs;
7398  return *this;
7399  }
7401  m_exprComponents.rhs = rhs;
7402  return *this;
7403  }
7405  m_exprComponents.op = op;
7406  return *this;
7407  }
7408 
7410  m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition );
7411  captureExpression();
7412  }
7413 
7415  m_assertionInfo.resultDisposition = resultDisposition;
7416  m_stream.oss << Catch::translateActiveException();
7417  captureResult( ResultWas::ThrewException );
7418  }
7419 
7420  void ResultBuilder::captureResult( ResultWas::OfType resultType ) {
7421  setResultType( resultType );
7422  captureExpression();
7423  }
7424 
7426  AssertionResult result = build();
7427  getResultCapture().assertionEnded( result );
7428 
7429  if( !result.isOk() ) {
7430  if( getCurrentContext().getConfig()->shouldDebugBreak() )
7431  m_shouldDebugBreak = true;
7432  if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) )
7433  m_shouldThrow = true;
7434  }
7435  }
7436  void ResultBuilder::react() {
7437  if( m_shouldThrow )
7439  }
7440 
7441  bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; }
7442  bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); }
7443 
7445  {
7446  assert( m_data.resultType != ResultWas::Unknown );
7447 
7448  AssertionResultData data = m_data;
7449 
7450  // Flip bool results if testFalse is set
7451  if( m_exprComponents.testFalse ) {
7452  if( data.resultType == ResultWas::Ok )
7454  else if( data.resultType == ResultWas::ExpressionFailed )
7455  data.resultType = ResultWas::Ok;
7456  }
7457 
7458  data.message = m_stream.oss.str();
7459  data.reconstructedExpression = reconstructExpression();
7460  if( m_exprComponents.testFalse ) {
7461  if( m_exprComponents.op == "" )
7462  data.reconstructedExpression = "!" + data.reconstructedExpression;
7463  else
7464  data.reconstructedExpression = "!(" + data.reconstructedExpression + ")";
7465  }
7466  return AssertionResult( m_assertionInfo, data );
7467  }
7469  if( m_exprComponents.op == "" )
7470  return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.op + m_exprComponents.lhs;
7471  else if( m_exprComponents.op == "matches" )
7472  return m_exprComponents.lhs + " " + m_exprComponents.rhs;
7473  else if( m_exprComponents.op != "!" ) {
7474  if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 &&
7475  m_exprComponents.lhs.find("\n") == std::string::npos &&
7476  m_exprComponents.rhs.find("\n") == std::string::npos )
7477  return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs;
7478  else
7479  return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs;
7480  }
7481  else
7482  return "{can't expand - use " + m_assertionInfo.macroName + "_FALSE( " + m_assertionInfo.capturedExpression.substr(1) + " ) instead of " + m_assertionInfo.macroName + "( " + m_assertionInfo.capturedExpression + " ) for better diagnostics}";
7483  }
7484 
7485 } // end namespace Catch
7486 
7487 // #included from: catch_tag_alias_registry.hpp
7488 #define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
7489 
7490 // #included from: catch_tag_alias_registry.h
7491 #define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED
7492 
7493 #include <map>
7494 
7495 namespace Catch {
7496 
7497  class TagAliasRegistry : public ITagAliasRegistry {
7498  public:
7499  virtual ~TagAliasRegistry();
7500  virtual Option<TagAlias> find( std::string const& alias ) const;
7501  virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const;
7502  void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
7503  static TagAliasRegistry& get();
7504 
7505  private:
7506  std::map<std::string, TagAlias> m_registry;
7507  };
7508 
7509 } // end namespace Catch
7510 
7511 #include <map>
7512 #include <iostream>
7513 
7514 namespace Catch {
7515 
7516  TagAliasRegistry::~TagAliasRegistry() {}
7517 
7518  Option<TagAlias> TagAliasRegistry::find( std::string const& alias ) const {
7519  std::map<std::string, TagAlias>::const_iterator it = m_registry.find( alias );
7520  if( it != m_registry.end() )
7521  return it->second;
7522  else
7523  return Option<TagAlias>();
7524  }
7525 
7526  std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
7527  std::string expandedTestSpec = unexpandedTestSpec;
7528  for( std::map<std::string, TagAlias>::const_iterator it = m_registry.begin(), itEnd = m_registry.end();
7529  it != itEnd;
7530  ++it ) {
7531  std::size_t pos = expandedTestSpec.find( it->first );
7532  if( pos != std::string::npos ) {
7533  expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
7534  it->second.tag +
7535  expandedTestSpec.substr( pos + it->first.size() );
7536  }
7537  }
7538  return expandedTestSpec;
7539  }
7540 
7541  void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
7542 
7543  if( !startsWith( alias, "[@" ) || !endsWith( alias, "]" ) ) {
7544  std::ostringstream oss;
7545  oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo;
7546  throw std::domain_error( oss.str().c_str() );
7547  }
7548  if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) {
7549  std::ostringstream oss;
7550  oss << "error: tag alias, \"" << alias << "\" already registered.\n"
7551  << "\tFirst seen at " << find(alias)->lineInfo << "\n"
7552  << "\tRedefined at " << lineInfo;
7553  throw std::domain_error( oss.str().c_str() );
7554  }
7555  }
7556 
7557  TagAliasRegistry& TagAliasRegistry::get() {
7558  static TagAliasRegistry instance;
7559  return instance;
7560 
7561  }
7562 
7564  ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); }
7565 
7566  RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
7567  try {
7568  TagAliasRegistry::get().add( alias, tag, lineInfo );
7569  }
7570  catch( std::exception& ex ) {
7571  Colour colourGuard( Colour::Red );
7572  Catch::cerr() << ex.what() << std::endl;
7573  exit(1);
7574  }
7575  }
7576 
7577 } // end namespace Catch
7578 
7579 // #included from: ../reporters/catch_reporter_xml.hpp
7580 #define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED
7581 
7582 // #included from: catch_reporter_bases.hpp
7583 #define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
7584 
7585 #include <cstring>
7586 
7587 namespace Catch {
7588 
7589  struct StreamingReporterBase : SharedImpl<IStreamingReporter> {
7590 
7591  StreamingReporterBase( ReporterConfig const& _config )
7592  : m_config( _config.fullConfig() ),
7593  stream( _config.stream() )
7594  {}
7595 
7596  virtual ~StreamingReporterBase();
7597 
7598  virtual void noMatchingTestCases( std::string const& ) {}
7599 
7600  virtual void testRunStarting( TestRunInfo const& _testRunInfo ) {
7601  currentTestRunInfo = _testRunInfo;
7602  }
7603  virtual void testGroupStarting( GroupInfo const& _groupInfo ) {
7604  currentGroupInfo = _groupInfo;
7605  }
7606 
7607  virtual void testCaseStarting( TestCaseInfo const& _testInfo ) {
7608  currentTestCaseInfo = _testInfo;
7609  }
7610  virtual void sectionStarting( SectionInfo const& _sectionInfo ) {
7611  m_sectionStack.push_back( _sectionInfo );
7612  }
7613 
7614  virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) {
7615  m_sectionStack.pop_back();
7616  }
7617  virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) {
7618  currentTestCaseInfo.reset();
7619  }
7620  virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) {
7621  currentGroupInfo.reset();
7622  }
7623  virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) {
7624  currentTestCaseInfo.reset();
7625  currentGroupInfo.reset();
7626  currentTestRunInfo.reset();
7627  }
7628 
7629  virtual void skipTest( TestCaseInfo const& ) {
7630  // Don't do anything with this by default.
7631  // It can optionally be overridden in the derived class.
7632  }
7633 
7634  Ptr<IConfig> m_config;
7635  std::ostream& stream;
7636 
7637  LazyStat<TestRunInfo> currentTestRunInfo;
7638  LazyStat<GroupInfo> currentGroupInfo;
7639  LazyStat<TestCaseInfo> currentTestCaseInfo;
7640 
7641  std::vector<SectionInfo> m_sectionStack;
7642  };
7643 
7644  struct CumulativeReporterBase : SharedImpl<IStreamingReporter> {
7645  template<typename T, typename ChildNodeT>
7646  struct Node : SharedImpl<> {
7647  explicit Node( T const& _value ) : value( _value ) {}
7648  virtual ~Node() {}
7649 
7650  typedef std::vector<Ptr<ChildNodeT> > ChildNodes;
7651  T value;
7652  ChildNodes children;
7653  };
7654  struct SectionNode : SharedImpl<> {
7655  explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {}
7656  virtual ~SectionNode();
7657 
7658  bool operator == ( SectionNode const& other ) const {
7659  return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
7660  }
7661  bool operator == ( Ptr<SectionNode> const& other ) const {
7662  return operator==( *other );
7663  }
7664 
7665  SectionStats stats;
7666  typedef std::vector<Ptr<SectionNode> > ChildSections;
7667  typedef std::vector<AssertionStats> Assertions;
7668  ChildSections childSections;
7669  Assertions assertions;
7670  std::string stdOut;
7671  std::string stdErr;
7672  };
7673 
7674  struct BySectionInfo {
7675  BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
7676  BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
7677  bool operator() ( Ptr<SectionNode> const& node ) const {
7678  return node->stats.sectionInfo.lineInfo == m_other.lineInfo;
7679  }
7680  private:
7681  void operator=( BySectionInfo const& );
7682  SectionInfo const& m_other;
7683  };
7684 
7685  typedef Node<TestCaseStats, SectionNode> TestCaseNode;
7686  typedef Node<TestGroupStats, TestCaseNode> TestGroupNode;
7687  typedef Node<TestRunStats, TestGroupNode> TestRunNode;
7688 
7689  CumulativeReporterBase( ReporterConfig const& _config )
7690  : m_config( _config.fullConfig() ),
7691  stream( _config.stream() )
7692  {}
7693  ~CumulativeReporterBase();
7694 
7695  virtual void testRunStarting( TestRunInfo const& ) {}
7696  virtual void testGroupStarting( GroupInfo const& ) {}
7697 
7698  virtual void testCaseStarting( TestCaseInfo const& ) {}
7699 
7700  virtual void sectionStarting( SectionInfo const& sectionInfo ) {
7701  SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
7702  Ptr<SectionNode> node;
7703  if( m_sectionStack.empty() ) {
7704  if( !m_rootSection )
7705  m_rootSection = new SectionNode( incompleteStats );
7706  node = m_rootSection;
7707  }
7708  else {
7709  SectionNode& parentNode = *m_sectionStack.back();
7710  SectionNode::ChildSections::const_iterator it =
7711  std::find_if( parentNode.childSections.begin(),
7712  parentNode.childSections.end(),
7713  BySectionInfo( sectionInfo ) );
7714  if( it == parentNode.childSections.end() ) {
7715  node = new SectionNode( incompleteStats );
7716  parentNode.childSections.push_back( node );
7717  }
7718  else
7719  node = *it;
7720  }
7721  m_sectionStack.push_back( node );
7722  m_deepestSection = node;
7723  }
7724 
7725  virtual void assertionStarting( AssertionInfo const& ) {}
7726 
7727  virtual bool assertionEnded( AssertionStats const& assertionStats ) {
7728  assert( !m_sectionStack.empty() );
7729  SectionNode& sectionNode = *m_sectionStack.back();
7730  sectionNode.assertions.push_back( assertionStats );
7731  return true;
7732  }
7733  virtual void sectionEnded( SectionStats const& sectionStats ) {
7734  assert( !m_sectionStack.empty() );
7735  SectionNode& node = *m_sectionStack.back();
7736  node.stats = sectionStats;
7737  m_sectionStack.pop_back();
7738  }
7739  virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
7740  Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats );
7741  assert( m_sectionStack.size() == 0 );
7742  node->children.push_back( m_rootSection );
7743  m_testCases.push_back( node );
7744  m_rootSection.reset();
7745 
7746  assert( m_deepestSection );
7747  m_deepestSection->stdOut = testCaseStats.stdOut;
7748  m_deepestSection->stdErr = testCaseStats.stdErr;
7749  }
7750  virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
7751  Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats );
7752  node->children.swap( m_testCases );
7753  m_testGroups.push_back( node );
7754  }
7755  virtual void testRunEnded( TestRunStats const& testRunStats ) {
7756  Ptr<TestRunNode> node = new TestRunNode( testRunStats );
7757  node->children.swap( m_testGroups );
7758  m_testRuns.push_back( node );
7759  testRunEndedCumulative();
7760  }
7761  virtual void testRunEndedCumulative() = 0;
7762 
7763  virtual void skipTest( TestCaseInfo const& ) {}
7764 
7765  Ptr<IConfig> m_config;
7766  std::ostream& stream;
7767  std::vector<AssertionStats> m_assertions;
7768  std::vector<std::vector<Ptr<SectionNode> > > m_sections;
7769  std::vector<Ptr<TestCaseNode> > m_testCases;
7770  std::vector<Ptr<TestGroupNode> > m_testGroups;
7771 
7772  std::vector<Ptr<TestRunNode> > m_testRuns;
7773 
7774  Ptr<SectionNode> m_rootSection;
7775  Ptr<SectionNode> m_deepestSection;
7776  std::vector<Ptr<SectionNode> > m_sectionStack;
7777 
7778  };
7779 
7780  template<char C>
7781  char const* getLineOfChars() {
7782  static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
7783  if( !*line ) {
7784  memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
7785  line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
7786  }
7787  return line;
7788  }
7789 
7790 } // end namespace Catch
7791 
7792 // #included from: ../internal/catch_reporter_registrars.hpp
7793 #define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
7794 
7795 namespace Catch {
7796 
7797  template<typename T>
7798  class LegacyReporterRegistrar {
7799 
7800  class ReporterFactory : public IReporterFactory {
7801  virtual IStreamingReporter* create( ReporterConfig const& config ) const {
7802  return new LegacyReporterAdapter( new T( config ) );
7803  }
7804 
7805  virtual std::string getDescription() const {
7806  return T::getDescription();
7807  }
7808  };
7809 
7810  public:
7811 
7812  LegacyReporterRegistrar( std::string const& name ) {
7813  getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
7814  }
7815  };
7816 
7817  template<typename T>
7818  class ReporterRegistrar {
7819 
7820  class ReporterFactory : public IReporterFactory {
7821 
7822  // *** Please Note ***:
7823  // - If you end up here looking at a compiler error because it's trying to register
7824  // your custom reporter class be aware that the native reporter interface has changed
7825  // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via
7826  // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter.
7827  // However please consider updating to the new interface as the old one is now
7828  // deprecated and will probably be removed quite soon!
7829  // Please contact me via github if you have any questions at all about this.
7830  // In fact, ideally, please contact me anyway to let me know you've hit this - as I have
7831  // no idea who is actually using custom reporters at all (possibly no-one!).
7832  // The new interface is designed to minimise exposure to interface changes in the future.
7833  virtual IStreamingReporter* create( ReporterConfig const& config ) const {
7834  return new T( config );
7835  }
7836 
7837  virtual std::string getDescription() const {
7838  return T::getDescription();
7839  }
7840  };
7841 
7842  public:
7843 
7844  ReporterRegistrar( std::string const& name ) {
7845  getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
7846  }
7847  };
7848 }
7849 
7850 #define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \
7851  namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
7852 #define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
7853  namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
7854 
7855 // #included from: ../internal/catch_xmlwriter.hpp
7856 #define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED
7857 
7858 #include <sstream>
7859 #include <string>
7860 #include <vector>
7861 
7862 namespace Catch {
7863 
7864  class XmlWriter {
7865  public:
7866 
7867  class ScopedElement {
7868  public:
7869  ScopedElement( XmlWriter* writer )
7870  : m_writer( writer )
7871  {}
7872 
7873  ScopedElement( ScopedElement const& other )
7874  : m_writer( other.m_writer ){
7875  other.m_writer = NULL;
7876  }
7877 
7878  ~ScopedElement() {
7879  if( m_writer )
7880  m_writer->endElement();
7881  }
7882 
7883  ScopedElement& writeText( std::string const& text, bool indent = true ) {
7884  m_writer->writeText( text, indent );
7885  return *this;
7886  }
7887 
7888  template<typename T>
7889  ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
7890  m_writer->writeAttribute( name, attribute );
7891  return *this;
7892  }
7893 
7894  private:
7895  mutable XmlWriter* m_writer;
7896  };
7897 
7898  XmlWriter()
7899  : m_tagIsOpen( false ),
7900  m_needsNewline( false ),
7901  m_os( &Catch::cout() )
7902  {}
7903 
7904  XmlWriter( std::ostream& os )
7905  : m_tagIsOpen( false ),
7906  m_needsNewline( false ),
7907  m_os( &os )
7908  {}
7909 
7910  ~XmlWriter() {
7911  while( !m_tags.empty() )
7912  endElement();
7913  }
7914 
7915  XmlWriter& startElement( std::string const& name ) {
7916  ensureTagClosed();
7917  newlineIfNecessary();
7918  stream() << m_indent << "<" << name;
7919  m_tags.push_back( name );
7920  m_indent += " ";
7921  m_tagIsOpen = true;
7922  return *this;
7923  }
7924 
7925  ScopedElement scopedElement( std::string const& name ) {
7926  ScopedElement scoped( this );
7927  startElement( name );
7928  return scoped;
7929  }
7930 
7931  XmlWriter& endElement() {
7932  newlineIfNecessary();
7933  m_indent = m_indent.substr( 0, m_indent.size()-2 );
7934  if( m_tagIsOpen ) {
7935  stream() << "/>\n";
7936  m_tagIsOpen = false;
7937  }
7938  else {
7939  stream() << m_indent << "</" << m_tags.back() << ">\n";
7940  }
7941  m_tags.pop_back();
7942  return *this;
7943  }
7944 
7945  XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {
7946  if( !name.empty() && !attribute.empty() ) {
7947  stream() << " " << name << "=\"";
7948  writeEncodedText( attribute );
7949  stream() << "\"";
7950  }
7951  return *this;
7952  }
7953 
7954  XmlWriter& writeAttribute( std::string const& name, bool attribute ) {
7955  stream() << " " << name << "=\"" << ( attribute ? "true" : "false" ) << "\"";
7956  return *this;
7957  }
7958 
7959  template<typename T>
7960  XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
7961  if( !name.empty() )
7962  stream() << " " << name << "=\"" << attribute << "\"";
7963  return *this;
7964  }
7965 
7966  XmlWriter& writeText( std::string const& text, bool indent = true ) {
7967  if( !text.empty() ){
7968  bool tagWasOpen = m_tagIsOpen;
7969  ensureTagClosed();
7970  if( tagWasOpen && indent )
7971  stream() << m_indent;
7972  writeEncodedText( text );
7973  m_needsNewline = true;
7974  }
7975  return *this;
7976  }
7977 
7978  XmlWriter& writeComment( std::string const& text ) {
7979  ensureTagClosed();
7980  stream() << m_indent << "<!--" << text << "-->";
7981  m_needsNewline = true;
7982  return *this;
7983  }
7984 
7985  XmlWriter& writeBlankLine() {
7986  ensureTagClosed();
7987  stream() << "\n";
7988  return *this;
7989  }
7990 
7991  void setStream( std::ostream& os ) {
7992  m_os = &os;
7993  }
7994 
7995  private:
7996  XmlWriter( XmlWriter const& );
7997  void operator=( XmlWriter const& );
7998 
7999  std::ostream& stream() {
8000  return *m_os;
8001  }
8002 
8003  void ensureTagClosed() {
8004  if( m_tagIsOpen ) {
8005  stream() << ">\n";
8006  m_tagIsOpen = false;
8007  }
8008  }
8009 
8010  void newlineIfNecessary() {
8011  if( m_needsNewline ) {
8012  stream() << "\n";
8013  m_needsNewline = false;
8014  }
8015  }
8016 
8017  void writeEncodedText( std::string const& text ) {
8018  static const char* charsToEncode = "<&\"";
8019  std::string mtext = text;
8020  std::string::size_type pos = mtext.find_first_of( charsToEncode );
8021  while( pos != std::string::npos ) {
8022  stream() << mtext.substr( 0, pos );
8023 
8024  switch( mtext[pos] ) {
8025  case '<':
8026  stream() << "&lt;";
8027  break;
8028  case '&':
8029  stream() << "&amp;";
8030  break;
8031  case '\"':
8032  stream() << "&quot;";
8033  break;
8034  }
8035  mtext = mtext.substr( pos+1 );
8036  pos = mtext.find_first_of( charsToEncode );
8037  }
8038  stream() << mtext;
8039  }
8040 
8041  bool m_tagIsOpen;
8042  bool m_needsNewline;
8043  std::vector<std::string> m_tags;
8044  std::string m_indent;
8045  std::ostream* m_os;
8046  };
8047 
8048 }
8049 namespace Catch {
8050  class XmlReporter : public StreamingReporterBase {
8051  public:
8052  XmlReporter( ReporterConfig const& _config )
8053  : StreamingReporterBase( _config ),
8054  m_sectionDepth( 0 )
8055  {}
8056 
8057  virtual ~XmlReporter();
8058 
8059  static std::string getDescription() {
8060  return "Reports test results as an XML document";
8061  }
8062 
8063  public: // StreamingReporterBase
8064  virtual ReporterPreferences getPreferences() const {
8065  ReporterPreferences prefs;
8066  prefs.shouldRedirectStdOut = true;
8067  return prefs;
8068  }
8069 
8070  virtual void noMatchingTestCases( std::string const& s ) {
8071  StreamingReporterBase::noMatchingTestCases( s );
8072  }
8073 
8074  virtual void testRunStarting( TestRunInfo const& testInfo ) {
8075  StreamingReporterBase::testRunStarting( testInfo );
8076  m_xml.setStream( stream );
8077  m_xml.startElement( "Catch" );
8078  if( !m_config->name().empty() )
8079  m_xml.writeAttribute( "name", m_config->name() );
8080  }
8081 
8082  virtual void testGroupStarting( GroupInfo const& groupInfo ) {
8083  StreamingReporterBase::testGroupStarting( groupInfo );
8084  m_xml.startElement( "Group" )
8085  .writeAttribute( "name", groupInfo.name );
8086  }
8087 
8088  virtual void testCaseStarting( TestCaseInfo const& testInfo ) {
8089  StreamingReporterBase::testCaseStarting(testInfo);
8090  m_xml.startElement( "TestCase" ).writeAttribute( "name", trim( testInfo.name ) );
8091 
8092  if ( m_config->showDurations() == ShowDurations::Always )
8093  m_testCaseTimer.start();
8094  }
8095 
8096  virtual void sectionStarting( SectionInfo const& sectionInfo ) {
8097  StreamingReporterBase::sectionStarting( sectionInfo );
8098  if( m_sectionDepth++ > 0 ) {
8099  m_xml.startElement( "Section" )
8100  .writeAttribute( "name", trim( sectionInfo.name ) )
8101  .writeAttribute( "description", sectionInfo.description );
8102  }
8103  }
8104 
8105  virtual void assertionStarting( AssertionInfo const& ) { }
8106 
8107  virtual bool assertionEnded( AssertionStats const& assertionStats ) {
8108  const AssertionResult& assertionResult = assertionStats.assertionResult;
8109 
8110  // Print any info messages in <Info> tags.
8111  if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
8112  for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
8113  it != itEnd;
8114  ++it ) {
8115  if( it->type == ResultWas::Info ) {
8116  m_xml.scopedElement( "Info" )
8117  .writeText( it->message );
8118  } else if ( it->type == ResultWas::Warning ) {
8119  m_xml.scopedElement( "Warning" )
8120  .writeText( it->message );
8121  }
8122  }
8123  }
8124 
8125  // Drop out if result was successful but we're not printing them.
8126  if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) )
8127  return true;
8128 
8129  // Print the expression if there is one.
8130  if( assertionResult.hasExpression() ) {
8131  m_xml.startElement( "Expression" )
8132  .writeAttribute( "success", assertionResult.succeeded() )
8133  .writeAttribute( "type", assertionResult.getTestMacroName() )
8134  .writeAttribute( "filename", assertionResult.getSourceInfo().file )
8135  .writeAttribute( "line", assertionResult.getSourceInfo().line );
8136 
8137  m_xml.scopedElement( "Original" )
8138  .writeText( assertionResult.getExpression() );
8139  m_xml.scopedElement( "Expanded" )
8140  .writeText( assertionResult.getExpandedExpression() );
8141  }
8142 
8143  // And... Print a result applicable to each result type.
8144  switch( assertionResult.getResultType() ) {
8146  m_xml.scopedElement( "Exception" )
8147  .writeAttribute( "filename", assertionResult.getSourceInfo().file )
8148  .writeAttribute( "line", assertionResult.getSourceInfo().line )
8149  .writeText( assertionResult.getMessage() );
8150  break;
8152  m_xml.scopedElement( "Fatal Error Condition" )
8153  .writeAttribute( "filename", assertionResult.getSourceInfo().file )
8154  .writeAttribute( "line", assertionResult.getSourceInfo().line )
8155  .writeText( assertionResult.getMessage() );
8156  break;
8157  case ResultWas::Info:
8158  m_xml.scopedElement( "Info" )
8159  .writeText( assertionResult.getMessage() );
8160  break;
8161  case ResultWas::Warning:
8162  // Warning will already have been written
8163  break;
8165  m_xml.scopedElement( "Failure" )
8166  .writeText( assertionResult.getMessage() );
8167  break;
8168  default:
8169  break;
8170  }
8171 
8172  if( assertionResult.hasExpression() )
8173  m_xml.endElement();
8174 
8175  return true;
8176  }
8177 
8178  virtual void sectionEnded( SectionStats const& sectionStats ) {
8179  StreamingReporterBase::sectionEnded( sectionStats );
8180  if( --m_sectionDepth > 0 ) {
8181  XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
8182  e.writeAttribute( "successes", sectionStats.assertions.passed );
8183  e.writeAttribute( "failures", sectionStats.assertions.failed );
8184  e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
8185 
8186  if ( m_config->showDurations() == ShowDurations::Always )
8187  e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
8188 
8189  m_xml.endElement();
8190  }
8191  }
8192 
8193  virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
8194  StreamingReporterBase::testCaseEnded( testCaseStats );
8195  XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
8196  e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
8197 
8198  if ( m_config->showDurations() == ShowDurations::Always )
8199  e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
8200 
8201  m_xml.endElement();
8202  }
8203 
8204  virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
8205  StreamingReporterBase::testGroupEnded( testGroupStats );
8206  // TODO: Check testGroupStats.aborting and act accordingly.
8207  m_xml.scopedElement( "OverallResults" )
8208  .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
8209  .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
8210  .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
8211  m_xml.endElement();
8212  }
8213 
8214  virtual void testRunEnded( TestRunStats const& testRunStats ) {
8215  StreamingReporterBase::testRunEnded( testRunStats );
8216  m_xml.scopedElement( "OverallResults" )
8217  .writeAttribute( "successes", testRunStats.totals.assertions.passed )
8218  .writeAttribute( "failures", testRunStats.totals.assertions.failed )
8219  .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
8220  m_xml.endElement();
8221  }
8222 
8223  private:
8224  Timer m_testCaseTimer;
8225  XmlWriter m_xml;
8226  int m_sectionDepth;
8227  };
8228 
8229  INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter )
8230 
8231 } // end namespace Catch
8232 
8233 // #included from: ../reporters/catch_reporter_junit.hpp
8234 #define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED
8235 
8236 #include <assert.h>
8237 
8238 namespace Catch {
8239 
8240  class JunitReporter : public CumulativeReporterBase {
8241  public:
8242  JunitReporter( ReporterConfig const& _config )
8243  : CumulativeReporterBase( _config ),
8244  xml( _config.stream() )
8245  {}
8246 
8247  ~JunitReporter();
8248 
8249  static std::string getDescription() {
8250  return "Reports test results in an XML format that looks like Ant's junitreport target";
8251  }
8252 
8253  virtual void noMatchingTestCases( std::string const& /*spec*/ ) {}
8254 
8255  virtual ReporterPreferences getPreferences() const {
8256  ReporterPreferences prefs;
8257  prefs.shouldRedirectStdOut = true;
8258  return prefs;
8259  }
8260 
8261  virtual void testRunStarting( TestRunInfo const& runInfo ) {
8262  CumulativeReporterBase::testRunStarting( runInfo );
8263  xml.startElement( "testsuites" );
8264  }
8265 
8266  virtual void testGroupStarting( GroupInfo const& groupInfo ) {
8267  suiteTimer.start();
8268  stdOutForSuite.str("");
8269  stdErrForSuite.str("");
8270  unexpectedExceptions = 0;
8271  CumulativeReporterBase::testGroupStarting( groupInfo );
8272  }
8273 
8274  virtual bool assertionEnded( AssertionStats const& assertionStats ) {
8275  if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException )
8276  unexpectedExceptions++;
8277  return CumulativeReporterBase::assertionEnded( assertionStats );
8278  }
8279 
8280  virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
8281  stdOutForSuite << testCaseStats.stdOut;
8282  stdErrForSuite << testCaseStats.stdErr;
8283  CumulativeReporterBase::testCaseEnded( testCaseStats );
8284  }
8285 
8286  virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
8287  double suiteTime = suiteTimer.getElapsedSeconds();
8288  CumulativeReporterBase::testGroupEnded( testGroupStats );
8289  writeGroup( *m_testGroups.back(), suiteTime );
8290  }
8291 
8292  virtual void testRunEndedCumulative() {
8293  xml.endElement();
8294  }
8295 
8296  void writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
8297  XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
8298  TestGroupStats const& stats = groupNode.value;
8299  xml.writeAttribute( "name", stats.groupInfo.name );
8300  xml.writeAttribute( "errors", unexpectedExceptions );
8301  xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
8302  xml.writeAttribute( "tests", stats.totals.assertions.total() );
8303  xml.writeAttribute( "hostname", "tbd" ); // !TBD
8304  if( m_config->showDurations() == ShowDurations::Never )
8305  xml.writeAttribute( "time", "" );
8306  else
8307  xml.writeAttribute( "time", suiteTime );
8308  xml.writeAttribute( "timestamp", "tbd" ); // !TBD
8309 
8310  // Write test cases
8311  for( TestGroupNode::ChildNodes::const_iterator
8312  it = groupNode.children.begin(), itEnd = groupNode.children.end();
8313  it != itEnd;
8314  ++it )
8315  writeTestCase( **it );
8316 
8317  xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false );
8318  xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false );
8319  }
8320 
8321  void writeTestCase( TestCaseNode const& testCaseNode ) {
8322  TestCaseStats const& stats = testCaseNode.value;
8323 
8324  // All test cases have exactly one section - which represents the
8325  // test case itself. That section may have 0-n nested sections
8326  assert( testCaseNode.children.size() == 1 );
8327  SectionNode const& rootSection = *testCaseNode.children.front();
8328 
8329  std::string className = stats.testInfo.className;
8330 
8331  if( className.empty() ) {
8332  if( rootSection.childSections.empty() )
8333  className = "global";
8334  }
8335  writeSection( className, "", rootSection );
8336  }
8337 
8338  void writeSection( std::string const& className,
8339  std::string const& rootName,
8340  SectionNode const& sectionNode ) {
8341  std::string name = trim( sectionNode.stats.sectionInfo.name );
8342  if( !rootName.empty() )
8343  name = rootName + "/" + name;
8344 
8345  if( !sectionNode.assertions.empty() ||
8346  !sectionNode.stdOut.empty() ||
8347  !sectionNode.stdErr.empty() ) {
8348  XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
8349  if( className.empty() ) {
8350  xml.writeAttribute( "classname", name );
8351  xml.writeAttribute( "name", "root" );
8352  }
8353  else {
8354  xml.writeAttribute( "classname", className );
8355  xml.writeAttribute( "name", name );
8356  }
8357  xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) );
8358 
8359  writeAssertions( sectionNode );
8360 
8361  if( !sectionNode.stdOut.empty() )
8362  xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
8363  if( !sectionNode.stdErr.empty() )
8364  xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
8365  }
8366  for( SectionNode::ChildSections::const_iterator
8367  it = sectionNode.childSections.begin(),
8368  itEnd = sectionNode.childSections.end();
8369  it != itEnd;
8370  ++it )
8371  if( className.empty() )
8372  writeSection( name, "", **it );
8373  else
8374  writeSection( className, name, **it );
8375  }
8376 
8377  void writeAssertions( SectionNode const& sectionNode ) {
8378  for( SectionNode::Assertions::const_iterator
8379  it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end();
8380  it != itEnd;
8381  ++it )
8382  writeAssertion( *it );
8383  }
8384  void writeAssertion( AssertionStats const& stats ) {
8385  AssertionResult const& result = stats.assertionResult;
8386  if( !result.isOk() ) {
8387  std::string elementName;
8388  switch( result.getResultType() ) {
8391  elementName = "error";
8392  break;
8394  elementName = "failure";
8395  break;
8397  elementName = "failure";
8398  break;
8400  elementName = "failure";
8401  break;
8402 
8403  // We should never see these here:
8404  case ResultWas::Info:
8405  case ResultWas::Warning:
8406  case ResultWas::Ok:
8407  case ResultWas::Unknown:
8408  case ResultWas::FailureBit:
8409  case ResultWas::Exception:
8410  elementName = "internalError";
8411  break;
8412  }
8413 
8414  XmlWriter::ScopedElement e = xml.scopedElement( elementName );
8415 
8416  xml.writeAttribute( "message", result.getExpandedExpression() );
8417  xml.writeAttribute( "type", result.getTestMacroName() );
8418 
8419  std::ostringstream oss;
8420  if( !result.getMessage().empty() )
8421  oss << result.getMessage() << "\n";
8422  for( std::vector<MessageInfo>::const_iterator
8423  it = stats.infoMessages.begin(),
8424  itEnd = stats.infoMessages.end();
8425  it != itEnd;
8426  ++it )
8427  if( it->type == ResultWas::Info )
8428  oss << it->message << "\n";
8429 
8430  oss << "at " << result.getSourceInfo();
8431  xml.writeText( oss.str(), false );
8432  }
8433  }
8434 
8435  XmlWriter xml;
8436  Timer suiteTimer;
8437  std::ostringstream stdOutForSuite;
8438  std::ostringstream stdErrForSuite;
8439  unsigned int unexpectedExceptions;
8440  };
8441 
8442  INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter )
8443 
8444 } // end namespace Catch
8445 
8446 // #included from: ../reporters/catch_reporter_console.hpp
8447 #define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED
8448 
8449 namespace Catch {
8450 
8451  struct ConsoleReporter : StreamingReporterBase {
8452  ConsoleReporter( ReporterConfig const& _config )
8453  : StreamingReporterBase( _config ),
8454  m_headerPrinted( false )
8455  {}
8456 
8457  virtual ~ConsoleReporter();
8458  static std::string getDescription() {
8459  return "Reports test results as plain lines of text";
8460  }
8461  virtual ReporterPreferences getPreferences() const {
8462  ReporterPreferences prefs;
8463  prefs.shouldRedirectStdOut = false;
8464  return prefs;
8465  }
8466 
8467  virtual void noMatchingTestCases( std::string const& spec ) {
8468  stream << "No test cases matched '" << spec << "'" << std::endl;
8469  }
8470 
8471  virtual void assertionStarting( AssertionInfo const& ) {
8472  }
8473 
8474  virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
8475  AssertionResult const& result = _assertionStats.assertionResult;
8476 
8477  bool printInfoMessages = true;
8478 
8479  // Drop out if result was successful and we're not printing those
8480  if( !m_config->includeSuccessfulResults() && result.isOk() ) {
8481  if( result.getResultType() != ResultWas::Warning )
8482  return false;
8483  printInfoMessages = false;
8484  }
8485 
8486  lazyPrint();
8487 
8488  AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
8489  printer.print();
8490  stream << std::endl;
8491  return true;
8492  }
8493 
8494  virtual void sectionStarting( SectionInfo const& _sectionInfo ) {
8495  m_headerPrinted = false;
8496  StreamingReporterBase::sectionStarting( _sectionInfo );
8497  }
8498  virtual void sectionEnded( SectionStats const& _sectionStats ) {
8499  if( _sectionStats.missingAssertions ) {
8500  lazyPrint();
8501  Colour colour( Colour::ResultError );
8502  if( m_sectionStack.size() > 1 )
8503  stream << "\nNo assertions in section";
8504  else
8505  stream << "\nNo assertions in test case";
8506  stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
8507  }
8508  if( m_headerPrinted ) {
8509  if( m_config->showDurations() == ShowDurations::Always )
8510  stream << "Completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
8511  m_headerPrinted = false;
8512  }
8513  else {
8514  if( m_config->showDurations() == ShowDurations::Always )
8515  stream << _sectionStats.sectionInfo.name << " completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
8516  }
8517  StreamingReporterBase::sectionEnded( _sectionStats );
8518  }
8519 
8520  virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) {
8521  StreamingReporterBase::testCaseEnded( _testCaseStats );
8522  m_headerPrinted = false;
8523  }
8524  virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) {
8525  if( currentGroupInfo.used ) {
8526  printSummaryDivider();
8527  stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
8528  printTotals( _testGroupStats.totals );
8529  stream << "\n" << std::endl;
8530  }
8531  StreamingReporterBase::testGroupEnded( _testGroupStats );
8532  }
8533  virtual void testRunEnded( TestRunStats const& _testRunStats ) {
8534  printTotalsDivider( _testRunStats.totals );
8535  printTotals( _testRunStats.totals );
8536  stream << std::endl;
8537  StreamingReporterBase::testRunEnded( _testRunStats );
8538  }
8539 
8540  private:
8541 
8542  class AssertionPrinter {
8543  void operator= ( AssertionPrinter const& );
8544  public:
8545  AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
8546  : stream( _stream ),
8547  stats( _stats ),
8548  result( _stats.assertionResult ),
8549  colour( Colour::None ),
8550  message( result.getMessage() ),
8551  messages( _stats.infoMessages ),
8552  printInfoMessages( _printInfoMessages )
8553  {
8554  switch( result.getResultType() ) {
8555  case ResultWas::Ok:
8556  colour = Colour::Success;
8557  passOrFail = "PASSED";
8558  //if( result.hasMessage() )
8559  if( _stats.infoMessages.size() == 1 )
8560  messageLabel = "with message";
8561  if( _stats.infoMessages.size() > 1 )
8562  messageLabel = "with messages";
8563  break;
8565  if( result.isOk() ) {
8566  colour = Colour::Success;
8567  passOrFail = "FAILED - but was ok";
8568  }
8569  else {
8570  colour = Colour::Error;
8571  passOrFail = "FAILED";
8572  }
8573  if( _stats.infoMessages.size() == 1 )
8574  messageLabel = "with message";
8575  if( _stats.infoMessages.size() > 1 )
8576  messageLabel = "with messages";
8577  break;
8579  colour = Colour::Error;
8580  passOrFail = "FAILED";
8581  messageLabel = "due to unexpected exception with message";
8582  break;
8584  colour = Colour::Error;
8585  passOrFail = "FAILED";
8586  messageLabel = "due to a fatal error condition";
8587  break;
8589  colour = Colour::Error;
8590  passOrFail = "FAILED";
8591  messageLabel = "because no exception was thrown where one was expected";
8592  break;
8593  case ResultWas::Info:
8594  messageLabel = "info";
8595  break;
8596  case ResultWas::Warning:
8597  messageLabel = "warning";
8598  break;
8600  passOrFail = "FAILED";
8601  colour = Colour::Error;
8602  if( _stats.infoMessages.size() == 1 )
8603  messageLabel = "explicitly with message";
8604  if( _stats.infoMessages.size() > 1 )
8605  messageLabel = "explicitly with messages";
8606  break;
8607  // These cases are here to prevent compiler warnings
8608  case ResultWas::Unknown:
8609  case ResultWas::FailureBit:
8610  case ResultWas::Exception:
8611  passOrFail = "** internal error **";
8612  colour = Colour::Error;
8613  break;
8614  }
8615  }
8616 
8617  void print() const {
8618  printSourceInfo();
8619  if( stats.totals.assertions.total() > 0 ) {
8620  if( result.isOk() )
8621  stream << "\n";
8622  printResultType();
8623  printOriginalExpression();
8624  printReconstructedExpression();
8625  }
8626  else {
8627  stream << "\n";
8628  }
8629  printMessage();
8630  }
8631 
8632  private:
8633  void printResultType() const {
8634  if( !passOrFail.empty() ) {
8635  Colour colourGuard( colour );
8636  stream << passOrFail << ":\n";
8637  }
8638  }
8639  void printOriginalExpression() const {
8640  if( result.hasExpression() ) {
8641  Colour colourGuard( Colour::OriginalExpression );
8642  stream << " ";
8643  stream << result.getExpressionInMacro();
8644  stream << "\n";
8645  }
8646  }
8647  void printReconstructedExpression() const {
8648  if( result.hasExpandedExpression() ) {
8649  stream << "with expansion:\n";
8650  Colour colourGuard( Colour::ReconstructedExpression );
8651  stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << "\n";
8652  }
8653  }
8654  void printMessage() const {
8655  if( !messageLabel.empty() )
8656  stream << messageLabel << ":" << "\n";
8657  for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();
8658  it != itEnd;
8659  ++it ) {
8660  // If this assertion is a warning ignore any INFO messages
8661  if( printInfoMessages || it->type != ResultWas::Info )
8662  stream << Text( it->message, TextAttributes().setIndent(2) ) << "\n";
8663  }
8664  }
8665  void printSourceInfo() const {
8666  Colour colourGuard( Colour::FileName );
8667  stream << result.getSourceInfo() << ": ";
8668  }
8669 
8670  std::ostream& stream;
8671  AssertionStats const& stats;
8672  AssertionResult const& result;
8673  Colour::Code colour;
8674  std::string passOrFail;
8675  std::string messageLabel;
8677  std::vector<MessageInfo> messages;
8678  bool printInfoMessages;
8679  };
8680 
8681  void lazyPrint() {
8682 
8683  if( !currentTestRunInfo.used )
8684  lazyPrintRunInfo();
8685  if( !currentGroupInfo.used )
8686  lazyPrintGroupInfo();
8687 
8688  if( !m_headerPrinted ) {
8689  printTestCaseAndSectionHeader();
8690  m_headerPrinted = true;
8691  }
8692  }
8693  void lazyPrintRunInfo() {
8694  stream << "\n" << getLineOfChars<'~'>() << "\n";
8695  Colour colour( Colour::SecondaryText );
8696  stream << currentTestRunInfo->name
8697  << " is a Catch v" << libraryVersion << " host application.\n"
8698  << "Run with -? for options\n\n";
8699 
8700  if( m_config->rngSeed() != 0 )
8701  stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
8702 
8703  currentTestRunInfo.used = true;
8704  }
8705  void lazyPrintGroupInfo() {
8706  if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {
8707  printClosedHeader( "Group: " + currentGroupInfo->name );
8708  currentGroupInfo.used = true;
8709  }
8710  }
8711  void printTestCaseAndSectionHeader() {
8712  assert( !m_sectionStack.empty() );
8713  printOpenHeader( currentTestCaseInfo->name );
8714 
8715  if( m_sectionStack.size() > 1 ) {
8716  Colour colourGuard( Colour::Headers );
8717 
8718  std::vector<SectionInfo>::const_iterator
8719  it = m_sectionStack.begin()+1, // Skip first section (test case)
8720  itEnd = m_sectionStack.end();
8721  for( ; it != itEnd; ++it )
8722  printHeaderString( it->name, 2 );
8723  }
8724 
8725  SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
8726 
8727  if( !lineInfo.empty() ){
8728  stream << getLineOfChars<'-'>() << "\n";
8729  Colour colourGuard( Colour::FileName );
8730  stream << lineInfo << "\n";
8731  }
8732  stream << getLineOfChars<'.'>() << "\n" << std::endl;
8733  }
8734 
8735  void printClosedHeader( std::string const& _name ) {
8736  printOpenHeader( _name );
8737  stream << getLineOfChars<'.'>() << "\n";
8738  }
8739  void printOpenHeader( std::string const& _name ) {
8740  stream << getLineOfChars<'-'>() << "\n";
8741  {
8742  Colour colourGuard( Colour::Headers );
8743  printHeaderString( _name );
8744  }
8745  }
8746 
8747  // if string has a : in first line will set indent to follow it on
8748  // subsequent lines
8749  void printHeaderString( std::string const& _string, std::size_t indent = 0 ) {
8750  std::size_t i = _string.find( ": " );
8751  if( i != std::string::npos )
8752  i+=2;
8753  else
8754  i = 0;
8755  stream << Text( _string, TextAttributes()
8756  .setIndent( indent+i)
8757  .setInitialIndent( indent ) ) << "\n";
8758  }
8759 
8760  struct SummaryColumn {
8761 
8762  SummaryColumn( std::string const& _label, Colour::Code _colour )
8763  : label( _label ),
8764  colour( _colour )
8765  {}
8766  SummaryColumn addRow( std::size_t count ) {
8767  std::ostringstream oss;
8768  oss << count;
8769  std::string row = oss.str();
8770  for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) {
8771  while( it->size() < row.size() )
8772  *it = " " + *it;
8773  while( it->size() > row.size() )
8774  row = " " + row;
8775  }
8776  rows.push_back( row );
8777  return *this;
8778  }
8779 
8781  Colour::Code colour;
8782  std::vector<std::string> rows;
8783 
8784  };
8785 
8786  void printTotals( Totals const& totals ) {
8787  if( totals.testCases.total() == 0 ) {
8788  stream << Colour( Colour::Warning ) << "No tests ran\n";
8789  }
8790  else if( totals.assertions.total() > 0 && totals.assertions.allPassed() ) {
8791  stream << Colour( Colour::ResultSuccess ) << "All tests passed";
8792  stream << " ("
8793  << pluralise( totals.assertions.passed, "assertion" ) << " in "
8794  << pluralise( totals.testCases.passed, "test case" ) << ")"
8795  << "\n";
8796  }
8797  else {
8798 
8799  std::vector<SummaryColumn> columns;
8800  columns.push_back( SummaryColumn( "", Colour::None )
8801  .addRow( totals.testCases.total() )
8802  .addRow( totals.assertions.total() ) );
8803  columns.push_back( SummaryColumn( "passed", Colour::Success )
8804  .addRow( totals.testCases.passed )
8805  .addRow( totals.assertions.passed ) );
8806  columns.push_back( SummaryColumn( "failed", Colour::ResultError )
8807  .addRow( totals.testCases.failed )
8808  .addRow( totals.assertions.failed ) );
8809  columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure )
8810  .addRow( totals.testCases.failedButOk )
8811  .addRow( totals.assertions.failedButOk ) );
8812 
8813  printSummaryRow( "test cases", columns, 0 );
8814  printSummaryRow( "assertions", columns, 1 );
8815  }
8816  }
8817  void printSummaryRow( std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row ) {
8818  for( std::vector<SummaryColumn>::const_iterator it = cols.begin(); it != cols.end(); ++it ) {
8819  std::string value = it->rows[row];
8820  if( it->label.empty() ) {
8821  stream << label << ": ";
8822  if( value != "0" )
8823  stream << value;
8824  else
8825  stream << Colour( Colour::Warning ) << "- none -";
8826  }
8827  else if( value != "0" ) {
8828  stream << Colour( Colour::LightGrey ) << " | ";
8829  stream << Colour( it->colour )
8830  << value << " " << it->label;
8831  }
8832  }
8833  stream << "\n";
8834  }
8835 
8836  static std::size_t makeRatio( std::size_t number, std::size_t total ) {
8837  std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0;
8838  return ( ratio == 0 && number > 0 ) ? 1 : ratio;
8839  }
8840  static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {
8841  if( i > j && i > k )
8842  return i;
8843  else if( j > k )
8844  return j;
8845  else
8846  return k;
8847  }
8848 
8849  void printTotalsDivider( Totals const& totals ) {
8850  if( totals.testCases.total() > 0 ) {
8851  std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() );
8852  std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() );
8853  std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() );
8854  while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 )
8855  findMax( failedRatio, failedButOkRatio, passedRatio )++;
8856  while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 )
8857  findMax( failedRatio, failedButOkRatio, passedRatio )--;
8858 
8859  stream << Colour( Colour::Error ) << std::string( failedRatio, '=' );
8860  stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' );
8861  if( totals.testCases.allPassed() )
8862  stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' );
8863  else
8864  stream << Colour( Colour::Success ) << std::string( passedRatio, '=' );
8865  }
8866  else {
8867  stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' );
8868  }
8869  stream << "\n";
8870  }
8871  void printSummaryDivider() {
8872  stream << getLineOfChars<'-'>() << "\n";
8873  }
8874 
8875  private:
8876  bool m_headerPrinted;
8877  };
8878 
8879  INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter )
8880 
8881 } // end namespace Catch
8882 
8883 // #included from: ../reporters/catch_reporter_compact.hpp
8884 #define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED
8885 
8886 namespace Catch {
8887 
8888  struct CompactReporter : StreamingReporterBase {
8889 
8890  CompactReporter( ReporterConfig const& _config )
8891  : StreamingReporterBase( _config )
8892  {}
8893 
8894  virtual ~CompactReporter();
8895 
8896  static std::string getDescription() {
8897  return "Reports test results on a single line, suitable for IDEs";
8898  }
8899 
8900  virtual ReporterPreferences getPreferences() const {
8901  ReporterPreferences prefs;
8902  prefs.shouldRedirectStdOut = false;
8903  return prefs;
8904  }
8905 
8906  virtual void noMatchingTestCases( std::string const& spec ) {
8907  stream << "No test cases matched '" << spec << "'" << std::endl;
8908  }
8909 
8910  virtual void assertionStarting( AssertionInfo const& ) {
8911  }
8912 
8913  virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
8914  AssertionResult const& result = _assertionStats.assertionResult;
8915 
8916  bool printInfoMessages = true;
8917 
8918  // Drop out if result was successful and we're not printing those
8919  if( !m_config->includeSuccessfulResults() && result.isOk() ) {
8920  if( result.getResultType() != ResultWas::Warning )
8921  return false;
8922  printInfoMessages = false;
8923  }
8924 
8925  AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
8926  printer.print();
8927 
8928  stream << std::endl;
8929  return true;
8930  }
8931 
8932  virtual void testRunEnded( TestRunStats const& _testRunStats ) {
8933  printTotals( _testRunStats.totals );
8934  stream << "\n" << std::endl;
8935  StreamingReporterBase::testRunEnded( _testRunStats );
8936  }
8937 
8938  private:
8939  class AssertionPrinter {
8940  void operator= ( AssertionPrinter const& );
8941  public:
8942  AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
8943  : stream( _stream )
8944  , stats( _stats )
8945  , result( _stats.assertionResult )
8946  , messages( _stats.infoMessages )
8947  , itMessage( _stats.infoMessages.begin() )
8948  , printInfoMessages( _printInfoMessages )
8949  {}
8950 
8951  void print() {
8952  printSourceInfo();
8953 
8954  itMessage = messages.begin();
8955 
8956  switch( result.getResultType() ) {
8957  case ResultWas::Ok:
8958  printResultType( Colour::ResultSuccess, passedString() );
8959  printOriginalExpression();
8960  printReconstructedExpression();
8961  if ( ! result.hasExpression() )
8962  printRemainingMessages( Colour::None );
8963  else
8964  printRemainingMessages();
8965  break;
8967  if( result.isOk() )
8968  printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) );
8969  else
8970  printResultType( Colour::Error, failedString() );
8971  printOriginalExpression();
8972  printReconstructedExpression();
8973  printRemainingMessages();
8974  break;
8976  printResultType( Colour::Error, failedString() );
8977  printIssue( "unexpected exception with message:" );
8978  printMessage();
8979  printExpressionWas();
8980  printRemainingMessages();
8981  break;
8983  printResultType( Colour::Error, failedString() );
8984  printIssue( "fatal error condition with message:" );
8985  printMessage();
8986  printExpressionWas();
8987  printRemainingMessages();
8988  break;
8990  printResultType( Colour::Error, failedString() );
8991  printIssue( "expected exception, got none" );
8992  printExpressionWas();
8993  printRemainingMessages();
8994  break;
8995  case ResultWas::Info:
8996  printResultType( Colour::None, "info" );
8997  printMessage();
8998  printRemainingMessages();
8999  break;
9000  case ResultWas::Warning:
9001  printResultType( Colour::None, "warning" );
9002  printMessage();
9003  printRemainingMessages();
9004  break;
9006  printResultType( Colour::Error, failedString() );
9007  printIssue( "explicitly" );
9008  printRemainingMessages( Colour::None );
9009  break;
9010  // These cases are here to prevent compiler warnings
9011  case ResultWas::Unknown:
9012  case ResultWas::FailureBit:
9013  case ResultWas::Exception:
9014  printResultType( Colour::Error, "** internal error **" );
9015  break;
9016  }
9017  }
9018 
9019  private:
9020  // Colour::LightGrey
9021 
9022  static Colour::Code dimColour() { return Colour::FileName; }
9023 
9024 #ifdef CATCH_PLATFORM_MAC
9025  static const char* failedString() { return "FAILED"; }
9026  static const char* passedString() { return "PASSED"; }
9027 #else
9028  static const char* failedString() { return "failed"; }
9029  static const char* passedString() { return "passed"; }
9030 #endif
9031 
9032  void printSourceInfo() const {
9033  Colour colourGuard( Colour::FileName );
9034  stream << result.getSourceInfo() << ":";
9035  }
9036 
9037  void printResultType( Colour::Code colour, std::string passOrFail ) const {
9038  if( !passOrFail.empty() ) {
9039  {
9040  Colour colourGuard( colour );
9041  stream << " " << passOrFail;
9042  }
9043  stream << ":";
9044  }
9045  }
9046 
9047  void printIssue( std::string issue ) const {
9048  stream << " " << issue;
9049  }
9050 
9051  void printExpressionWas() {
9052  if( result.hasExpression() ) {
9053  stream << ";";
9054  {
9055  Colour colour( dimColour() );
9056  stream << " expression was:";
9057  }
9058  printOriginalExpression();
9059  }
9060  }
9061 
9062  void printOriginalExpression() const {
9063  if( result.hasExpression() ) {
9064  stream << " " << result.getExpression();
9065  }
9066  }
9067 
9068  void printReconstructedExpression() const {
9069  if( result.hasExpandedExpression() ) {
9070  {
9071  Colour colour( dimColour() );
9072  stream << " for: ";
9073  }
9074  stream << result.getExpandedExpression();
9075  }
9076  }
9077 
9078  void printMessage() {
9079  if ( itMessage != messages.end() ) {
9080  stream << " '" << itMessage->message << "'";
9081  ++itMessage;
9082  }
9083  }
9084 
9085  void printRemainingMessages( Colour::Code colour = dimColour() ) {
9086  if ( itMessage == messages.end() )
9087  return;
9088 
9089  // using messages.end() directly yields compilation error:
9090  std::vector<MessageInfo>::const_iterator itEnd = messages.end();
9091  const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );
9092 
9093  {
9094  Colour colourGuard( colour );
9095  stream << " with " << pluralise( N, "message" ) << ":";
9096  }
9097 
9098  for(; itMessage != itEnd; ) {
9099  // If this assertion is a warning ignore any INFO messages
9100  if( printInfoMessages || itMessage->type != ResultWas::Info ) {
9101  stream << " '" << itMessage->message << "'";
9102  if ( ++itMessage != itEnd ) {
9103  Colour colourGuard( dimColour() );
9104  stream << " and";
9105  }
9106  }
9107  }
9108  }
9109 
9110  private:
9111  std::ostream& stream;
9112  AssertionStats const& stats;
9113  AssertionResult const& result;
9114  std::vector<MessageInfo> messages;
9115  std::vector<MessageInfo>::const_iterator itMessage;
9116  bool printInfoMessages;
9117  };
9118 
9119  // Colour, message variants:
9120  // - white: No tests ran.
9121  // - red: Failed [both/all] N test cases, failed [both/all] M assertions.
9122  // - white: Passed [both/all] N test cases (no assertions).
9123  // - red: Failed N tests cases, failed M assertions.
9124  // - green: Passed [both/all] N tests cases with M assertions.
9125 
9126  std::string bothOrAll( std::size_t count ) const {
9127  return count == 1 ? "" : count == 2 ? "both " : "all " ;
9128  }
9129 
9130  void printTotals( const Totals& totals ) const {
9131  if( totals.testCases.total() == 0 ) {
9132  stream << "No tests ran.";
9133  }
9134  else if( totals.testCases.failed == totals.testCases.total() ) {
9135  Colour colour( Colour::ResultError );
9136  const std::string qualify_assertions_failed =
9137  totals.assertions.failed == totals.assertions.total() ?
9138  bothOrAll( totals.assertions.failed ) : "";
9139  stream <<
9140  "Failed " << bothOrAll( totals.testCases.failed )
9141  << pluralise( totals.testCases.failed, "test case" ) << ", "
9142  "failed " << qualify_assertions_failed <<
9143  pluralise( totals.assertions.failed, "assertion" ) << ".";
9144  }
9145  else if( totals.assertions.total() == 0 ) {
9146  stream <<
9147  "Passed " << bothOrAll( totals.testCases.total() )
9148  << pluralise( totals.testCases.total(), "test case" )
9149  << " (no assertions).";
9150  }
9151  else if( totals.assertions.failed ) {
9152  Colour colour( Colour::ResultError );
9153  stream <<
9154  "Failed " << pluralise( totals.testCases.failed, "test case" ) << ", "
9155  "failed " << pluralise( totals.assertions.failed, "assertion" ) << ".";
9156  }
9157  else {
9158  Colour colour( Colour::ResultSuccess );
9159  stream <<
9160  "Passed " << bothOrAll( totals.testCases.passed )
9161  << pluralise( totals.testCases.passed, "test case" ) <<
9162  " with " << pluralise( totals.assertions.passed, "assertion" ) << ".";
9163  }
9164  }
9165  };
9166 
9167  INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter )
9168 
9169 } // end namespace Catch
9170 
9171 namespace Catch {
9173  IShared::~IShared() {}
9174  StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}
9175  IContext::~IContext() {}
9183  IReporter::~IReporter() {}
9184  IReporterFactory::~IReporterFactory() {}
9185  IReporterRegistry::~IReporterRegistry() {}
9186  IStreamingReporter::~IStreamingReporter() {}
9187  AssertionStats::~AssertionStats() {}
9188  SectionStats::~SectionStats() {}
9189  TestCaseStats::~TestCaseStats() {}
9190  TestGroupStats::~TestGroupStats() {}
9191  TestRunStats::~TestRunStats() {}
9192  CumulativeReporterBase::SectionNode::~SectionNode() {}
9193  CumulativeReporterBase::~CumulativeReporterBase() {}
9194 
9195  StreamingReporterBase::~StreamingReporterBase() {}
9196  ConsoleReporter::~ConsoleReporter() {}
9197  CompactReporter::~CompactReporter() {}
9198  IRunner::~IRunner() {}
9200  IConfig::~IConfig() {}
9201  XmlReporter::~XmlReporter() {}
9202  JunitReporter::~JunitReporter() {}
9203  TestRegistry::~TestRegistry() {}
9204  FreeFunctionTestCase::~FreeFunctionTestCase() {}
9207  TestSpec::Pattern::~Pattern() {}
9208  TestSpec::NamePattern::~NamePattern() {}
9209  TestSpec::TagPattern::~TagPattern() {}
9210  TestSpec::ExcludedPattern::~ExcludedPattern() {}
9211 
9216 
9217  void Config::dummy() {}
9218 }
9219 
9220 #ifdef __clang__
9221 #pragma clang diagnostic pop
9222 #endif
9223 
9224 #endif
9225 
9226 #ifdef CATCH_CONFIG_MAIN
9227 // #included from: internal/catch_default_main.hpp
9228 #define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
9229 
9230 #ifndef __OBJC__
9231 
9232 // Standard C/C++ main entry point
9233 int main (int argc, char * const argv[]) {
9234  return Catch::Session().run( argc, argv );
9235 }
9236 
9237 #else // __OBJC__
9238 
9239 // Objective-C entry point
9240 int main (int argc, char * const argv[]) {
9241 #if !CATCH_ARC_ENABLED
9242  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
9243 #endif
9244 
9245  Catch::registerTestMethods();
9246  int result = Catch::Session().run( argc, (char* const*)argv );
9247 
9248 #if !CATCH_ARC_ENABLED
9249  [pool drain];
9250 #endif
9251 
9252  return result;
9253 }
9254 
9255 #endif // __OBJC__
9256 
9257 #endif
9258 
9259 #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
9260 # undef CLARA_CONFIG_MAIN
9261 #endif
9262 
9264 
9265 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
9266 #ifdef CATCH_CONFIG_PREFIX_ALL
9267 
9268 #define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" )
9269 #define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" )
9270 
9271 #define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS" )
9272 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" )
9273 #define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" )
9274 
9275 #define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" )
9276 #define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CATCH_CHECK_FALSE" )
9277 #define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" )
9278 #define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" )
9279 #define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" )
9280 
9281 #define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS" )
9282 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" )
9283 #define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" )
9284 
9285 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" )
9286 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" )
9287 
9288 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
9289 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg )
9290 #define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
9291 #define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
9292 #define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
9293 
9294 #ifdef CATCH_CONFIG_VARIADIC_MACROS
9295  #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
9296  #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
9297  #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
9298  #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
9299  #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ )
9300  #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ )
9301 #else
9302  #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
9303  #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
9304  #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
9305  #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
9306  #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg )
9307  #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg )
9308 #endif
9309 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
9310 
9311 #define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
9312 #define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
9313 
9314 #define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
9315 
9316 // "BDD-style" convenience wrappers
9317 #ifdef CATCH_CONFIG_VARIADIC_MACROS
9318 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
9319 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
9320 #else
9321 #define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags )
9322 #define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
9323 #endif
9324 #define CATCH_GIVEN( desc ) CATCH_SECTION( "Given: " desc, "" )
9325 #define CATCH_WHEN( desc ) CATCH_SECTION( " When: " desc, "" )
9326 #define CATCH_AND_WHEN( desc ) CATCH_SECTION( " And: " desc, "" )
9327 #define CATCH_THEN( desc ) CATCH_SECTION( " Then: " desc, "" )
9328 #define CATCH_AND_THEN( desc ) CATCH_SECTION( " And: " desc, "" )
9329 
9330 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
9331 #else
9332 
9333 #define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" )
9334 #define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" )
9335 
9336 #define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "REQUIRE_THROWS" )
9337 #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" )
9338 #define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" )
9339 
9340 #define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" )
9341 #define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CHECK_FALSE" )
9342 #define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" )
9343 #define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" )
9344 #define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" )
9345 
9346 #define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS" )
9347 #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" )
9348 #define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
9349 
9350 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" )
9351 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" )
9352 
9353 #define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
9354 #define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg )
9355 #define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
9356 #define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
9357 #define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
9358 
9359 #ifdef CATCH_CONFIG_VARIADIC_MACROS
9360  #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
9361  #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
9362  #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
9363  #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
9364  #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ )
9365  #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ )
9366 #else
9367  #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
9368  #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
9369  #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
9370  #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
9371  #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg )
9372  #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg )
9373 #endif
9374 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
9375 
9376 #define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
9377 #define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
9378 
9379 #define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
9380 
9381 #endif
9382 
9383 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
9384 
9385 // "BDD-style" convenience wrappers
9386 #ifdef CATCH_CONFIG_VARIADIC_MACROS
9387 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
9388 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
9389 #else
9390 #define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags )
9391 #define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
9392 #endif
9393 #define GIVEN( desc ) SECTION( " Given: " desc, "" )
9394 #define WHEN( desc ) SECTION( " When: " desc, "" )
9395 #define AND_WHEN( desc ) SECTION( "And when: " desc, "" )
9396 #define THEN( desc ) SECTION( " Then: " desc, "" )
9397 #define AND_THEN( desc ) SECTION( " And: " desc, "" )
9398 
9399 using Catch::Detail::Approx;
9400 
9401 // #included from: internal/catch_reenable_warnings.h
9402 
9403 #define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED
9404 
9405 #ifdef __clang__
9406 # ifdef __ICC // icpc defines the __clang__ macro
9407 # pragma warning(pop)
9408 # else
9409 # pragma clang diagnostic pop
9410 # endif
9411 #elif defined __GNUC__
9412 # pragma GCC diagnostic pop
9413 #endif
9414 
9415 #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
9416 
std::string macroName
Definition: catch.hpp:714
virtual std::string getCurrentTestName() const =0
virtual std::size_t size() const
Definition: catch.hpp:1880
std::vector< Ptr< Matcher< ExpressionT > > > m_matchers
Definition: catch.hpp:2278
std::string macroName
Definition: catch.hpp:1420
virtual std::string toString() const
Definition: catch.hpp:2345
Equals(std::string const &str)
Definition: catch.hpp:2289
bool okToFail() const
bool alwaysTrue()
Definition: catch.hpp:310
SourceLineInfo lineInfo
Definition: catch.hpp:1421
std::size_t m_count
Definition: catch.hpp:284
Approx operator()(double value)
Definition: catch.hpp:2131
virtual std::string toString() const
Definition: catch.hpp:2265
unsigned int sequence
Definition: catch.hpp:1424
GLfixed GLfixed GLint GLint order
Definition: glext.h:4927
Option(Option const &_other)
Definition: catch.hpp:2447
const GLint * first
Definition: glext.h:368
std::vector< T > m_values
Definition: catch.hpp:1885
std::string toString(std::vector< T, Allocator > const &v)
Definition: catch.hpp:1222
std::string rawMemoryToString(const T &object)
Definition: catch.hpp:1178
std::string file
Definition: catch.hpp:302
MessageInfo m_info
Definition: catch.hpp:1449
virtual ~NonCopyable()
bool isFalseTest(int flags)
Definition: catch.hpp:694
static Approx custom()
Definition: catch.hpp:2127
ExceptionTranslatorRegistrar(std::string(*translateFunction)(T &))
Definition: catch.hpp:2091
NameAndDesc(const char *_name="", const char *_description="")
Definition: catch.hpp:558
std::string getMessage() const
Impl::StdString::StartsWith StartsWith(const char *substr)
Definition: catch.hpp:2394
Counts testCases
Definition: catch.hpp:1771
bool operator<(TestCase const &other) const
Counts assertions
Definition: catch.hpp:1770
bool allPassed() const
Definition: catch.hpp:1732
CopyableStream & operator=(CopyableStream const &other)
Definition: catch.hpp:774
virtual void registerTest(TestCase const &testInfo)=0
Approx & scale(double newScale)
Definition: catch.hpp:2160
virtual ~ITestCase()
Option & operator=(Option const &_other)
Definition: catch.hpp:2455
std::string toString() const
Definition: catch.hpp:2165
void toLowerInPlace(std::string &s)
bool isTrue(bool value)
Definition: catch.hpp:309
std::string name
Definition: catch.hpp:2550
virtual Ptr< Matcher > clone() const =0
std::string getExpressionInMacro() const
std::string reconstructedExpression
Definition: catch.hpp:724
INT64 INT64 INT64 remainder
Definition: wglext.h:822
ResultDisposition::Flags operator|(ResultDisposition::Flags lhs, ResultDisposition::Flags rhs)
Definition: catch.hpp:689
std::string rawMemoryToString(const void *object, std::size_t size)
std::ostream & operator<<(std::ostream &os, SourceLineInfo const &info)
void cleanUpContext()
rs_error * e
bool contains(std::string const &s, std::string const &infix)
std::string m_name
Definition: catch.hpp:1815
const GLfloat * m
Definition: glext.h:6461
double getElapsedSeconds() const
SectionInfo m_info
Definition: catch.hpp:1813
bool expectedToFail() const
ExpressionLhs< T const & > operator<=(T const &operand)
Definition: catch.hpp:1398
virtual ~IShared()
void writeToDebugConsole(std::string const &text)
std::set< std::string > lcaseTags
Definition: catch.hpp:2554
T const & operator+(T const &value, StreamEndStop)
Definition: catch.hpp:325
EndsWith(std::string const &substr)
Definition: catch.hpp:2337
float3 operator*(const float3 &a, float b)
Definition: types.h:115
virtual T getValue(std::size_t index) const
Definition: catch.hpp:1853
SpecialProperties properties
Definition: catch.hpp:2557
GLuint GLsizei const GLchar * message
Definition: glext.h:2482
std::string(* exceptionTranslateFunction)()
Definition: catch.hpp:2054
std::size_t failedButOk
Definition: catch.hpp:1741
T valueOr(T const &defaultValue) const
Definition: catch.hpp:2480
virtual ~NotImplementedException() CATCH_NOEXCEPT
Definition: catch.hpp:343
BetweenGenerator(T from, T to)
Definition: catch.hpp:1851
void deleteAll(ContainerT &container)
Definition: catch.hpp:257
virtual void popScopedMessage(MessageInfo const &message)=0
virtual bool advanceGeneratorsForCurrentTest()=0
typedef HANDLE(WINAPI *PFNWGLCREATEBUFFERREGIONARBPROC)(HDC hDC
IResultCapture & getResultCapture()
GLsizei const GLchar *const * string
Definition: glext.h:683
const char * name
Definition: catch.hpp:562
Ptr(T *p)
Definition: catch.hpp:401
std::vector< Ptr< Matcher< ExpressionT > > > m_matchers
Definition: catch.hpp:2244
T const & operator*() const
Definition: catch.hpp:2476
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:2479
static bool evaluate(T1 const &lhs, T2 const &rhs)
Definition: catch.hpp:903
unsigned int getElapsedMilliseconds() const
bool replaceInPlace(std::string &str, std::string const &replaceThis, std::string const &withThis)
bool succeeded() const
bool allOk() const
Definition: catch.hpp:1735
bool some() const
Definition: catch.hpp:2484
Definition: catch.hpp:227
std::string getExpandedExpression() const
IGeneratorsForTest * createGeneratorsForTest()
virtual void registerReporter(std::string const &name, IReporterFactory *factory)=0
AssertionResultData m_data
Definition: catch.hpp:822
virtual void invoke() const
Definition: catch.hpp:544
bool empty() const
T * operator->()
Definition: catch.hpp:2477
Counts m_assertions
Definition: catch.hpp:1816
GLbitfield flags
Definition: glext.h:1478
GLuint GLuint stream
Definition: glext.h:1774
#define CATCH_INTERNAL_ERROR(msg)
Definition: catch.hpp:331
void trueValue() const
Definition: catch.hpp:253
IMutableRegistryHub & getMutableRegistryHub()
GLdouble n
Definition: glext.h:1950
GLhandleARB obj
Definition: glext.h:3919
T * m_p
Definition: catch.hpp:437
GLsizei GLsizei GLfloat distance
Definition: glext.h:9615
GLsizei const GLubyte * commands
Definition: glext.h:9570
ScopedMessage(MessageBuilder const &builder)
virtual void handleFatalErrorCondition(std::string const &message)=0
void config(uvc::device &device, uint8_t gyro_bw, uint8_t gyro_range, uint8_t accel_bw, uint8_t accel_range, uint32_t time_seed)
bool operator==(TestCase const &other) const
CompositeGenerator(CompositeGenerator &other)
Definition: catch.hpp:1894
static std::string convert(U *p)
Definition: catch.hpp:1191
TestCase makeTestCase(ITestCase *testCase, std::string const &className, std::string const &name, std::string const &description, SourceLineInfo const &lineInfo)
virtual void pushScopedMessage(MessageInfo const &message)=0
virtual bool aborting() const =0
ResultDisposition::Flags resultDisposition
Definition: catch.hpp:717
ExceptionTranslator(std::string(*translateFunction)(T &))
Definition: catch.hpp:2072
static bool evaluate(T1 const &lhs, T2 const &rhs)
Definition: catch.hpp:915
Impl::Generic::AllOf< ExpressionT > AllOf(Impl::Matcher< ExpressionT > const &m1, Impl::Matcher< ExpressionT > const &m2, Impl::Matcher< ExpressionT > const &m3)
Definition: catch.hpp:2362
static bool evaluate(T1 const &lhs, T2 const &rhs)
Definition: catch.hpp:891
AssertionInfo m_info
Definition: catch.hpp:755
IRegistryHub & getRegistryHub()
bool none() const
Definition: catch.hpp:2485
virtual std::string toString() const
Definition: catch.hpp:2231
bool shouldContinueOnFailure(int flags)
Definition: catch.hpp:693
virtual std::size_t size() const
Definition: catch.hpp:1857
std::ostringstream oss
Definition: catch.hpp:779
std::string getTestMacroName() const
Contains(std::string const &substr)
Definition: catch.hpp:2305
ResultBuilder & setLhs(std::string const &lhs)
ResultWas::OfType resultType
Definition: catch.hpp:726
bool isJustInfo(int flags)
Definition: catch.hpp:676
void add(T value)
Definition: catch.hpp:1872
void add(const IGenerator< T > *generator)
Definition: catch.hpp:1928
bool isHidden() const
AssertionResult build() const
#define CATCH_NOEXCEPT
Definition: catch.hpp:223
GLsizeiptr const void GLenum usage
Definition: glext.h:532
bool throws() const
static type makeSafe(bool value)
Definition: catch.hpp:249
std::string description
Definition: catch.hpp:1699
virtual T getValue(std::size_t index) const
Definition: catch.hpp:1876
virtual bool match(std::string const &expr) const
Definition: catch.hpp:2326
GLint level
Definition: glext.h:112
std::string reconstructExpression() const
static ITagAliasRegistry const & get()
Totals delta(Totals const &prevTotals) const
Definition: catch.hpp:1753
T * operator->() const
Definition: catch.hpp:432
static std::string convert(R C::*p)
Definition: catch.hpp:1201
std::size_t failed
Definition: catch.hpp:1740
Option(T const &_value)
Definition: catch.hpp:2444
SourceLineInfo getSourceInfo() const
void cleanUp()
unsigned int m_rc
Definition: catch.hpp:459
GLuint index
Definition: glext.h:655
const GLubyte * c
Definition: glext.h:11542
bool operator<(SourceLineInfo const &other) const
ResultBuilder & m_rb
Definition: catch.hpp:1388
GLuint GLuint GLsizei count
Definition: glext.h:111
Impl::StdString::Contains Contains(const char *substr)
Definition: catch.hpp:2388
TestCase(ITestCase *testCase, TestCaseInfo const &info)
bool shouldSuppressFailure(int flags)
Definition: catch.hpp:695
virtual void assertionEnded(AssertionResult const &result)=0
virtual ~IRegistryHub()
ResultWas::OfType getResultType() const
GLenum GLint GLint * precision
Definition: glext.h:1867
bool isOk(ResultWas::OfType resultType)
Definition: catch.hpp:673
ResultWas::OfType type
Definition: catch.hpp:1422
virtual void registerTranslator(const IExceptionTranslator *translator)=0
GLuint GLuint end
Definition: glext.h:111
ResultBuilder & setResultType(ResultWas::OfType result)
virtual bool match(std::string const &expr) const
Definition: catch.hpp:2342
static bool evaluate(T1 const &lhs, T2 const &rhs)
Definition: catch.hpp:885
static bool evaluate(T1 const &lhs, T2 const &rhs)
Definition: catch.hpp:897
GLfloat f
Definition: glext.h:1868
GLenum GLenum GLsizei void * row
Definition: glext.h:2717
TestCase & operator=(TestCase const &other)
SourceLineInfo lineInfo
Definition: catch.hpp:2556
MethodTestCase(void(C::*method)())
Definition: catch.hpp:542
bool operator==(SourceLineInfo const &other) const
bool hasMessage() const
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
MessageInfo(std::string const &_macroName, SourceLineInfo const &_lineInfo, ResultWas::OfType _type)
virtual std::string translateActiveException() const =0
virtual bool match(std::string const &expr) const
Definition: catch.hpp:2294
std::string className
Definition: catch.hpp:2551
static const char * getName()
Definition: catch.hpp:862
std::string m_label
Definition: catch.hpp:285
void throwLogicError(std::string const &message, SourceLineInfo const &locationInfo)
NotImplementedException(SourceLineInfo const &lineInfo)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * data
Definition: glext.h:223
SourceLineInfo lineInfo
Definition: catch.hpp:2424
std::string trim(std::string const &str)
bool endsWith(std::string const &s, std::string const &suffix)
AutoReg(TestFunction function, SourceLineInfo const &lineInfo, NameAndDesc const &nameAndDesc)
GLuint GLsizei const GLchar * label
Definition: glext.h:2484
std::string makeString(const char *str)
Definition: catch.hpp:2286
std::string toLower(std::string const &s)
void swap(TestCase &other)
std::string operator+()
Definition: catch.hpp:320
ResultBuilder & captureExpression(RhsT const &rhs)
Definition: catch.hpp:1379
std::string translateActiveException()
MessageBuilder(std::string const &macroName, SourceLineInfo const &lineInfo, ResultWas::OfType type)
Definition: catch.hpp:1437
void(SafeBool::* type)() const
Definition: catch.hpp:247
TestCaseInfo(std::string const &_name, std::string const &_className, std::string const &_description, std::set< std::string > const &_tags, SourceLineInfo const &_lineInfo)
std::string m_fileInfo
Definition: catch.hpp:1954
std::set< std::string > tags
Definition: catch.hpp:2553
TestCase withName(std::string const &_newName) const
NonCopyable & operator=(NonCopyable const &)
virtual size_t getGeneratorIndex(std::string const &fileInfo, size_t totalSize)=0
SourceLineInfo m_lineInfo
Definition: catch.hpp:349
TagAlias(std::string _tag, SourceLineInfo _lineInfo)
Definition: catch.hpp:2421
virtual ITestCaseRegistry const & getTestCaseRegistry() const =0
Approx(double value)
Definition: catch.hpp:2115
CopyableStream(CopyableStream const &other)
Definition: catch.hpp:771
GLdouble GLdouble t
Definition: glext.h:239
std::ostringstream m_stream
Definition: catch.hpp:1450
void registerTestCase(ITestCase *testCase, char const *className, NameAndDesc const &nameAndDesc, SourceLineInfo const &lineInfo)
std::string name
Definition: catch.hpp:1698
GLsizei const GLfloat * value
Definition: glext.h:693
Ptr< ITestCase > test
Definition: catch.hpp:2578
virtual T getValue(std::size_t index) const =0
std::size_t total() const
Definition: catch.hpp:1729
bool hasExpandedExpression() const
IContext & getCurrentContext()
virtual bool match(ExpressionT const &expr) const
Definition: catch.hpp:2224
AssertionResultData m_resultData
Definition: catch.hpp:756
#define INTERNAL_CATCH_STRINGIFY(expr)
Definition: catch.hpp:70
const GLdouble * v
Definition: glext.h:232
bool allowThrows() const
virtual bool match(std::string const &expr) const
Definition: catch.hpp:2310
GLenum mode
Definition: glext.h:1117
void(* TestFunction)()
Definition: catch.hpp:555
Ptr(Ptr const &other)
Definition: catch.hpp:405
void reset()
Definition: catch.hpp:413
RegistrarForTagAliases(char const *alias, char const *tag, SourceLineInfo const &lineInfo)
int main()
bool applyEvaluator(T1 const &lhs, T2 const &rhs)
Definition: catch.hpp:921
virtual Ptr< Matcher< ExpressionT > > clone() const
Definition: catch.hpp:2206
FalseType testStreamable(FalseType)
static unsigned int globalCount
Definition: catch.hpp:1433
void deleteAllValues(AssociativeContainerT &container)
Definition: catch.hpp:264
void captureResult(ResultWas::OfType resultType)
typedef void(APIENTRYP PFNGLDRAWRANGEELEMENTSPROC)(GLenum mode
virtual bool moveNext()=0
virtual std::string toString() const
Definition: catch.hpp:2297
GLubyte * pattern
Definition: glext.h:2714
StartsWith(std::string const &substr)
Definition: catch.hpp:2321
TestCaseInfo const & getTestCaseInfo() const
SourceLineInfo lineInfo
Definition: catch.hpp:715
AssertionInfo m_assertionInfo
Definition: catch.hpp:821
ExpressionLhs(ResultBuilder &rb, T lhs)
Definition: catch.hpp:1316
AllOf & add(Matcher< ExpressionT > const &matcher)
Definition: catch.hpp:2220
std::string toString(T const &value)
converts any type to a string
Definition: catch.hpp:1283
CompositeGenerator & then(CompositeGenerator &other)
Definition: catch.hpp:1933
CompositeGenerator & setFileInfo(const char *fileInfo)
Definition: catch.hpp:1901
AnyOf & add(Matcher< ExpressionT > const &matcher)
Definition: catch.hpp:2254
GLenum GLsizei GLsizei GLint * values
Definition: glext.h:1484
virtual std::size_t size() const =0
GLuint id
Definition: glext.h:523
bool compare(T *lhs, int rhs)
Definition: catch.hpp:990
Stream createStream(std::string const &streamName)
virtual std::string toString() const
Definition: catch.hpp:2313
GLdouble s
Definition: glext.h:231
GLboolean reset
Definition: glext.h:2718
virtual void release() const
Definition: catch.hpp:454
GLint GLint GLsizei width
Definition: glext.h:112
Section(SectionInfo const &info)
SectionInfo(SourceLineInfo const &_lineInfo, std::string const &_name, std::string const &_description=std::string())
GLuint const GLchar * name
Definition: glext.h:655
virtual IReporterRegistry const & getReporterRegistry() const =0
GLsizeiptr size
Definition: glext.h:532
ResultBuilder & setOp(std::string const &op)
virtual IResultCapture * getResultCapture()=0
static bool evaluate(T1 const &lhs, T2 const &rhs)
Definition: catch.hpp:909
CompositeGenerator< T > between(T from, T to)
Definition: catch.hpp:1961
Impl::StdString::EndsWith EndsWith(const char *substr)
Definition: catch.hpp:2400
std::string tag
Definition: catch.hpp:2423
GLuint GLsizei GLsizei * length
Definition: glext.h:664
void useActiveException(ResultDisposition::Flags resultDisposition=ResultDisposition::Normal)
const T * operator->() const
Definition: catch.hpp:2478
MessageInfo m_info
Definition: catch.hpp:1459
virtual ~IRunner()
std::size_t passed
Definition: catch.hpp:1739
std::string unprintableString
static std::string convert(T const &_value)
Definition: catch.hpp:1168
std::size_t line
Definition: catch.hpp:303
bool shouldDebugBreak() const
bool alwaysFalse()
Definition: catch.hpp:311
virtual const char * what() const CATCH_NOEXCEPT
void move(CompositeGenerator &other)
Definition: catch.hpp:1947
Approx(Approx const &other)
Definition: catch.hpp:2121
virtual ~IGenerator()
Definition: catch.hpp:1843
std::string rangeToString(InputIterator first, InputIterator last)
Definition: catch.hpp:1289
ResultBuilder & setRhs(std::string const &rhs)
Impl::Generic::AnyOf< ExpressionT > AnyOf(Impl::Matcher< ExpressionT > const &m1, Impl::Matcher< ExpressionT > const &m2, Impl::Matcher< ExpressionT > const &m3)
Definition: catch.hpp:2373
T * nullableValue
Definition: catch.hpp:2493
virtual void addRef() const
Definition: catch.hpp:451
IMutableContext & getCurrentMutableContext()
bool m_sectionIncluded
Definition: catch.hpp:1817
T & operator*()
Definition: catch.hpp:2475
void invoke() const
virtual bool match(ExpressionT const &expr) const
Definition: catch.hpp:2258
T & operator*() const
Definition: catch.hpp:431
GLuint GLenum GLenum transform
Definition: glext.h:10445
const char * description
Definition: catch.hpp:563
Timer m_timer
Definition: catch.hpp:1818
GLuint object
Definition: glext.h:6426
bool operator==(const float3 &a, const float3 &b)
Definition: types.h:113
virtual IExceptionTranslatorRegistry & getExceptionTranslatorRegistry()=0
void reset()
Definition: catch.hpp:2469
std::string tagsAsString
Definition: catch.hpp:2555
std::string description
Definition: catch.hpp:2552
virtual std::string toString() const
Definition: catch.hpp:2329
SourceLineInfo lineInfo
Definition: catch.hpp:1700
T & opCast(T const &t)
Definition: catch.hpp:871
void swap(Ptr &other)
Definition: catch.hpp:428
uint64_t m_ticks
Definition: catch.hpp:1795
virtual void sectionEnded(SectionInfo const &name, Counts const &assertions, double _durationInSeconds)=0
std::string message
Definition: catch.hpp:1423
virtual ~MethodTestCase()
Definition: catch.hpp:550
bool isDebuggerActive()
GLfloat GLfloat p
Definition: glext.h:11539
StartsWith(StartsWith const &other)
Definition: catch.hpp:2322
virtual ~IContext()
GLuint64EXT * result
Definition: glext.h:9881
NotImplementedException(NotImplementedException const &)
Definition: catch.hpp:341
std::string getExpression() const
AutoReg(void(C::*method)(), char const *className, NameAndDesc const &nameAndDesc, SourceLineInfo const &lineInfo)
Definition: catch.hpp:573
GLint GLint GLint GLint GLint x
Definition: glext.h:114
CopyableStream m_stream
Definition: catch.hpp:828
virtual void getFilteredTests(TestSpec const &testSpec, IConfig const &config, std::vector< TestCase > &matchingTestCases, bool negated=false) const =0
static std::string convert(T const &)
Definition: catch.hpp:1161
virtual std::string expandAliases(std::string const &unexpandedTestSpec) const =0
ResultBuilder(char const *macroName, SourceLineInfo const &lineInfo, char const *capturedExpression, ResultDisposition::Flags resultDisposition)
bool hasExpression() const
unsigned int getElapsedMicroseconds() const
GLuint start
Definition: glext.h:111
CompositeGenerator & then(T value)
Definition: catch.hpp:1938
Approx & epsilon(double newEpsilon)
Definition: catch.hpp:2155
pluralise(std::size_t count, std::string const &label)
static std::ostream & s
Definition: catch.hpp:1126
std::string capturedExpression
Definition: catch.hpp:716
virtual Ptr< IConfig const > getConfig() const =0
std::vector< const IGenerator< T > * > m_composed
Definition: catch.hpp:1953
GLuint GLuint GLsizei GLenum type
Definition: glext.h:111
bool startsWith(std::string const &s, std::string const &prefix)
virtual IRunner * getRunner()=0
Impl::StdString::Equals Equals(const char *str)
Definition: catch.hpp:2382


librealsense
Author(s): Sergey Dorodnicov , Mark Horn , Reagan Lopez
autogenerated on Fri Mar 13 2020 03:16:16