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 
6031