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