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