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