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