CustusX  2020.12.15-dev+develop.686e7
An IGT application
catch.hpp
Go to the documentation of this file.
1 /*
2  * CATCH v1.0 build 10 (master branch)
3  * Generated: 2013-09-14 19:56:34.776409
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 diagnostic ignored "-Wglobal-constructors"
18 #pragma clang diagnostic ignored "-Wvariadic-macros"
19 
20 #pragma clang diagnostic push
21 #pragma clang diagnostic ignored "-Wpadded"
22 #endif
23 
24 // #included from: internal/catch_notimplemented_exception.h
25 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED
26 
27 // #included from: catch_common.h
28 #define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
29 
30 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
31 #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
32 #define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
33 
34 #define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
35 #define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
36 
37 #include <sstream>
38 #include <stdexcept>
39 #include <algorithm>
40 
41 // #included from: catch_compiler_capabilities.h
42 #define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
43 
44 // Much of the following code is based on Boost (1.53)
45 
47 // Borland
48 #ifdef __BORLANDC__
49 
50 #if (__BORLANDC__ > 0x582 )
51 //#define CATCH_CONFIG_SFINAE // Not confirmed
52 #endif
53 
54 #endif // __BORLANDC__
55 
57 // EDG
58 #ifdef __EDG_VERSION__
59 
60 #if (__EDG_VERSION__ > 238 )
61 //#define CATCH_CONFIG_SFINAE // Not confirmed
62 #endif
63 
64 #endif // __EDG_VERSION__
65 
67 // Digital Mars
68 #ifdef __DMC__
69 
70 #if (__DMC__ > 0x840 )
71 //#define CATCH_CONFIG_SFINAE // Not confirmed
72 #endif
73 
74 #endif // __DMC__
75 
77 // GCC
78 #ifdef __GNUC__
79 
80 #if __GNUC__ < 3
81 
82 #if (__GNUC_MINOR__ >= 96 )
83 //#define CATCH_CONFIG_SFINAE
84 #endif
85 
86 #elif __GNUC__ >= 3
87 
88 // #define CATCH_CONFIG_SFINAE // Taking this out completely for now
89 
90 #endif // __GNUC__ < 3
91 
92 #endif // __GNUC__
93 
95 // Visual C++
96 #ifdef _MSC_VER
97 
98 #if (_MSC_VER >= 1310 ) // (VC++ 7.0+)
99 //#define CATCH_CONFIG_SFINAE // Not confirmed
100 #endif
101 
102 #endif // _MSC_VER
103 
104 // Use variadic macros if the compiler supports them
105 #if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
106  ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
107  ( defined __GNUC__ && __GNUC__ >= 3 ) || \
108  ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
109 
110 #ifndef CATCH_CONFIG_NO_VARIADIC_MACROS
111 #define CATCH_CONFIG_VARIADIC_MACROS
112 #endif
113 
114 #endif
115 
116 namespace Catch {
117 
118  class NonCopyable {
119  NonCopyable( NonCopyable const& );
120  void operator = ( NonCopyable const& );
121  protected:
123  virtual ~NonCopyable();
124  };
125 
126  class SafeBool {
127  public:
128  typedef void (SafeBool::*type)() const;
129 
130  static type makeSafe( bool value ) {
131  return value ? &SafeBool::trueValue : 0;
132  }
133  private:
134  void trueValue() const {}
135  };
136 
137  template<typename ContainerT>
138  inline void deleteAll( ContainerT& container ) {
139  typename ContainerT::const_iterator it = container.begin();
140  typename ContainerT::const_iterator itEnd = container.end();
141  for(; it != itEnd; ++it )
142  delete *it;
143  }
144  template<typename AssociativeContainerT>
145  inline void deleteAllValues( AssociativeContainerT& container ) {
146  typename AssociativeContainerT::const_iterator it = container.begin();
147  typename AssociativeContainerT::const_iterator itEnd = container.end();
148  for(; it != itEnd; ++it )
149  delete it->second;
150  }
151 
152  template<typename ContainerT, typename Function>
153  inline void forEach( ContainerT& container, Function function ) {
154  std::for_each( container.begin(), container.end(), function );
155  }
156 
157  template<typename ContainerT, typename Function>
158  inline void forEach( ContainerT const& container, Function function ) {
159  std::for_each( container.begin(), container.end(), function );
160  }
161 
162  inline bool startsWith( std::string const& s, std::string const& prefix ) {
163  return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
164  }
165  inline bool endsWith( std::string const& s, std::string const& suffix ) {
166  return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
167  }
168  inline bool contains( std::string const& s, std::string const& infix ) {
169  return s.find( infix ) != std::string::npos;
170  }
171  inline void toLowerInPlace( std::string& s ) {
172  std::transform( s.begin(), s.end(), s.begin(), ::tolower );
173  }
174  inline std::string toLower( std::string const& s ) {
175  std::string lc = s;
176  toLowerInPlace( lc );
177  return lc;
178  }
179 
180  struct pluralise {
181  pluralise( std::size_t count, std::string const& label )
182  : m_count( count ),
183  m_label( label )
184  {}
185 
186  friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
187  os << pluraliser.m_count << " " << pluraliser.m_label;
188  if( pluraliser.m_count != 1 )
189  os << "s";
190  return os;
191  }
192 
193  std::size_t m_count;
194  std::string m_label;
195  };
196 
197  struct SourceLineInfo {
198 
199  SourceLineInfo() : line( 0 ){}
200  SourceLineInfo( std::string const& _file, std::size_t _line )
201  : file( _file ),
202  line( _line )
203  {}
205  : file( other.file ),
206  line( other.line )
207  {}
208  bool empty() const {
209  return file.empty();
210  }
211  bool operator == ( SourceLineInfo const& other ) const {
212  return line == other.line && file == other.file;
213  }
214  std::string file;
215  std::size_t line;
216  };
217 
218  inline std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
219 #ifndef __GNUG__
220  os << info.file << "(" << info.line << ")";
221 #else
222  os << info.file << ":" << info.line;
223 #endif
224  return os;
225  }
226 
227  // This is just here to avoid compiler warnings with macro constants and boolean literals
228  inline bool isTrue( bool value ){ return value; }
229 
230  inline void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
231  std::ostringstream oss;
232  oss << locationInfo << ": Internal Catch error: '" << message << "'";
233  if( isTrue( true ))
234  throw std::logic_error( oss.str() );
235  }
236 }
237 
238 #define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
239 #define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
240 
241 #include <ostream>
242 
243 namespace Catch {
244 
245  class NotImplementedException : public std::exception
246  {
247  public:
248  NotImplementedException( SourceLineInfo const& lineInfo );
249 
250  virtual ~NotImplementedException() throw() {}
251 
252  virtual const char* what() const throw();
253 
254  private:
255  std::string m_what;
256  SourceLineInfo m_lineInfo;
257  };
258 
259 } // end namespace Catch
260 
262 #define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )
263 
264 // #included from: internal/catch_context.h
265 #define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
266 
267 // #included from: catch_interfaces_generators.h
268 #define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED
269 
270 #include <string>
271 
272 namespace Catch {
273 
274  struct IGeneratorInfo {
275  virtual ~IGeneratorInfo();
276  virtual bool moveNext() = 0;
277  virtual std::size_t getCurrentIndex() const = 0;
278  };
279 
281  virtual ~IGeneratorsForTest();
282 
283  virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0;
284  virtual bool moveNext() = 0;
285  };
286 
288 
289 } // end namespace Catch
290 
291 // #included from: catch_ptr.hpp
292 #define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
293 
294 #ifdef __clang__
295 #pragma clang diagnostic push
296 #pragma clang diagnostic ignored "-Wpadded"
297 #endif
298 
299 namespace Catch {
300 
301  // An intrusive reference counting smart pointer.
302  // T must implement addRef() and release() methods
303  // typically implementing the IShared interface
304  template<typename T>
305  class Ptr {
306  public:
307  Ptr() : m_p( NULL ){}
308  Ptr( T* p ) : m_p( p ){
309  if( m_p )
310  m_p->addRef();
311  }
312  Ptr( Ptr const& other ) : m_p( other.m_p ){
313  if( m_p )
314  m_p->addRef();
315  }
316  ~Ptr(){
317  if( m_p )
318  m_p->release();
319  }
320  void reset() {
321  if( m_p )
322  m_p->release();
323  m_p = NULL;
324  }
325  Ptr& operator = ( T* p ){
326  Ptr temp( p );
327  swap( temp );
328  return *this;
329  }
330  Ptr& operator = ( Ptr const& other ){
331  Ptr temp( other );
332  swap( temp );
333  return *this;
334  }
335  void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
336  T* get() { return m_p; }
337  const T* get() const{ return m_p; }
338  T& operator*() const { return *m_p; }
339  T* operator->() const { return m_p; }
340  bool operator !() const { return m_p == NULL; }
341  operator SafeBool::type() const { return SafeBool::makeSafe( m_p != NULL ); }
342 
343  private:
344  T* m_p;
345  };
346 
347  struct IShared : NonCopyable {
348  virtual ~IShared();
349  virtual void addRef() const = 0;
350  virtual void release() const = 0;
351  };
352 
353  template<typename T = IShared>
354  struct SharedImpl : T {
355 
356  SharedImpl() : m_rc( 0 ){}
357 
358  virtual void addRef() const {
359  ++m_rc;
360  }
361  virtual void release() const {
362  if( --m_rc == 0 )
363  delete this;
364  }
365 
366  mutable unsigned int m_rc;
367  };
368 
369 } // end namespace Catch
370 
371 #ifdef __clang__
372 #pragma clang diagnostic pop
373 #endif
374 
375 #include <memory>
376 #include <vector>
377 #include <stdlib.h>
378 
379 namespace Catch {
380 
381  class TestCase;
382  class Stream;
383  struct IResultCapture;
384  struct IRunner;
385  struct IGeneratorsForTest;
386  struct IConfig;
387 
388  struct IContext
389  {
390  virtual ~IContext();
391 
392  virtual IResultCapture& getResultCapture() = 0;
393  virtual IRunner& getRunner() = 0;
394  virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;
395  virtual bool advanceGeneratorsForCurrentTest() = 0;
396  virtual Ptr<IConfig const> getConfig() const = 0;
397  };
398 
400  {
401  virtual ~IMutableContext();
402  virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
403  virtual void setRunner( IRunner* runner ) = 0;
404  virtual void setConfig( Ptr<IConfig const> const& config ) = 0;
405  };
406 
409  void cleanUpContext();
410  Stream createStream( std::string const& streamName );
411 
412 }
413 
414 // #included from: internal/catch_test_registry.hpp
415 #define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
416 
417 // #included from: catch_interfaces_testcase.h
418 #define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
419 
420 #include <vector>
421 
422 namespace Catch {
423 
424  class TestCaseFilters;
425 
426  struct ITestCase : IShared {
427  virtual void invoke () const = 0;
428  protected:
429  virtual ~ITestCase();
430  };
431 
432  class TestCase;
433 
435  virtual ~ITestCaseRegistry();
436  virtual std::vector<TestCase> const& getAllTests() const = 0;
437  virtual std::vector<TestCase> getMatchingTestCases( std::string const& rawTestSpec ) const = 0;
438  };
439 }
440 
441 namespace Catch {
442 
443 template<typename C>
444 class MethodTestCase : public SharedImpl<ITestCase> {
445 
446 public:
447  MethodTestCase( void (C::*method)() ) : m_method( method ) {}
448 
449  virtual void invoke() const {
450  C obj;
451  (obj.*m_method)();
452  }
453 
454 private:
455  virtual ~MethodTestCase() {}
456 
457  void (C::*m_method)();
458 };
459 
460 typedef void(*TestFunction)();
461 
462 struct NameAndDesc {
463  NameAndDesc( const char* _name = "", const char* _description= "" )
464  : name( _name ), description( _description )
465  {}
466 
467  const char* name;
468  const char* description;
469 };
470 
471 struct AutoReg {
472 
473  AutoReg( TestFunction function,
474  SourceLineInfo const& lineInfo,
475  NameAndDesc const& nameAndDesc );
476 
477  template<typename C>
478  AutoReg( void (C::*method)(),
479  char const* className,
480  NameAndDesc const& nameAndDesc,
481  SourceLineInfo const& lineInfo ) {
482  registerTestCase( new MethodTestCase<C>( method ),
483  className,
484  nameAndDesc,
485  lineInfo );
486  }
487 
488  void registerTestCase( ITestCase* testCase,
489  char const* className,
490  NameAndDesc const& nameAndDesc,
491  SourceLineInfo const& lineInfo );
492 
493  ~AutoReg();
494 
495 private:
496  AutoReg( AutoReg const& );
497  void operator= ( AutoReg const& );
498 };
499 
500 } // end namespace Catch
501 
502 #ifdef CATCH_CONFIG_VARIADIC_MACROS
503  #define INTERNAL_CATCH_TESTCASE( ... ) \
505  static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
506  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__ ) ); }\
507  static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )()
508 
510  #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
511  namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
512 
514  #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... )\
515  namespace{ \
516  struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
517  void test(); \
518  }; \
519  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 ); \
520  } \
521  void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
522 
523 #else
524  #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
526  static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
527  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 ) ); }\
528  static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )()
529 
531  #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
532  namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
533 
535  #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
536  namespace{ \
537  struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
538  void test(); \
539  }; \
540  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 ); \
541  } \
542  void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
543 
544 #endif
545 
546 // #included from: internal/catch_capture.hpp
547 #define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
548 
549 // #included from: catch_expression_decomposer.hpp
550 #define TWOBLUECUBES_CATCH_EXPRESSION_DECOMPOSER_HPP_INCLUDED
551 
552 // #included from: catch_expression_lhs.hpp
553 #define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
554 
555 // #included from: catch_expressionresult_builder.h
556 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_BUILDER_H_INCLUDED
557 
558 // #included from: catch_tostring.hpp
559 #define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED
560 
561 // #included from: catch_sfinae.hpp
562 #define TWOBLUECUBES_CATCH_SFINAE_HPP_INCLUDED
563 
564 // Try to detect if the current compiler supports SFINAE
565 
566 namespace Catch {
567 
568  struct TrueType {
569  static const bool value = true;
570  typedef void Enable;
571  char sizer[1];
572  };
573  struct FalseType {
574  static const bool value = false;
575  typedef void Disable;
576  char sizer[2];
577  };
578 
579 #ifdef CATCH_CONFIG_SFINAE
580 
581  template<bool> struct NotABooleanExpression;
582 
583  template<bool c> struct If : NotABooleanExpression<c> {};
584  template<> struct If<true> : TrueType {};
585  template<> struct If<false> : FalseType {};
586 
587  template<int size> struct SizedIf;
588  template<> struct SizedIf<sizeof(TrueType)> : TrueType {};
589  template<> struct SizedIf<sizeof(FalseType)> : FalseType {};
590 
591 #endif // CATCH_CONFIG_SFINAE
592 
593 } // end namespace Catch
594 
595 #include <sstream>
596 #include <iomanip>
597 #include <limits>
598 
599 #ifdef __OBJC__
600 // #included from: catch_objc_arc.hpp
601 #define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED
602 
603 #import <Foundation/Foundation.h>
604 
605 #ifdef __has_feature
606 #define CATCH_ARC_ENABLED __has_feature(objc_arc)
607 #else
608 #define CATCH_ARC_ENABLED 0
609 #endif
610 
611 void arcSafeRelease( NSObject* obj );
612 id performOptionalSelector( id obj, SEL sel );
613 
614 #if !CATCH_ARC_ENABLED
615 inline void arcSafeRelease( NSObject* obj ) {
616  [obj release];
617 }
618 inline id performOptionalSelector( id obj, SEL sel ) {
619  if( [obj respondsToSelector: sel] )
620  return [obj performSelector: sel];
621  return nil;
622 }
623 #define CATCH_UNSAFE_UNRETAINED
624 #define CATCH_ARC_STRONG
625 #else
626 inline void arcSafeRelease( NSObject* ){}
627 inline id performOptionalSelector( id obj, SEL sel ) {
628 #ifdef __clang__
629 #pragma clang diagnostic push
630 #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
631 #endif
632  if( [obj respondsToSelector: sel] )
633  return [obj performSelector: sel];
634 #ifdef __clang__
635 #pragma clang diagnostic pop
636 #endif
637  return nil;
638 }
639 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
640 #define CATCH_ARC_STRONG __strong
641 #endif
642 
643 #endif
644 
645 namespace Catch {
646 namespace Detail {
647 
648 // SFINAE is currently disabled by default for all compilers.
649 // If the non SFINAE version of IsStreamInsertable is ambiguous for you
650 // and your compiler supports SFINAE, try #defining CATCH_CONFIG_SFINAE
651 #ifdef CATCH_CONFIG_SFINAE
652 
653  template<typename T>
654  class IsStreamInsertableHelper {
655  template<int N> struct TrueIfSizeable : TrueType {};
656 
657  template<typename T2>
658  static TrueIfSizeable<sizeof((*(std::ostream*)0) << *((T2 const*)0))> dummy(T2*);
659  static FalseType dummy(...);
660 
661  public:
662  typedef SizedIf<sizeof(dummy((T*)0))> type;
663  };
664 
665  template<typename T>
666  struct IsStreamInsertable : IsStreamInsertableHelper<T>::type {};
667 
668 #else
669 
670  struct BorgType {
671  template<typename T> BorgType( T const& );
672  };
673 
674  TrueType& testStreamable( std::ostream& );
676 
677  FalseType operator<<( std::ostream const&, BorgType const& );
678 
679  template<typename T>
681  static std::ostream &s;
682  static T const&t;
683  enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
684  };
685 
686 #endif
687 
688  template<bool C>
690  template<typename T>
691  static std::string convert( T const& ) { return "{?}"; }
692  };
693 
694  template<>
695  struct StringMakerBase<true> {
696  template<typename T>
697  static std::string convert( T const& _value ) {
698  std::ostringstream oss;
699  oss << _value;
700  return oss.str();
701  }
702  };
703 
704 } // end namespace Detail
705 
706 template<typename T>
707 std::string toString( T const& value );
708 
709 template<typename T>
710 struct StringMaker :
711  Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};
712 
713 template<typename T>
714 struct StringMaker<T*> {
715  template<typename U>
716  static std::string convert( U* p ) {
717  if( !p )
718  return INTERNAL_CATCH_STRINGIFY( NULL );
719  std::ostringstream oss;
720  oss << p;
721  return oss.str();
722  }
723 };
724 
725 template<typename T>
726 struct StringMaker<std::vector<T> > {
727  static std::string convert( std::vector<T> const& v ) {
728  std::ostringstream oss;
729  oss << "{ ";
730  for( std::size_t i = 0; i < v.size(); ++ i ) {
731  oss << toString( v[i] );
732  if( i < v.size() - 1 )
733  oss << ", ";
734  }
735  oss << " }";
736  return oss.str();
737  }
738 };
739 
740 namespace Detail {
741  template<typename T>
742  inline std::string makeString( T const& value ) {
743  return StringMaker<T>::convert( value );
744  }
745 } // end namespace Detail
746 
754 template<typename T>
755 std::string toString( T const& value ) {
756  return StringMaker<T>::convert( value );
757 }
758 
759 // Built in overloads
760 
761 inline std::string toString( std::string const& value ) {
762  return "\"" + value + "\"";
763 }
764 
765 inline std::string toString( std::wstring const& value ) {
766  std::ostringstream oss;
767  oss << "\"";
768  for(size_t i = 0; i < value.size(); ++i )
769  oss << static_cast<char>( value[i] <= 0xff ? value[i] : '?');
770  oss << "\"";
771  return oss.str();
772 }
773 
774 inline std::string toString( const char* const value ) {
775  return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" );
776 }
777 
778 inline std::string toString( char* const value ) {
779  return Catch::toString( static_cast<const char*>( value ) );
780 }
781 
782 inline std::string toString( int value ) {
783  std::ostringstream oss;
784  oss << value;
785  return oss.str();
786 }
787 
788 inline std::string toString( unsigned long value ) {
789  std::ostringstream oss;
790  if( value > 8192 )
791  oss << "0x" << std::hex << value;
792  else
793  oss << value;
794  return oss.str();
795 }
796 
797 inline std::string toString( unsigned int value ) {
798  return toString( static_cast<unsigned long>( value ) );
799 }
800 
801 inline std::string toString( const double value ) {
802  std::ostringstream oss;
803  oss << std::setprecision( 10 )
804  << std::fixed
805  << value;
806  std::string d = oss.str();
807  std::size_t i = d.find_last_not_of( '0' );
808  if( i != std::string::npos && i != d.size()-1 ) {
809  if( d[i] == '.' )
810  i++;
811  d = d.substr( 0, i+1 );
812  }
813  return d;
814 }
815 
816 inline std::string toString( bool value ) {
817  return value ? "true" : "false";
818 }
819 
820 inline std::string toString( char value ) {
821  return value < ' '
822  ? toString( static_cast<unsigned int>( value ) )
823  : Detail::makeString( value );
824 }
825 
826 inline std::string toString( signed char value ) {
827  return toString( static_cast<char>( value ) );
828 }
829 
830 inline std::string toString( unsigned char value ) {
831  return toString( static_cast<char>( value ) );
832 }
833 
834 #ifdef CATCH_CONFIG_CPP11_NULLPTR
835 inline std::string toString( std::nullptr_t ) {
836  return "nullptr";
837 }
838 #endif
839 
840 #ifdef __OBJC__
841  inline std::string toString( NSString const * const& nsstring ) {
842  if( !nsstring )
843  return "nil";
844  return std::string( "@\"" ) + [nsstring UTF8String] + "\"";
845  }
846  inline std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) {
847  if( !nsstring )
848  return "nil";
849  return std::string( "@\"" ) + [nsstring UTF8String] + "\"";
850  }
851  inline std::string toString( NSObject* const& nsObject ) {
852  return toString( [nsObject description] );
853  }
854 #endif
855 
856 } // end namespace Catch
857 
858 // #included from: catch_assertionresult.h
859 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
860 
861 #include <string>
862 // #included from: catch_result_type.h
863 #define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
864 
865 namespace Catch {
866 
867  // ResultWas::OfType enum
868  struct ResultWas { enum OfType {
869  Unknown = -1,
870  Ok = 0,
871  Info = 1,
872  Warning = 2,
873 
874  FailureBit = 0x10,
875 
876  ExpressionFailed = FailureBit | 1,
877  ExplicitFailure = FailureBit | 2,
878 
879  Exception = 0x100 | FailureBit,
880 
881  ThrewException = Exception | 1,
882  DidntThrowException = Exception | 2
883 
884  }; };
885 
886  inline bool isOk( ResultWas::OfType resultType ) {
887  return ( resultType & ResultWas::FailureBit ) == 0;
888  }
889  inline bool isJustInfo( int flags ) {
890  return flags == ResultWas::Info;
891  }
892 
893  // ResultAction::Value enum
894  struct ResultAction { enum Value {
896  Failed = 1, // Failure - but no debug break if Debug bit not set
897  Debug = 2, // If this bit is set, invoke the debugger
898  Abort = 4 // Test run should abort
899  }; };
900 
901  // ResultDisposition::Flags enum
902  struct ResultDisposition { enum Flags {
903  Normal = 0x00,
904 
905  ContinueOnFailure = 0x01, // Failures fail test, but execution continues
906  NegateResult = 0x02, // Prefix expressiom with !
907  SuppressFail = 0x04 // Failures are reported but do not fail the test
908  }; };
909 
911  return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
912  }
913 
914  inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
915  inline bool shouldNegate( int flags ) { return ( flags & ResultDisposition::NegateResult ) != 0; }
916  inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
917 
918 } // end namespace Catch
919 
920 
921 namespace Catch {
922 
924  {
926  AssertionInfo( std::string const& _macroName,
927  SourceLineInfo const& _lineInfo,
928  std::string const& _capturedExpression,
929  ResultDisposition::Flags _resultDisposition );
930 
931  std::string macroName;
933  std::string capturedExpression;
935  };
936 
938  {
939  AssertionResultData() : resultType( ResultWas::Unknown ) {}
940 
942  std::string message;
944  };
945 
947  public:
948  AssertionResult();
949  AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
950  ~AssertionResult();
951 
952  bool isOk() const;
953  bool succeeded() const;
954  ResultWas::OfType getResultType() const;
955  bool hasExpression() const;
956  bool hasMessage() const;
957  std::string getExpression() const;
958  std::string getExpressionInMacro() const;
959  bool hasExpandedExpression() const;
960  std::string getExpandedExpression() const;
961  std::string getMessage() const;
962  SourceLineInfo getSourceInfo() const;
963  std::string getTestMacroName() const;
964 
965  protected:
968  };
969 
970 } // end namespace Catch
971 
972 // #included from: catch_evaluate.hpp
973 #define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
974 
975 #ifdef _MSC_VER
976 #pragma warning(push)
977 #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
978 #endif
979 
980 namespace Catch {
981 namespace Internal {
982 
983  enum Operator {
990  };
991 
992  template<Operator Op> struct OperatorTraits { static const char* getName(){ return "*error*"; } };
993  template<> struct OperatorTraits<IsEqualTo> { static const char* getName(){ return "=="; } };
994  template<> struct OperatorTraits<IsNotEqualTo> { static const char* getName(){ return "!="; } };
995  template<> struct OperatorTraits<IsLessThan> { static const char* getName(){ return "<"; } };
996  template<> struct OperatorTraits<IsGreaterThan> { static const char* getName(){ return ">"; } };
997  template<> struct OperatorTraits<IsLessThanOrEqualTo> { static const char* getName(){ return "<="; } };
998  template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
999 
1000  template<typename T>
1001  inline T& opCast(T const& t) { return const_cast<T&>(t); }
1002 
1003 // nullptr_t support based on pull request #154 from Konstantin Baumann
1004 #ifdef CATCH_CONFIG_CPP11_NULLPTR
1005  inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
1006 #endif // CATCH_CONFIG_CPP11_NULLPTR
1007 
1008  // So the compare overloads can be operator agnostic we convey the operator as a template
1009  // enum, which is used to specialise an Evaluator for doing the comparison.
1010  template<typename T1, typename T2, Operator Op>
1011  class Evaluator{};
1012 
1013  template<typename T1, typename T2>
1014  struct Evaluator<T1, T2, IsEqualTo> {
1015  static bool evaluate( T1 const& lhs, T2 const& rhs) {
1016  return opCast( lhs ) == opCast( rhs );
1017  }
1018  };
1019  template<typename T1, typename T2>
1020  struct Evaluator<T1, T2, IsNotEqualTo> {
1021  static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1022  return opCast( lhs ) != opCast( rhs );
1023  }
1024  };
1025  template<typename T1, typename T2>
1026  struct Evaluator<T1, T2, IsLessThan> {
1027  static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1028  return opCast( lhs ) < opCast( rhs );
1029  }
1030  };
1031  template<typename T1, typename T2>
1032  struct Evaluator<T1, T2, IsGreaterThan> {
1033  static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1034  return opCast( lhs ) > opCast( rhs );
1035  }
1036  };
1037  template<typename T1, typename T2>
1039  static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1040  return opCast( lhs ) >= opCast( rhs );
1041  }
1042  };
1043  template<typename T1, typename T2>
1044  struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
1045  static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1046  return opCast( lhs ) <= opCast( rhs );
1047  }
1048  };
1049 
1050  template<Operator Op, typename T1, typename T2>
1051  bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
1052  return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
1053  }
1054 
1055  // This level of indirection allows us to specialise for integer types
1056  // to avoid signed/ unsigned warnings
1057 
1058  // "base" overload
1059  template<Operator Op, typename T1, typename T2>
1060  bool compare( T1 const& lhs, T2 const& rhs ) {
1061  return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
1062  }
1063 
1064  // unsigned X to int
1065  template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
1066  return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
1067  }
1068  template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
1069  return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
1070  }
1071  template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
1072  return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
1073  }
1074 
1075  // unsigned X to long
1076  template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
1077  return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
1078  }
1079  template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
1080  return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
1081  }
1082  template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
1083  return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
1084  }
1085 
1086  // int to unsigned X
1087  template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
1088  return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
1089  }
1090  template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
1091  return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
1092  }
1093  template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
1094  return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
1095  }
1096 
1097  // long to unsigned X
1098  template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
1099  return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1100  }
1101  template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
1102  return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1103  }
1104  template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
1105  return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1106  }
1107 
1108  // pointer to long (when comparing against NULL)
1109  template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
1110  return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
1111  }
1112  template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
1113  return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
1114  }
1115 
1116  // pointer to int (when comparing against NULL)
1117  template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
1118  return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
1119  }
1120  template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
1121  return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
1122  }
1123 
1124 #ifdef CATCH_CONFIG_CPP11_NULLPTR
1125  // pointer to nullptr_t (when comparing against nullptr)
1126  template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
1127  return Evaluator<T*, T*, Op>::evaluate( NULL, rhs );
1128  }
1129  template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
1130  return Evaluator<T*, T*, Op>::evaluate( lhs, NULL );
1131  }
1132 #endif // CATCH_CONFIG_CPP11_NULLPTR
1133 
1134 } // end of namespace Internal
1135 } // end of namespace Catch
1136 
1137 #ifdef _MSC_VER
1138 #pragma warning(pop)
1139 #endif
1140 
1141 namespace Catch {
1142 
1143 struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
1144 
1145 // Wraps the (stringised versions of) the lhs, operator and rhs of an expression - as well as
1146 // the result of evaluating it. This is used to build an AssertionResult object
1148 public:
1149 
1152  ExpressionResultBuilder& operator=(ExpressionResultBuilder const& other );
1153 
1154  ExpressionResultBuilder& setResultType( ResultWas::OfType result );
1155  ExpressionResultBuilder& setResultType( bool result );
1156  ExpressionResultBuilder& setLhs( std::string const& lhs );
1157  ExpressionResultBuilder& setRhs( std::string const& rhs );
1158  ExpressionResultBuilder& setOp( std::string const& op );
1159 
1160  ExpressionResultBuilder& endExpression( ResultDisposition::Flags resultDisposition );
1161 
1162  template<typename T>
1164  m_stream << value;
1165  return *this;
1166  }
1167 
1168  std::string reconstructExpression( AssertionInfo const& info ) const;
1169 
1170  AssertionResult buildResult( AssertionInfo const& info ) const;
1171 
1172  template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
1173  template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
1174 
1175 private:
1176  AssertionResultData m_data;
1177  struct ExprComponents {
1178  ExprComponents() : shouldNegate( false ) {}
1179  bool shouldNegate;
1180  std::string lhs, rhs, op;
1181  } m_exprComponents;
1182  std::ostringstream m_stream;
1183 };
1184 
1185 } // end namespace Catch
1186 
1187 namespace Catch {
1188 
1189 // Wraps the LHS of an expression and captures the operator and RHS (if any) - wrapping them all
1190 // in an ExpressionResultBuilder object
1191 template<typename T>
1193  void operator = ( ExpressionLhs const& );
1194 
1195 public:
1196  ExpressionLhs( T lhs ) : m_lhs( lhs ) {}
1197 
1198  template<typename RhsT>
1200  return captureExpression<Internal::IsEqualTo>( rhs );
1201  }
1202 
1203  template<typename RhsT>
1204  ExpressionResultBuilder& operator != ( RhsT const& rhs ) {
1205  return captureExpression<Internal::IsNotEqualTo>( rhs );
1206  }
1207 
1208  template<typename RhsT>
1209  ExpressionResultBuilder& operator < ( RhsT const& rhs ) {
1210  return captureExpression<Internal::IsLessThan>( rhs );
1211  }
1212 
1213  template<typename RhsT>
1214  ExpressionResultBuilder& operator > ( RhsT const& rhs ) {
1215  return captureExpression<Internal::IsGreaterThan>( rhs );
1216  }
1217 
1218  template<typename RhsT>
1219  ExpressionResultBuilder& operator <= ( RhsT const& rhs ) {
1220  return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
1221  }
1222 
1223  template<typename RhsT>
1224  ExpressionResultBuilder& operator >= ( RhsT const& rhs ) {
1225  return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
1226  }
1227 
1229  return captureExpression<Internal::IsEqualTo>( rhs );
1230  }
1231 
1232  ExpressionResultBuilder& operator != ( bool rhs ) {
1233  return captureExpression<Internal::IsNotEqualTo>( rhs );
1234  }
1235 
1237  bool value = m_lhs ? true : false;
1238  return m_result
1239  .setLhs( Catch::toString( value ) )
1240  .setResultType( value )
1241  .endExpression( resultDisposition );
1242  }
1243 
1244  // Only simple binary expressions are allowed on the LHS.
1245  // If more complex compositions are required then place the sub expression in parentheses
1246  template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& );
1247  template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& );
1248  template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& );
1249  template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& );
1250  template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
1251  template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
1252 
1253 private:
1254  template<Internal::Operator Op, typename RhsT>
1255  ExpressionResultBuilder& captureExpression( RhsT const& rhs ) {
1256  return m_result
1257  .setResultType( Internal::compare<Op>( m_lhs, rhs ) )
1258  .setLhs( Catch::toString( m_lhs ) )
1259  .setRhs( Catch::toString( rhs ) )
1261  }
1262 
1263 private:
1264  ExpressionResultBuilder m_result;
1265  T m_lhs;
1266 };
1267 
1268 } // end namespace Catch
1269 
1270 namespace Catch {
1271 
1272 // Captures the LHS of the expression and wraps it in an Expression Lhs object
1274 public:
1275 
1276  template<typename T>
1277  ExpressionLhs<T const&> operator->* ( T const& operand ) {
1278  return ExpressionLhs<T const&>( operand );
1279  }
1280 
1281  ExpressionLhs<bool> operator->* ( bool value ) {
1282  return ExpressionLhs<bool>( value );
1283  }
1284 };
1285 
1286 } // end namespace Catch
1287 
1288 // #included from: catch_message.h
1289 #define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
1290 
1291 #include <string>
1292 
1293 namespace Catch {
1294 
1295  struct MessageInfo {
1296  MessageInfo( std::string const& _macroName,
1297  SourceLineInfo const& _lineInfo,
1298  ResultWas::OfType _type );
1299 
1300  std::string macroName;
1303  std::string message;
1304  unsigned int sequence;
1305 
1306  bool operator == ( MessageInfo const& other ) const {
1307  return sequence == other.sequence;
1308  }
1309  bool operator < ( MessageInfo const& other ) const {
1310  return sequence < other.sequence;
1311  }
1312  private:
1313  static unsigned int globalCount;
1314  };
1315 
1317  MessageBuilder( std::string const& macroName,
1318  SourceLineInfo const& lineInfo,
1319  ResultWas::OfType type )
1320  : m_info( macroName, lineInfo, type )
1321  {}
1322 
1323  template<typename T>
1324  MessageBuilder& operator << ( T const& value ) {
1325  m_stream << value;
1326  return *this;
1327  }
1328 
1330  std::ostringstream m_stream;
1331  };
1332 
1334  public:
1335  ScopedMessage( MessageBuilder const& builder );
1336  ~ScopedMessage();
1337 
1339  };
1340 
1341 } // end namespace Catch
1342 
1343 // #included from: catch_interfaces_capture.h
1344 #define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
1345 
1346 #include <string>
1347 // #included from: catch_totals.hpp
1348 #define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED
1349 
1350 #include <cstddef>
1351 
1352 namespace Catch {
1353 
1354  struct Counts {
1355  Counts() : passed( 0 ), failed( 0 ) {}
1356 
1357  Counts operator - ( Counts const& other ) const {
1358  Counts diff;
1359  diff.passed = passed - other.passed;
1360  diff.failed = failed - other.failed;
1361  return diff;
1362  }
1363  Counts& operator += ( Counts const& other ) {
1364  passed += other.passed;
1365  failed += other.failed;
1366  return *this;
1367  }
1368 
1369  std::size_t total() const {
1370  return passed + failed;
1371  }
1372 
1373  std::size_t passed;
1374  std::size_t failed;
1375  };
1376 
1377  struct Totals {
1378 
1379  Totals operator - ( Totals const& other ) const {
1380  Totals diff;
1381  diff.assertions = assertions - other.assertions;
1382  diff.testCases = testCases - other.testCases;
1383  return diff;
1384  }
1385 
1386  Totals delta( Totals const& prevTotals ) const {
1387  Totals diff = *this - prevTotals;
1388  if( diff.assertions.failed > 0 )
1389  ++diff.testCases.failed;
1390  else
1391  ++diff.testCases.passed;
1392  return diff;
1393  }
1394 
1395  Totals& operator += ( Totals const& other ) {
1396  assertions += other.assertions;
1397  testCases += other.testCases;
1398  return *this;
1399  }
1400 
1403  };
1404 }
1405 
1406 
1407 namespace Catch {
1408 
1409  class TestCase;
1411  class AssertionResult;
1412  struct AssertionInfo;
1413  struct SectionInfo;
1414  struct MessageInfo;
1415  class ScopedMessageBuilder;
1416 
1418 
1419  virtual ~IResultCapture();
1420 
1421  virtual void assertionEnded( AssertionResult const& result ) = 0;
1422  virtual bool sectionStarted( SectionInfo const& sectionInfo,
1423  Counts& assertions ) = 0;
1424  virtual void sectionEnded( SectionInfo const& name, Counts const& assertions, double _durationInSeconds ) = 0;
1425  virtual void pushScopedMessage( MessageInfo const& message ) = 0;
1426  virtual void popScopedMessage( MessageInfo const& message ) = 0;
1427 
1428  virtual bool shouldDebugBreak() const = 0;
1429 
1430  virtual ResultAction::Value acceptExpression( ExpressionResultBuilder const& assertionResult, AssertionInfo const& assertionInfo ) = 0;
1431 
1432  virtual std::string getCurrentTestName() const = 0;
1433  virtual const AssertionResult* getLastResult() const = 0;
1434  };
1435 }
1436 
1437 // #included from: catch_debugger.hpp
1438 #define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
1439 
1440 #include <iostream>
1441 
1442 // #included from: catch_platform.h
1443 #define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
1444 
1445 #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
1446 #define CATCH_PLATFORM_MAC
1447 #elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
1448 #define CATCH_PLATFORM_IPHONE
1449 #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
1450 #define CATCH_PLATFORM_WINDOWS
1451 #endif
1452 
1453 #ifdef CATCH_PLATFORM_MAC
1454 
1455  #include <assert.h>
1456  #include <stdbool.h>
1457  #include <sys/types.h>
1458  #include <unistd.h>
1459  #include <sys/sysctl.h>
1460 
1461  namespace Catch{
1462 
1463  // The following function is taken directly from the following technical note:
1464  // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
1465 
1466  // Returns true if the current process is being debugged (either
1467  // running under the debugger or has a debugger attached post facto).
1468  inline bool isDebuggerActive(){
1469 
1470  int junk;
1471  int mib[4];
1472  struct kinfo_proc info;
1473  size_t size;
1474 
1475  // Initialize the flags so that, if sysctl fails for some bizarre
1476  // reason, we get a predictable result.
1477 
1478  info.kp_proc.p_flag = 0;
1479 
1480  // Initialize mib, which tells sysctl the info we want, in this case
1481  // we're looking for information about a specific process ID.
1482 
1483  mib[0] = CTL_KERN;
1484  mib[1] = KERN_PROC;
1485  mib[2] = KERN_PROC_PID;
1486  mib[3] = getpid();
1487 
1488  // Call sysctl.
1489 
1490  size = sizeof(info);
1491  junk = sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0);
1492  assert(junk == 0);
1493 
1494  // We're being debugged if the P_TRACED flag is set.
1495 
1496  return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
1497  }
1498  }
1499 
1500  // The following code snippet taken from:
1501  // http://cocoawithlove.com/2008/03/break-into-debugger.html
1502  #ifdef DEBUG
1503  #if defined(__ppc64__) || defined(__ppc__)
1504  #define BreakIntoDebugger() \
1505  if( Catch::isDebuggerActive() ) { \
1506  __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
1507  : : : "memory","r0","r3","r4" ); \
1508  }
1509  #else
1510  #define BreakIntoDebugger() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );}
1511  #endif
1512  #else
1513  inline void BreakIntoDebugger(){}
1514  #endif
1515 
1516 #elif defined(_MSC_VER)
1517  extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
1518  #define BreakIntoDebugger() if (IsDebuggerPresent() ) { __debugbreak(); }
1519  inline bool isDebuggerActive() {
1520  return IsDebuggerPresent() != 0;
1521  }
1522 #elif defined(__MINGW32__)
1523  extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
1524  extern "C" __declspec(dllimport) void __stdcall DebugBreak();
1525  #define BreakIntoDebugger() if (IsDebuggerPresent() ) { DebugBreak(); }
1526  inline bool isDebuggerActive() {
1527  return IsDebuggerPresent() != 0;
1528  }
1529 #else
1530  inline void BreakIntoDebugger(){}
1531  inline bool isDebuggerActive() { return false; }
1532 #endif
1533 
1534 #ifdef CATCH_PLATFORM_WINDOWS
1535 extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* );
1536 inline void writeToDebugConsole( std::string const& text ) {
1537  ::OutputDebugStringA( text.c_str() );
1538 }
1539 #else
1540 inline void writeToDebugConsole( std::string const& text ) {
1541  // !TBD: Need a version for Mac/ XCode and other IDEs
1542  std::cout << text;
1543 }
1544 #endif // CATCH_PLATFORM_WINDOWS
1545 
1546 // #included from: catch_interfaces_registry_hub.h
1547 #define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
1548 
1549 // #included from: catch_interfaces_reporter.h
1550 #define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
1551 
1552 // #included from: catch_config.hpp
1553 #define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
1554 
1555 // #included from: catch_test_spec.h
1556 #define TWOBLUECUBES_CATCH_TEST_SPEC_H_INCLUDED
1557 
1558 // #included from: catch_test_case_info.h
1559 #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED
1560 
1561 #include <string>
1562 #include <set>
1563 
1564 #ifdef __clang__
1565 #pragma clang diagnostic push
1566 #pragma clang diagnostic ignored "-Wpadded"
1567 #endif
1568 
1569 namespace Catch {
1570 
1571  struct ITestCase;
1572 
1573  struct TestCaseInfo {
1574  TestCaseInfo( std::string const& _name,
1575  std::string const& _className,
1576  std::string const& _description,
1577  std::set<std::string> const& _tags,
1578  bool _isHidden,
1579  SourceLineInfo const& _lineInfo );
1580 
1581  TestCaseInfo( TestCaseInfo const& other );
1582 
1583  std::string name;
1584  std::string className;
1585  std::string description;
1586  std::set<std::string> tags;
1587  std::string tagsAsString;
1589  bool isHidden;
1590  };
1591 
1592  class TestCase : protected TestCaseInfo {
1593  public:
1594 
1595  TestCase( ITestCase* testCase, TestCaseInfo const& info );
1596  TestCase( TestCase const& other );
1597 
1598  TestCase withName( std::string const& _newName ) const;
1599 
1600  void invoke() const;
1601 
1602  TestCaseInfo const& getTestCaseInfo() const;
1603 
1604  bool isHidden() const;
1605  bool hasTag( std::string const& tag ) const;
1606  bool matchesTags( std::string const& tagPattern ) const;
1607  std::set<std::string> const& getTags() const;
1608 
1609  void swap( TestCase& other );
1610  bool operator == ( TestCase const& other ) const;
1611  bool operator < ( TestCase const& other ) const;
1612  TestCase& operator = ( TestCase const& other );
1613 
1614  private:
1615  Ptr<ITestCase> test;
1616  };
1617 
1618  TestCase makeTestCase( ITestCase* testCase,
1619  std::string const& className,
1620  std::string const& name,
1621  std::string const& description,
1622  SourceLineInfo const& lineInfo );
1623 }
1624 
1625 #ifdef __clang__
1626 #pragma clang diagnostic pop
1627 #endif
1628 
1629 // #included from: catch_tags.hpp
1630 #define TWOBLUECUBES_CATCH_TAGS_HPP_INCLUDED
1631 
1632 #include <string>
1633 #include <set>
1634 #include <map>
1635 #include <vector>
1636 
1637 #ifdef __clang__
1638 #pragma clang diagnostic ignored "-Wpadded"
1639 #endif
1640 
1641 namespace Catch {
1642  class TagParser {
1643  public:
1644  virtual ~TagParser();
1645 
1646  void parse( std::string const& str ) {
1647  std::size_t pos = 0;
1648  while( pos < str.size() ) {
1649  char c = str[pos];
1650  if( c == '[' ) {
1651  std::size_t end = str.find_first_of( ']', pos );
1652  if( end != std::string::npos ) {
1653  acceptTag( str.substr( pos+1, end-pos-1 ) );
1654  pos = end+1;
1655  }
1656  else {
1657  acceptChar( c );
1658  pos++;
1659  }
1660  }
1661  else {
1662  acceptChar( c );
1663  pos++;
1664  }
1665  }
1666  endParse();
1667  }
1668 
1669  protected:
1670  virtual void acceptTag( std::string const& tag ) = 0;
1671  virtual void acceptChar( char c ) = 0;
1672  virtual void endParse() {}
1673 
1674  private:
1675  };
1676 
1677  class TagExtracter : public TagParser {
1678  public:
1679 
1680  TagExtracter( std::set<std::string>& tags )
1681  : m_tags( tags )
1682  {}
1683  virtual ~TagExtracter();
1684 
1685  void parse( std::string& description ) {
1686  TagParser::parse( description );
1687  description = m_remainder;
1688  }
1689 
1690  private:
1691  virtual void acceptTag( std::string const& tag ) {
1692  m_tags.insert( toLower( tag ) );
1693  }
1694  virtual void acceptChar( char c ) {
1695  m_remainder += c;
1696  }
1697 
1698  TagExtracter& operator=(TagExtracter const&);
1699 
1700  std::set<std::string>& m_tags;
1701  std::string m_remainder;
1702  };
1703 
1704  class Tag {
1705  public:
1707  : m_isNegated( false )
1708  {}
1709 
1710  Tag( std::string const& name, bool isNegated )
1711  : m_name( name ),
1712  m_isNegated( isNegated )
1713  {}
1714 
1715  std::string getName() const {
1716  return m_name;
1717  }
1718  bool isNegated() const {
1719  return m_isNegated;
1720  }
1721 
1722  bool operator ! () const {
1723  return m_name.empty();
1724  }
1725 
1726  private:
1727  std::string m_name;
1728  bool m_isNegated;
1729  };
1730 
1731  class TagSet {
1732  typedef std::map<std::string, Tag> TagMap;
1733  public:
1734  void add( Tag const& tag ) {
1735  m_tags.insert( std::make_pair( toLower( tag.getName() ), tag ) );
1736  }
1737 
1738  bool empty() const {
1739  return m_tags.empty();
1740  }
1741 
1742  bool matches( std::set<std::string> const& tags ) const {
1743  TagMap::const_iterator it = m_tags.begin();
1744  TagMap::const_iterator itEnd = m_tags.end();
1745  for(; it != itEnd; ++it ) {
1746  bool found = tags.find( it->first ) != tags.end();
1747  if( found == it->second.isNegated() )
1748  return false;
1749  }
1750  return true;
1751  }
1752 
1753  private:
1754  TagMap m_tags;
1755  };
1756 
1758  public:
1759  bool matches( std::set<std::string> const& tags ) const {
1760  std::vector<TagSet>::const_iterator it = m_tagSets.begin();
1761  std::vector<TagSet>::const_iterator itEnd = m_tagSets.end();
1762  for(; it != itEnd; ++it )
1763  if( it->matches( tags ) )
1764  return true;
1765  return false;
1766  }
1767 
1768  private:
1769  friend class TagExpressionParser;
1770 
1771  std::vector<TagSet> m_tagSets;
1772  };
1773 
1775  public:
1777  : m_isNegated( false ),
1778  m_exp( exp )
1779  {}
1780 
1782 
1783  private:
1784  virtual void acceptTag( std::string const& tag ) {
1785  m_currentTagSet.add( Tag( tag, m_isNegated ) );
1786  m_isNegated = false;
1787  }
1788  virtual void acceptChar( char c ) {
1789  switch( c ) {
1790  case '~':
1791  m_isNegated = true;
1792  break;
1793  case ',':
1794  m_exp.m_tagSets.push_back( m_currentTagSet );
1795  break;
1796  }
1797  }
1798  virtual void endParse() {
1799  if( !m_currentTagSet.empty() )
1800  m_exp.m_tagSets.push_back( m_currentTagSet );
1801  }
1802 
1803  TagExpressionParser& operator=(TagExpressionParser const&);
1804 
1805  bool m_isNegated;
1806  TagSet m_currentTagSet;
1807  TagExpression& m_exp;
1808  };
1809 
1810 } // end namespace Catch
1811 
1812 #include <string>
1813 #include <vector>
1814 
1815 namespace Catch {
1816 
1817  struct IfFilterMatches{ enum DoWhat {
1820  ExcludeTests
1821  }; };
1822 
1824  enum WildcardPosition {
1825  NoWildcard = 0,
1826  WildcardAtStart = 1,
1827  WildcardAtEnd = 2,
1828  WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
1829  };
1830 
1831  public:
1832  TestCaseFilter( std::string const& testSpec, IfFilterMatches::DoWhat matchBehaviour = IfFilterMatches::AutoDetectBehaviour )
1833  : m_stringToMatch( toLower( testSpec ) ),
1834  m_filterType( matchBehaviour ),
1835  m_wildcardPosition( NoWildcard )
1836  {
1837  if( m_filterType == IfFilterMatches::AutoDetectBehaviour ) {
1838  if( startsWith( m_stringToMatch, "exclude:" ) ) {
1839  m_stringToMatch = m_stringToMatch.substr( 8 );
1840  m_filterType = IfFilterMatches::ExcludeTests;
1841  }
1842  else if( startsWith( m_stringToMatch, "~" ) ) {
1843  m_stringToMatch = m_stringToMatch.substr( 1 );
1844  m_filterType = IfFilterMatches::ExcludeTests;
1845  }
1846  else {
1847  m_filterType = IfFilterMatches::IncludeTests;
1848  }
1849  }
1850 
1851  if( startsWith( m_stringToMatch, "*" ) ) {
1852  m_stringToMatch = m_stringToMatch.substr( 1 );
1853  m_wildcardPosition = (WildcardPosition)( m_wildcardPosition | WildcardAtStart );
1854  }
1855  if( endsWith( m_stringToMatch, "*" ) ) {
1856  m_stringToMatch = m_stringToMatch.substr( 0, m_stringToMatch.size()-1 );
1857  m_wildcardPosition = (WildcardPosition)( m_wildcardPosition | WildcardAtEnd );
1858  }
1859  }
1860 
1862  return m_filterType;
1863  }
1864 
1865  bool shouldInclude( TestCase const& testCase ) const {
1866  return isMatch( testCase ) == (m_filterType == IfFilterMatches::IncludeTests);
1867  }
1868  private:
1869 
1870 #ifdef __clang__
1871 #pragma clang diagnostic push
1872 #pragma clang diagnostic ignored "-Wunreachable-code"
1873 #endif
1874 
1875  bool isMatch( TestCase const& testCase ) const {
1876  std::string name = testCase.getTestCaseInfo().name;
1877  toLowerInPlace( name );
1878 
1879  switch( m_wildcardPosition ) {
1880  case NoWildcard:
1881  return m_stringToMatch == name;
1882  case WildcardAtStart:
1883  return endsWith( name, m_stringToMatch );
1884  case WildcardAtEnd:
1885  return startsWith( name, m_stringToMatch );
1886  case WildcardAtBothEnds:
1887  return contains( name, m_stringToMatch );
1888  }
1889  throw std::logic_error( "Unhandled wildcard type" );
1890  }
1891 
1892 #ifdef __clang__
1893 #pragma clang diagnostic pop
1894 #endif
1895 
1896  std::string m_stringToMatch;
1897  IfFilterMatches::DoWhat m_filterType;
1898  WildcardPosition m_wildcardPosition;
1899  };
1900 
1902  public:
1903  TestCaseFilters( std::string const& name ) : m_name( name ) {}
1904 
1905  std::string getName() const {
1906  return m_name;
1907  }
1908 
1909  void addFilter( TestCaseFilter const& filter ) {
1911  m_exclusionFilters.push_back( filter );
1912  else
1913  m_inclusionFilters.push_back( filter );
1914  }
1915 
1916  void addTags( std::string const& tagPattern ) {
1917  TagExpression exp;
1918  TagExpressionParser( exp ).parse( tagPattern );
1919 
1920  m_tagExpressions.push_back( exp );
1921  }
1922 
1923  bool shouldInclude( TestCase const& testCase ) const {
1924  if( !m_tagExpressions.empty() ) {
1925  std::vector<TagExpression>::const_iterator it = m_tagExpressions.begin();
1926  std::vector<TagExpression>::const_iterator itEnd = m_tagExpressions.end();
1927  for(; it != itEnd; ++it )
1928  if( it->matches( testCase.getTags() ) )
1929  break;
1930  if( it == itEnd )
1931  return false;
1932  }
1933 
1934  if( !m_inclusionFilters.empty() ) {
1935  std::vector<TestCaseFilter>::const_iterator it = m_inclusionFilters.begin();
1936  std::vector<TestCaseFilter>::const_iterator itEnd = m_inclusionFilters.end();
1937  for(; it != itEnd; ++it )
1938  if( it->shouldInclude( testCase ) )
1939  break;
1940  if( it == itEnd )
1941  return false;
1942  }
1943  else if( m_exclusionFilters.empty() && m_tagExpressions.empty() ) {
1944  return !testCase.isHidden();
1945  }
1946 
1947  std::vector<TestCaseFilter>::const_iterator it = m_exclusionFilters.begin();
1948  std::vector<TestCaseFilter>::const_iterator itEnd = m_exclusionFilters.end();
1949  for(; it != itEnd; ++it )
1950  if( !it->shouldInclude( testCase ) )
1951  return false;
1952  return true;
1953  }
1954  private:
1955  std::vector<TagExpression> m_tagExpressions;
1956  std::vector<TestCaseFilter> m_inclusionFilters;
1957  std::vector<TestCaseFilter> m_exclusionFilters;
1958  std::string m_name;
1959  };
1960 
1961 }
1962 
1963 // #included from: catch_interfaces_config.h
1964 #define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
1965 
1966 #include <iostream>
1967 #include <string>
1968 
1969 namespace Catch {
1970 
1971  struct Verbosity { enum Level {
1972  NoOutput = 0,
1974  Normal
1975  }; };
1976 
1977  struct WarnAbout { enum What {
1978  Nothing = 0x00,
1979  NoAssertions = 0x01
1980  }; };
1981 
1982  struct ShowDurations { enum OrNot {
1985  Never
1986  }; };
1987 
1988  struct IConfig : IShared {
1989 
1990  virtual ~IConfig();
1991 
1992  virtual bool allowThrows() const = 0;
1993  virtual std::ostream& stream() const = 0;
1994  virtual std::string name() const = 0;
1995  virtual bool includeSuccessfulResults() const = 0;
1996  virtual bool shouldDebugBreak() const = 0;
1997  virtual bool warnAboutMissingAssertions() const = 0;
1998  virtual int abortAfter() const = 0;
1999  virtual ShowDurations::OrNot showDurations() const = 0;
2000  };
2001 }
2002 
2003 // #included from: catch_stream.hpp
2004 #define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
2005 
2006 // #included from: catch_streambuf.h
2007 #define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED
2008 
2009 #include <streambuf>
2010 
2011 namespace Catch {
2012 
2013  class StreamBufBase : public std::streambuf {
2014  public:
2015  virtual ~StreamBufBase() throw();
2016  };
2017 }
2018 
2019 #include <stdexcept>
2020 #include <cstdio>
2021 
2022 namespace Catch {
2023 
2024  template<typename WriterF, size_t bufferSize=256>
2025  class StreamBufImpl : public StreamBufBase {
2026  char data[bufferSize];
2027  WriterF m_writer;
2028 
2029  public:
2031  setp( data, data + sizeof(data) );
2032  }
2033 
2034  ~StreamBufImpl() throw() {
2035  sync();
2036  }
2037 
2038  private:
2039  int overflow( int c ) {
2040  sync();
2041 
2042  if( c != EOF ) {
2043  if( pbase() == epptr() )
2044  m_writer( std::string( 1, static_cast<char>( c ) ) );
2045  else
2046  sputc( static_cast<char>( c ) );
2047  }
2048  return 0;
2049  }
2050 
2051  int sync() {
2052  if( pbase() != pptr() ) {
2053  m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
2054  setp( pbase(), epptr() );
2055  }
2056  return 0;
2057  }
2058  };
2059 
2061 
2063 
2064  void operator()( std::string const&str ) {
2065  writeToDebugConsole( str );
2066  }
2067  };
2068 
2069  class Stream {
2070  public:
2072  : streamBuf( NULL ), isOwned( false )
2073  {}
2074 
2075  Stream( std::streambuf* _streamBuf, bool _isOwned )
2076  : streamBuf( _streamBuf ), isOwned( _isOwned )
2077  {}
2078 
2079  void release() {
2080  if( isOwned ) {
2081  delete streamBuf;
2082  streamBuf = NULL;
2083  isOwned = false;
2084  }
2085  }
2086 
2087  std::streambuf* streamBuf;
2088 
2089  private:
2090  bool isOwned;
2091  };
2092 }
2093 
2094 #include <memory>
2095 #include <vector>
2096 #include <string>
2097 #include <iostream>
2098 
2099 #ifndef CATCH_CONFIG_CONSOLE_WIDTH
2100 #define CATCH_CONFIG_CONSOLE_WIDTH 80
2101 #endif
2102 
2103 namespace Catch {
2104 
2105  struct ConfigData {
2106 
2108  : listTests( false ),
2109  listTags( false ),
2110  listReporters( false ),
2111  showSuccessfulTests( false ),
2112  shouldDebugBreak( false ),
2113  noThrow( false ),
2114  showHelp( false ),
2115  abortAfter( -1 ),
2116  verbosity( Verbosity::Normal ),
2117  warnings( WarnAbout::Nothing ),
2118  showDurations( ShowDurations::DefaultForReporter )
2119  {}
2120 
2122  bool listTags;
2124 
2127  bool noThrow;
2128  bool showHelp;
2129 
2131 
2135 
2136  std::string reporterName;
2137  std::string outputFilename;
2138  std::string name;
2139  std::string processName;
2140 
2141  std::vector<std::string> testsOrTags;
2142  };
2143 
2144  class Config : public SharedImpl<IConfig> {
2145  private:
2146  Config( Config const& other );
2147  Config& operator = ( Config const& other );
2148  virtual void dummy();
2149  public:
2150 
2152  : m_os( std::cout.rdbuf() )
2153  {}
2154 
2155  Config( ConfigData const& data )
2156  : m_data( data ),
2157  m_os( std::cout.rdbuf() )
2158  {
2159  if( !data.testsOrTags.empty() ) {
2160  std::string groupName;
2161  for( std::size_t i = 0; i < data.testsOrTags.size(); ++i ) {
2162  if( i != 0 )
2163  groupName += " ";
2164  groupName += data.testsOrTags[i];
2165  }
2166  TestCaseFilters filters( groupName );
2167  for( std::size_t i = 0; i < data.testsOrTags.size(); ++i ) {
2168  std::string filter = data.testsOrTags[i];
2169  if( startsWith( filter, "[" ) || startsWith( filter, "~[" ) )
2170  filters.addTags( filter );
2171  else
2172  filters.addFilter( TestCaseFilter( filter ) );
2173  }
2174  m_filterSets.push_back( filters );
2175  }
2176  }
2177 
2178  virtual ~Config() {
2179  m_os.rdbuf( std::cout.rdbuf() );
2180  m_stream.release();
2181  }
2182 
2183  void setFilename( std::string const& filename ) {
2184  m_data.outputFilename = filename;
2185  }
2186 
2187  std::string const& getFilename() const {
2188  return m_data.outputFilename ;
2189  }
2190 
2191  bool listTests() const { return m_data.listTests; }
2192  bool listTags() const { return m_data.listTags; }
2193  bool listReporters() const { return m_data.listReporters; }
2194 
2195  std::string getProcessName() const {
2196  return m_data.processName;
2197  }
2198 
2199  bool shouldDebugBreak() const {
2200  return m_data.shouldDebugBreak;
2201  }
2202 
2203  void setStreamBuf( std::streambuf* buf ) {
2204  m_os.rdbuf( buf ? buf : std::cout.rdbuf() );
2205  }
2206 
2207  void useStream( std::string const& streamName ) {
2208  Stream stream = createStream( streamName );
2209  setStreamBuf( stream.streamBuf );
2210  m_stream.release();
2211  m_stream = stream;
2212  }
2213 
2214  std::string getReporterName() const { return m_data.reporterName; }
2215 
2216  void addTestSpec( std::string const& testSpec ) {
2217  TestCaseFilters filters( testSpec );
2218  filters.addFilter( TestCaseFilter( testSpec ) );
2219  m_filterSets.push_back( filters );
2220  }
2221 
2222  int abortAfter() const {
2223  return m_data.abortAfter;
2224  }
2225 
2226  std::vector<TestCaseFilters> const& filters() const {
2227  return m_filterSets;
2228  }
2229 
2230  bool showHelp() const { return m_data.showHelp; }
2231 
2232  // IConfig interface
2233  virtual bool allowThrows() const { return !m_data.noThrow; }
2234  virtual std::ostream& stream() const { return m_os; }
2235  virtual std::string name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
2236  virtual bool includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
2237  virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
2238  virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }
2239 
2240  private:
2241  ConfigData m_data;
2242 
2243  Stream m_stream;
2244  mutable std::ostream m_os;
2245  std::vector<TestCaseFilters> m_filterSets;
2246  };
2247 
2248 } // end namespace Catch
2249 
2250 // #included from: catch_option.hpp
2251 #define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
2252 
2253 namespace Catch {
2254 
2255  // An optional type
2256  template<typename T>
2257  class Option {
2258  public:
2259  Option() : nullableValue( NULL ) {}
2260  Option( T const& _value )
2261  : nullableValue( new( storage ) T( _value ) )
2262  {}
2263  Option( Option const& _other )
2264  : nullableValue( _other ? new( storage ) T( *_other ) : NULL )
2265  {}
2266 
2268  reset();
2269  }
2270 
2271  Option& operator= ( Option const& _other ) {
2272  reset();
2273  if( _other )
2274  nullableValue = new( storage ) T( *_other );
2275  return *this;
2276  }
2277  Option& operator = ( T const& _value ) {
2278  reset();
2279  nullableValue = new( storage ) T( _value );
2280  return *this;
2281  }
2282 
2283  void reset() {
2284  if( nullableValue )
2285  nullableValue->~T();
2286  nullableValue = NULL;
2287  }
2288 
2289  T& operator*() { return *nullableValue; }
2290  T const& operator*() const { return *nullableValue; }
2291  T* operator->() { return nullableValue; }
2292  const T* operator->() const { return nullableValue; }
2293 
2294  T valueOr( T const& defaultValue ) const {
2295  return nullableValue ? *nullableValue : defaultValue;
2296  }
2297 
2298  bool some() const { return nullableValue != NULL; }
2299  bool none() const { return nullableValue == NULL; }
2300 
2301  bool operator !() const { return nullableValue == NULL; }
2302  operator SafeBool::type() const {
2303  return SafeBool::makeSafe( some() );
2304  }
2305 
2306  private:
2307  T* nullableValue;
2308  char storage[sizeof(T)];
2309  };
2310 
2311 } // end namespace Catch
2312 
2313 #include <string>
2314 #include <ostream>
2315 #include <map>
2316 #include <assert.h>
2317 
2318 namespace Catch
2319 {
2321  explicit ReporterConfig( Ptr<IConfig> const& _fullConfig )
2322  : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
2323 
2324  ReporterConfig( Ptr<IConfig> const& _fullConfig, std::ostream& _stream )
2325  : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
2326 
2327  std::ostream& stream() const { return *m_stream; }
2328  Ptr<IConfig> fullConfig() const { return m_fullConfig; }
2329 
2330  private:
2331  std::ostream* m_stream;
2332  Ptr<IConfig> m_fullConfig;
2333  };
2334 
2337  : shouldRedirectStdOut( false )
2338  {}
2339 
2341  };
2342 
2343  template<typename T>
2344  struct LazyStat : Option<T> {
2345  LazyStat() : used( false ) {}
2346  LazyStat& operator=( T const& _value ) {
2347  Option<T>::operator=( _value );
2348  used = false;
2349  return *this;
2350  }
2351  void reset() {
2352  Option<T>::reset();
2353  used = false;
2354  }
2355  bool used;
2356  };
2357 
2358  struct TestRunInfo {
2359  TestRunInfo( std::string const& _name ) : name( _name ) {}
2360  std::string name;
2361  };
2362  struct GroupInfo {
2363  GroupInfo( std::string const& _name,
2364  std::size_t _groupIndex,
2365  std::size_t _groupsCount )
2366  : name( _name ),
2367  groupIndex( _groupIndex ),
2368  groupsCounts( _groupsCount )
2369  {}
2370 
2371  std::string name;
2372  std::size_t groupIndex;
2373  std::size_t groupsCounts;
2374  };
2375 
2376  struct SectionInfo {
2377  SectionInfo( std::string const& _name,
2378  std::string const& _description,
2379  SourceLineInfo const& _lineInfo )
2380  : name( _name ),
2381  description( _description ),
2382  lineInfo( _lineInfo )
2383  {}
2384 
2385  std::string name;
2386  std::string description;
2388  };
2389 
2391  AssertionStats( AssertionResult const& _assertionResult,
2392  std::vector<MessageInfo> const& _infoMessages,
2393  Totals const& _totals )
2394  : assertionResult( _assertionResult ),
2395  infoMessages( _infoMessages ),
2396  totals( _totals )
2397  {
2398  if( assertionResult.hasMessage() ) {
2399  // Copy message into messages list.
2400  // !TBD This should have been done earlier, somewhere
2401  MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
2402  builder << assertionResult.getMessage();
2403  builder.m_info.message = builder.m_stream.str();
2404 
2405  infoMessages.push_back( builder.m_info );
2406  }
2407  }
2408  virtual ~AssertionStats();
2409 
2411  std::vector<MessageInfo> infoMessages;
2413  };
2414 
2415  struct SectionStats {
2416  SectionStats( SectionInfo const& _sectionInfo,
2417  Counts const& _assertions,
2418  double _durationInSeconds,
2419  bool _missingAssertions )
2420  : sectionInfo( _sectionInfo ),
2421  assertions( _assertions ),
2422  durationInSeconds( _durationInSeconds ),
2423  missingAssertions( _missingAssertions )
2424  {}
2425  virtual ~SectionStats();
2426 
2431  };
2432 
2433  struct TestCaseStats {
2434  TestCaseStats( TestCaseInfo const& _testInfo,
2435  Totals const& _totals,
2436  std::string const& _stdOut,
2437  std::string const& _stdErr,
2438  bool _aborting )
2439  : testInfo( _testInfo ),
2440  totals( _totals ),
2441  stdOut( _stdOut ),
2442  stdErr( _stdErr ),
2443  aborting( _aborting )
2444  {}
2445  virtual ~TestCaseStats();
2446 
2449  std::string stdOut;
2450  std::string stdErr;
2451  bool aborting;
2452  };
2453 
2455  TestGroupStats( GroupInfo const& _groupInfo,
2456  Totals const& _totals,
2457  bool _aborting )
2458  : groupInfo( _groupInfo ),
2459  totals( _totals ),
2460  aborting( _aborting )
2461  {}
2462  TestGroupStats( GroupInfo const& _groupInfo )
2463  : groupInfo( _groupInfo ),
2464  aborting( false )
2465  {}
2466  virtual ~TestGroupStats();
2467 
2470  bool aborting;
2471  };
2472 
2473  struct TestRunStats {
2474  TestRunStats( TestRunInfo const& _runInfo,
2475  Totals const& _totals,
2476  bool _aborting )
2477  : runInfo( _runInfo ),
2478  totals( _totals ),
2479  aborting( _aborting )
2480  {}
2481  TestRunStats( TestRunStats const& _other )
2482  : runInfo( _other.runInfo ),
2483  totals( _other.totals ),
2484  aborting( _other.aborting )
2485  {}
2486  virtual ~TestRunStats();
2487 
2490  bool aborting;
2491  };
2492 
2494  virtual ~IStreamingReporter();
2495 
2496  // Implementing class must also provide the following static method:
2497  // static std::string getDescription();
2498 
2499  virtual ReporterPreferences getPreferences() const = 0;
2500 
2501  virtual void noMatchingTestCases( std::string const& spec ) = 0;
2502 
2503  virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
2504  virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
2505 
2506  virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
2507  virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
2508 
2509  virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
2510 
2511  virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
2512  virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
2513  virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
2514  virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
2515  virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
2516  };
2517 
2518  struct StreamingReporterBase : SharedImpl<IStreamingReporter> {
2519 
2521  : m_config( _config.fullConfig() ),
2522  stream( _config.stream() )
2523  {}
2524 
2525  virtual ~StreamingReporterBase();
2526 
2527  virtual void noMatchingTestCases( std::string const& ) {}
2528 
2529  virtual void testRunStarting( TestRunInfo const& _testRunInfo ) {
2530  currentTestRunInfo = _testRunInfo;
2531  }
2532  virtual void testGroupStarting( GroupInfo const& _groupInfo ) {
2533  currentGroupInfo = _groupInfo;
2534  }
2535 
2536  virtual void testCaseStarting( TestCaseInfo const& _testInfo ) {
2537  currentTestCaseInfo = _testInfo;
2538  }
2539  virtual void sectionStarting( SectionInfo const& _sectionInfo ) {
2540  m_sectionStack.push_back( _sectionInfo );
2541  }
2542 
2543  virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) {
2544  m_sectionStack.pop_back();
2545  }
2546  virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) {
2547  currentTestCaseInfo.reset();
2548  assert( m_sectionStack.empty() );
2549  }
2550  virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) {
2551  currentGroupInfo.reset();
2552  }
2553  virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) {
2554  currentTestCaseInfo.reset();
2555  currentGroupInfo.reset();
2556  currentTestRunInfo.reset();
2557  }
2558 
2560  std::ostream& stream;
2561 
2565 
2566  std::vector<SectionInfo> m_sectionStack;
2567  };
2568 
2569  struct CumulativeReporterBase : SharedImpl<IStreamingReporter> {
2570  template<typename T, typename ChildNodeT>
2571  struct Node : SharedImpl<> {
2572  explicit Node( T const& _value ) : value( _value ) {}
2573  virtual ~Node() {}
2574 
2575  typedef std::vector<Ptr<ChildNodeT> > ChildNodes;
2577  ChildNodes children;
2578  };
2580  explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {}
2581  virtual ~SectionNode();
2582 
2583  bool operator == ( SectionNode const& other ) const {
2584  return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
2585  }
2586  bool operator == ( Ptr<SectionNode> const& other ) const {
2587  return operator==( *other );
2588  }
2589 
2591  typedef std::vector<Ptr<SectionNode> > ChildSections;
2592  typedef std::vector<AssertionStats> Assertions;
2593  ChildSections childSections;
2594  Assertions assertions;
2595  std::string stdOut;
2596  std::string stdErr;
2597  };
2598  friend bool operator == ( Ptr<SectionNode> const& node, SectionInfo const& other ) {
2599  return node->stats.sectionInfo.lineInfo == other.lineInfo;
2600  }
2601 
2605 
2607  : m_config( _config.fullConfig() ),
2608  stream( _config.stream() )
2609  {}
2611 
2612  virtual void testRunStarting( TestRunInfo const& ) {}
2613  virtual void testGroupStarting( GroupInfo const& ) {}
2614 
2615  virtual void testCaseStarting( TestCaseInfo const& ) {}
2616 
2617  virtual void sectionStarting( SectionInfo const& sectionInfo ) {
2618  SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
2619  Ptr<SectionNode> node;
2620  if( m_sectionStack.empty() ) {
2621  if( !m_rootSection )
2622  m_rootSection = new SectionNode( incompleteStats );
2623  node = m_rootSection;
2624  }
2625  else {
2626  SectionNode& parentNode = *m_sectionStack.back();
2627  SectionNode::ChildSections::const_iterator it =
2628  std::find( parentNode.childSections.begin(), parentNode.childSections.end(), sectionInfo );
2629  if( it == parentNode.childSections.end() ) {
2630  node = new SectionNode( incompleteStats );
2631  parentNode.childSections.push_back( node );
2632  }
2633  else
2634  node = *it;
2635  }
2636  m_sectionStack.push_back( node );
2637  m_deepestSection = node;
2638  }
2639 
2640  virtual void assertionStarting( AssertionInfo const& ) {}
2641 
2642  virtual bool assertionEnded( AssertionStats const& assertionStats ) {
2643  assert( !m_sectionStack.empty() );
2644  SectionNode& sectionNode = *m_sectionStack.back();
2645  sectionNode.assertions.push_back( assertionStats );
2646  return true;
2647  }
2648  virtual void sectionEnded( SectionStats const& sectionStats ) {
2649  assert( !m_sectionStack.empty() );
2650  SectionNode& node = *m_sectionStack.back();
2651  node.stats = sectionStats;
2652  m_sectionStack.pop_back();
2653  }
2654  virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
2655  Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats );
2656  assert( m_sectionStack.size() == 0 );
2657  node->children.push_back( m_rootSection );
2658  m_testCases.push_back( node );
2659  m_rootSection.reset();
2660 
2661  assert( m_deepestSection );
2662  m_deepestSection->stdOut = testCaseStats.stdOut;
2663  m_deepestSection->stdErr = testCaseStats.stdErr;
2664  }
2665  virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
2666  Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats );
2667  node->children.swap( m_testCases );
2668  m_testGroups.push_back( node );
2669  }
2670  virtual void testRunEnded( TestRunStats const& testRunStats ) {
2671  Ptr<TestRunNode> node = new TestRunNode( testRunStats );
2672  node->children.swap( m_testGroups );
2673  m_testRuns.push_back( node );
2674  testRunEnded();
2675  }
2676  virtual void testRunEnded() = 0;
2677 
2679  std::ostream& stream;
2680  std::vector<AssertionStats> m_assertions;
2681  std::vector<std::vector<Ptr<SectionNode> > > m_sections;
2682  std::vector<Ptr<TestCaseNode> > m_testCases;
2683  std::vector<Ptr<TestGroupNode> > m_testGroups;
2684 
2685  std::vector<Ptr<TestRunNode> > m_testRuns;
2686 
2689  std::vector<Ptr<SectionNode> > m_sectionStack;
2690 
2691  };
2692 
2693  // Deprecated
2694  struct IReporter : IShared {
2695  virtual ~IReporter();
2696 
2697  virtual bool shouldRedirectStdout() const = 0;
2698 
2699  virtual void StartTesting() = 0;
2700  virtual void EndTesting( Totals const& totals ) = 0;
2701  virtual void StartGroup( std::string const& groupName ) = 0;
2702  virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0;
2703  virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0;
2704  virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0;
2705  virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0;
2706  virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0;
2707  virtual void NoAssertionsInSection( std::string const& sectionName ) = 0;
2708  virtual void NoAssertionsInTestCase( std::string const& testName ) = 0;
2709  virtual void Aborted() = 0;
2710  virtual void Result( AssertionResult const& result ) = 0;
2711  };
2712 
2714  virtual ~IReporterFactory();
2715  virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0;
2716  virtual std::string getDescription() const = 0;
2717  };
2718 
2720  typedef std::map<std::string, IReporterFactory*> FactoryMap;
2721 
2722  virtual ~IReporterRegistry();
2723  virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig> const& config ) const = 0;
2724  virtual FactoryMap const& getFactories() const = 0;
2725  };
2726 
2727  inline std::string trim( std::string const& str ) {
2728  static char const* whitespaceChars = "\n\r\t ";
2729  std::string::size_type start = str.find_first_not_of( whitespaceChars );
2730  std::string::size_type end = str.find_last_not_of( whitespaceChars );
2731 
2732  return start != std::string::npos ? str.substr( start, 1+end-start ) : "";
2733  }
2734 }
2735 
2736 #include <vector>
2737 
2738 namespace Catch {
2739 
2740  class TestCase;
2741  struct ITestCaseRegistry;
2743  struct IExceptionTranslator;
2744 
2745  struct IRegistryHub {
2746  virtual ~IRegistryHub();
2747 
2748  virtual IReporterRegistry const& getReporterRegistry() const = 0;
2749  virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
2750  virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
2751  };
2752 
2754  virtual ~IMutableRegistryHub();
2755  virtual void registerReporter( std::string const& name, IReporterFactory* factory ) = 0;
2756  virtual void registerTest( TestCase const& testInfo ) = 0;
2757  virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
2758  };
2759 
2762  void cleanUp();
2763  std::string translateActiveException();
2764 
2765 }
2766 
2767 #include <ostream>
2768 
2769 namespace Catch {
2770 
2773  }
2774 
2775  template<typename MatcherT>
2777  std::string const& matcherCallAsString ) {
2778  std::string matcherAsString = matcher.toString();
2779  if( matcherAsString == "{?}" )
2780  matcherAsString = matcherCallAsString;
2781  return ExpressionResultBuilder()
2782  .setRhs( matcherAsString )
2783  .setOp( "matches" );
2784  }
2785 
2786  template<typename MatcherT, typename ArgT>
2788  ArgT const& arg,
2789  std::string const& matcherCallAsString ) {
2790  return expressionResultBuilderFromMatcher( matcher, matcherCallAsString )
2791  .setLhs( Catch::toString( arg ) )
2792  .setResultType( matcher.match( arg ) );
2793  }
2794 
2795  template<typename MatcherT, typename ArgT>
2797  ArgT* arg,
2798  std::string const& matcherCallAsString ) {
2799  return expressionResultBuilderFromMatcher( matcher, matcherCallAsString )
2800  .setLhs( Catch::toString( arg ) )
2801  .setResultType( matcher.match( arg ) );
2802  }
2803 
2805 
2806 } // end namespace Catch
2807 
2809 #define INTERNAL_CATCH_ASSERTIONINFO_NAME INTERNAL_CATCH_UNIQUE_NAME( __assertionInfo )
2810 
2812 #define INTERNAL_CATCH_ACCEPT_EXPR( evaluatedExpr, resultDisposition, originalExpr ) \
2813  if( Catch::ResultAction::Value internal_catch_action = Catch::getResultCapture().acceptExpression( evaluatedExpr, INTERNAL_CATCH_ASSERTIONINFO_NAME ) ) { \
2814  if( internal_catch_action & Catch::ResultAction::Debug ) BreakIntoDebugger(); \
2815  if( internal_catch_action & Catch::ResultAction::Abort ) throw Catch::TestFailureException(); \
2816  if( !Catch::shouldContinueOnFailure( resultDisposition ) ) throw Catch::TestFailureException(); \
2817  Catch::isTrue( false && originalExpr ); \
2818  }
2819 
2821 #define INTERNAL_CATCH_ACCEPT_INFO( expr, macroName, resultDisposition ) \
2822  Catch::AssertionInfo INTERNAL_CATCH_ASSERTIONINFO_NAME( macroName, CATCH_INTERNAL_LINEINFO, expr, resultDisposition );
2823 
2825 #define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \
2826  do { \
2827  INTERNAL_CATCH_ACCEPT_INFO( #expr, macroName, resultDisposition ); \
2828  try { \
2829  INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionDecomposer()->*expr ).endExpression( resultDisposition ), resultDisposition, expr ); \
2830  } catch( Catch::TestFailureException& ) { \
2831  throw; \
2832  } catch( ... ) { \
2833  INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::ThrewException ) << Catch::translateActiveException(), \
2834  resultDisposition | Catch::ResultDisposition::ContinueOnFailure, expr ); \
2835  } \
2836  } while( Catch::isTrue( false ) )
2837 
2839 #define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
2840  INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
2841  if( Catch::getResultCapture().getLastResult()->succeeded() )
2842 
2844 #define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \
2845  INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
2846  if( !Catch::getResultCapture().getLastResult()->succeeded() )
2847 
2849 #define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \
2850  do { \
2851  INTERNAL_CATCH_ACCEPT_INFO( #expr, macroName, resultDisposition ); \
2852  try { \
2853  expr; \
2854  INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::Ok ), resultDisposition, false ); \
2855  } \
2856  catch( ... ) { \
2857  INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::ThrewException ) << Catch::translateActiveException(), resultDisposition, false ); \
2858  } \
2859 } while( Catch::isTrue( false ) )
2860 
2862 #define INTERNAL_CATCH_THROWS_IMPL( expr, exceptionType, resultDisposition ) \
2863  try { \
2864  if( Catch::getCurrentContext().getConfig()->allowThrows() ) { \
2865  expr; \
2866  INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::DidntThrowException ), resultDisposition, false ); \
2867  } \
2868  } \
2869  catch( Catch::TestFailureException& ) { \
2870  throw; \
2871  } \
2872  catch( exceptionType ) { \
2873  INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::Ok ), resultDisposition, false ); \
2874  }
2875 
2877 #define INTERNAL_CATCH_THROWS( expr, exceptionType, resultDisposition, macroName ) \
2878  do { \
2879  INTERNAL_CATCH_ACCEPT_INFO( #expr, macroName, resultDisposition ); \
2880  INTERNAL_CATCH_THROWS_IMPL( expr, exceptionType, resultDisposition ) \
2881  } while( Catch::isTrue( false ) )
2882 
2884 #define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \
2885  do { \
2886  INTERNAL_CATCH_ACCEPT_INFO( #expr, macroName, resultDisposition ); \
2887  INTERNAL_CATCH_THROWS_IMPL( expr, exceptionType, resultDisposition ) \
2888  catch( ... ) { \
2889  INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionResultBuilder( Catch::ResultWas::ThrewException ) << Catch::translateActiveException() ), \
2890  resultDisposition | Catch::ResultDisposition::ContinueOnFailure, false ); \
2891  } \
2892  } while( Catch::isTrue( false ) )
2893 
2895 #define INTERNAL_CATCH_MSG( log, messageType, resultDisposition, macroName ) \
2896  do { \
2897  INTERNAL_CATCH_ACCEPT_INFO( "", macroName, resultDisposition ); \
2898  INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( messageType ) << log, resultDisposition, true ) \
2899  } while( Catch::isTrue( false ) )
2900 
2902 #define INTERNAL_CATCH_INFO( log, macroName ) \
2903  Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
2904 
2906 #define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \
2907  do { \
2908  INTERNAL_CATCH_ACCEPT_INFO( #arg " " #matcher, macroName, resultDisposition ); \
2909  try { \
2910  INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::expressionResultBuilderFromMatcher( ::Catch::Matchers::matcher, arg, #matcher ) ), resultDisposition, false ); \
2911  } catch( Catch::TestFailureException& ) { \
2912  throw; \
2913  } catch( ... ) { \
2914  INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionResultBuilder( Catch::ResultWas::ThrewException ) << Catch::translateActiveException() ), \
2915  resultDisposition | Catch::ResultDisposition::ContinueOnFailure, false ); \
2916  } \
2917  } while( Catch::isTrue( false ) )
2918 
2919 // #included from: internal/catch_section.hpp
2920 #define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
2921 
2922 // #included from: catch_timer.h
2923 #define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED
2924 
2925 #ifdef CATCH_PLATFORM_WINDOWS
2926 typedef unsigned long long uint64_t;
2927 #else
2928 #include <stdint.h>
2929 #endif
2930 
2931 namespace Catch {
2932 
2933  class Timer {
2934  public:
2935  Timer() : m_ticks( 0 ) {}
2936  void start();
2937  unsigned int getElapsedNanoseconds() const;
2938  unsigned int getElapsedMilliseconds() const;
2939  double getElapsedSeconds() const;
2940 
2941  private:
2942  uint64_t m_ticks;
2943  };
2944 
2945 } // namespace Catch
2946 
2947 #include <string>
2948 
2949 namespace Catch {
2950 
2951  class Section {
2952  public:
2953  Section( SourceLineInfo const& lineInfo,
2954  std::string const& name,
2955  std::string const& description = "" )
2956  : m_info( name, description, lineInfo ),
2957  m_sectionIncluded( getCurrentContext().getResultCapture().sectionStarted( m_info, m_assertions ) )
2958  {
2959  m_timer.start();
2960  }
2961 
2963  if( m_sectionIncluded )
2964  getCurrentContext().getResultCapture().sectionEnded( m_info, m_assertions, m_timer.getElapsedSeconds() );
2965  }
2966 
2967  // This indicates whether the section should be executed or not
2968  operator bool() {
2969  return m_sectionIncluded;
2970  }
2971 
2972  private:
2973  SectionInfo m_info;
2974 
2975  std::string m_name;
2976  Counts m_assertions;
2977  bool m_sectionIncluded;
2978  Timer m_timer;
2979  };
2980 
2981 } // end namespace Catch
2982 
2983 #ifdef CATCH_CONFIG_VARIADIC_MACROS
2984  #define INTERNAL_CATCH_SECTION( ... ) \
2985  if( Catch::Section INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::Section( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
2986 #else
2987  #define INTERNAL_CATCH_SECTION( name, desc ) \
2988  if( Catch::Section INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::Section( CATCH_INTERNAL_LINEINFO, name, desc ) )
2989 #endif
2990 
2991 // #included from: internal/catch_generators.hpp
2992 #define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
2993 
2994 #include <iterator>
2995 #include <vector>
2996 #include <string>
2997 #include <stdlib.h>
2998 
2999 namespace Catch {
3000 
3001 template<typename T>
3002 struct IGenerator {
3003  virtual ~IGenerator() {}
3004  virtual T getValue( std::size_t index ) const = 0;
3005  virtual std::size_t size () const = 0;
3006 };
3007 
3008 template<typename T>
3009 class BetweenGenerator : public IGenerator<T> {
3010 public:
3011  BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){}
3012 
3013  virtual T getValue( std::size_t index ) const {
3014  return m_from+static_cast<int>( index );
3015  }
3016 
3017  virtual std::size_t size() const {
3018  return static_cast<std::size_t>( 1+m_to-m_from );
3019  }
3020 
3021 private:
3022 
3023  T m_from;
3024  T m_to;
3025 };
3026 
3027 template<typename T>
3028 class ValuesGenerator : public IGenerator<T> {
3029 public:
3031 
3032  void add( T value ) {
3033  m_values.push_back( value );
3034  }
3035 
3036  virtual T getValue( std::size_t index ) const {
3037  return m_values[index];
3038  }
3039 
3040  virtual std::size_t size() const {
3041  return m_values.size();
3042  }
3043 
3044 private:
3045  std::vector<T> m_values;
3046 };
3047 
3048 template<typename T>
3050 public:
3051  CompositeGenerator() : m_totalSize( 0 ) {}
3052 
3053  // *** Move semantics, similar to auto_ptr ***
3055  : m_fileInfo( other.m_fileInfo ),
3056  m_totalSize( 0 )
3057  {
3058  move( other );
3059  }
3060 
3061  CompositeGenerator& setFileInfo( const char* fileInfo ) {
3062  m_fileInfo = fileInfo;
3063  return *this;
3064  }
3065 
3067  deleteAll( m_composed );
3068  }
3069 
3070  operator T () const {
3071  size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );
3072 
3073  typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
3074  typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
3075  for( size_t index = 0; it != itEnd; ++it )
3076  {
3077  const IGenerator<T>* generator = *it;
3078  if( overallIndex >= index && overallIndex < index + generator->size() )
3079  {
3080  return generator->getValue( overallIndex-index );
3081  }
3082  index += generator->size();
3083  }
3084  CATCH_INTERNAL_ERROR( "Indexed past end of generated range" );
3085  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
3086  }
3087 
3088  void add( const IGenerator<T>* generator ) {
3089  m_totalSize += generator->size();
3090  m_composed.push_back( generator );
3091  }
3092 
3094  move( other );
3095  return *this;
3096  }
3097 
3098  CompositeGenerator& then( T value ) {
3099  ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
3100  valuesGen->add( value );
3101  add( valuesGen );
3102  return *this;
3103  }
3104 
3105 private:
3106 
3107  void move( CompositeGenerator& other ) {
3108  std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );
3109  m_totalSize += other.m_totalSize;
3110  other.m_composed.clear();
3111  }
3112 
3113  std::vector<const IGenerator<T>*> m_composed;
3114  std::string m_fileInfo;
3115  size_t m_totalSize;
3116 };
3117 
3118 namespace Generators
3119 {
3120  template<typename T>
3121  CompositeGenerator<T> between( T from, T to ) {
3122  CompositeGenerator<T> generators;
3123  generators.add( new BetweenGenerator<T>( from, to ) );
3124  return generators;
3125  }
3126 
3127  template<typename T>
3128  CompositeGenerator<T> values( T val1, T val2 ) {
3129  CompositeGenerator<T> generators;
3130  ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
3131  valuesGen->add( val1 );
3132  valuesGen->add( val2 );
3133  generators.add( valuesGen );
3134  return generators;
3135  }
3136 
3137  template<typename T>
3138  CompositeGenerator<T> values( T val1, T val2, T val3 ){
3139  CompositeGenerator<T> generators;
3140  ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
3141  valuesGen->add( val1 );
3142  valuesGen->add( val2 );
3143  valuesGen->add( val3 );
3144  generators.add( valuesGen );
3145  return generators;
3146  }
3147 
3148  template<typename T>
3149  CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) {
3150  CompositeGenerator<T> generators;
3151  ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
3152  valuesGen->add( val1 );
3153  valuesGen->add( val2 );
3154  valuesGen->add( val3 );
3155  valuesGen->add( val4 );
3156  generators.add( valuesGen );
3157  return generators;
3158  }
3159 
3160 } // end namespace Generators
3161 
3162 using namespace Generators;
3163 
3164 } // end namespace Catch
3165 
3166 #define INTERNAL_CATCH_LINESTR2( line ) #line
3167 #define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )
3168 
3169 #define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" )
3170 
3171 // #included from: internal/catch_interfaces_exception.h
3172 #define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
3173 
3174 #include <string>
3175 
3176 namespace Catch {
3177 
3178  typedef std::string(*exceptionTranslateFunction)();
3179 
3181  virtual ~IExceptionTranslator();
3182  virtual std::string translate() const = 0;
3183  };
3184 
3186  virtual ~IExceptionTranslatorRegistry();
3187 
3188  virtual std::string translateActiveException() const = 0;
3189  };
3190 
3192  template<typename T>
3193  class ExceptionTranslator : public IExceptionTranslator {
3194  public:
3195 
3196  ExceptionTranslator( std::string(*translateFunction)( T& ) )
3197  : m_translateFunction( translateFunction )
3198  {}
3199 
3200  virtual std::string translate() const {
3201  try {
3202  throw;
3203  }
3204  catch( T& ex ) {
3205  return m_translateFunction( ex );
3206  }
3207  }
3208 
3209  protected:
3210  std::string(*m_translateFunction)( T& );
3211  };
3212 
3213  public:
3214  template<typename T>
3215  ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
3217  ( new ExceptionTranslator<T>( translateFunction ) );
3218  }
3219  };
3220 }
3221 
3223 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) \
3224  static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ); \
3225  namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ) ); }\
3226  static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature )
3227 
3228 // #included from: internal/catch_approx.hpp
3229 #define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
3230 
3231 #include <cmath>
3232 #include <limits>
3233 
3234 namespace Catch {
3235 namespace Detail {
3236 
3237  class Approx {
3238  public:
3239  explicit Approx ( double value )
3240  : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
3241  m_scale( 1.0 ),
3242  m_value( value )
3243  {}
3244 
3245  Approx( Approx const& other )
3246  : m_epsilon( other.m_epsilon ),
3247  m_scale( other.m_scale ),
3248  m_value( other.m_value )
3249  {}
3250 
3251  static Approx custom() {
3252  return Approx( 0 );
3253  }
3254 
3255  Approx operator()( double value ) {
3256  Approx approx( value );
3257  approx.epsilon( m_epsilon );
3258  approx.scale( m_scale );
3259  return approx;
3260  }
3261 
3262  friend bool operator == ( double lhs, Approx const& rhs ) {
3263  // Thanks to Richard Harris for his help refining this formula
3264  return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );
3265  }
3266 
3267  friend bool operator == ( Approx const& lhs, double rhs ) {
3268  return operator==( rhs, lhs );
3269  }
3270 
3271  friend bool operator != ( double lhs, Approx const& rhs ) {
3272  return !operator==( lhs, rhs );
3273  }
3274 
3275  friend bool operator != ( Approx const& lhs, double rhs ) {
3276  return !operator==( rhs, lhs );
3277  }
3278 
3279  Approx& epsilon( double newEpsilon ) {
3280  m_epsilon = newEpsilon;
3281  return *this;
3282  }
3283 
3284  Approx& scale( double newScale ) {
3285  m_scale = newScale;
3286  return *this;
3287  }
3288 
3289  std::string toString() const {
3290  std::ostringstream oss;
3291  oss << "Approx( " << m_value << " )";
3292  return oss.str();
3293  }
3294 
3295  private:
3296  double m_epsilon;
3297  double m_scale;
3298  double m_value;
3299  };
3300 }
3301 
3302 template<>
3303 inline std::string toString<Detail::Approx>( Detail::Approx const& value ) {
3304  return value.toString();
3305 }
3306 
3307 } // end namespace Catch
3308 
3309 // #included from: internal/catch_matchers.hpp
3310 #define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
3311 
3312 namespace Catch {
3313 namespace Matchers {
3314  namespace Impl {
3315 
3316  template<typename ExpressionT>
3317  struct Matcher : SharedImpl<IShared>
3318  {
3319  typedef ExpressionT ExpressionType;
3320 
3321  virtual ~Matcher() {}
3322  virtual Ptr<Matcher> clone() const = 0;
3323  virtual bool match( ExpressionT const& expr ) const = 0;
3324  virtual std::string toString() const = 0;
3325  };
3326 
3327  template<typename DerivedT, typename ExpressionT>
3328  struct MatcherImpl : Matcher<ExpressionT> {
3329 
3330  virtual Ptr<Matcher<ExpressionT> > clone() const {
3331  return Ptr<Matcher<ExpressionT> >( new DerivedT( static_cast<DerivedT const&>( *this ) ) );
3332  }
3333  };
3334 
3335  namespace Generic {
3336 
3337  template<typename ExpressionT>
3338  class AllOf : public MatcherImpl<AllOf<ExpressionT>, ExpressionT> {
3339  public:
3340 
3341  AllOf() {}
3342  AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {}
3343 
3344  AllOf& add( Matcher<ExpressionT> const& matcher ) {
3345  m_matchers.push_back( matcher.clone() );
3346  return *this;
3347  }
3348  virtual bool match( ExpressionT const& expr ) const
3349  {
3350  for( std::size_t i = 0; i < m_matchers.size(); ++i )
3351  if( !m_matchers[i]->match( expr ) )
3352  return false;
3353  return true;
3354  }
3355  virtual std::string toString() const {
3356  std::ostringstream oss;
3357  oss << "( ";
3358  for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
3359  if( i != 0 )
3360  oss << " and ";
3361  oss << m_matchers[i]->toString();
3362  }
3363  oss << " )";
3364  return oss.str();
3365  }
3366 
3367  private:
3368  std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
3369  };
3370 
3371  template<typename ExpressionT>
3372  class AnyOf : public MatcherImpl<AnyOf<ExpressionT>, ExpressionT> {
3373  public:
3374 
3375  AnyOf() {}
3376  AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {}
3377 
3378  AnyOf& add( Matcher<ExpressionT> const& matcher ) {
3379  m_matchers.push_back( matcher.clone() );
3380  return *this;
3381  }
3382  virtual bool match( ExpressionT const& expr ) const
3383  {
3384  for( std::size_t i = 0; i < m_matchers.size(); ++i )
3385  if( m_matchers[i]->match( expr ) )
3386  return true;
3387  return false;
3388  }
3389  virtual std::string toString() const {
3390  std::ostringstream oss;
3391  oss << "( ";
3392  for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
3393  if( i != 0 )
3394  oss << " or ";
3395  oss << m_matchers[i]->toString();
3396  }
3397  oss << " )";
3398  return oss.str();
3399  }
3400 
3401  private:
3402  std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
3403  };
3404 
3405  }
3406 
3407  namespace StdString {
3408 
3409  inline std::string makeString( std::string const& str ) { return str; }
3410  inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); }
3411 
3412  struct Equals : MatcherImpl<Equals, std::string> {
3413  Equals( std::string const& str ) : m_str( str ){}
3414  Equals( Equals const& other ) : m_str( other.m_str ){}
3415 
3416  virtual ~Equals();
3417 
3418  virtual bool match( std::string const& expr ) const {
3419  return m_str == expr;
3420  }
3421  virtual std::string toString() const {
3422  return "equals: \"" + m_str + "\"";
3423  }
3424 
3425  std::string m_str;
3426  };
3427 
3428  struct Contains : MatcherImpl<Contains, std::string> {
3429  Contains( std::string const& substr ) : m_substr( substr ){}
3430  Contains( Contains const& other ) : m_substr( other.m_substr ){}
3431 
3432  virtual ~Contains();
3433 
3434  virtual bool match( std::string const& expr ) const {
3435  return expr.find( m_substr ) != std::string::npos;
3436  }
3437  virtual std::string toString() const {
3438  return "contains: \"" + m_substr + "\"";
3439  }
3440 
3441  std::string m_substr;
3442  };
3443 
3444  struct StartsWith : MatcherImpl<StartsWith, std::string> {
3445  StartsWith( std::string const& substr ) : m_substr( substr ){}
3446  StartsWith( StartsWith const& other ) : m_substr( other.m_substr ){}
3447 
3448  virtual ~StartsWith();
3449 
3450  virtual bool match( std::string const& expr ) const {
3451  return expr.find( m_substr ) == 0;
3452  }
3453  virtual std::string toString() const {
3454  return "starts with: \"" + m_substr + "\"";
3455  }
3456 
3457  std::string m_substr;
3458  };
3459 
3460  struct EndsWith : MatcherImpl<EndsWith, std::string> {
3461  EndsWith( std::string const& substr ) : m_substr( substr ){}
3462  EndsWith( EndsWith const& other ) : m_substr( other.m_substr ){}
3463 
3464  virtual ~EndsWith();
3465 
3466  virtual bool match( std::string const& expr ) const {
3467  return expr.find( m_substr ) == expr.size() - m_substr.size();
3468  }
3469  virtual std::string toString() const {
3470  return "ends with: \"" + m_substr + "\"";
3471  }
3472 
3473  std::string m_substr;
3474  };
3475  } // namespace StdString
3476  } // namespace Impl
3477 
3478  // The following functions create the actual matcher objects.
3479  // This allows the types to be inferred
3480  template<typename ExpressionT>
3482  Impl::Matcher<ExpressionT> const& m2 ) {
3483  return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 );
3484  }
3485  template<typename ExpressionT>
3487  Impl::Matcher<ExpressionT> const& m2,
3488  Impl::Matcher<ExpressionT> const& m3 ) {
3489  return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
3490  }
3491  template<typename ExpressionT>
3493  Impl::Matcher<ExpressionT> const& m2 ) {
3494  return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 );
3495  }
3496  template<typename ExpressionT>
3498  Impl::Matcher<ExpressionT> const& m2,
3499  Impl::Matcher<ExpressionT> const& m3 ) {
3500  return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
3501  }
3502 
3503  inline Impl::StdString::Equals Equals( std::string const& str ) {
3504  return Impl::StdString::Equals( str );
3505  }
3506  inline Impl::StdString::Equals Equals( const char* str ) {
3508  }
3509  inline Impl::StdString::Contains Contains( std::string const& substr ) {
3510  return Impl::StdString::Contains( substr );
3511  }
3512  inline Impl::StdString::Contains Contains( const char* substr ) {
3514  }
3515  inline Impl::StdString::StartsWith StartsWith( std::string const& substr ) {
3516  return Impl::StdString::StartsWith( substr );
3517  }
3518  inline Impl::StdString::StartsWith StartsWith( const char* substr ) {
3520  }
3521  inline Impl::StdString::EndsWith EndsWith( std::string const& substr ) {
3522  return Impl::StdString::EndsWith( substr );
3523  }
3524  inline Impl::StdString::EndsWith EndsWith( const char* substr ) {
3526  }
3527 
3528 } // namespace Matchers
3529 
3530 using namespace Matchers;
3531 
3532 } // namespace Catch
3533 
3534 // These files are included here so the single_include script doesn't put them
3535 // in the conditionally compiled sections
3536 // #included from: internal/catch_interfaces_runner.h
3537 #define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
3538 
3539 #include <string>
3540 
3541 namespace Catch {
3542  class TestCase;
3543 
3544  struct IRunner {
3545  virtual ~IRunner();
3546  };
3547 }
3548 
3549 
3550 #ifdef __OBJC__
3551 // #included from: internal/catch_objc.hpp
3552 #define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
3553 
3554 #import <objc/runtime.h>
3555 
3556 #include <string>
3557 
3558 // NB. Any general catch headers included here must be included
3559 // in catch.hpp first to make sure they are included by the single
3560 // header for non obj-usage
3561 
3563 // This protocol is really only here for (self) documenting purposes, since
3564 // all its methods are optional.
3565 @protocol OcFixture
3566 
3567 @optional
3568 
3569 -(void) setUp;
3570 -(void) tearDown;
3571 
3572 @end
3573 
3574 namespace Catch {
3575 
3576  class OcMethod : public SharedImpl<ITestCase> {
3577 
3578  public:
3579  OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
3580 
3581  virtual void invoke() const {
3582  id obj = [[m_cls alloc] init];
3583 
3584  performOptionalSelector( obj, @selector(setUp) );
3585  performOptionalSelector( obj, m_sel );
3586  performOptionalSelector( obj, @selector(tearDown) );
3587 
3588  arcSafeRelease( obj );
3589  }
3590  private:
3591  virtual ~OcMethod() {}
3592 
3593  Class m_cls;
3594  SEL m_sel;
3595  };
3596 
3597  namespace Detail{
3598 
3599  inline bool startsWith( std::string const& str, std::string const& sub ) {
3600  return str.length() > sub.length() && str.substr( 0, sub.length() ) == sub;
3601  }
3602 
3603  inline std::string getAnnotation( Class cls,
3604  std::string const& annotationName,
3605  std::string const& testCaseName ) {
3606  NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
3607  SEL sel = NSSelectorFromString( selStr );
3608  arcSafeRelease( selStr );
3609  id value = performOptionalSelector( cls, sel );
3610  if( value )
3611  return [(NSString*)value UTF8String];
3612  return "";
3613  }
3614  }
3615 
3616  inline size_t registerTestMethods() {
3617  size_t noTestMethods = 0;
3618  int noClasses = objc_getClassList( NULL, 0 );
3619 
3620  Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
3621  objc_getClassList( classes, noClasses );
3622 
3623  for( int c = 0; c < noClasses; c++ ) {
3624  Class cls = classes[c];
3625  {
3626  u_int count;
3627  Method* methods = class_copyMethodList( cls, &count );
3628  for( u_int m = 0; m < count ; m++ ) {
3629  SEL selector = method_getName(methods[m]);
3630  std::string methodName = sel_getName(selector);
3631  if( Detail::startsWith( methodName, "Catch_TestCase_" ) ) {
3632  std::string testCaseName = methodName.substr( 15 );
3633  std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
3634  std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
3635  const char* className = class_getName( cls );
3636 
3637  getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) );
3638  noTestMethods++;
3639  }
3640  }
3641  free(methods);
3642  }
3643  }
3644  return noTestMethods;
3645  }
3646 
3647  namespace Matchers {
3648  namespace Impl {
3649  namespace NSStringMatchers {
3650 
3651  template<typename MatcherT>
3652  struct StringHolder : MatcherImpl<MatcherT, NSString*>{
3653  StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
3654  StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
3655  StringHolder() {
3656  arcSafeRelease( m_substr );
3657  }
3658 
3659  NSString* m_substr;
3660  };
3661 
3662  struct Equals : StringHolder<Equals> {
3663  Equals( NSString* substr ) : StringHolder( substr ){}
3664 
3665  virtual bool match( ExpressionType const& str ) const {
3666  return (str != nil || m_substr == nil ) &&
3667  [str isEqualToString:m_substr];
3668  }
3669 
3670  virtual std::string toString() const {
3671  return "equals string: \"" + Catch::toString( m_substr ) + "\"";
3672  }
3673  };
3674 
3675  struct Contains : StringHolder<Contains> {
3676  Contains( NSString* substr ) : StringHolder( substr ){}
3677 
3678  virtual bool match( ExpressionType const& str ) const {
3679  return (str != nil || m_substr == nil ) &&
3680  [str rangeOfString:m_substr].location != NSNotFound;
3681  }
3682 
3683  virtual std::string toString() const {
3684  return "contains string: \"" + Catch::toString( m_substr ) + "\"";
3685  }
3686  };
3687 
3688  struct StartsWith : StringHolder<StartsWith> {
3689  StartsWith( NSString* substr ) : StringHolder( substr ){}
3690 
3691  virtual bool match( ExpressionType const& str ) const {
3692  return (str != nil || m_substr == nil ) &&
3693  [str rangeOfString:m_substr].location == 0;
3694  }
3695 
3696  virtual std::string toString() const {
3697  return "starts with: \"" + Catch::toString( m_substr ) + "\"";
3698  }
3699  };
3700  struct EndsWith : StringHolder<EndsWith> {
3701  EndsWith( NSString* substr ) : StringHolder( substr ){}
3702 
3703  virtual bool match( ExpressionType const& str ) const {
3704  return (str != nil || m_substr == nil ) &&
3705  [str rangeOfString:m_substr].location == [str length] - [m_substr length];
3706  }
3707 
3708  virtual std::string toString() const {
3709  return "ends with: \"" + Catch::toString( m_substr ) + "\"";
3710  }
3711  };
3712 
3713  } // namespace NSStringMatchers
3714  } // namespace Impl
3715 
3717  Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
3718 
3720  Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
3721 
3723  StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
3724 
3726  EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
3727 
3728  } // namespace Matchers
3729 
3730  using namespace Matchers;
3731 
3732 } // namespace Catch
3733 
3735 #define OC_TEST_CASE( name, desc )\
3736 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
3737 {\
3738 return @ name; \
3739 }\
3740 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
3741 { \
3742 return @ desc; \
3743 } \
3744 -(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
3745 
3746 #endif
3747 
3748 #if defined( CATCH_CONFIG_MAIN ) || defined( CATCH_CONFIG_RUNNER )
3749 // #included from: internal/catch_impl.hpp
3750 #define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED
3751 
3752 // Collect all the implementation files together here
3753 // These are the equivalent of what would usually be cpp files
3754 
3755 #ifdef __clang__
3756 #pragma clang diagnostic push
3757 #pragma clang diagnostic ignored "-Wweak-vtables"
3758 #endif
3759 
3760 // #included from: catch_runner.hpp
3761 #define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
3762 
3763 // #included from: internal/catch_commandline.hpp
3764 #define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
3765 
3766 // #included from: clara.h
3767 #define TWOBLUECUBES_CLARA_H_INCLUDED
3768 
3769 // #included from: catch_text.h
3770 #define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED
3771 
3772 #include <string>
3773 #include <vector>
3774 
3775 namespace Catch {
3776 
3777  struct TextAttributes {
3778  TextAttributes()
3779  : initialIndent( std::string::npos ),
3780  indent( 0 ),
3781  width( CATCH_CONFIG_CONSOLE_WIDTH-1 ),
3782  tabChar( '\t' )
3783  {}
3784 
3785  TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
3786  TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
3787  TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
3788  TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; }
3789 
3790  std::size_t initialIndent; // indent of first line, or npos
3791  std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos
3792  std::size_t width; // maximum width of text, including indent. Longer text will wrap
3793  char tabChar; // If this char is seen the indent is changed to current pos
3794  };
3795 
3796  class Text {
3797  public:
3798  Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() );
3799  void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos );
3800 
3801  typedef std::vector<std::string>::const_iterator const_iterator;
3802 
3803  const_iterator begin() const { return lines.begin(); }
3804  const_iterator end() const { return lines.end(); }
3805  std::string const& last() const { return lines.back(); }
3806  std::size_t size() const { return lines.size(); }
3807  std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
3808  std::string toString() const;
3809 
3810  friend std::ostream& operator << ( std::ostream& _stream, Text const& _text );
3811 
3812  private:
3813  std::string str;
3814  TextAttributes attr;
3815  std::vector<std::string> lines;
3816  };
3817 
3818 } // end namespace Catch
3819 
3820 namespace Clara {
3821  namespace Detail {
3822  template<typename T> struct RemoveConstRef{ typedef T type; };
3823  template<typename T> struct RemoveConstRef<T&>{ typedef T type; };
3824  template<typename T> struct RemoveConstRef<T const&>{ typedef T type; };
3825  template<typename T> struct RemoveConstRef<T const>{ typedef T type; };
3826 
3827  template<typename T> struct IsBool { static const bool value = false; };
3828  template<> struct IsBool<bool> { static const bool value = true; };
3829 
3830  template<typename T>
3831  void convertInto( std::string const& _source, T& _dest ) {
3832  std::stringstream ss;
3833  ss << _source;
3834  ss >> _dest;
3835  if( ss.fail() )
3836  throw std::runtime_error( "Unable to convert " + _source + " to destination type" );
3837  }
3838  inline void convertInto( std::string const& _source, std::string& _dest ) {
3839  _dest = _source;
3840  }
3841  inline void convertInto( std::string const& _source, bool& _dest ) {
3842  std::string sourceLC = _source;
3843  std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), ::tolower );
3844  if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" )
3845  _dest = true;
3846  else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" )
3847  _dest = false;
3848  else
3849  throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" );
3850  }
3851  inline void convertInto( bool _source, bool& _dest ) {
3852  _dest = _source;
3853  }
3854  template<typename T>
3855  inline void convertInto( bool, T& ) {
3856  throw std::runtime_error( "Invalid conversion" );
3857  }
3858 
3859  template<typename ConfigT>
3860  struct IArgFunction {
3861  virtual ~IArgFunction() {}
3862  virtual void set( ConfigT& config, std::string const& value ) const = 0;
3863  virtual void setFlag( ConfigT& config ) const = 0;
3864  virtual bool takesArg() const = 0;
3865  virtual IArgFunction* clone() const = 0;
3866  };
3867 
3868  template<typename ConfigT>
3869  class BoundArgFunction {
3870  public:
3871  BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
3872  BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj->clone() ) {}
3873  BoundArgFunction& operator = ( BoundArgFunction const& other ) {
3874  IArgFunction<ConfigT>* newFunctionObj = other.functionObj->clone();
3875  delete functionObj;
3876  functionObj = newFunctionObj;
3877  return *this;
3878  }
3879  ~BoundArgFunction() { delete functionObj; }
3880 
3881  void set( ConfigT& config, std::string const& value ) const {
3882  functionObj->set( config, value );
3883  }
3884  void setFlag( ConfigT& config ) const {
3885  functionObj->setFlag( config );
3886  }
3887  bool takesArg() const { return functionObj->takesArg(); }
3888  private:
3889  IArgFunction<ConfigT>* functionObj;
3890  };
3891 
3892  template<typename C>
3893  struct NullBinder : IArgFunction<C>{
3894  virtual void set( C&, std::string const& ) const {}
3895  virtual void setFlag( C& ) const {}
3896  virtual bool takesArg() const { return true; }
3897  virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }
3898  };
3899 
3900  template<typename C, typename M>
3901  struct BoundDataMember : IArgFunction<C>{
3902  BoundDataMember( M C::* _member ) : member( _member ) {}
3903  virtual void set( C& p, std::string const& stringValue ) const {
3904  convertInto( stringValue, p.*member );
3905  }
3906  virtual void setFlag( C& p ) const {
3907  convertInto( true, p.*member );
3908  }
3909  virtual bool takesArg() const { return !IsBool<M>::value; }
3910  virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }
3911  M C::* member;
3912  };
3913  template<typename C, typename M>
3914  struct BoundUnaryMethod : IArgFunction<C>{
3915  BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {}
3916  virtual void set( C& p, std::string const& stringValue ) const {
3917  typename RemoveConstRef<M>::type value;
3918  convertInto( stringValue, value );
3919  (p.*member)( value );
3920  }
3921  virtual void setFlag( C& p ) const {
3922  typename RemoveConstRef<M>::type value;
3923  convertInto( true, value );
3924  (p.*member)( value );
3925  }
3926  virtual bool takesArg() const { return !IsBool<M>::value; }
3927  virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }
3928  void (C::*member)( M );
3929  };
3930  template<typename C>
3931  struct BoundNullaryMethod : IArgFunction<C>{
3932  BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {}
3933  virtual void set( C& p, std::string const& stringValue ) const {
3934  bool value;
3935  convertInto( stringValue, value );
3936  if( value )
3937  (p.*member)();
3938  }
3939  virtual void setFlag( C& p ) const {
3940  (p.*member)();
3941  }
3942  virtual bool takesArg() const { return false; }
3943  virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }
3944  void (C::*member)();
3945  };
3946 
3947  template<typename C>
3948  struct BoundUnaryFunction : IArgFunction<C>{
3949  BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {}
3950  virtual void set( C& obj, std::string const& stringValue ) const {
3951  bool value;
3952  convertInto( stringValue, value );
3953  if( value )
3954  function( obj );
3955  }
3956  virtual void setFlag( C& p ) const {
3957  function( p );
3958  }
3959  virtual bool takesArg() const { return false; }
3960  virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }
3961  void (*function)( C& );
3962  };
3963 
3964  template<typename C, typename T>
3965  struct BoundBinaryFunction : IArgFunction<C>{
3966  BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {}
3967  virtual void set( C& obj, std::string const& stringValue ) const {
3968  typename RemoveConstRef<T>::type value;
3969  convertInto( stringValue, value );
3970  function( obj, value );
3971  }
3972  virtual void setFlag( C& obj ) const {
3973  typename RemoveConstRef<T>::type value;
3974  convertInto( true, value );
3975  function( obj, value );
3976  }
3977  virtual bool takesArg() const { return !IsBool<T>::value; }
3978  virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }
3979  void (*function)( C&, T );
3980  };
3981 
3982  template<typename C, typename M>
3983  BoundArgFunction<C> makeBoundField( M C::* _member ) {
3984  return BoundArgFunction<C>( new BoundDataMember<C,M>( _member ) );
3985  }
3986  template<typename C, typename M>
3987  BoundArgFunction<C> makeBoundField( void (C::*_member)( M ) ) {
3988  return BoundArgFunction<C>( new BoundUnaryMethod<C,M>( _member ) );
3989  }
3990  template<typename C>
3991  BoundArgFunction<C> makeBoundField( void (C::*_member)() ) {
3992  return BoundArgFunction<C>( new BoundNullaryMethod<C>( _member ) );
3993  }
3994  template<typename C>
3995  BoundArgFunction<C> makeBoundField( void (*_function)( C& ) ) {
3996  return BoundArgFunction<C>( new BoundUnaryFunction<C>( _function ) );
3997  }
3998  template<typename C, typename T>
3999  BoundArgFunction<C> makeBoundField( void (*_function)( C&, T ) ) {
4000  return BoundArgFunction<C>( new BoundBinaryFunction<C, T>( _function ) );
4001  }
4002  } // namespace Detail
4003 
4004  struct Parser {
4005  Parser() : separators( " \t=:" ) {}
4006 
4007  struct Token {
4008  enum Type { Positional, ShortOpt, LongOpt };
4009  Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {}
4010  Type type;
4011  std::string data;
4012  };
4013 
4014  void parseIntoTokens( int argc, char const * const * argv, std::vector<Parser::Token>& tokens ) const {
4015  for( int i = 1; i < argc; ++i )
4016  parseIntoTokens( argv[i] , tokens);
4017  }
4018  void parseIntoTokens( std::string arg, std::vector<Parser::Token>& tokens ) const {
4019  while( !arg.empty() ) {
4020  Parser::Token token( Parser::Token::Positional, arg );
4021  arg = "";
4022  if( token.data[0] == '-' ) {
4023  if( token.data.size() > 1 && token.data[1] == '-' ) {
4024  token = Parser::Token( Parser::Token::LongOpt, token.data.substr( 2 ) );
4025  }
4026  else {
4027  token = Parser::Token( Parser::Token::ShortOpt, token.data.substr( 1 ) );
4028  if( token.data.size() > 1 && separators.find( token.data[1] ) == std::string::npos ) {
4029  arg = "-" + token.data.substr( 1 );
4030  token.data = token.data.substr( 0, 1 );
4031  }
4032  }
4033  }
4034  if( token.type != Parser::Token::Positional ) {
4035  std::size_t pos = token.data.find_first_of( separators );
4036  if( pos != std::string::npos ) {
4037  arg = token.data.substr( pos+1 );
4038  token.data = token.data.substr( 0, pos );
4039  }
4040  }
4041  tokens.push_back( token );
4042  }
4043  }
4044  std::string separators;
4045  };
4046 
4047  template<typename ConfigT>
4048  class CommandLine {
4049 
4050  struct Arg {
4051  Arg( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ), position( -1 ) {}
4052 
4053  bool hasShortName( std::string const& shortName ) const {
4054  for( std::vector<std::string>::const_iterator
4055  it = shortNames.begin(), itEnd = shortNames.end();
4056  it != itEnd;
4057  ++it )
4058  if( *it == shortName )
4059  return true;
4060  return false;
4061  }
4062  bool hasLongName( std::string const& _longName ) const {
4063  return _longName == longName;
4064  }
4065  bool takesArg() const {
4066  return !hint.empty();
4067  }
4068  bool isFixedPositional() const {
4069  return position != -1;
4070  }
4071  bool isAnyPositional() const {
4072  return position == -1 && shortNames.empty() && longName.empty();
4073  }
4074  std::string dbgName() const {
4075  if( !longName.empty() )
4076  return "--" + longName;
4077  if( !shortNames.empty() )
4078  return "-" + shortNames[0];
4079  return "positional args";
4080  }
4081  void validate() const {
4082  if( boundField.takesArg() && !takesArg() )
4083  throw std::logic_error( dbgName() + " must specify an arg name" );
4084  }
4085  std::string commands() const {
4086  std::ostringstream oss;
4087  bool first = true;
4088  std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();
4089  for(; it != itEnd; ++it ) {
4090  if( first )
4091  first = false;
4092  else
4093  oss << ", ";
4094  oss << "-" << *it;
4095  }
4096  if( !longName.empty() ) {
4097  if( !first )
4098  oss << ", ";
4099  oss << "--" << longName;
4100  }
4101  if( !hint.empty() )
4102  oss << " <" << hint << ">";
4103  return oss.str();
4104  }
4105 
4106  Detail::BoundArgFunction<ConfigT> boundField;
4107  std::vector<std::string> shortNames;
4108  std::string longName;
4109  std::string description;
4110  std::string hint;
4111  int position;
4112  };
4113 
4114  class ArgBinder {
4115  public:
4116  template<typename F>
4117  ArgBinder( CommandLine* cl, F f )
4118  : m_cl( cl ),
4119  m_arg( Detail::makeBoundField( f ) )
4120  {}
4121  ArgBinder( ArgBinder& other )
4122  : m_cl( other.m_cl ),
4123  m_arg( other.m_arg )
4124  {
4125  other.m_cl = NULL;
4126  }
4127  ~ArgBinder() {
4128  if( m_cl ) {
4129  m_arg.validate();
4130  if( m_arg.isFixedPositional() ) {
4131  m_cl->m_positionalArgs.insert( std::make_pair( m_arg.position, m_arg ) );
4132  if( m_arg.position > m_cl->m_highestSpecifiedArgPosition )
4133  m_cl->m_highestSpecifiedArgPosition = m_arg.position;
4134  }
4135  else if( m_arg.isAnyPositional() ) {
4136  if( m_cl->m_arg.get() )
4137  throw std::logic_error( "Only one unpositional argument can be added" );
4138  m_cl->m_arg = std::auto_ptr<Arg>( new Arg( m_arg ) );
4139  }
4140  else
4141  m_cl->m_options.push_back( m_arg );
4142  }
4143  }
4144  ArgBinder& shortOpt( std::string const& name ) {
4145  m_arg.shortNames.push_back( name );
4146  return *this;
4147  }
4148  ArgBinder& longOpt( std::string const& name ) {
4149  m_arg.longName = name;
4150  return *this;
4151  }
4152  ArgBinder& describe( std::string const& description ) {
4153  m_arg.description = description;
4154  return *this;
4155  }
4156  ArgBinder& hint( std::string const& hint ) {
4157  m_arg.hint = hint;
4158  return *this;
4159  }
4160  ArgBinder& position( int position ) {
4161  m_arg.position = position;
4162  return *this;
4163  }
4164  private:
4165  CommandLine* m_cl;
4166  Arg m_arg;
4167  };
4168 
4169  public:
4170 
4171  CommandLine()
4172  : m_boundProcessName( new Detail::NullBinder<ConfigT>() ),
4173  m_highestSpecifiedArgPosition( 0 )
4174  {}
4175  CommandLine( CommandLine const& other )
4176  : m_boundProcessName( other.m_boundProcessName ),
4177  m_options ( other.m_options ),
4178  m_positionalArgs( other.m_positionalArgs ),
4179  m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition )
4180  {
4181  if( other.m_arg.get() )
4182  m_arg = std::auto_ptr<Arg>( new Arg( *other.m_arg ) );
4183  }
4184 
4185  template<typename F>
4186  ArgBinder bind( F f ) {
4187  ArgBinder binder( this, f );
4188  return binder;
4189  }
4190  template<typename F>
4191  void bindProcessName( F f ) {
4192  m_boundProcessName = Detail::makeBoundField( f );
4193  }
4194 
4195  void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = CATCH_CONFIG_CONSOLE_WIDTH ) const {
4196  typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;
4197  std::size_t maxWidth = 0;
4198  for( it = itBegin; it != itEnd; ++it )
4199  maxWidth = (std::max)( maxWidth, it->commands().size() );
4200 
4201  for( it = itBegin; it != itEnd; ++it ) {
4202  Catch::Text usage( it->commands(), Catch::TextAttributes()
4203  .setWidth( maxWidth+indent )
4204  .setIndent( indent ) );
4205  // !TBD handle longer usage strings
4206  Catch::Text desc( it->description, Catch::TextAttributes()
4207  .setWidth( width - maxWidth -3 ) );
4208 
4209  for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) {
4210  std::string usageCol = i < usage.size() ? usage[i] : "";
4211  os << usageCol;
4212 
4213  if( i < desc.size() && !desc[i].empty() )
4214  os << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' )
4215  << desc[i];
4216  os << "\n";
4217  }
4218  }
4219  }
4220  std::string optUsage() const {
4221  std::ostringstream oss;
4222  optUsage( oss );
4223  return oss.str();
4224  }
4225 
4226  void argSynopsis( std::ostream& os ) const {
4227  for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {
4228  if( i > 1 )
4229  os << " ";
4230  typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
4231  if( it != m_positionalArgs.end() )
4232  os << "<" << it->second.hint << ">";
4233  else if( m_arg.get() )
4234  os << "<" << m_arg->hint << ">";
4235  else
4236  throw std::logic_error( "non consecutive positional arguments with no floating args" );
4237  }
4238  // !TBD No indication of mandatory args
4239  if( m_arg.get() ) {
4240  if( m_highestSpecifiedArgPosition > 1 )
4241  os << " ";
4242  os << "[<" << m_arg->hint << "> ...]";
4243  }
4244  }
4245  std::string argSynopsis() const {
4246  std::ostringstream oss;
4247  argSynopsis( oss );
4248  return oss.str();
4249  }
4250 
4251  void usage( std::ostream& os, std::string const& procName ) const {
4252  os << "usage:\n " << procName << " ";
4253  argSynopsis( os );
4254  if( !m_options.empty() ) {
4255  os << " [options]\n\nwhere options are: \n";
4256  optUsage( os, 2 );
4257  }
4258  os << "\n";
4259  }
4260  std::string usage( std::string const& procName ) const {
4261  std::ostringstream oss;
4262  usage( oss, procName );
4263  return oss.str();
4264  }
4265 
4266  std::vector<Parser::Token> parseInto( int argc, char const * const * argv, ConfigT& config ) const {
4267  std::string processName = argv[0];
4268  std::size_t lastSlash = processName.find_last_of( "/\\" );
4269  if( lastSlash != std::string::npos )
4270  processName = processName.substr( lastSlash+1 );
4271  m_boundProcessName.set( config, processName );
4272  std::vector<Parser::Token> tokens;
4273  Parser parser;
4274  parser.parseIntoTokens( argc, argv, tokens );
4275  return populate( tokens, config );
4276  }
4277 
4278  std::vector<Parser::Token> populate( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
4279  if( m_options.empty() && m_positionalArgs.empty() )
4280  throw std::logic_error( "No options or arguments specified" );
4281 
4282  std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config );
4283  unusedTokens = populateFixedArgs( unusedTokens, config );
4284  unusedTokens = populateFloatingArgs( unusedTokens, config );
4285  return unusedTokens;
4286  }
4287 
4288  std::vector<Parser::Token> populateOptions( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
4289  std::vector<Parser::Token> unusedTokens;
4290  for( std::size_t i = 0; i < tokens.size(); ++i ) {
4291  Parser::Token const& token = tokens[i];
4292  typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();
4293  for(; it != itEnd; ++it ) {
4294  Arg const& arg = *it;
4295 
4296  try {
4297  if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||
4298  ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {
4299  if( arg.takesArg() ) {
4300  if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional )
4301  throw std::domain_error( "Expected argument to option " + token.data );
4302  arg.boundField.set( config, tokens[++i].data );
4303  }
4304  else {
4305  arg.boundField.setFlag( config );
4306  }
4307  break;
4308  }
4309  }
4310  catch( std::exception& ex ) {
4311  throw std::runtime_error( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" );
4312  }
4313  }
4314  if( it == itEnd )
4315  unusedTokens.push_back( token );
4316  }
4317  return unusedTokens;
4318  }
4319  std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
4320  std::vector<Parser::Token> unusedTokens;
4321  int position = 1;
4322  for( std::size_t i = 0; i < tokens.size(); ++i ) {
4323  Parser::Token const& token = tokens[i];
4324  typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );
4325  if( it != m_positionalArgs.end() )
4326  it->second.boundField.set( config, token.data );
4327  else
4328  unusedTokens.push_back( token );
4329  if( token.type == Parser::Token::Positional )
4330  position++;
4331  }
4332  return unusedTokens;
4333  }
4334  std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
4335  if( !m_arg.get() )
4336  return tokens;
4337  std::vector<Parser::Token> unusedTokens;
4338  for( std::size_t i = 0; i < tokens.size(); ++i ) {
4339  Parser::Token const& token = tokens[i];
4340  if( token.type == Parser::Token::Positional )
4341  m_arg->boundField.set( config, token.data );
4342  else
4343  unusedTokens.push_back( token );
4344  }
4345  return unusedTokens;
4346  }
4347 
4348  private:
4349  Detail::BoundArgFunction<ConfigT> m_boundProcessName;
4350  std::vector<Arg> m_options;
4351  std::map<int, Arg> m_positionalArgs;
4352  std::auto_ptr<Arg> m_arg;
4353  int m_highestSpecifiedArgPosition;
4354  };
4355 
4356 } // end namespace Clara
4357 
4358 namespace Catch {
4359 
4360  inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }
4361  inline void abortAfterX( ConfigData& config, int x ) {
4362  if( x < 1 )
4363  throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" );
4364  config.abortAfter = x;
4365  }
4366  inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
4367 
4368  inline void addWarning( ConfigData& config, std::string const& _warning ) {
4369  if( _warning == "NoAssertions" )
4371  else
4372  throw std::runtime_error( "Unrecognised warning: '" + _warning + "'" );
4373 
4374  }
4375  inline void setVerbosity( ConfigData& config, int level ) {
4376  // !TBD: accept strings?
4377  config.verbosity = (Verbosity::Level)level;
4378  }
4379  inline void setShowDurations( ConfigData& config, bool _showDurations ) {
4380  config.showDurations = _showDurations
4383  }
4384 
4385  inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
4386 
4387  Clara::CommandLine<ConfigData> cli;
4388 
4389  cli.bindProcessName( &ConfigData::processName );
4390 
4391  cli.bind( &ConfigData::showHelp )
4392  .describe( "display usage information" )
4393  .shortOpt( "?")
4394  .shortOpt( "h")
4395  .longOpt( "help" );
4396 
4397  cli.bind( &ConfigData::listTests )
4398  .describe( "list all (or matching) test cases" )
4399  .shortOpt( "l")
4400  .longOpt( "list-tests" );
4401 
4402  cli.bind( &ConfigData::listTags )
4403  .describe( "list all (or matching) tags" )
4404  .shortOpt( "t")
4405  .longOpt( "list-tags" );
4406 
4407  cli.bind( &ConfigData::listReporters )
4408  .describe( "list all reporters" )
4409  .longOpt( "list-reporters" );
4410 
4411  cli.bind( &ConfigData::showSuccessfulTests )
4412  .describe( "include successful tests in output" )
4413  .shortOpt( "s")
4414  .longOpt( "success" );
4415 
4416  cli.bind( &ConfigData::shouldDebugBreak )
4417  .describe( "break into debugger on failure" )
4418  .shortOpt( "b")
4419  .longOpt( "break" );
4420 
4421  cli.bind( &ConfigData::noThrow )
4422  .describe( "skip exception tests" )
4423  .shortOpt( "e")
4424  .longOpt( "nothrow" );
4425 
4426  cli.bind( &ConfigData::outputFilename )
4427  .describe( "output filename" )
4428  .shortOpt( "o")
4429  .longOpt( "out" )
4430  .hint( "filename" );
4431 
4432  cli.bind( &ConfigData::reporterName )
4433  .describe( "reporter to use - defaults to console" )
4434  .shortOpt( "r")
4435  .longOpt( "reporter" )
4436 // .hint( "name[:filename]" );
4437  .hint( "name" );
4438 
4439  cli.bind( &ConfigData::name )
4440  .describe( "suite name" )
4441  .shortOpt( "n")
4442  .longOpt( "name" )
4443  .hint( "name" );
4444 
4445  cli.bind( &abortAfterFirst )
4446  .describe( "abort at first failure" )
4447  .shortOpt( "a")
4448  .longOpt( "abort" );
4449 
4450  cli.bind( &abortAfterX )
4451  .describe( "abort after x failures" )
4452  .shortOpt( "x")
4453  .longOpt( "abortx" )
4454  .hint( "number of failures" );
4455 
4456  cli.bind( &addWarning )
4457  .describe( "enable warnings" )
4458  .shortOpt( "w")
4459  .longOpt( "warn" )
4460  .hint( "warning name" );
4461 
4462 // cli.bind( &setVerbosity )
4463 // .describe( "level of verbosity (0=no output)" )
4464 // .shortOpt( "v")
4465 // .longOpt( "verbosity" )
4466 // .hint( "level" );
4467 
4468  cli.bind( &addTestOrTags )
4469  .describe( "which test or tests to use" )
4470  .hint( "test name, pattern or tags" );
4471 
4472  cli.bind( &setShowDurations )
4473  .describe( "show test durations" )
4474  .shortOpt( "d")
4475  .longOpt( "durations" )
4476  .hint( "yes/no" );
4477 
4478  return cli;
4479  }
4480 
4481 } // end namespace Catch
4482 
4483 // #included from: internal/catch_list.hpp
4484 #define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED
4485 
4486 // #included from: catch_console_colour.hpp
4487 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED
4488 
4489 namespace Catch {
4490 
4491  namespace Detail {
4492  struct IColourImpl;
4493  }
4494 
4495  struct Colour {
4496  enum Code {
4497  None = 0,
4498 
4499  White,
4500  Red,
4501  Green,
4502  Blue,
4503  Cyan,
4504  Yellow,
4505  Grey,
4506 
4507  Bright = 0x10,
4508 
4509  BrightRed = Bright | Red,
4510  BrightGreen = Bright | Green,
4511  LightGrey = Bright | Grey,
4512  BrightWhite = Bright | White,
4513 
4514  // By intention
4515  FileName = LightGrey,
4516  ResultError = BrightRed,
4517  ResultSuccess = BrightGreen,
4518 
4519  Error = BrightRed,
4520  Success = Green,
4521 
4522  OriginalExpression = Cyan,
4523  ReconstructedExpression = Yellow,
4524 
4525  SecondaryText = LightGrey,
4526  Headers = White
4527  };
4528 
4529  // Use constructed object for RAII guard
4530  Colour( Code _colourCode );
4531  ~Colour();
4532 
4533  // Use static method for one-shot changes
4534  static void use( Code _colourCode );
4535 
4536  private:
4537  static Detail::IColourImpl* impl;
4538  };
4539 
4540 } // end namespace Catch
4541 
4542 #include <limits>
4543 #include <algorithm>
4544 
4545 namespace Catch {
4546  inline bool matchesFilters( std::vector<TestCaseFilters> const& filters, TestCase const& testCase ) {
4547  std::vector<TestCaseFilters>::const_iterator it = filters.begin();
4548  std::vector<TestCaseFilters>::const_iterator itEnd = filters.end();
4549  for(; it != itEnd; ++it )
4550  if( !it->shouldInclude( testCase ) )
4551  return false;
4552  return true;
4553  }
4554 
4555  inline std::size_t listTests( Config const& config ) {
4556  if( config.filters().empty() )
4557  std::cout << "All available test cases:\n";
4558  else
4559  std::cout << "Matching test cases:\n";
4560  std::vector<TestCase> const& allTests = getRegistryHub().getTestCaseRegistry().getAllTests();
4561  std::vector<TestCase>::const_iterator it = allTests.begin(), itEnd = allTests.end();
4562 
4563  // First pass - get max tags
4564  std::size_t maxTagLen = 0;
4565  std::size_t maxNameLen = 0;
4566  for(; it != itEnd; ++it ) {
4567  if( matchesFilters( config.filters(), *it ) ) {
4568  maxTagLen = (std::max)( it->getTestCaseInfo().tagsAsString.size(), maxTagLen );
4569  maxNameLen = (std::max)( it->getTestCaseInfo().name.size(), maxNameLen );
4570  }
4571  }
4572 
4573  // Try to fit everything in. If not shrink tag column first, down to 30
4574  // then shrink name column until it all fits (strings will be wrapped within column)
4575  while( maxTagLen + maxNameLen > CATCH_CONFIG_CONSOLE_WIDTH-5 ) {
4576  if( maxTagLen > 30 )
4577  --maxTagLen;
4578  else
4579  --maxNameLen;
4580  }
4581 
4582  std::size_t matchedTests = 0;
4583  for( it = allTests.begin(); it != itEnd; ++it ) {
4584  if( matchesFilters( config.filters(), *it ) ) {
4585  matchedTests++;
4586  Text nameWrapper( it->getTestCaseInfo().name,
4587  TextAttributes()
4588  .setWidth( maxNameLen )
4589  .setInitialIndent(2)
4590  .setIndent(4) );
4591 
4592  Text tagsWrapper( it->getTestCaseInfo().tagsAsString,
4593  TextAttributes()
4594  .setWidth( maxTagLen )
4595  .setInitialIndent(0)
4596  .setIndent( 2 ) );
4597 
4598  for( std::size_t i = 0; i < (std::max)( nameWrapper.size(), tagsWrapper.size() ); ++i ) {
4599  Colour::Code colour = Colour::None;
4600  if( it->getTestCaseInfo().isHidden )
4601  colour = Colour::SecondaryText;
4602  std::string nameCol;
4603  if( i < nameWrapper.size() ) {
4604  nameCol = nameWrapper[i];
4605  }
4606  else {
4607  nameCol = " ...";
4608  colour = Colour::SecondaryText;
4609  }
4610 
4611  {
4612  Colour colourGuard( colour );
4613  std::cout << nameCol;
4614  }
4615  if( i < tagsWrapper.size() && !tagsWrapper[i].empty() ) {
4616  if( i == 0 ) {
4617  Colour colourGuard( Colour::SecondaryText );
4618  std::cout << " " << std::string( maxNameLen - nameCol.size(), '.' ) << " ";
4619  }
4620  else {
4621  std::cout << std::string( maxNameLen - nameCol.size(), ' ' ) << " ";
4622  }
4623  std::cout << tagsWrapper[i];
4624  }
4625  std::cout << "\n";
4626  }
4627  }
4628  }
4629  if( config.filters().empty() )
4630  std::cout << pluralise( matchedTests, "test case" ) << "\n" << std::endl;
4631  else
4632  std::cout << pluralise( matchedTests, "matching test case" ) << "\n" << std::endl;
4633  return matchedTests;
4634  }
4635 
4636  inline std::size_t listTags( Config const& config ) {
4637  if( config.filters().empty() )
4638  std::cout << "All available tags:\n";
4639  else
4640  std::cout << "Matching tags:\n";
4641  std::vector<TestCase> const& allTests = getRegistryHub().getTestCaseRegistry().getAllTests();
4642  std::vector<TestCase>::const_iterator it = allTests.begin(), itEnd = allTests.end();
4643 
4644  std::map<std::string, int> tagCounts;
4645 
4646  std::size_t maxTagLen = 0;
4647 
4648  for(; it != itEnd; ++it ) {
4649  if( matchesFilters( config.filters(), *it ) ) {
4650  for( std::set<std::string>::const_iterator tagIt = it->getTestCaseInfo().tags.begin(),
4651  tagItEnd = it->getTestCaseInfo().tags.end();
4652  tagIt != tagItEnd;
4653  ++tagIt ) {
4654  std::string tagName = *tagIt;
4655  maxTagLen = (std::max)( maxTagLen, tagName.size() );
4656  std::map<std::string, int>::iterator countIt = tagCounts.find( tagName );
4657  if( countIt == tagCounts.end() )
4658  tagCounts.insert( std::make_pair( tagName, 1 ) );
4659  else
4660  countIt->second++;
4661  }
4662  }
4663  }
4664  maxTagLen +=4;
4665  if( maxTagLen > CATCH_CONFIG_CONSOLE_WIDTH-10 )
4666  maxTagLen = CATCH_CONFIG_CONSOLE_WIDTH-10;
4667 
4668  for( std::map<std::string, int>::const_iterator countIt = tagCounts.begin(), countItEnd = tagCounts.end();
4669  countIt != countItEnd;
4670  ++countIt ) {
4671  Text wrapper( "[" + countIt->first + "]", TextAttributes()
4672  .setIndent(2)
4673  .setWidth( maxTagLen ) );
4674  std::cout << wrapper;
4675  std::size_t dots = 2;
4676  if( maxTagLen > wrapper.last().size() )
4677  dots += maxTagLen - wrapper.last().size();
4678  {
4679  Colour colourGuard( Colour::SecondaryText );
4680  std::cout << std::string( dots, '.' );
4681  }
4682  std::cout << countIt->second
4683  << "\n";
4684  }
4685  std::cout << pluralise( tagCounts.size(), "tag" ) << "\n" << std::endl;
4686  return tagCounts.size();
4687  }
4688 
4689  inline std::size_t listReporters( Config const& /*config*/ ) {
4690  std::cout << "Available reports:\n";
4692  IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;
4693  std::size_t maxNameLen = 0;
4694  for(it = itBegin; it != itEnd; ++it )
4695  maxNameLen = (std::max)( maxNameLen, it->first.size() );
4696 
4697  for(it = itBegin; it != itEnd; ++it ) {
4698  Text wrapper( it->second->getDescription(), TextAttributes()
4699  .setInitialIndent( 0 )
4700  .setIndent( 7+maxNameLen )
4701  .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );
4702  std::cout << " "
4703  << it->first
4704  << ":"
4705  << std::string( maxNameLen - it->first.size() + 2, ' ' )
4706  << wrapper << "\n";
4707  }
4708  std::cout << std::endl;
4709  return factories.size();
4710  }
4711 
4712  inline Option<std::size_t> list( Config const& config ) {
4713  Option<std::size_t> listedCount;
4714  if( config.listTests() )
4715  listedCount = listedCount.valueOr(0) + listTests( config );
4716  if( config.listTags() )
4717  listedCount = listedCount.valueOr(0) + listTags( config );
4718  if( config.listReporters() )
4719  listedCount = listedCount.valueOr(0) + listReporters( config );
4720  return listedCount;
4721  }
4722 
4723 } // end namespace Catch
4724 
4725 // #included from: internal/catch_runner_impl.hpp
4726 #define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
4727 
4728 // #included from: catch_test_case_tracker.hpp
4729 #define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
4730 
4731 #include <map>
4732 #include <string>
4733 #include <assert.h>
4734 
4735 namespace Catch {
4736 namespace SectionTracking {
4737 
4738  class TrackedSection {
4739 
4740  typedef std::map<std::string, TrackedSection> TrackedSections;
4741 
4742  public:
4743  enum RunState {
4744  NotStarted,
4745  Executing,
4746  ExecutingChildren,
4747  Completed
4748  };
4749 
4750  TrackedSection( std::string const& name, TrackedSection* parent )
4751  : m_name( name ), m_runState( NotStarted ), m_parent( parent )
4752  {}
4753 
4754  RunState runState() const { return m_runState; }
4755 
4756  void addChild( std::string const& childName ) {
4757  m_children.insert( std::make_pair( childName, TrackedSection( childName, this ) ) );
4758  }
4759  TrackedSection* getChild( std::string const& childName ) {
4760  return &m_children.find( childName )->second;
4761  }
4762 
4763  void enter() {
4764  if( m_runState == NotStarted )
4765  m_runState = Executing;
4766  }
4767  void leave() {
4768  for( TrackedSections::const_iterator it = m_children.begin(), itEnd = m_children.end();
4769  it != itEnd;
4770  ++it )
4771  if( it->second.runState() != Completed ) {
4772  m_runState = ExecutingChildren;
4773  return;
4774  }
4775  m_runState = Completed;
4776  }
4777  TrackedSection* getParent() {
4778  return m_parent;
4779  }
4780  bool hasChildren() const {
4781  return !m_children.empty();
4782  }
4783 
4784  private:
4785  std::string m_name;
4786  RunState m_runState;
4787  TrackedSections m_children;
4788  TrackedSection* m_parent;
4789 
4790  };
4791 
4792  class TestCaseTracker {
4793  public:
4794  TestCaseTracker( std::string const& testCaseName )
4795  : m_testCase( testCaseName, NULL ),
4796  m_currentSection( &m_testCase ),
4797  m_completedASectionThisRun( false )
4798  {}
4799 
4800  bool enterSection( std::string const& name ) {
4801  if( m_completedASectionThisRun )
4802  return false;
4803  if( m_currentSection->runState() == TrackedSection::Executing ) {
4804  m_currentSection->addChild( name );
4805  return false;
4806  }
4807  else {
4808  TrackedSection* child = m_currentSection->getChild( name );
4809  if( child->runState() != TrackedSection::Completed ) {
4810  m_currentSection = child;
4811  m_currentSection->enter();
4812  return true;
4813  }
4814  return false;
4815  }
4816  }
4817  void leaveSection() {
4818  m_currentSection->leave();
4819  m_currentSection = m_currentSection->getParent();
4820  assert( m_currentSection != NULL );
4821  m_completedASectionThisRun = true;
4822  }
4823 
4824  bool currentSectionHasChildren() const {
4825  return m_currentSection->hasChildren();
4826  }
4827  bool isCompleted() const {
4828  return m_testCase.runState() == TrackedSection::Completed;
4829  }
4830 
4831  class Guard {
4832  public:
4833  Guard( TestCaseTracker& tracker )
4834  : m_tracker( tracker )
4835  {
4836  m_tracker.enterTestCase();
4837  }
4838  ~Guard() {
4839  m_tracker.leaveTestCase();
4840  }
4841  private:
4842  Guard( Guard const& );
4843  void operator = ( Guard const& );
4844  TestCaseTracker& m_tracker;
4845  };
4846 
4847  private:
4848  void enterTestCase() {
4849  m_currentSection = &m_testCase;
4850  m_completedASectionThisRun = false;
4851  m_testCase.enter();
4852  }
4853  void leaveTestCase() {
4854  m_testCase.leave();
4855  }
4856 
4857  TrackedSection m_testCase;
4858  TrackedSection* m_currentSection;
4859  bool m_completedASectionThisRun;
4860  };
4861 
4862 } // namespace SectionTracking
4863 
4864 using SectionTracking::TestCaseTracker;
4865 
4866 } // namespace Catch
4867 
4868 #include <set>
4869 #include <string>
4870 
4871 namespace Catch {
4872 
4873  class StreamRedirect {
4874 
4875  public:
4876  StreamRedirect( std::ostream& stream, std::string& targetString )
4877  : m_stream( stream ),
4878  m_prevBuf( stream.rdbuf() ),
4879  m_targetString( targetString )
4880  {
4881  stream.rdbuf( m_oss.rdbuf() );
4882  }
4883 
4884  ~StreamRedirect() {
4885  m_targetString += m_oss.str();
4886  m_stream.rdbuf( m_prevBuf );
4887  }
4888 
4889  private:
4890  std::ostream& m_stream;
4891  std::streambuf* m_prevBuf;
4892  std::ostringstream m_oss;
4893  std::string& m_targetString;
4894  };
4895 
4897 
4898  class RunContext : public IResultCapture, public IRunner {
4899 
4900  RunContext( RunContext const& );
4901  void operator =( RunContext const& );
4902 
4903  public:
4904 
4905  explicit RunContext( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> const& reporter )
4906  : m_runInfo( config->name() ),
4907  m_context( getCurrentMutableContext() ),
4908  m_activeTestCase( NULL ),
4909  m_config( config ),
4910  m_reporter( reporter ),
4911  m_prevRunner( &m_context.getRunner() ),
4912  m_prevResultCapture( &m_context.getResultCapture() ),
4913  m_prevConfig( m_context.getConfig() )
4914  {
4915  m_context.setRunner( this );
4916  m_context.setConfig( m_config );
4917  m_context.setResultCapture( this );
4918  m_reporter->testRunStarting( m_runInfo );
4919  }
4920 
4921  virtual ~RunContext() {
4922  m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );
4923  m_context.setRunner( m_prevRunner );
4924  m_context.setConfig( NULL );
4925  m_context.setResultCapture( m_prevResultCapture );
4926  m_context.setConfig( m_prevConfig );
4927  }
4928 
4929  void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
4930  m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) );
4931  }
4932  void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) {
4933  m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );
4934  }
4935 
4936  Totals runMatching( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
4937 
4938  std::vector<TestCase> matchingTests = getRegistryHub().getTestCaseRegistry().getMatchingTestCases( testSpec );
4939 
4940  Totals totals;
4941 
4942  testGroupStarting( testSpec, groupIndex, groupsCount );
4943 
4944  std::vector<TestCase>::const_iterator it = matchingTests.begin();
4945  std::vector<TestCase>::const_iterator itEnd = matchingTests.end();
4946  for(; it != itEnd; ++it )
4947  totals += runTest( *it );
4948 
4949  testGroupEnded( testSpec, totals, groupIndex, groupsCount );
4950  return totals;
4951  }
4952 
4953  Totals runTest( TestCase const& testCase ) {
4954  Totals prevTotals = m_totals;
4955 
4956  std::string redirectedCout;
4957  std::string redirectedCerr;
4958 
4959  TestCaseInfo testInfo = testCase.getTestCaseInfo();
4960 
4961  m_reporter->testCaseStarting( testInfo );
4962 
4963  m_activeTestCase = &testCase;
4964  m_testCaseTracker = TestCaseTracker( testInfo.name );
4965 
4966  do {
4967  do {
4968  runCurrentTest( redirectedCout, redirectedCerr );
4969  }
4970  while( !m_testCaseTracker->isCompleted() && !aborting() );
4971  }
4972  while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
4973 
4974  Totals deltaTotals = m_totals.delta( prevTotals );
4975  m_totals.testCases += deltaTotals.testCases;
4976  m_reporter->testCaseEnded( TestCaseStats( testInfo,
4977  deltaTotals,
4978  redirectedCout,
4979  redirectedCerr,
4980  aborting() ) );
4981 
4982  m_activeTestCase = NULL;
4983  m_testCaseTracker.reset();
4984 
4985  return deltaTotals;
4986  }
4987 
4988  Ptr<IConfig const> config() const {
4989  return m_config;
4990  }
4991 
4992  private: // IResultCapture
4993 
4994  virtual ResultAction::Value acceptExpression( ExpressionResultBuilder const& assertionResult, AssertionInfo const& assertionInfo ) {
4995  m_lastAssertionInfo = assertionInfo;
4996  return actOnCurrentResult( assertionResult.buildResult( assertionInfo ) );
4997  }
4998 
4999  virtual void assertionEnded( AssertionResult const& result ) {
5000  if( result.getResultType() == ResultWas::Ok ) {
5001  m_totals.assertions.passed++;
5002  }
5003  else if( !result.isOk() ) {
5004  m_totals.assertions.failed++;
5005  }
5006 
5007  if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) )
5008  m_messages.clear();
5009 
5010  // Reset working state
5011  m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
5012  }
5013 
5014  virtual bool sectionStarted (
5015  SectionInfo const& sectionInfo,
5016  Counts& assertions
5017  )
5018  {
5019  std::ostringstream oss;
5020  oss << sectionInfo.name << "@" << sectionInfo.lineInfo;
5021 
5022  if( !m_testCaseTracker->enterSection( oss.str() ) )
5023  return false;
5024 
5025  m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
5026 
5027  m_reporter->sectionStarting( sectionInfo );
5028 
5029  assertions = m_totals.assertions;
5030 
5031  return true;
5032  }
5033  bool testForMissingAssertions( Counts& assertions ) {
5034  if( assertions.total() != 0 ||
5035  !m_config->warnAboutMissingAssertions() ||
5036  m_testCaseTracker->currentSectionHasChildren() )
5037  return false;
5038  m_totals.assertions.failed++;
5039  assertions.failed++;
5040  return true;
5041  }
5042 
5043  virtual void sectionEnded( SectionInfo const& info, Counts const& prevAssertions, double _durationInSeconds ) {
5044  if( std::uncaught_exception() ) {
5045  m_unfinishedSections.push_back( UnfinishedSections( info, prevAssertions, _durationInSeconds ) );
5046  return;
5047  }
5048 
5049  Counts assertions = m_totals.assertions - prevAssertions;
5050  bool missingAssertions = testForMissingAssertions( assertions );
5051 
5052  m_testCaseTracker->leaveSection();
5053 
5054  m_reporter->sectionEnded( SectionStats( info, assertions, _durationInSeconds, missingAssertions ) );
5055  m_messages.clear();
5056  }
5057 
5058  virtual void pushScopedMessage( MessageInfo const& message ) {
5059  m_messages.push_back( message );
5060  }
5061 
5062  virtual void popScopedMessage( MessageInfo const& message ) {
5063  m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() );
5064  }
5065 
5066  virtual bool shouldDebugBreak() const {
5067  return m_config->shouldDebugBreak();
5068  }
5069 
5070  virtual std::string getCurrentTestName() const {
5071  return m_activeTestCase
5072  ? m_activeTestCase->getTestCaseInfo().name
5073  : "";
5074  }
5075 
5076  virtual const AssertionResult* getLastResult() const {
5077  return &m_lastResult;
5078  }
5079 
5080  public:
5081  // !TBD We need to do this another way!
5082  bool aborting() const {
5083  return m_totals.assertions.failed == static_cast<std::size_t>( m_config->abortAfter() );
5084  }
5085 
5086  private:
5087 
5088  ResultAction::Value actOnCurrentResult( AssertionResult const& result ) {
5089  m_lastResult = result;
5090  assertionEnded( m_lastResult );
5091 
5093 
5094  if( !m_lastResult.isOk() ) {
5095  action = ResultAction::Failed;
5096  if( shouldDebugBreak() )
5097  action = (ResultAction::Value)( action | ResultAction::Debug );
5098  if( aborting() )
5099  action = (ResultAction::Value)( action | ResultAction::Abort );
5100  }
5101  return action;
5102  }
5103 
5104  void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
5105  TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
5106  SectionInfo testCaseSection( testCaseInfo.name, testCaseInfo.description, testCaseInfo.lineInfo );
5107  m_reporter->sectionStarting( testCaseSection );
5108  Counts prevAssertions = m_totals.assertions;
5109  double duration = 0;
5110  try {
5111  m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
5112  TestCaseTracker::Guard guard( *m_testCaseTracker );
5113 
5114  Timer timer;
5115  timer.start();
5116  if( m_reporter->getPreferences().shouldRedirectStdOut ) {
5117  StreamRedirect coutRedir( std::cout, redirectedCout );
5118  StreamRedirect cerrRedir( std::cerr, redirectedCerr );
5119  m_activeTestCase->invoke();
5120  }
5121  else {
5122  m_activeTestCase->invoke();
5123  }
5124  duration = timer.getElapsedSeconds();
5125  }
5126  catch( TestFailureException& ) {
5127  // This just means the test was aborted due to failure
5128  }
5129  catch(...) {
5131  exResult << translateActiveException();
5132  actOnCurrentResult( exResult.buildResult( m_lastAssertionInfo ) );
5133  }
5134  // If sections ended prematurely due to an exception we stored their
5135  // infos here so we can tear them down outside the unwind process.
5136  for( std::vector<UnfinishedSections>::const_iterator it = m_unfinishedSections.begin(),
5137  itEnd = m_unfinishedSections.end();
5138  it != itEnd;
5139  ++it )
5140  sectionEnded( it->info, it->prevAssertions, it->durationInSeconds );
5141  m_unfinishedSections.clear();
5142  m_messages.clear();
5143 
5144  Counts assertions = m_totals.assertions - prevAssertions;
5145  bool missingAssertions = testForMissingAssertions( assertions );
5146 
5147  SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );
5148  m_reporter->sectionEnded( testCaseSectionStats );
5149  }
5150 
5151  private:
5152  struct UnfinishedSections {
5153  UnfinishedSections( SectionInfo const& _info, Counts const& _prevAssertions, double _durationInSeconds )
5154  : info( _info ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
5155  {}
5156 
5157  SectionInfo info;
5158  Counts prevAssertions;
5159  double durationInSeconds;
5160  };
5161 
5162  TestRunInfo m_runInfo;
5163  IMutableContext& m_context;
5164  TestCase const* m_activeTestCase;
5165  Option<TestCaseTracker> m_testCaseTracker;
5166  AssertionResult m_lastResult;
5167 
5168  Ptr<IConfig const> m_config;
5169  Totals m_totals;
5170  Ptr<IStreamingReporter> m_reporter;
5171  std::vector<MessageInfo> m_messages;
5172  IRunner* m_prevRunner;
5173  IResultCapture* m_prevResultCapture;
5174  Ptr<IConfig const> m_prevConfig;
5175  AssertionInfo m_lastAssertionInfo;
5176  std::vector<UnfinishedSections> m_unfinishedSections;
5177  };
5178 
5179 } // end namespace Catch
5180 
5181 // #included from: internal/catch_version.h
5182 #define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED
5183 
5184 namespace Catch {
5185 
5186  // Versioning information
5187  struct Version {
5188  Version( unsigned int _majorVersion,
5189  unsigned int _minorVersion,
5190  unsigned int _buildNumber,
5191  std::string const& _branchName )
5192  : majorVersion( _majorVersion ),
5193  minorVersion( _minorVersion ),
5194  buildNumber( _buildNumber ),
5195  branchName( _branchName )
5196  {}
5197 
5198  const unsigned int majorVersion;
5199  const unsigned int minorVersion;
5200  const unsigned int buildNumber;
5201  const std::string branchName;
5202 
5203  private:
5204  void operator=( Version const& );
5205  };
5206 
5207  extern Version libraryVersion;
5208 }
5209 
5210 #include <fstream>
5211 #include <stdlib.h>
5212 #include <limits>
5213 
5214 namespace Catch {
5215 
5216  class Runner {
5217 
5218  public:
5219  Runner( Ptr<Config> const& config )
5220  : m_config( config )
5221  {
5222  openStream();
5223  makeReporter();
5224  }
5225 
5226  Totals runTests() {
5227 
5228  std::vector<TestCaseFilters> filterGroups = m_config->filters();
5229  if( filterGroups.empty() ) {
5230  TestCaseFilters filterGroup( "" );
5231  filterGroups.push_back( filterGroup );
5232  }
5233 
5234  RunContext context( m_config.get(), m_reporter );
5235 
5236  Totals totals;
5237 
5238  for( std::size_t i=0; i < filterGroups.size() && !context.aborting(); ++i ) {
5239  context.testGroupStarting( filterGroups[i].getName(), i, filterGroups.size() );
5240  totals += runTestsForGroup( context, filterGroups[i] );
5241  context.testGroupEnded( filterGroups[i].getName(), totals, i, filterGroups.size() );
5242  }
5243  return totals;
5244  }
5245 
5246  Totals runTestsForGroup( RunContext& context, const TestCaseFilters& filterGroup ) {
5247  Totals totals;
5248  std::vector<TestCase>::const_iterator it = getRegistryHub().getTestCaseRegistry().getAllTests().begin();
5249  std::vector<TestCase>::const_iterator itEnd = getRegistryHub().getTestCaseRegistry().getAllTests().end();
5250  int testsRunForGroup = 0;
5251  for(; it != itEnd; ++it ) {
5252  if( filterGroup.shouldInclude( *it ) ) {
5253  testsRunForGroup++;
5254  if( m_testsAlreadyRun.find( *it ) == m_testsAlreadyRun.end() ) {
5255 
5256  if( context.aborting() )
5257  break;
5258 
5259  totals += context.runTest( *it );
5260  m_testsAlreadyRun.insert( *it );
5261  }
5262  }
5263  }
5264  if( testsRunForGroup == 0 && !filterGroup.getName().empty() )
5265  m_reporter->noMatchingTestCases( filterGroup.getName() );
5266  return totals;
5267 
5268  }
5269 
5270  private:
5271  void openStream() {
5272  // Open output file, if specified
5273  if( !m_config->getFilename().empty() ) {
5274  m_ofs.open( m_config->getFilename().c_str() );
5275  if( m_ofs.fail() ) {
5276  std::ostringstream oss;
5277  oss << "Unable to open file: '" << m_config->getFilename() << "'";
5278  throw std::domain_error( oss.str() );
5279  }
5280  m_config->setStreamBuf( m_ofs.rdbuf() );
5281  }
5282  }
5283  void makeReporter() {
5284  std::string reporterName = m_config->getReporterName().empty()
5285  ? "console"
5286  : m_config->getReporterName();
5287 
5288  m_reporter = getRegistryHub().getReporterRegistry().create( reporterName, m_config.get() );
5289  if( !m_reporter ) {
5290  std::ostringstream oss;
5291  oss << "No reporter registered with name: '" << reporterName << "'";
5292  throw std::domain_error( oss.str() );
5293  }
5294  }
5295 
5296  private:
5297  Ptr<Config> m_config;
5298  std::ofstream m_ofs;
5299  Ptr<IStreamingReporter> m_reporter;
5300  std::set<TestCase> m_testsAlreadyRun;
5301  };
5302 
5303  class Session {
5304  static bool alreadyInstantiated;
5305 
5306  public:
5307 
5308  struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; };
5309 
5310  Session()
5311  : m_cli( makeCommandLineParser() ) {
5312  if( alreadyInstantiated ) {
5313  std::string msg = "Only one instance of Catch::Session can ever be used";
5314  std::cerr << msg << std::endl;
5315  throw std::logic_error( msg );
5316  }
5317  alreadyInstantiated = true;
5318  }
5319  ~Session() {
5320  Catch::cleanUp();
5321  }
5322 
5323  void showHelp( std::string const& processName ) {
5324  std::cout << "\nCatch v" << libraryVersion.majorVersion << "."
5325  << libraryVersion.minorVersion << " build "
5326  << libraryVersion.buildNumber;
5327  if( libraryVersion.branchName != "master" )
5328  std::cout << " (" << libraryVersion.branchName << " branch)";
5329  std::cout << "\n";
5330 
5331  m_cli.usage( std::cout, processName );
5332  std::cout << "For more detail usage please see the project docs\n" << std::endl;
5333  }
5334 
5335  int applyCommandLine( int argc, char* const argv[], OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
5336  try {
5337  m_unusedTokens = m_cli.parseInto( argc, argv, m_configData );
5338  if( unusedOptionBehaviour == OnUnusedOptions::Fail )
5339  enforceNoUsedTokens();
5340  if( m_configData.showHelp )
5341  showHelp( m_configData.processName );
5342  m_config.reset();
5343  }
5344  catch( std::exception& ex ) {
5345  {
5346  Colour colourGuard( Colour::Red );
5347  std::cerr << "\nError in input:\n"
5348  << Text( ex.what(), TextAttributes().setIndent(2) )
5349  << "\n\n";
5350  }
5351  m_cli.usage( std::cout, m_configData.processName );
5352  return (std::numeric_limits<int>::max)();
5353  }
5354  return 0;
5355  }
5356 
5357  void useConfigData( ConfigData const& _configData ) {
5358  m_configData = _configData;
5359  m_config.reset();
5360  }
5361 
5362  void enforceNoUsedTokens() const {
5363  if( !m_unusedTokens.empty() ) {
5364  std::vector<Clara::Parser::Token>::const_iterator
5365  it = m_unusedTokens.begin(),
5366  itEnd = m_unusedTokens.end();
5367  std::string msg;
5368  for(; it != itEnd; ++it )
5369  msg += " unrecognised option: " + it->data + "\n";
5370  throw std::runtime_error( msg.substr( 0, msg.size()-1 ) );
5371  }
5372  }
5373 
5374  int run( int argc, char* const argv[] ) {
5375 
5376  int returnCode = applyCommandLine( argc, argv );
5377  if( returnCode == 0 )
5378  returnCode = run();
5379  return returnCode;
5380  }
5381 
5382  int run() {
5383  if( m_configData.showHelp )
5384  return 0;
5385 
5386  try
5387  {
5388  config(); // Force config to be constructed
5389  Runner runner( m_config );
5390 
5391  // Handle list request
5392  if( Option<std::size_t> listed = list( config() ) )
5393  return static_cast<int>( *listed );
5394 
5395  return static_cast<int>( runner.runTests().assertions.failed );
5396  }
5397  catch( std::exception& ex ) {
5398  std::cerr << ex.what() << std::endl;
5399  return (std::numeric_limits<int>::max)();
5400  }
5401  }
5402 
5403  Clara::CommandLine<ConfigData> const& cli() const {
5404  return m_cli;
5405  }
5406  std::vector<Clara::Parser::Token> const& unusedTokens() const {
5407  return m_unusedTokens;
5408  }
5409  ConfigData& configData() {
5410  return m_configData;
5411  }
5412  Config& config() {
5413  if( !m_config )
5414  m_config = new Config( m_configData );
5415  return *m_config;
5416  }
5417 
5418  private:
5419  Clara::CommandLine<ConfigData> m_cli;
5420  std::vector<Clara::Parser::Token> m_unusedTokens;
5421  ConfigData m_configData;
5422  Ptr<Config> m_config;
5423  };
5424 
5425  bool Session::alreadyInstantiated = false;
5426 
5427 } // end namespace Catch
5428 
5429 // #included from: catch_registry_hub.hpp
5430 #define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED
5431 
5432 // #included from: catch_test_case_registry_impl.hpp
5433 #define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
5434 
5435 #include <vector>
5436 #include <set>
5437 #include <sstream>
5438 #include <iostream>
5439 
5440 namespace Catch {
5441 
5442  class TestRegistry : public ITestCaseRegistry {
5443  public:
5444  TestRegistry() : m_unnamedCount( 0 ) {}
5445  virtual ~TestRegistry();
5446 
5447  virtual void registerTest( TestCase const& testCase ) {
5448  std::string name = testCase.getTestCaseInfo().name;
5449  if( name == "" ) {
5450  std::ostringstream oss;
5451  oss << "Anonymous test case " << ++m_unnamedCount;
5452  return registerTest( testCase.withName( oss.str() ) );
5453  }
5454 
5455  if( m_functions.find( testCase ) == m_functions.end() ) {
5456  m_functions.insert( testCase );
5457  m_functionsInOrder.push_back( testCase );
5458  if( !testCase.isHidden() )
5459  m_nonHiddenFunctions.push_back( testCase );
5460  }
5461  else {
5462  TestCase const& prev = *m_functions.find( testCase );
5463  std::cerr << "error: TEST_CASE( \"" << name << "\" ) already defined.\n"
5464  << "\tFirst seen at " << SourceLineInfo( prev.getTestCaseInfo().lineInfo ) << "\n"
5465  << "\tRedefined at " << SourceLineInfo( testCase.getTestCaseInfo().lineInfo ) << std::endl;
5466  exit(1);
5467  }
5468  }
5469 
5470  virtual std::vector<TestCase> const& getAllTests() const {
5471  return m_functionsInOrder;
5472  }
5473 
5474  virtual std::vector<TestCase> const& getAllNonHiddenTests() const {
5475  return m_nonHiddenFunctions;
5476  }
5477 
5478  // !TBD deprecated
5479  virtual std::vector<TestCase> getMatchingTestCases( std::string const& rawTestSpec ) const {
5480  std::vector<TestCase> matchingTests;
5481  getMatchingTestCases( rawTestSpec, matchingTests );
5482  return matchingTests;
5483  }
5484 
5485  // !TBD deprecated
5486  virtual void getMatchingTestCases( std::string const& rawTestSpec, std::vector<TestCase>& matchingTestsOut ) const {
5487  TestCaseFilter filter( rawTestSpec );
5488 
5489  std::vector<TestCase>::const_iterator it = m_functionsInOrder.begin();
5490  std::vector<TestCase>::const_iterator itEnd = m_functionsInOrder.end();
5491  for(; it != itEnd; ++it ) {
5492  if( filter.shouldInclude( *it ) ) {
5493  matchingTestsOut.push_back( *it );
5494  }
5495  }
5496  }
5497  virtual void getMatchingTestCases( TestCaseFilters const& filters, std::vector<TestCase>& matchingTestsOut ) const {
5498  std::vector<TestCase>::const_iterator it = m_functionsInOrder.begin();
5499  std::vector<TestCase>::const_iterator itEnd = m_functionsInOrder.end();
5500  // !TBD: replace with algorithm
5501  for(; it != itEnd; ++it )
5502  if( filters.shouldInclude( *it ) )
5503  matchingTestsOut.push_back( *it );
5504  }
5505 
5506  private:
5507 
5508  std::set<TestCase> m_functions;
5509  std::vector<TestCase> m_functionsInOrder;
5510  std::vector<TestCase> m_nonHiddenFunctions;
5511  size_t m_unnamedCount;
5512  };
5513 
5515 
5516  class FreeFunctionTestCase : public SharedImpl<ITestCase> {
5517  public:
5518 
5519  FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}
5520 
5521  virtual void invoke() const {
5522  m_fun();
5523  }
5524 
5525  private:
5526  virtual ~FreeFunctionTestCase();
5527 
5528  TestFunction m_fun;
5529  };
5530 
5531  inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) {
5532  std::string className = classOrQualifiedMethodName;
5533  if( startsWith( className, "&" ) )
5534  {
5535  std::size_t lastColons = className.rfind( "::" );
5536  std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
5537  if( penultimateColons == std::string::npos )
5538  penultimateColons = 1;
5539  className = className.substr( penultimateColons, lastColons-penultimateColons );
5540  }
5541  return className;
5542  }
5543 
5545 
5546  AutoReg::AutoReg( TestFunction function,
5547  SourceLineInfo const& lineInfo,
5548  NameAndDesc const& nameAndDesc ) {
5549  registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
5550  }
5551 
5552  AutoReg::~AutoReg() {}
5553 
5554  void AutoReg::registerTestCase( ITestCase* testCase,
5555  char const* classOrQualifiedMethodName,
5556  NameAndDesc const& nameAndDesc,
5557  SourceLineInfo const& lineInfo ) {
5558 
5560  ( makeTestCase( testCase,
5561  extractClassName( classOrQualifiedMethodName ),
5562  nameAndDesc.name,
5563  nameAndDesc.description,
5564  lineInfo ) );
5565  }
5566 
5567 } // end namespace Catch
5568 
5569 // #included from: catch_reporter_registry.hpp
5570 #define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED
5571 
5572 #include <map>
5573 
5574 namespace Catch {
5575 
5576  class ReporterRegistry : public IReporterRegistry {
5577 
5578  public:
5579 
5580  virtual ~ReporterRegistry() {
5581  deleteAllValues( m_factories );
5582  }
5583 
5584  virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig> const& config ) const {
5585  FactoryMap::const_iterator it = m_factories.find( name );
5586  if( it == m_factories.end() )
5587  return NULL;
5588  return it->second->create( ReporterConfig( config ) );
5589  }
5590 
5591  void registerReporter( std::string const& name, IReporterFactory* factory ) {
5592  m_factories.insert( std::make_pair( name, factory ) );
5593  }
5594 
5595  FactoryMap const& getFactories() const {
5596  return m_factories;
5597  }
5598 
5599  private:
5600  FactoryMap m_factories;
5601  };
5602 }
5603 
5604 // #included from: catch_exception_translator_registry.hpp
5605 #define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
5606 
5607 #ifdef __OBJC__
5608 #import "Foundation/Foundation.h"
5609 #endif
5610 
5611 namespace Catch {
5612 
5613  class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
5614  public:
5615  ~ExceptionTranslatorRegistry() {
5616  deleteAll( m_translators );
5617  }
5618 
5619  virtual void registerTranslator( const IExceptionTranslator* translator ) {
5620  m_translators.push_back( translator );
5621  }
5622 
5623  virtual std::string translateActiveException() const {
5624  try {
5625 #ifdef __OBJC__
5626  // In Objective-C try objective-c exceptions first
5627  @try {
5628  throw;
5629  }
5630  @catch (NSException *exception) {
5631  return toString( [exception description] );
5632  }
5633 #else
5634  throw;
5635 #endif
5636  }
5637  catch( std::exception& ex ) {
5638  return ex.what();
5639  }
5640  catch( std::string& msg ) {
5641  return msg;
5642  }
5643  catch( const char* msg ) {
5644  return msg;
5645  }
5646  catch(...) {
5647  return tryTranslators( m_translators.begin() );
5648  }
5649  }
5650 
5651  std::string tryTranslators( std::vector<const IExceptionTranslator*>::const_iterator it ) const {
5652  if( it == m_translators.end() )
5653  return "Unknown exception";
5654 
5655  try {
5656  return (*it)->translate();
5657  }
5658  catch(...) {
5659  return tryTranslators( it+1 );
5660  }
5661  }
5662 
5663  private:
5664  std::vector<const IExceptionTranslator*> m_translators;
5665  };
5666 }
5667 
5668 namespace Catch {
5669 
5670  namespace {
5671 
5672  class RegistryHub : public IRegistryHub, public IMutableRegistryHub {
5673 
5674  RegistryHub( RegistryHub const& );
5675  void operator=( RegistryHub const& );
5676 
5677  public: // IRegistryHub
5678  RegistryHub() {
5679  }
5680  virtual IReporterRegistry const& getReporterRegistry() const {
5681  return m_reporterRegistry;
5682  }
5683  virtual ITestCaseRegistry const& getTestCaseRegistry() const {
5684  return m_testCaseRegistry;
5685  }
5686  virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() {
5687  return m_exceptionTranslatorRegistry;
5688  }
5689 
5690  public: // IMutableRegistryHub
5691  virtual void registerReporter( std::string const& name, IReporterFactory* factory ) {
5692  m_reporterRegistry.registerReporter( name, factory );
5693  }
5694  virtual void registerTest( TestCase const& testInfo ) {
5695  m_testCaseRegistry.registerTest( testInfo );
5696  }
5697  virtual void registerTranslator( const IExceptionTranslator* translator ) {
5698  m_exceptionTranslatorRegistry.registerTranslator( translator );
5699  }
5700 
5701  private:
5702  TestRegistry m_testCaseRegistry;
5703  ReporterRegistry m_reporterRegistry;
5704  ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
5705  };
5706 
5707  // Single, global, instance
5708  inline RegistryHub*& getTheRegistryHub() {
5709  static RegistryHub* theRegistryHub = NULL;
5710  if( !theRegistryHub )
5711  theRegistryHub = new RegistryHub();
5712  return theRegistryHub;
5713  }
5714  }
5715 
5717  return *getTheRegistryHub();
5718  }
5720  return *getTheRegistryHub();
5721  }
5722  void cleanUp() {
5723  delete getTheRegistryHub();
5724  getTheRegistryHub() = NULL;
5725  cleanUpContext();
5726  }
5727  std::string translateActiveException() {
5729  }
5730 
5731 } // end namespace Catch
5732 
5733 // #included from: catch_notimplemented_exception.hpp
5734 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED
5735 
5736 #include <ostream>
5737 
5738 namespace Catch {
5739 
5741  : m_lineInfo( lineInfo ) {
5742  std::ostringstream oss;
5743  oss << lineInfo << ": function ";
5744  oss << "not implemented";
5745  m_what = oss.str();
5746  }
5747 
5748  const char* NotImplementedException::what() const throw() {
5749  return m_what.c_str();
5750  }
5751 
5752 } // end namespace Catch
5753 
5754 // #included from: catch_context_impl.hpp
5755 #define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
5756 
5757 namespace Catch {
5758 
5759  class Context : public IMutableContext {
5760 
5761  Context() : m_config( NULL ) {}
5762  Context( Context const& );
5763  void operator=( Context const& );
5764 
5765  public: // IContext
5766  virtual IResultCapture& getResultCapture() {
5767  return *m_resultCapture;
5768  }
5769  virtual IRunner& getRunner() {
5770  return *m_runner;
5771  }
5772  virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) {
5773  return getGeneratorsForCurrentTest()
5774  .getGeneratorInfo( fileInfo, totalSize )
5775  .getCurrentIndex();
5776  }
5777  virtual bool advanceGeneratorsForCurrentTest() {
5778  IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
5779  return generators && generators->moveNext();
5780  }
5781 
5782  virtual Ptr<IConfig const> getConfig() const {
5783  return m_config;
5784  }
5785 
5786  public: // IMutableContext
5787  virtual void setResultCapture( IResultCapture* resultCapture ) {
5788  m_resultCapture = resultCapture;
5789  }
5790  virtual void setRunner( IRunner* runner ) {
5791  m_runner = runner;
5792  }
5793  virtual void setConfig( Ptr<IConfig const> const& config ) {
5794  m_config = config;
5795  }
5796 
5798 
5799  private:
5800  IGeneratorsForTest* findGeneratorsForCurrentTest() {
5801  std::string testName = getResultCapture().getCurrentTestName();
5802 
5803  std::map<std::string, IGeneratorsForTest*>::const_iterator it =
5804  m_generatorsByTestName.find( testName );
5805  return it != m_generatorsByTestName.end()
5806  ? it->second
5807  : NULL;
5808  }
5809 
5810  IGeneratorsForTest& getGeneratorsForCurrentTest() {
5811  IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
5812  if( !generators ) {
5813  std::string testName = getResultCapture().getCurrentTestName();
5814  generators = createGeneratorsForTest();
5815  m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
5816  }
5817  return *generators;
5818  }
5819 
5820  private:
5821  IRunner* m_runner;
5822  IResultCapture* m_resultCapture;
5823  Ptr<IConfig const> m_config;
5824  std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
5825  };
5826 
5827  namespace {
5828  Context* currentContext = NULL;
5829  }
5831  if( !currentContext )
5832  currentContext = new Context();
5833  return *currentContext;
5834  }
5836  return getCurrentMutableContext();
5837  }
5838 
5839  Stream createStream( std::string const& streamName ) {
5840  if( streamName == "stdout" ) return Stream( std::cout.rdbuf(), false );
5841  if( streamName == "stderr" ) return Stream( std::cerr.rdbuf(), false );
5842  if( streamName == "debug" ) return Stream( new StreamBufImpl<OutputDebugWriter>, true );
5843 
5844  throw std::domain_error( "Unknown stream: " + streamName );
5845  }
5846 
5847  void cleanUpContext() {
5848  delete currentContext;
5849  currentContext = NULL;
5850  }
5851 }
5852 
5853 // #included from: catch_console_colour_impl.hpp
5854 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
5855 
5856 namespace Catch { namespace Detail {
5857  struct IColourImpl {
5858  virtual ~IColourImpl() {}
5859  virtual void use( Colour::Code _colourCode ) = 0;
5860  };
5861 }}
5862 
5863 #if defined ( CATCH_PLATFORM_WINDOWS )
5864 
5865 #ifndef NOMINMAX
5866 #define NOMINMAX
5867 #endif
5868 
5869 #ifdef __AFXDLL
5870 #include <AfxWin.h>
5871 #else
5872 #include <windows.h>
5873 #endif
5874 
5875 namespace Catch {
5876 namespace {
5877 
5878  class Win32ColourImpl : public Detail::IColourImpl {
5879  public:
5880  Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
5881  {
5882  CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
5883  GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
5884  originalAttributes = csbiInfo.wAttributes;
5885  }
5886 
5887  virtual void use( Colour::Code _colourCode ) {
5888  switch( _colourCode ) {
5889  case Colour::None: return setTextAttribute( originalAttributes );
5890  case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
5891  case Colour::Red: return setTextAttribute( FOREGROUND_RED );
5892  case Colour::Green: return setTextAttribute( FOREGROUND_GREEN );
5893  case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE );
5894  case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
5895  case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
5896  case Colour::Grey: return setTextAttribute( 0 );
5897 
5898  case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY );
5899  case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
5900  case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
5901  case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
5902 
5903  case Colour::Bright: throw std::logic_error( "not a colour" );
5904  }
5905  }
5906 
5907  private:
5908  void setTextAttribute( WORD _textAttribute ) {
5909  SetConsoleTextAttribute( stdoutHandle, _textAttribute );
5910  }
5911  HANDLE stdoutHandle;
5912  WORD originalAttributes;
5913  };
5914 
5915  inline bool shouldUseColourForPlatform() {
5916  return true;
5917  }
5918 
5919  Win32ColourImpl platformColourImpl;
5920 
5921 } // end anon namespace
5922 } // end namespace Catch
5923 
5924 #else // Not Windows - assumed to be POSIX compatible
5925 
5926 #include <unistd.h>
5927 
5928 namespace Catch {
5929 namespace {
5930 
5931  // use POSIX/ ANSI console terminal codes
5932  // Thanks to Adam Strzelecki for original contribution
5933  // (http://github.com/nanoant)
5934  // https://github.com/philsquared/Catch/pull/131
5935  class PosixColourImpl : public Detail::IColourImpl {
5936  public:
5937  virtual void use( Colour::Code _colourCode ) {
5938  switch( _colourCode ) {
5939  case Colour::None:
5940  case Colour::White: return setColour( "[0m" );
5941  case Colour::Red: return setColour( "[0;31m" );
5942  case Colour::Green: return setColour( "[0;32m" );
5943  case Colour::Blue: return setColour( "[0:34m" );
5944  case Colour::Cyan: return setColour( "[0;36m" );
5945  case Colour::Yellow: return setColour( "[0;33m" );
5946  case Colour::Grey: return setColour( "[1;30m" );
5947 
5948