summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta-oe/recipes-devtools/nlohmann-fifo/nlohmann-fifo/0001-catch.hpp-Upgrade-to-latest-from-Catch-v1.12.2.patch22371
-rw-r--r--meta-oe/recipes-devtools/nlohmann-fifo/nlohmann-fifo/0002-catch.hpp-Define-SIGSTKSZ-as-constant.patch41
-rw-r--r--meta-oe/recipes-devtools/nlohmann-fifo/nlohmann-fifo_git.bb6
3 files changed, 22416 insertions, 2 deletions
diff --git a/meta-oe/recipes-devtools/nlohmann-fifo/nlohmann-fifo/0001-catch.hpp-Upgrade-to-latest-from-Catch-v1.12.2.patch b/meta-oe/recipes-devtools/nlohmann-fifo/nlohmann-fifo/0001-catch.hpp-Upgrade-to-latest-from-Catch-v1.12.2.patch
new file mode 100644
index 0000000000..6237456047
--- /dev/null
+++ b/meta-oe/recipes-devtools/nlohmann-fifo/nlohmann-fifo/0001-catch.hpp-Upgrade-to-latest-from-Catch-v1.12.2.patch
@@ -0,0 +1,22371 @@
1From 1c3b6a5aa0d1a489ae3e7bb65aa9f30151b84c90 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Fri, 1 Aug 2025 11:07:01 -0700
4Subject: [PATCH 1/2] catch.hpp: Upgrade to latest from Catch v1.12.2
5
6This is a copy of
7https://github.com/catchorg/Catch2/blob/Catch1.x/single_include/catch.hpp
8
9Upstream-Status: Backport [https://github.com/catchorg/Catch2/blob/Catch1.x/single_include/catch.hpp]
10Signed-off-by: Khem Raj <raj.khem@gmail.com>
11---
12 test/thirdparty/catch/catch.hpp | 22352 ++++++++++++++++--------------
13 1 file changed, 11689 insertions(+), 10663 deletions(-)
14
15diff --git a/test/thirdparty/catch/catch.hpp b/test/thirdparty/catch/catch.hpp
16index 15f7893..fdb046f 100644
17--- a/test/thirdparty/catch/catch.hpp
18+++ b/test/thirdparty/catch/catch.hpp
19@@ -1,10663 +1,11689 @@
20-/*
21- * Catch v1.6.1
22- * Generated: 2017-01-20 12:33:53.497767
23- * ----------------------------------------------------------
24- * This file has been merged from multiple headers. Please don't edit it directly
25- * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
26- *
27- * Distributed under the Boost Software License, Version 1.0. (See accompanying
28- * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
29- */
30-#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
31-#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
32-
33-#define TWOBLUECUBES_CATCH_HPP_INCLUDED
34-
35-#ifdef __clang__
36-# pragma clang system_header
37-#elif defined __GNUC__
38-# pragma GCC system_header
39-#endif
40-
41-// #included from: internal/catch_suppress_warnings.h
42-
43-#ifdef __clang__
44-# ifdef __ICC // icpc defines the __clang__ macro
45-# pragma warning(push)
46-# pragma warning(disable: 161 1682)
47-# else // __ICC
48-# pragma clang diagnostic ignored "-Wglobal-constructors"
49-# pragma clang diagnostic ignored "-Wvariadic-macros"
50-# pragma clang diagnostic ignored "-Wc99-extensions"
51-# pragma clang diagnostic ignored "-Wunused-variable"
52-# pragma clang diagnostic push
53-# pragma clang diagnostic ignored "-Wpadded"
54-# pragma clang diagnostic ignored "-Wc++98-compat"
55-# pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
56-# pragma clang diagnostic ignored "-Wswitch-enum"
57-# pragma clang diagnostic ignored "-Wcovered-switch-default"
58-# endif
59-#elif defined __GNUC__
60-# pragma GCC diagnostic ignored "-Wvariadic-macros"
61-# pragma GCC diagnostic ignored "-Wunused-variable"
62-# pragma GCC diagnostic push
63-# pragma GCC diagnostic ignored "-Wpadded"
64-#endif
65-#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
66-# define CATCH_IMPL
67-#endif
68-
69-#ifdef CATCH_IMPL
70-# ifndef CLARA_CONFIG_MAIN
71-# define CLARA_CONFIG_MAIN_NOT_DEFINED
72-# define CLARA_CONFIG_MAIN
73-# endif
74-#endif
75-
76-// #included from: internal/catch_notimplemented_exception.h
77-#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED
78-
79-// #included from: catch_common.h
80-#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
81-
82-// #included from: catch_compiler_capabilities.h
83-#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
84-
85-// Detect a number of compiler features - mostly C++11/14 conformance - by compiler
86-// The following features are defined:
87-//
88-// CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported?
89-// CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
90-// CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
91-// CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported?
92-// CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported
93-// CATCH_CONFIG_CPP11_LONG_LONG : is long long supported?
94-// CATCH_CONFIG_CPP11_OVERRIDE : is override supported?
95-// CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
96-
97-// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
98-
99-// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
100-// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
101-// ****************
102-// Note to maintainers: if new toggles are added please document them
103-// in configuration.md, too
104-// ****************
105-
106-// In general each macro has a _NO_<feature name> form
107-// (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
108-// Many features, at point of detection, define an _INTERNAL_ macro, so they
109-// can be combined, en-mass, with the _NO_ forms later.
110-
111-// All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11
112-
113-#ifdef __cplusplus
114-
115-# if __cplusplus >= 201103L
116-# define CATCH_CPP11_OR_GREATER
117-# endif
118-
119-# if __cplusplus >= 201402L
120-# define CATCH_CPP14_OR_GREATER
121-# endif
122-
123-#endif
124-
125-#ifdef __clang__
126-
127-# if __has_feature(cxx_nullptr)
128-# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
129-# endif
130-
131-# if __has_feature(cxx_noexcept)
132-# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
133-# endif
134-
135-# if defined(CATCH_CPP11_OR_GREATER)
136-# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
137-# endif
138-
139-#endif // __clang__
140-
141-////////////////////////////////////////////////////////////////////////////////
142-// Borland
143-#ifdef __BORLANDC__
144-
145-#endif // __BORLANDC__
146-
147-////////////////////////////////////////////////////////////////////////////////
148-// EDG
149-#ifdef __EDG_VERSION__
150-
151-#endif // __EDG_VERSION__
152-
153-////////////////////////////////////////////////////////////////////////////////
154-// Digital Mars
155-#ifdef __DMC__
156-
157-#endif // __DMC__
158-
159-////////////////////////////////////////////////////////////////////////////////
160-// GCC
161-#ifdef __GNUC__
162-
163-# if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
164-# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
165-# endif
166-
167-# if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) && defined(CATCH_CPP11_OR_GREATER)
168-# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "GCC diagnostic ignored \"-Wparentheses\"" )
169-# endif
170-
171-// - otherwise more recent versions define __cplusplus >= 201103L
172-// and will get picked up below
173-
174-#endif // __GNUC__
175-
176-////////////////////////////////////////////////////////////////////////////////
177-// Visual C++
178-#ifdef _MSC_VER
179-
180-#if (_MSC_VER >= 1600)
181-# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
182-# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
183-#endif
184-
185-#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
186-#define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
187-#define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
188-#define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE
189-#endif
190-
191-#endif // _MSC_VER
192-
193-////////////////////////////////////////////////////////////////////////////////
194-
195-// Use variadic macros if the compiler supports them
196-#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
197- ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
198- ( defined __GNUC__ && __GNUC__ >= 3 ) || \
199- ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
200-
201-#define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
202-
203-#endif
204-
205-// Use __COUNTER__ if the compiler supports it
206-#if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \
207- ( defined __GNUC__ && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 ) || \
208- ( defined __clang__ && __clang_major__ >= 3 )
209-
210-#define CATCH_INTERNAL_CONFIG_COUNTER
211-
212-#endif
213-
214-////////////////////////////////////////////////////////////////////////////////
215-// C++ language feature support
216-
217-// catch all support for C++11
218-#if defined(CATCH_CPP11_OR_GREATER)
219-
220-# if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR)
221-# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
222-# endif
223-
224-# ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
225-# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
226-# endif
227-
228-# ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
229-# define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
230-# endif
231-
232-# ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
233-# define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
234-# endif
235-
236-# ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE
237-# define CATCH_INTERNAL_CONFIG_CPP11_TUPLE
238-# endif
239-
240-# ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
241-# define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
242-# endif
243-
244-# if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG)
245-# define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG
246-# endif
247-
248-# if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE)
249-# define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE
250-# endif
251-# if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
252-# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
253-# endif
254-# if !defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE)
255-# define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE
256-# endif
257-
258-#endif // __cplusplus >= 201103L
259-
260-// Now set the actual defines based on the above + anything the user has configured
261-#if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11)
262-# define CATCH_CONFIG_CPP11_NULLPTR
263-#endif
264-#if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11)
265-# define CATCH_CONFIG_CPP11_NOEXCEPT
266-#endif
267-#if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11)
268-# define CATCH_CONFIG_CPP11_GENERATED_METHODS
269-#endif
270-#if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11)
271-# define CATCH_CONFIG_CPP11_IS_ENUM
272-#endif
273-#if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11)
274-# define CATCH_CONFIG_CPP11_TUPLE
275-#endif
276-#if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS)
277-# define CATCH_CONFIG_VARIADIC_MACROS
278-#endif
279-#if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11)
280-# define CATCH_CONFIG_CPP11_LONG_LONG
281-#endif
282-#if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11)
283-# define CATCH_CONFIG_CPP11_OVERRIDE
284-#endif
285-#if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11)
286-# define CATCH_CONFIG_CPP11_UNIQUE_PTR
287-#endif
288-// Use of __COUNTER__ is suppressed if __JETBRAINS_IDE__ is #defined (meaning we're being parsed by a JetBrains IDE for
289-// analytics) because, at time of writing, __COUNTER__ is not properly handled by it.
290-// This does not affect compilation
291-#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) && !defined(__JETBRAINS_IDE__)
292-# define CATCH_CONFIG_COUNTER
293-#endif
294-#if defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_NO_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_NO_CPP11)
295-# define CATCH_CONFIG_CPP11_SHUFFLE
296-#endif
297-
298-#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
299-# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
300-#endif
301-
302-// noexcept support:
303-#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)
304-# define CATCH_NOEXCEPT noexcept
305-# define CATCH_NOEXCEPT_IS(x) noexcept(x)
306-#else
307-# define CATCH_NOEXCEPT throw()
308-# define CATCH_NOEXCEPT_IS(x)
309-#endif
310-
311-// nullptr support
312-#ifdef CATCH_CONFIG_CPP11_NULLPTR
313-# define CATCH_NULL nullptr
314-#else
315-# define CATCH_NULL NULL
316-#endif
317-
318-// override support
319-#ifdef CATCH_CONFIG_CPP11_OVERRIDE
320-# define CATCH_OVERRIDE override
321-#else
322-# define CATCH_OVERRIDE
323-#endif
324-
325-// unique_ptr support
326-#ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR
327-# define CATCH_AUTO_PTR( T ) std::unique_ptr<T>
328-#else
329-# define CATCH_AUTO_PTR( T ) std::auto_ptr<T>
330-#endif
331-
332-#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
333-#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
334-#ifdef CATCH_CONFIG_COUNTER
335-# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
336-#else
337-# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
338-#endif
339-
340-#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
341-#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
342-
343-#include <sstream>
344-#include <stdexcept>
345-#include <algorithm>
346-
347-namespace Catch {
348-
349- struct IConfig;
350-
351- struct CaseSensitive { enum Choice {
352- Yes,
353- No
354- }; };
355-
356- class NonCopyable {
357-#ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
358- NonCopyable( NonCopyable const& ) = delete;
359- NonCopyable( NonCopyable && ) = delete;
360- NonCopyable& operator = ( NonCopyable const& ) = delete;
361- NonCopyable& operator = ( NonCopyable && ) = delete;
362-#else
363- NonCopyable( NonCopyable const& info );
364- NonCopyable& operator = ( NonCopyable const& );
365-#endif
366-
367- protected:
368- NonCopyable() {}
369- virtual ~NonCopyable();
370- };
371-
372- class SafeBool {
373- public:
374- typedef void (SafeBool::*type)() const;
375-
376- static type makeSafe( bool value ) {
377- return value ? &SafeBool::trueValue : 0;
378- }
379- private:
380- void trueValue() const {}
381- };
382-
383- template<typename ContainerT>
384- inline void deleteAll( ContainerT& container ) {
385- typename ContainerT::const_iterator it = container.begin();
386- typename ContainerT::const_iterator itEnd = container.end();
387- for(; it != itEnd; ++it )
388- delete *it;
389- }
390- template<typename AssociativeContainerT>
391- inline void deleteAllValues( AssociativeContainerT& container ) {
392- typename AssociativeContainerT::const_iterator it = container.begin();
393- typename AssociativeContainerT::const_iterator itEnd = container.end();
394- for(; it != itEnd; ++it )
395- delete it->second;
396- }
397-
398- bool startsWith( std::string const& s, std::string const& prefix );
399- bool endsWith( std::string const& s, std::string const& suffix );
400- bool contains( std::string const& s, std::string const& infix );
401- void toLowerInPlace( std::string& s );
402- std::string toLower( std::string const& s );
403- std::string trim( std::string const& str );
404- bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
405-
406- struct pluralise {
407- pluralise( std::size_t count, std::string const& label );
408-
409- friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
410-
411- std::size_t m_count;
412- std::string m_label;
413- };
414-
415- struct SourceLineInfo {
416-
417- SourceLineInfo();
418- SourceLineInfo( char const* _file, std::size_t _line );
419- SourceLineInfo( SourceLineInfo const& other );
420-# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
421- SourceLineInfo( SourceLineInfo && ) = default;
422- SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
423- SourceLineInfo& operator = ( SourceLineInfo && ) = default;
424-# endif
425- bool empty() const;
426- bool operator == ( SourceLineInfo const& other ) const;
427- bool operator < ( SourceLineInfo const& other ) const;
428-
429- std::string file;
430- std::size_t line;
431- };
432-
433- std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
434-
435- // This is just here to avoid compiler warnings with macro constants and boolean literals
436- inline bool alwaysTrue( std::size_t = 0 ) { return true; }
437- inline bool alwaysFalse( std::size_t = 0 ) { return false; }
438-
439- void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
440-
441- void seedRng( IConfig const& config );
442- unsigned int rngSeed();
443-
444- // Use this in variadic streaming macros to allow
445- // >> +StreamEndStop
446- // as well as
447- // >> stuff +StreamEndStop
448- struct StreamEndStop {
449- std::string operator+() {
450- return std::string();
451- }
452- };
453- template<typename T>
454- T const& operator + ( T const& value, StreamEndStop ) {
455- return value;
456- }
457-}
458-
459-#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
460-#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
461-
462-#include <ostream>
463-
464-namespace Catch {
465-
466- class NotImplementedException : public std::exception
467- {
468- public:
469- NotImplementedException( SourceLineInfo const& lineInfo );
470- NotImplementedException( NotImplementedException const& ) {}
471-
472- virtual ~NotImplementedException() CATCH_NOEXCEPT {}
473-
474- virtual const char* what() const CATCH_NOEXCEPT;
475-
476- private:
477- std::string m_what;
478- SourceLineInfo m_lineInfo;
479- };
480-
481-} // end namespace Catch
482-
483-///////////////////////////////////////////////////////////////////////////////
484-#define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )
485-
486-// #included from: internal/catch_context.h
487-#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
488-
489-// #included from: catch_interfaces_generators.h
490-#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED
491-
492-#include <string>
493-
494-namespace Catch {
495-
496- struct IGeneratorInfo {
497- virtual ~IGeneratorInfo();
498- virtual bool moveNext() = 0;
499- virtual std::size_t getCurrentIndex() const = 0;
500- };
501-
502- struct IGeneratorsForTest {
503- virtual ~IGeneratorsForTest();
504-
505- virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0;
506- virtual bool moveNext() = 0;
507- };
508-
509- IGeneratorsForTest* createGeneratorsForTest();
510-
511-} // end namespace Catch
512-
513-// #included from: catch_ptr.hpp
514-#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
515-
516-#ifdef __clang__
517-#pragma clang diagnostic push
518-#pragma clang diagnostic ignored "-Wpadded"
519-#endif
520-
521-namespace Catch {
522-
523- // An intrusive reference counting smart pointer.
524- // T must implement addRef() and release() methods
525- // typically implementing the IShared interface
526- template<typename T>
527- class Ptr {
528- public:
529- Ptr() : m_p( CATCH_NULL ){}
530- Ptr( T* p ) : m_p( p ){
531- if( m_p )
532- m_p->addRef();
533- }
534- Ptr( Ptr const& other ) : m_p( other.m_p ){
535- if( m_p )
536- m_p->addRef();
537- }
538- ~Ptr(){
539- if( m_p )
540- m_p->release();
541- }
542- void reset() {
543- if( m_p )
544- m_p->release();
545- m_p = CATCH_NULL;
546- }
547- Ptr& operator = ( T* p ){
548- Ptr temp( p );
549- swap( temp );
550- return *this;
551- }
552- Ptr& operator = ( Ptr const& other ){
553- Ptr temp( other );
554- swap( temp );
555- return *this;
556- }
557- void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
558- T* get() const{ return m_p; }
559- T& operator*() const { return *m_p; }
560- T* operator->() const { return m_p; }
561- bool operator !() const { return m_p == CATCH_NULL; }
562- operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); }
563-
564- private:
565- T* m_p;
566- };
567-
568- struct IShared : NonCopyable {
569- virtual ~IShared();
570- virtual void addRef() const = 0;
571- virtual void release() const = 0;
572- };
573-
574- template<typename T = IShared>
575- struct SharedImpl : T {
576-
577- SharedImpl() : m_rc( 0 ){}
578-
579- virtual void addRef() const {
580- ++m_rc;
581- }
582- virtual void release() const {
583- if( --m_rc == 0 )
584- delete this;
585- }
586-
587- mutable unsigned int m_rc;
588- };
589-
590-} // end namespace Catch
591-
592-#ifdef __clang__
593-#pragma clang diagnostic pop
594-#endif
595-
596-#include <memory>
597-#include <vector>
598-#include <stdlib.h>
599-
600-namespace Catch {
601-
602- class TestCase;
603- class Stream;
604- struct IResultCapture;
605- struct IRunner;
606- struct IGeneratorsForTest;
607- struct IConfig;
608-
609- struct IContext
610- {
611- virtual ~IContext();
612-
613- virtual IResultCapture* getResultCapture() = 0;
614- virtual IRunner* getRunner() = 0;
615- virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;
616- virtual bool advanceGeneratorsForCurrentTest() = 0;
617- virtual Ptr<IConfig const> getConfig() const = 0;
618- };
619-
620- struct IMutableContext : IContext
621- {
622- virtual ~IMutableContext();
623- virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
624- virtual void setRunner( IRunner* runner ) = 0;
625- virtual void setConfig( Ptr<IConfig const> const& config ) = 0;
626- };
627-
628- IContext& getCurrentContext();
629- IMutableContext& getCurrentMutableContext();
630- void cleanUpContext();
631- Stream createStream( std::string const& streamName );
632-
633-}
634-
635-// #included from: internal/catch_test_registry.hpp
636-#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
637-
638-// #included from: catch_interfaces_testcase.h
639-#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
640-
641-#include <vector>
642-
643-namespace Catch {
644-
645- class TestSpec;
646-
647- struct ITestCase : IShared {
648- virtual void invoke () const = 0;
649- protected:
650- virtual ~ITestCase();
651- };
652-
653- class TestCase;
654- struct IConfig;
655-
656- struct ITestCaseRegistry {
657- virtual ~ITestCaseRegistry();
658- virtual std::vector<TestCase> const& getAllTests() const = 0;
659- virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
660- };
661-
662- bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
663- std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
664- std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
665-
666-}
667-
668-namespace Catch {
669-
670-template<typename C>
671-class MethodTestCase : public SharedImpl<ITestCase> {
672-
673-public:
674- MethodTestCase( void (C::*method)() ) : m_method( method ) {}
675-
676- virtual void invoke() const {
677- C obj;
678- (obj.*m_method)();
679- }
680-
681-private:
682- virtual ~MethodTestCase() {}
683-
684- void (C::*m_method)();
685-};
686-
687-typedef void(*TestFunction)();
688-
689-struct NameAndDesc {
690- NameAndDesc( const char* _name = "", const char* _description= "" )
691- : name( _name ), description( _description )
692- {}
693-
694- const char* name;
695- const char* description;
696-};
697-
698-void registerTestCase
699- ( ITestCase* testCase,
700- char const* className,
701- NameAndDesc const& nameAndDesc,
702- SourceLineInfo const& lineInfo );
703-
704-struct AutoReg {
705-
706- AutoReg
707- ( TestFunction function,
708- SourceLineInfo const& lineInfo,
709- NameAndDesc const& nameAndDesc );
710-
711- template<typename C>
712- AutoReg
713- ( void (C::*method)(),
714- char const* className,
715- NameAndDesc const& nameAndDesc,
716- SourceLineInfo const& lineInfo ) {
717-
718- registerTestCase
719- ( new MethodTestCase<C>( method ),
720- className,
721- nameAndDesc,
722- lineInfo );
723- }
724-
725- ~AutoReg();
726-
727-private:
728- AutoReg( AutoReg const& );
729- void operator= ( AutoReg const& );
730-};
731-
732-void registerTestCaseFunction
733- ( TestFunction function,
734- SourceLineInfo const& lineInfo,
735- NameAndDesc const& nameAndDesc );
736-
737-} // end namespace Catch
738-
739-#ifdef CATCH_CONFIG_VARIADIC_MACROS
740- ///////////////////////////////////////////////////////////////////////////////
741- #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
742- static void TestName(); \
743- namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
744- static void TestName()
745- #define INTERNAL_CATCH_TESTCASE( ... ) \
746- INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
747-
748- ///////////////////////////////////////////////////////////////////////////////
749- #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
750- namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
751-
752- ///////////////////////////////////////////////////////////////////////////////
753- #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
754- namespace{ \
755- struct TestName : ClassName{ \
756- void test(); \
757- }; \
758- Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
759- } \
760- void TestName::test()
761- #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
762- INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
763-
764- ///////////////////////////////////////////////////////////////////////////////
765- #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
766- Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) );
767-
768-#else
769- ///////////////////////////////////////////////////////////////////////////////
770- #define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \
771- static void TestName(); \
772- namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
773- static void TestName()
774- #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
775- INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc )
776-
777- ///////////////////////////////////////////////////////////////////////////////
778- #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
779- namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
780-
781- ///////////////////////////////////////////////////////////////////////////////
782- #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\
783- namespace{ \
784- struct TestCaseName : ClassName{ \
785- void test(); \
786- }; \
787- Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
788- } \
789- void TestCaseName::test()
790- #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
791- INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc )
792-
793- ///////////////////////////////////////////////////////////////////////////////
794- #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \
795- Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) );
796-#endif
797-
798-// #included from: internal/catch_capture.hpp
799-#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
800-
801-// #included from: catch_result_builder.h
802-#define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
803-
804-// #included from: catch_result_type.h
805-#define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
806-
807-namespace Catch {
808-
809- // ResultWas::OfType enum
810- struct ResultWas { enum OfType {
811- Unknown = -1,
812- Ok = 0,
813- Info = 1,
814- Warning = 2,
815-
816- FailureBit = 0x10,
817-
818- ExpressionFailed = FailureBit | 1,
819- ExplicitFailure = FailureBit | 2,
820-
821- Exception = 0x100 | FailureBit,
822-
823- ThrewException = Exception | 1,
824- DidntThrowException = Exception | 2,
825-
826- FatalErrorCondition = 0x200 | FailureBit
827-
828- }; };
829-
830- inline bool isOk( ResultWas::OfType resultType ) {
831- return ( resultType & ResultWas::FailureBit ) == 0;
832- }
833- inline bool isJustInfo( int flags ) {
834- return flags == ResultWas::Info;
835- }
836-
837- // ResultDisposition::Flags enum
838- struct ResultDisposition { enum Flags {
839- Normal = 0x01,
840-
841- ContinueOnFailure = 0x02, // Failures fail test, but execution continues
842- FalseTest = 0x04, // Prefix expression with !
843- SuppressFail = 0x08 // Failures are reported but do not fail the test
844- }; };
845-
846- inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
847- return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
848- }
849-
850- inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
851- inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
852- inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
853-
854-} // end namespace Catch
855-
856-// #included from: catch_assertionresult.h
857-#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
858-
859-#include <string>
860-
861-namespace Catch {
862-
863- struct AssertionInfo
864- {
865- AssertionInfo() {}
866- AssertionInfo( std::string const& _macroName,
867- SourceLineInfo const& _lineInfo,
868- std::string const& _capturedExpression,
869- ResultDisposition::Flags _resultDisposition );
870-
871- std::string macroName;
872- SourceLineInfo lineInfo;
873- std::string capturedExpression;
874- ResultDisposition::Flags resultDisposition;
875- };
876-
877- struct AssertionResultData
878- {
879- AssertionResultData() : resultType( ResultWas::Unknown ) {}
880-
881- std::string reconstructedExpression;
882- std::string message;
883- ResultWas::OfType resultType;
884- };
885-
886- class AssertionResult {
887- public:
888- AssertionResult();
889- AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
890- ~AssertionResult();
891-# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
892- AssertionResult( AssertionResult const& ) = default;
893- AssertionResult( AssertionResult && ) = default;
894- AssertionResult& operator = ( AssertionResult const& ) = default;
895- AssertionResult& operator = ( AssertionResult && ) = default;
896-# endif
897-
898- bool isOk() const;
899- bool succeeded() const;
900- ResultWas::OfType getResultType() const;
901- bool hasExpression() const;
902- bool hasMessage() const;
903- std::string getExpression() const;
904- std::string getExpressionInMacro() const;
905- bool hasExpandedExpression() const;
906- std::string getExpandedExpression() const;
907- std::string getMessage() const;
908- SourceLineInfo getSourceInfo() const;
909- std::string getTestMacroName() const;
910-
911- protected:
912- AssertionInfo m_info;
913- AssertionResultData m_resultData;
914- };
915-
916-} // end namespace Catch
917-
918-// #included from: catch_matchers.hpp
919-#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
920-
921-namespace Catch {
922-namespace Matchers {
923- namespace Impl {
924-
925- namespace Generic {
926- template<typename ExpressionT> class AllOf;
927- template<typename ExpressionT> class AnyOf;
928- template<typename ExpressionT> class Not;
929- }
930-
931- template<typename ExpressionT>
932- struct Matcher : SharedImpl<IShared>
933- {
934- typedef ExpressionT ExpressionType;
935-
936- virtual ~Matcher() {}
937- virtual Ptr<Matcher> clone() const = 0;
938- virtual bool match( ExpressionT const& expr ) const = 0;
939- virtual std::string toString() const = 0;
940-
941- Generic::AllOf<ExpressionT> operator && ( Matcher<ExpressionT> const& other ) const;
942- Generic::AnyOf<ExpressionT> operator || ( Matcher<ExpressionT> const& other ) const;
943- Generic::Not<ExpressionT> operator ! () const;
944- };
945-
946- template<typename DerivedT, typename ExpressionT>
947- struct MatcherImpl : Matcher<ExpressionT> {
948-
949- virtual Ptr<Matcher<ExpressionT> > clone() const {
950- return Ptr<Matcher<ExpressionT> >( new DerivedT( static_cast<DerivedT const&>( *this ) ) );
951- }
952- };
953-
954- namespace Generic {
955- template<typename ExpressionT>
956- class Not : public MatcherImpl<Not<ExpressionT>, ExpressionT> {
957- public:
958- explicit Not( Matcher<ExpressionT> const& matcher ) : m_matcher(matcher.clone()) {}
959- Not( Not const& other ) : m_matcher( other.m_matcher ) {}
960-
961- virtual bool match( ExpressionT const& expr ) const CATCH_OVERRIDE {
962- return !m_matcher->match( expr );
963- }
964-
965- virtual std::string toString() const CATCH_OVERRIDE {
966- return "not " + m_matcher->toString();
967- }
968- private:
969- Ptr< Matcher<ExpressionT> > m_matcher;
970- };
971-
972- template<typename ExpressionT>
973- class AllOf : public MatcherImpl<AllOf<ExpressionT>, ExpressionT> {
974- public:
975-
976- AllOf() {}
977- AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {}
978-
979- AllOf& add( Matcher<ExpressionT> const& matcher ) {
980- m_matchers.push_back( matcher.clone() );
981- return *this;
982- }
983- virtual bool match( ExpressionT const& expr ) const
984- {
985- for( std::size_t i = 0; i < m_matchers.size(); ++i )
986- if( !m_matchers[i]->match( expr ) )
987- return false;
988- return true;
989- }
990- virtual std::string toString() const {
991- std::ostringstream oss;
992- oss << "( ";
993- for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
994- if( i != 0 )
995- oss << " and ";
996- oss << m_matchers[i]->toString();
997- }
998- oss << " )";
999- return oss.str();
1000- }
1001-
1002- AllOf operator && ( Matcher<ExpressionT> const& other ) const {
1003- AllOf allOfExpr( *this );
1004- allOfExpr.add( other );
1005- return allOfExpr;
1006- }
1007-
1008- private:
1009- std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
1010- };
1011-
1012- template<typename ExpressionT>
1013- class AnyOf : public MatcherImpl<AnyOf<ExpressionT>, ExpressionT> {
1014- public:
1015-
1016- AnyOf() {}
1017- AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {}
1018-
1019- AnyOf& add( Matcher<ExpressionT> const& matcher ) {
1020- m_matchers.push_back( matcher.clone() );
1021- return *this;
1022- }
1023- virtual bool match( ExpressionT const& expr ) const
1024- {
1025- for( std::size_t i = 0; i < m_matchers.size(); ++i )
1026- if( m_matchers[i]->match( expr ) )
1027- return true;
1028- return false;
1029- }
1030- virtual std::string toString() const {
1031- std::ostringstream oss;
1032- oss << "( ";
1033- for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
1034- if( i != 0 )
1035- oss << " or ";
1036- oss << m_matchers[i]->toString();
1037- }
1038- oss << " )";
1039- return oss.str();
1040- }
1041-
1042- AnyOf operator || ( Matcher<ExpressionT> const& other ) const {
1043- AnyOf anyOfExpr( *this );
1044- anyOfExpr.add( other );
1045- return anyOfExpr;
1046- }
1047-
1048- private:
1049- std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
1050- };
1051-
1052- } // namespace Generic
1053-
1054- template<typename ExpressionT>
1055- Generic::AllOf<ExpressionT> Matcher<ExpressionT>::operator && ( Matcher<ExpressionT> const& other ) const {
1056- Generic::AllOf<ExpressionT> allOfExpr;
1057- allOfExpr.add( *this );
1058- allOfExpr.add( other );
1059- return allOfExpr;
1060- }
1061-
1062- template<typename ExpressionT>
1063- Generic::AnyOf<ExpressionT> Matcher<ExpressionT>::operator || ( Matcher<ExpressionT> const& other ) const {
1064- Generic::AnyOf<ExpressionT> anyOfExpr;
1065- anyOfExpr.add( *this );
1066- anyOfExpr.add( other );
1067- return anyOfExpr;
1068- }
1069-
1070- template<typename ExpressionT>
1071- Generic::Not<ExpressionT> Matcher<ExpressionT>::operator ! () const {
1072- return Generic::Not<ExpressionT>( *this );
1073- }
1074-
1075- namespace StdString {
1076-
1077- inline std::string makeString( std::string const& str ) { return str; }
1078- inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); }
1079-
1080- struct CasedString
1081- {
1082- CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
1083- : m_caseSensitivity( caseSensitivity ),
1084- m_str( adjustString( str ) )
1085- {}
1086- std::string adjustString( std::string const& str ) const {
1087- return m_caseSensitivity == CaseSensitive::No
1088- ? toLower( str )
1089- : str;
1090-
1091- }
1092- std::string toStringSuffix() const
1093- {
1094- return m_caseSensitivity == CaseSensitive::No
1095- ? " (case insensitive)"
1096- : "";
1097- }
1098- CaseSensitive::Choice m_caseSensitivity;
1099- std::string m_str;
1100- };
1101-
1102- struct Equals : MatcherImpl<Equals, std::string> {
1103- Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
1104- : m_data( str, caseSensitivity )
1105- {}
1106- Equals( Equals const& other ) : m_data( other.m_data ){}
1107-
1108- virtual ~Equals();
1109-
1110- virtual bool match( std::string const& expr ) const {
1111- return m_data.m_str == m_data.adjustString( expr );;
1112- }
1113- virtual std::string toString() const {
1114- return "equals: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
1115- }
1116-
1117- CasedString m_data;
1118- };
1119-
1120- struct Contains : MatcherImpl<Contains, std::string> {
1121- Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
1122- : m_data( substr, caseSensitivity ){}
1123- Contains( Contains const& other ) : m_data( other.m_data ){}
1124-
1125- virtual ~Contains();
1126-
1127- virtual bool match( std::string const& expr ) const {
1128- return m_data.adjustString( expr ).find( m_data.m_str ) != std::string::npos;
1129- }
1130- virtual std::string toString() const {
1131- return "contains: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
1132- }
1133-
1134- CasedString m_data;
1135- };
1136-
1137- struct StartsWith : MatcherImpl<StartsWith, std::string> {
1138- StartsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
1139- : m_data( substr, caseSensitivity ){}
1140-
1141- StartsWith( StartsWith const& other ) : m_data( other.m_data ){}
1142-
1143- virtual ~StartsWith();
1144-
1145- virtual bool match( std::string const& expr ) const {
1146- return startsWith( m_data.adjustString( expr ), m_data.m_str );
1147- }
1148- virtual std::string toString() const {
1149- return "starts with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
1150- }
1151-
1152- CasedString m_data;
1153- };
1154-
1155- struct EndsWith : MatcherImpl<EndsWith, std::string> {
1156- EndsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
1157- : m_data( substr, caseSensitivity ){}
1158- EndsWith( EndsWith const& other ) : m_data( other.m_data ){}
1159-
1160- virtual ~EndsWith();
1161-
1162- virtual bool match( std::string const& expr ) const {
1163- return endsWith( m_data.adjustString( expr ), m_data.m_str );
1164- }
1165- virtual std::string toString() const {
1166- return "ends with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
1167- }
1168-
1169- CasedString m_data;
1170- };
1171- } // namespace StdString
1172- } // namespace Impl
1173-
1174- // The following functions create the actual matcher objects.
1175- // This allows the types to be inferred
1176- template<typename ExpressionT>
1177- inline Impl::Generic::Not<ExpressionT> Not( Impl::Matcher<ExpressionT> const& m ) {
1178- return Impl::Generic::Not<ExpressionT>( m );
1179- }
1180-
1181- template<typename ExpressionT>
1182- inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
1183- Impl::Matcher<ExpressionT> const& m2 ) {
1184- return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 );
1185- }
1186- template<typename ExpressionT>
1187- inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
1188- Impl::Matcher<ExpressionT> const& m2,
1189- Impl::Matcher<ExpressionT> const& m3 ) {
1190- return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
1191- }
1192- template<typename ExpressionT>
1193- inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
1194- Impl::Matcher<ExpressionT> const& m2 ) {
1195- return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 );
1196- }
1197- template<typename ExpressionT>
1198- inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
1199- Impl::Matcher<ExpressionT> const& m2,
1200- Impl::Matcher<ExpressionT> const& m3 ) {
1201- return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
1202- }
1203-
1204- inline Impl::StdString::Equals Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
1205- return Impl::StdString::Equals( str, caseSensitivity );
1206- }
1207- inline Impl::StdString::Equals Equals( const char* str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
1208- return Impl::StdString::Equals( Impl::StdString::makeString( str ), caseSensitivity );
1209- }
1210- inline Impl::StdString::Contains Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
1211- return Impl::StdString::Contains( substr, caseSensitivity );
1212- }
1213- inline Impl::StdString::Contains Contains( const char* substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
1214- return Impl::StdString::Contains( Impl::StdString::makeString( substr ), caseSensitivity );
1215- }
1216- inline Impl::StdString::StartsWith StartsWith( std::string const& substr ) {
1217- return Impl::StdString::StartsWith( substr );
1218- }
1219- inline Impl::StdString::StartsWith StartsWith( const char* substr ) {
1220- return Impl::StdString::StartsWith( Impl::StdString::makeString( substr ) );
1221- }
1222- inline Impl::StdString::EndsWith EndsWith( std::string const& substr ) {
1223- return Impl::StdString::EndsWith( substr );
1224- }
1225- inline Impl::StdString::EndsWith EndsWith( const char* substr ) {
1226- return Impl::StdString::EndsWith( Impl::StdString::makeString( substr ) );
1227- }
1228-
1229-} // namespace Matchers
1230-
1231-using namespace Matchers;
1232-
1233-} // namespace Catch
1234-
1235-namespace Catch {
1236-
1237- struct TestFailureException{};
1238-
1239- template<typename T> class ExpressionLhs;
1240-
1241- struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
1242-
1243- struct CopyableStream {
1244- CopyableStream() {}
1245- CopyableStream( CopyableStream const& other ) {
1246- oss << other.oss.str();
1247- }
1248- CopyableStream& operator=( CopyableStream const& other ) {
1249- oss.str("");
1250- oss << other.oss.str();
1251- return *this;
1252- }
1253- std::ostringstream oss;
1254- };
1255-
1256- class ResultBuilder {
1257- public:
1258- ResultBuilder( char const* macroName,
1259- SourceLineInfo const& lineInfo,
1260- char const* capturedExpression,
1261- ResultDisposition::Flags resultDisposition,
1262- char const* secondArg = "" );
1263-
1264- template<typename T>
1265- ExpressionLhs<T const&> operator <= ( T const& operand );
1266- ExpressionLhs<bool> operator <= ( bool value );
1267-
1268- template<typename T>
1269- ResultBuilder& operator << ( T const& value ) {
1270- m_stream.oss << value;
1271- return *this;
1272- }
1273-
1274- template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
1275- template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
1276-
1277- ResultBuilder& setResultType( ResultWas::OfType result );
1278- ResultBuilder& setResultType( bool result );
1279- ResultBuilder& setLhs( std::string const& lhs );
1280- ResultBuilder& setRhs( std::string const& rhs );
1281- ResultBuilder& setOp( std::string const& op );
1282-
1283- void endExpression();
1284-
1285- std::string reconstructExpression() const;
1286- AssertionResult build() const;
1287-
1288- void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
1289- void captureResult( ResultWas::OfType resultType );
1290- void captureExpression();
1291- void captureExpectedException( std::string const& expectedMessage );
1292- void captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher );
1293- void handleResult( AssertionResult const& result );
1294- void react();
1295- bool shouldDebugBreak() const;
1296- bool allowThrows() const;
1297-
1298- private:
1299- AssertionInfo m_assertionInfo;
1300- AssertionResultData m_data;
1301- struct ExprComponents {
1302- ExprComponents() : testFalse( false ) {}
1303- bool testFalse;
1304- std::string lhs, rhs, op;
1305- } m_exprComponents;
1306- CopyableStream m_stream;
1307-
1308- bool m_shouldDebugBreak;
1309- bool m_shouldThrow;
1310- };
1311-
1312-} // namespace Catch
1313-
1314-// Include after due to circular dependency:
1315-// #included from: catch_expression_lhs.hpp
1316-#define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
1317-
1318-// #included from: catch_evaluate.hpp
1319-#define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
1320-
1321-#ifdef _MSC_VER
1322-#pragma warning(push)
1323-#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
1324-#endif
1325-
1326-#include <cstddef>
1327-
1328-namespace Catch {
1329-namespace Internal {
1330-
1331- enum Operator {
1332- IsEqualTo,
1333- IsNotEqualTo,
1334- IsLessThan,
1335- IsGreaterThan,
1336- IsLessThanOrEqualTo,
1337- IsGreaterThanOrEqualTo
1338- };
1339-
1340- template<Operator Op> struct OperatorTraits { static const char* getName(){ return "*error*"; } };
1341- template<> struct OperatorTraits<IsEqualTo> { static const char* getName(){ return "=="; } };
1342- template<> struct OperatorTraits<IsNotEqualTo> { static const char* getName(){ return "!="; } };
1343- template<> struct OperatorTraits<IsLessThan> { static const char* getName(){ return "<"; } };
1344- template<> struct OperatorTraits<IsGreaterThan> { static const char* getName(){ return ">"; } };
1345- template<> struct OperatorTraits<IsLessThanOrEqualTo> { static const char* getName(){ return "<="; } };
1346- template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
1347-
1348- template<typename T>
1349- inline T& opCast(T const& t) { return const_cast<T&>(t); }
1350-
1351-// nullptr_t support based on pull request #154 from Konstantin Baumann
1352-#ifdef CATCH_CONFIG_CPP11_NULLPTR
1353- inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
1354-#endif // CATCH_CONFIG_CPP11_NULLPTR
1355-
1356- // So the compare overloads can be operator agnostic we convey the operator as a template
1357- // enum, which is used to specialise an Evaluator for doing the comparison.
1358- template<typename T1, typename T2, Operator Op>
1359- class Evaluator{};
1360-
1361- template<typename T1, typename T2>
1362- struct Evaluator<T1, T2, IsEqualTo> {
1363- static bool evaluate( T1 const& lhs, T2 const& rhs) {
1364- return bool( opCast( lhs ) == opCast( rhs ) );
1365- }
1366- };
1367- template<typename T1, typename T2>
1368- struct Evaluator<T1, T2, IsNotEqualTo> {
1369- static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1370- return bool( opCast( lhs ) != opCast( rhs ) );
1371- }
1372- };
1373- template<typename T1, typename T2>
1374- struct Evaluator<T1, T2, IsLessThan> {
1375- static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1376- return bool( opCast( lhs ) < opCast( rhs ) );
1377- }
1378- };
1379- template<typename T1, typename T2>
1380- struct Evaluator<T1, T2, IsGreaterThan> {
1381- static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1382- return bool( opCast( lhs ) > opCast( rhs ) );
1383- }
1384- };
1385- template<typename T1, typename T2>
1386- struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
1387- static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1388- return bool( opCast( lhs ) >= opCast( rhs ) );
1389- }
1390- };
1391- template<typename T1, typename T2>
1392- struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
1393- static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1394- return bool( opCast( lhs ) <= opCast( rhs ) );
1395- }
1396- };
1397-
1398- template<Operator Op, typename T1, typename T2>
1399- bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
1400- return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
1401- }
1402-
1403- // This level of indirection allows us to specialise for integer types
1404- // to avoid signed/ unsigned warnings
1405-
1406- // "base" overload
1407- template<Operator Op, typename T1, typename T2>
1408- bool compare( T1 const& lhs, T2 const& rhs ) {
1409- return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
1410- }
1411-
1412- // unsigned X to int
1413- template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
1414- return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
1415- }
1416- template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
1417- return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
1418- }
1419- template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
1420- return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
1421- }
1422-
1423- // unsigned X to long
1424- template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
1425- return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
1426- }
1427- template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
1428- return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
1429- }
1430- template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
1431- return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
1432- }
1433-
1434- // int to unsigned X
1435- template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
1436- return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
1437- }
1438- template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
1439- return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
1440- }
1441- template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
1442- return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
1443- }
1444-
1445- // long to unsigned X
1446- template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
1447- return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1448- }
1449- template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
1450- return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1451- }
1452- template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
1453- return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1454- }
1455-
1456- // pointer to long (when comparing against NULL)
1457- template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
1458- return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
1459- }
1460- template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
1461- return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
1462- }
1463-
1464- // pointer to int (when comparing against NULL)
1465- template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
1466- return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
1467- }
1468- template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
1469- return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
1470- }
1471-
1472-#ifdef CATCH_CONFIG_CPP11_LONG_LONG
1473- // long long to unsigned X
1474- template<Operator Op> bool compare( long long lhs, unsigned int rhs ) {
1475- return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1476- }
1477- template<Operator Op> bool compare( long long lhs, unsigned long rhs ) {
1478- return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1479- }
1480- template<Operator Op> bool compare( long long lhs, unsigned long long rhs ) {
1481- return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1482- }
1483- template<Operator Op> bool compare( long long lhs, unsigned char rhs ) {
1484- return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1485- }
1486-
1487- // unsigned long long to X
1488- template<Operator Op> bool compare( unsigned long long lhs, int rhs ) {
1489- return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
1490- }
1491- template<Operator Op> bool compare( unsigned long long lhs, long rhs ) {
1492- return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
1493- }
1494- template<Operator Op> bool compare( unsigned long long lhs, long long rhs ) {
1495- return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
1496- }
1497- template<Operator Op> bool compare( unsigned long long lhs, char rhs ) {
1498- return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
1499- }
1500-
1501- // pointer to long long (when comparing against NULL)
1502- template<Operator Op, typename T> bool compare( long long lhs, T* rhs ) {
1503- return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
1504- }
1505- template<Operator Op, typename T> bool compare( T* lhs, long long rhs ) {
1506- return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
1507- }
1508-#endif // CATCH_CONFIG_CPP11_LONG_LONG
1509-
1510-#ifdef CATCH_CONFIG_CPP11_NULLPTR
1511- // pointer to nullptr_t (when comparing against nullptr)
1512- template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
1513- return Evaluator<T*, T*, Op>::evaluate( nullptr, rhs );
1514- }
1515- template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
1516- return Evaluator<T*, T*, Op>::evaluate( lhs, nullptr );
1517- }
1518-#endif // CATCH_CONFIG_CPP11_NULLPTR
1519-
1520-} // end of namespace Internal
1521-} // end of namespace Catch
1522-
1523-#ifdef _MSC_VER
1524-#pragma warning(pop)
1525-#endif
1526-
1527-// #included from: catch_tostring.h
1528-#define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED
1529-
1530-#include <sstream>
1531-#include <iomanip>
1532-#include <limits>
1533-#include <vector>
1534-#include <cstddef>
1535-
1536-#ifdef __OBJC__
1537-// #included from: catch_objc_arc.hpp
1538-#define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED
1539-
1540-#import <Foundation/Foundation.h>
1541-
1542-#ifdef __has_feature
1543-#define CATCH_ARC_ENABLED __has_feature(objc_arc)
1544-#else
1545-#define CATCH_ARC_ENABLED 0
1546-#endif
1547-
1548-void arcSafeRelease( NSObject* obj );
1549-id performOptionalSelector( id obj, SEL sel );
1550-
1551-#if !CATCH_ARC_ENABLED
1552-inline void arcSafeRelease( NSObject* obj ) {
1553- [obj release];
1554-}
1555-inline id performOptionalSelector( id obj, SEL sel ) {
1556- if( [obj respondsToSelector: sel] )
1557- return [obj performSelector: sel];
1558- return nil;
1559-}
1560-#define CATCH_UNSAFE_UNRETAINED
1561-#define CATCH_ARC_STRONG
1562-#else
1563-inline void arcSafeRelease( NSObject* ){}
1564-inline id performOptionalSelector( id obj, SEL sel ) {
1565-#ifdef __clang__
1566-#pragma clang diagnostic push
1567-#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
1568-#endif
1569- if( [obj respondsToSelector: sel] )
1570- return [obj performSelector: sel];
1571-#ifdef __clang__
1572-#pragma clang diagnostic pop
1573-#endif
1574- return nil;
1575-}
1576-#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
1577-#define CATCH_ARC_STRONG __strong
1578-#endif
1579-
1580-#endif
1581-
1582-#ifdef CATCH_CONFIG_CPP11_TUPLE
1583-#include <tuple>
1584-#endif
1585-
1586-#ifdef CATCH_CONFIG_CPP11_IS_ENUM
1587-#include <type_traits>
1588-#endif
1589-
1590-namespace Catch {
1591-
1592-// Why we're here.
1593-template<typename T>
1594-std::string toString( T const& value );
1595-
1596-// Built in overloads
1597-
1598-std::string toString( std::string const& value );
1599-std::string toString( std::wstring const& value );
1600-std::string toString( const char* const value );
1601-std::string toString( char* const value );
1602-std::string toString( const wchar_t* const value );
1603-std::string toString( wchar_t* const value );
1604-std::string toString( int value );
1605-std::string toString( unsigned long value );
1606-std::string toString( unsigned int value );
1607-std::string toString( const double value );
1608-std::string toString( const float value );
1609-std::string toString( bool value );
1610-std::string toString( char value );
1611-std::string toString( signed char value );
1612-std::string toString( unsigned char value );
1613-
1614-#ifdef CATCH_CONFIG_CPP11_LONG_LONG
1615-std::string toString( long long value );
1616-std::string toString( unsigned long long value );
1617-#endif
1618-
1619-#ifdef CATCH_CONFIG_CPP11_NULLPTR
1620-std::string toString( std::nullptr_t );
1621-#endif
1622-
1623-#ifdef __OBJC__
1624- std::string toString( NSString const * const& nsstring );
1625- std::string toString( NSString * CATCH_ARC_STRONG const& nsstring );
1626- std::string toString( NSObject* const& nsObject );
1627-#endif
1628-
1629-namespace Detail {
1630-
1631- extern const std::string unprintableString;
1632-
1633- struct BorgType {
1634- template<typename T> BorgType( T const& );
1635- };
1636-
1637- struct TrueType { char sizer[1]; };
1638- struct FalseType { char sizer[2]; };
1639-
1640- TrueType& testStreamable( std::ostream& );
1641- FalseType testStreamable( FalseType );
1642-
1643- FalseType operator<<( std::ostream const&, BorgType const& );
1644-
1645- template<typename T>
1646- struct IsStreamInsertable {
1647- static std::ostream &s;
1648- static T const&t;
1649- enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
1650- };
1651-
1652-#if defined(CATCH_CONFIG_CPP11_IS_ENUM)
1653- template<typename T,
1654- bool IsEnum = std::is_enum<T>::value
1655- >
1656- struct EnumStringMaker
1657- {
1658- static std::string convert( T const& ) { return unprintableString; }
1659- };
1660-
1661- template<typename T>
1662- struct EnumStringMaker<T,true>
1663- {
1664- static std::string convert( T const& v )
1665- {
1666- return ::Catch::toString(
1667- static_cast<typename std::underlying_type<T>::type>(v)
1668- );
1669- }
1670- };
1671-#endif
1672- template<bool C>
1673- struct StringMakerBase {
1674-#if defined(CATCH_CONFIG_CPP11_IS_ENUM)
1675- template<typename T>
1676- static std::string convert( T const& v )
1677- {
1678- return EnumStringMaker<T>::convert( v );
1679- }
1680-#else
1681- template<typename T>
1682- static std::string convert( T const& ) { return unprintableString; }
1683-#endif
1684- };
1685-
1686- template<>
1687- struct StringMakerBase<true> {
1688- template<typename T>
1689- static std::string convert( T const& _value ) {
1690- std::ostringstream oss;
1691- oss << _value;
1692- return oss.str();
1693- }
1694- };
1695-
1696- std::string rawMemoryToString( const void *object, std::size_t size );
1697-
1698- template<typename T>
1699- inline std::string rawMemoryToString( const T& object ) {
1700- return rawMemoryToString( &object, sizeof(object) );
1701- }
1702-
1703-} // end namespace Detail
1704-
1705-template<typename T>
1706-struct StringMaker :
1707- Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};
1708-
1709-template<typename T>
1710-struct StringMaker<T*> {
1711- template<typename U>
1712- static std::string convert( U* p ) {
1713- if( !p )
1714- return "NULL";
1715- else
1716- return Detail::rawMemoryToString( p );
1717- }
1718-};
1719-
1720-template<typename R, typename C>
1721-struct StringMaker<R C::*> {
1722- static std::string convert( R C::* p ) {
1723- if( !p )
1724- return "NULL";
1725- else
1726- return Detail::rawMemoryToString( p );
1727- }
1728-};
1729-
1730-namespace Detail {
1731- template<typename InputIterator>
1732- std::string rangeToString( InputIterator first, InputIterator last );
1733-}
1734-
1735-//template<typename T, typename Allocator>
1736-//struct StringMaker<std::vector<T, Allocator> > {
1737-// static std::string convert( std::vector<T,Allocator> const& v ) {
1738-// return Detail::rangeToString( v.begin(), v.end() );
1739-// }
1740-//};
1741-
1742-template<typename T, typename Allocator>
1743-std::string toString( std::vector<T,Allocator> const& v ) {
1744- return Detail::rangeToString( v.begin(), v.end() );
1745-}
1746-
1747-#ifdef CATCH_CONFIG_CPP11_TUPLE
1748-
1749-// toString for tuples
1750-namespace TupleDetail {
1751- template<
1752- typename Tuple,
1753- std::size_t N = 0,
1754- bool = (N < std::tuple_size<Tuple>::value)
1755- >
1756- struct ElementPrinter {
1757- static void print( const Tuple& tuple, std::ostream& os )
1758- {
1759- os << ( N ? ", " : " " )
1760- << Catch::toString(std::get<N>(tuple));
1761- ElementPrinter<Tuple,N+1>::print(tuple,os);
1762- }
1763- };
1764-
1765- template<
1766- typename Tuple,
1767- std::size_t N
1768- >
1769- struct ElementPrinter<Tuple,N,false> {
1770- static void print( const Tuple&, std::ostream& ) {}
1771- };
1772-
1773-}
1774-
1775-template<typename ...Types>
1776-struct StringMaker<std::tuple<Types...>> {
1777-
1778- static std::string convert( const std::tuple<Types...>& tuple )
1779- {
1780- std::ostringstream os;
1781- os << '{';
1782- TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os );
1783- os << " }";
1784- return os.str();
1785- }
1786-};
1787-#endif // CATCH_CONFIG_CPP11_TUPLE
1788-
1789-namespace Detail {
1790- template<typename T>
1791- std::string makeString( T const& value ) {
1792- return StringMaker<T>::convert( value );
1793- }
1794-} // end namespace Detail
1795-
1796-/// \brief converts any type to a string
1797-///
1798-/// The default template forwards on to ostringstream - except when an
1799-/// ostringstream overload does not exist - in which case it attempts to detect
1800-/// that and writes {?}.
1801-/// Overload (not specialise) this template for custom typs that you don't want
1802-/// to provide an ostream overload for.
1803-template<typename T>
1804-std::string toString( T const& value ) {
1805- return StringMaker<T>::convert( value );
1806-}
1807-
1808- namespace Detail {
1809- template<typename InputIterator>
1810- std::string rangeToString( InputIterator first, InputIterator last ) {
1811- std::ostringstream oss;
1812- oss << "{ ";
1813- if( first != last ) {
1814- oss << Catch::toString( *first );
1815- for( ++first ; first != last ; ++first )
1816- oss << ", " << Catch::toString( *first );
1817- }
1818- oss << " }";
1819- return oss.str();
1820- }
1821-}
1822-
1823-} // end namespace Catch
1824-
1825-namespace Catch {
1826-
1827-// Wraps the LHS of an expression and captures the operator and RHS (if any) -
1828-// wrapping them all in a ResultBuilder object
1829-template<typename T>
1830-class ExpressionLhs {
1831- ExpressionLhs& operator = ( ExpressionLhs const& );
1832-# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
1833- ExpressionLhs& operator = ( ExpressionLhs && ) = delete;
1834-# endif
1835-
1836-public:
1837- ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {}
1838-# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
1839- ExpressionLhs( ExpressionLhs const& ) = default;
1840- ExpressionLhs( ExpressionLhs && ) = default;
1841-# endif
1842-
1843- template<typename RhsT>
1844- ResultBuilder& operator == ( RhsT const& rhs ) {
1845- return captureExpression<Internal::IsEqualTo>( rhs );
1846- }
1847-
1848- template<typename RhsT>
1849- ResultBuilder& operator != ( RhsT const& rhs ) {
1850- return captureExpression<Internal::IsNotEqualTo>( rhs );
1851- }
1852-
1853- template<typename RhsT>
1854- ResultBuilder& operator < ( RhsT const& rhs ) {
1855- return captureExpression<Internal::IsLessThan>( rhs );
1856- }
1857-
1858- template<typename RhsT>
1859- ResultBuilder& operator > ( RhsT const& rhs ) {
1860- return captureExpression<Internal::IsGreaterThan>( rhs );
1861- }
1862-
1863- template<typename RhsT>
1864- ResultBuilder& operator <= ( RhsT const& rhs ) {
1865- return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
1866- }
1867-
1868- template<typename RhsT>
1869- ResultBuilder& operator >= ( RhsT const& rhs ) {
1870- return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
1871- }
1872-
1873- ResultBuilder& operator == ( bool rhs ) {
1874- return captureExpression<Internal::IsEqualTo>( rhs );
1875- }
1876-
1877- ResultBuilder& operator != ( bool rhs ) {
1878- return captureExpression<Internal::IsNotEqualTo>( rhs );
1879- }
1880-
1881- void endExpression() {
1882- bool value = m_lhs ? true : false;
1883- m_rb
1884- .setLhs( Catch::toString( value ) )
1885- .setResultType( value )
1886- .endExpression();
1887- }
1888-
1889- // Only simple binary expressions are allowed on the LHS.
1890- // If more complex compositions are required then place the sub expression in parentheses
1891- template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& );
1892- template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& );
1893- template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& );
1894- template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& );
1895- template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
1896- template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
1897-
1898-private:
1899- template<Internal::Operator Op, typename RhsT>
1900- ResultBuilder& captureExpression( RhsT const& rhs ) {
1901- return m_rb
1902- .setResultType( Internal::compare<Op>( m_lhs, rhs ) )
1903- .setLhs( Catch::toString( m_lhs ) )
1904- .setRhs( Catch::toString( rhs ) )
1905- .setOp( Internal::OperatorTraits<Op>::getName() );
1906- }
1907-
1908-private:
1909- ResultBuilder& m_rb;
1910- T m_lhs;
1911-};
1912-
1913-} // end namespace Catch
1914-
1915-
1916-namespace Catch {
1917-
1918- template<typename T>
1919- inline ExpressionLhs<T const&> ResultBuilder::operator <= ( T const& operand ) {
1920- return ExpressionLhs<T const&>( *this, operand );
1921- }
1922-
1923- inline ExpressionLhs<bool> ResultBuilder::operator <= ( bool value ) {
1924- return ExpressionLhs<bool>( *this, value );
1925- }
1926-
1927-} // namespace Catch
1928-
1929-// #included from: catch_message.h
1930-#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
1931-
1932-#include <string>
1933-
1934-namespace Catch {
1935-
1936- struct MessageInfo {
1937- MessageInfo( std::string const& _macroName,
1938- SourceLineInfo const& _lineInfo,
1939- ResultWas::OfType _type );
1940-
1941- std::string macroName;
1942- SourceLineInfo lineInfo;
1943- ResultWas::OfType type;
1944- std::string message;
1945- unsigned int sequence;
1946-
1947- bool operator == ( MessageInfo const& other ) const {
1948- return sequence == other.sequence;
1949- }
1950- bool operator < ( MessageInfo const& other ) const {
1951- return sequence < other.sequence;
1952- }
1953- private:
1954- static unsigned int globalCount;
1955- };
1956-
1957- struct MessageBuilder {
1958- MessageBuilder( std::string const& macroName,
1959- SourceLineInfo const& lineInfo,
1960- ResultWas::OfType type )
1961- : m_info( macroName, lineInfo, type )
1962- {}
1963-
1964- template<typename T>
1965- MessageBuilder& operator << ( T const& value ) {
1966- m_stream << value;
1967- return *this;
1968- }
1969-
1970- MessageInfo m_info;
1971- std::ostringstream m_stream;
1972- };
1973-
1974- class ScopedMessage {
1975- public:
1976- ScopedMessage( MessageBuilder const& builder );
1977- ScopedMessage( ScopedMessage const& other );
1978- ~ScopedMessage();
1979-
1980- MessageInfo m_info;
1981- };
1982-
1983-} // end namespace Catch
1984-
1985-// #included from: catch_interfaces_capture.h
1986-#define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
1987-
1988-#include <string>
1989-
1990-namespace Catch {
1991-
1992- class TestCase;
1993- class AssertionResult;
1994- struct AssertionInfo;
1995- struct SectionInfo;
1996- struct SectionEndInfo;
1997- struct MessageInfo;
1998- class ScopedMessageBuilder;
1999- struct Counts;
2000-
2001- struct IResultCapture {
2002-
2003- virtual ~IResultCapture();
2004-
2005- virtual void assertionEnded( AssertionResult const& result ) = 0;
2006- virtual bool sectionStarted( SectionInfo const& sectionInfo,
2007- Counts& assertions ) = 0;
2008- virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
2009- virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
2010- virtual void pushScopedMessage( MessageInfo const& message ) = 0;
2011- virtual void popScopedMessage( MessageInfo const& message ) = 0;
2012-
2013- virtual std::string getCurrentTestName() const = 0;
2014- virtual const AssertionResult* getLastResult() const = 0;
2015-
2016- virtual void handleFatalErrorCondition( std::string const& message ) = 0;
2017- };
2018-
2019- IResultCapture& getResultCapture();
2020-}
2021-
2022-// #included from: catch_debugger.h
2023-#define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
2024-
2025-// #included from: catch_platform.h
2026-#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
2027-
2028-#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
2029-# define CATCH_PLATFORM_MAC
2030-#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
2031-# define CATCH_PLATFORM_IPHONE
2032-#elif defined(linux) || defined(__linux) || defined(__linux__)
2033-# define CATCH_PLATFORM_LINUX
2034-#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
2035-# define CATCH_PLATFORM_WINDOWS
2036-# if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
2037-# define CATCH_DEFINES_NOMINMAX
2038-# endif
2039-# if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
2040-# define CATCH_DEFINES_WIN32_LEAN_AND_MEAN
2041-# endif
2042-#endif
2043-
2044-#include <string>
2045-
2046-namespace Catch{
2047-
2048- bool isDebuggerActive();
2049- void writeToDebugConsole( std::string const& text );
2050-}
2051-
2052-#ifdef CATCH_PLATFORM_MAC
2053-
2054- // The following code snippet based on:
2055- // http://cocoawithlove.com/2008/03/break-into-debugger.html
2056- #ifdef DEBUG
2057- #if defined(__ppc64__) || defined(__ppc__)
2058- #define CATCH_TRAP() \
2059- __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
2060- : : : "memory","r0","r3","r4" )
2061- #else
2062- #define CATCH_TRAP() _asm__("int $3\n" : : )
2063- #endif
2064- #endif
2065-
2066-#elif defined(CATCH_PLATFORM_LINUX)
2067- // If we can use inline assembler, do it because this allows us to break
2068- // directly at the location of the failing check instead of breaking inside
2069- // raise() called from it, i.e. one stack frame below.
2070- #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
2071- #define CATCH_TRAP() asm volatile ("int $3")
2072- #else // Fall back to the generic way.
2073- #include <signal.h>
2074-
2075- #define CATCH_TRAP() raise(SIGTRAP)
2076- #endif
2077-#elif defined(_MSC_VER)
2078- #define CATCH_TRAP() __debugbreak()
2079-#elif defined(__MINGW32__)
2080- extern "C" __declspec(dllimport) void __stdcall DebugBreak();
2081- #define CATCH_TRAP() DebugBreak()
2082-#endif
2083-
2084-#ifdef CATCH_TRAP
2085- #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); }
2086-#else
2087- #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
2088-#endif
2089-
2090-// #included from: catch_interfaces_runner.h
2091-#define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
2092-
2093-namespace Catch {
2094- class TestCase;
2095-
2096- struct IRunner {
2097- virtual ~IRunner();
2098- virtual bool aborting() const = 0;
2099- };
2100-}
2101-
2102-///////////////////////////////////////////////////////////////////////////////
2103-// In the event of a failure works out if the debugger needs to be invoked
2104-// and/or an exception thrown and takes appropriate action.
2105-// This needs to be done as a macro so the debugger will stop in the user
2106-// source code rather than in Catch library code
2107-#define INTERNAL_CATCH_REACT( resultBuilder ) \
2108- if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
2109- resultBuilder.react();
2110-
2111-///////////////////////////////////////////////////////////////////////////////
2112-#define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \
2113- do { \
2114- Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
2115- try { \
2116- CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
2117- ( __catchResult <= expr ).endExpression(); \
2118- } \
2119- catch( ... ) { \
2120- __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \
2121- } \
2122- INTERNAL_CATCH_REACT( __catchResult ) \
2123- } while( Catch::alwaysFalse( sizeof(expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
2124-
2125-///////////////////////////////////////////////////////////////////////////////
2126-#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
2127- INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
2128- if( Catch::getResultCapture().getLastResult()->succeeded() )
2129-
2130-///////////////////////////////////////////////////////////////////////////////
2131-#define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \
2132- INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
2133- if( !Catch::getResultCapture().getLastResult()->succeeded() )
2134-
2135-///////////////////////////////////////////////////////////////////////////////
2136-#define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \
2137- do { \
2138- Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
2139- try { \
2140- expr; \
2141- __catchResult.captureResult( Catch::ResultWas::Ok ); \
2142- } \
2143- catch( ... ) { \
2144- __catchResult.useActiveException( resultDisposition ); \
2145- } \
2146- INTERNAL_CATCH_REACT( __catchResult ) \
2147- } while( Catch::alwaysFalse() )
2148-
2149-///////////////////////////////////////////////////////////////////////////////
2150-#define INTERNAL_CATCH_THROWS( expr, resultDisposition, matcher, macroName ) \
2151- do { \
2152- Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition, #matcher ); \
2153- if( __catchResult.allowThrows() ) \
2154- try { \
2155- expr; \
2156- __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
2157- } \
2158- catch( ... ) { \
2159- __catchResult.captureExpectedException( matcher ); \
2160- } \
2161- else \
2162- __catchResult.captureResult( Catch::ResultWas::Ok ); \
2163- INTERNAL_CATCH_REACT( __catchResult ) \
2164- } while( Catch::alwaysFalse() )
2165-
2166-///////////////////////////////////////////////////////////////////////////////
2167-#define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \
2168- do { \
2169- Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
2170- if( __catchResult.allowThrows() ) \
2171- try { \
2172- expr; \
2173- __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
2174- } \
2175- catch( exceptionType ) { \
2176- __catchResult.captureResult( Catch::ResultWas::Ok ); \
2177- } \
2178- catch( ... ) { \
2179- __catchResult.useActiveException( resultDisposition ); \
2180- } \
2181- else \
2182- __catchResult.captureResult( Catch::ResultWas::Ok ); \
2183- INTERNAL_CATCH_REACT( __catchResult ) \
2184- } while( Catch::alwaysFalse() )
2185-
2186-///////////////////////////////////////////////////////////////////////////////
2187-#ifdef CATCH_CONFIG_VARIADIC_MACROS
2188- #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \
2189- do { \
2190- Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
2191- __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \
2192- __catchResult.captureResult( messageType ); \
2193- INTERNAL_CATCH_REACT( __catchResult ) \
2194- } while( Catch::alwaysFalse() )
2195-#else
2196- #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \
2197- do { \
2198- Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
2199- __catchResult << log + ::Catch::StreamEndStop(); \
2200- __catchResult.captureResult( messageType ); \
2201- INTERNAL_CATCH_REACT( __catchResult ) \
2202- } while( Catch::alwaysFalse() )
2203-#endif
2204-
2205-///////////////////////////////////////////////////////////////////////////////
2206-#define INTERNAL_CATCH_INFO( log, macroName ) \
2207- Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
2208-
2209-///////////////////////////////////////////////////////////////////////////////
2210-#define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \
2211- do { \
2212- Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \
2213- try { \
2214- std::string matcherAsString = (matcher).toString(); \
2215- __catchResult \
2216- .setLhs( Catch::toString( arg ) ) \
2217- .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \
2218- .setOp( "matches" ) \
2219- .setResultType( (matcher).match( arg ) ); \
2220- __catchResult.captureExpression(); \
2221- } catch( ... ) { \
2222- __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
2223- } \
2224- INTERNAL_CATCH_REACT( __catchResult ) \
2225- } while( Catch::alwaysFalse() )
2226-
2227-// #included from: internal/catch_section.h
2228-#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
2229-
2230-// #included from: catch_section_info.h
2231-#define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
2232-
2233-// #included from: catch_totals.hpp
2234-#define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED
2235-
2236-#include <cstddef>
2237-
2238-namespace Catch {
2239-
2240- struct Counts {
2241- Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {}
2242-
2243- Counts operator - ( Counts const& other ) const {
2244- Counts diff;
2245- diff.passed = passed - other.passed;
2246- diff.failed = failed - other.failed;
2247- diff.failedButOk = failedButOk - other.failedButOk;
2248- return diff;
2249- }
2250- Counts& operator += ( Counts const& other ) {
2251- passed += other.passed;
2252- failed += other.failed;
2253- failedButOk += other.failedButOk;
2254- return *this;
2255- }
2256-
2257- std::size_t total() const {
2258- return passed + failed + failedButOk;
2259- }
2260- bool allPassed() const {
2261- return failed == 0 && failedButOk == 0;
2262- }
2263- bool allOk() const {
2264- return failed == 0;
2265- }
2266-
2267- std::size_t passed;
2268- std::size_t failed;
2269- std::size_t failedButOk;
2270- };
2271-
2272- struct Totals {
2273-
2274- Totals operator - ( Totals const& other ) const {
2275- Totals diff;
2276- diff.assertions = assertions - other.assertions;
2277- diff.testCases = testCases - other.testCases;
2278- return diff;
2279- }
2280-
2281- Totals delta( Totals const& prevTotals ) const {
2282- Totals diff = *this - prevTotals;
2283- if( diff.assertions.failed > 0 )
2284- ++diff.testCases.failed;
2285- else if( diff.assertions.failedButOk > 0 )
2286- ++diff.testCases.failedButOk;
2287- else
2288- ++diff.testCases.passed;
2289- return diff;
2290- }
2291-
2292- Totals& operator += ( Totals const& other ) {
2293- assertions += other.assertions;
2294- testCases += other.testCases;
2295- return *this;
2296- }
2297-
2298- Counts assertions;
2299- Counts testCases;
2300- };
2301-}
2302-
2303-namespace Catch {
2304-
2305- struct SectionInfo {
2306- SectionInfo
2307- ( SourceLineInfo const& _lineInfo,
2308- std::string const& _name,
2309- std::string const& _description = std::string() );
2310-
2311- std::string name;
2312- std::string description;
2313- SourceLineInfo lineInfo;
2314- };
2315-
2316- struct SectionEndInfo {
2317- SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )
2318- : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
2319- {}
2320-
2321- SectionInfo sectionInfo;
2322- Counts prevAssertions;
2323- double durationInSeconds;
2324- };
2325-
2326-} // end namespace Catch
2327-
2328-// #included from: catch_timer.h
2329-#define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED
2330-
2331-#ifdef CATCH_PLATFORM_WINDOWS
2332-typedef unsigned long long uint64_t;
2333-#else
2334-#include <stdint.h>
2335-#endif
2336-
2337-namespace Catch {
2338-
2339- class Timer {
2340- public:
2341- Timer() : m_ticks( 0 ) {}
2342- void start();
2343- unsigned int getElapsedMicroseconds() const;
2344- unsigned int getElapsedMilliseconds() const;
2345- double getElapsedSeconds() const;
2346-
2347- private:
2348- uint64_t m_ticks;
2349- };
2350-
2351-} // namespace Catch
2352-
2353-#include <string>
2354-
2355-namespace Catch {
2356-
2357- class Section : NonCopyable {
2358- public:
2359- Section( SectionInfo const& info );
2360- ~Section();
2361-
2362- // This indicates whether the section should be executed or not
2363- operator bool() const;
2364-
2365- private:
2366- SectionInfo m_info;
2367-
2368- std::string m_name;
2369- Counts m_assertions;
2370- bool m_sectionIncluded;
2371- Timer m_timer;
2372- };
2373-
2374-} // end namespace Catch
2375-
2376-#ifdef CATCH_CONFIG_VARIADIC_MACROS
2377- #define INTERNAL_CATCH_SECTION( ... ) \
2378- if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
2379-#else
2380- #define INTERNAL_CATCH_SECTION( name, desc ) \
2381- if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) )
2382-#endif
2383-
2384-// #included from: internal/catch_generators.hpp
2385-#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
2386-
2387-#include <iterator>
2388-#include <vector>
2389-#include <string>
2390-#include <stdlib.h>
2391-
2392-namespace Catch {
2393-
2394-template<typename T>
2395-struct IGenerator {
2396- virtual ~IGenerator() {}
2397- virtual T getValue( std::size_t index ) const = 0;
2398- virtual std::size_t size () const = 0;
2399-};
2400-
2401-template<typename T>
2402-class BetweenGenerator : public IGenerator<T> {
2403-public:
2404- BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){}
2405-
2406- virtual T getValue( std::size_t index ) const {
2407- return m_from+static_cast<int>( index );
2408- }
2409-
2410- virtual std::size_t size() const {
2411- return static_cast<std::size_t>( 1+m_to-m_from );
2412- }
2413-
2414-private:
2415-
2416- T m_from;
2417- T m_to;
2418-};
2419-
2420-template<typename T>
2421-class ValuesGenerator : public IGenerator<T> {
2422-public:
2423- ValuesGenerator(){}
2424-
2425- void add( T value ) {
2426- m_values.push_back( value );
2427- }
2428-
2429- virtual T getValue( std::size_t index ) const {
2430- return m_values[index];
2431- }
2432-
2433- virtual std::size_t size() const {
2434- return m_values.size();
2435- }
2436-
2437-private:
2438- std::vector<T> m_values;
2439-};
2440-
2441-template<typename T>
2442-class CompositeGenerator {
2443-public:
2444- CompositeGenerator() : m_totalSize( 0 ) {}
2445-
2446- // *** Move semantics, similar to auto_ptr ***
2447- CompositeGenerator( CompositeGenerator& other )
2448- : m_fileInfo( other.m_fileInfo ),
2449- m_totalSize( 0 )
2450- {
2451- move( other );
2452- }
2453-
2454- CompositeGenerator& setFileInfo( const char* fileInfo ) {
2455- m_fileInfo = fileInfo;
2456- return *this;
2457- }
2458-
2459- ~CompositeGenerator() {
2460- deleteAll( m_composed );
2461- }
2462-
2463- operator T () const {
2464- size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );
2465-
2466- typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
2467- typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
2468- for( size_t index = 0; it != itEnd; ++it )
2469- {
2470- const IGenerator<T>* generator = *it;
2471- if( overallIndex >= index && overallIndex < index + generator->size() )
2472- {
2473- return generator->getValue( overallIndex-index );
2474- }
2475- index += generator->size();
2476- }
2477- CATCH_INTERNAL_ERROR( "Indexed past end of generated range" );
2478- return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so
2479- }
2480-
2481- void add( const IGenerator<T>* generator ) {
2482- m_totalSize += generator->size();
2483- m_composed.push_back( generator );
2484- }
2485-
2486- CompositeGenerator& then( CompositeGenerator& other ) {
2487- move( other );
2488- return *this;
2489- }
2490-
2491- CompositeGenerator& then( T value ) {
2492- ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
2493- valuesGen->add( value );
2494- add( valuesGen );
2495- return *this;
2496- }
2497-
2498-private:
2499-
2500- void move( CompositeGenerator& other ) {
2501- std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );
2502- m_totalSize += other.m_totalSize;
2503- other.m_composed.clear();
2504- }
2505-
2506- std::vector<const IGenerator<T>*> m_composed;
2507- std::string m_fileInfo;
2508- size_t m_totalSize;
2509-};
2510-
2511-namespace Generators
2512-{
2513- template<typename T>
2514- CompositeGenerator<T> between( T from, T to ) {
2515- CompositeGenerator<T> generators;
2516- generators.add( new BetweenGenerator<T>( from, to ) );
2517- return generators;
2518- }
2519-
2520- template<typename T>
2521- CompositeGenerator<T> values( T val1, T val2 ) {
2522- CompositeGenerator<T> generators;
2523- ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
2524- valuesGen->add( val1 );
2525- valuesGen->add( val2 );
2526- generators.add( valuesGen );
2527- return generators;
2528- }
2529-
2530- template<typename T>
2531- CompositeGenerator<T> values( T val1, T val2, T val3 ){
2532- CompositeGenerator<T> generators;
2533- ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
2534- valuesGen->add( val1 );
2535- valuesGen->add( val2 );
2536- valuesGen->add( val3 );
2537- generators.add( valuesGen );
2538- return generators;
2539- }
2540-
2541- template<typename T>
2542- CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) {
2543- CompositeGenerator<T> generators;
2544- ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
2545- valuesGen->add( val1 );
2546- valuesGen->add( val2 );
2547- valuesGen->add( val3 );
2548- valuesGen->add( val4 );
2549- generators.add( valuesGen );
2550- return generators;
2551- }
2552-
2553-} // end namespace Generators
2554-
2555-using namespace Generators;
2556-
2557-} // end namespace Catch
2558-
2559-#define INTERNAL_CATCH_LINESTR2( line ) #line
2560-#define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )
2561-
2562-#define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" )
2563-
2564-// #included from: internal/catch_interfaces_exception.h
2565-#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
2566-
2567-#include <string>
2568-#include <vector>
2569-
2570-// #included from: catch_interfaces_registry_hub.h
2571-#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
2572-
2573-#include <string>
2574-
2575-namespace Catch {
2576-
2577- class TestCase;
2578- struct ITestCaseRegistry;
2579- struct IExceptionTranslatorRegistry;
2580- struct IExceptionTranslator;
2581- struct IReporterRegistry;
2582- struct IReporterFactory;
2583-
2584- struct IRegistryHub {
2585- virtual ~IRegistryHub();
2586-
2587- virtual IReporterRegistry const& getReporterRegistry() const = 0;
2588- virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
2589- virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
2590- };
2591-
2592- struct IMutableRegistryHub {
2593- virtual ~IMutableRegistryHub();
2594- virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) = 0;
2595- virtual void registerListener( Ptr<IReporterFactory> const& factory ) = 0;
2596- virtual void registerTest( TestCase const& testInfo ) = 0;
2597- virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
2598- };
2599-
2600- IRegistryHub& getRegistryHub();
2601- IMutableRegistryHub& getMutableRegistryHub();
2602- void cleanUp();
2603- std::string translateActiveException();
2604-
2605-}
2606-
2607-namespace Catch {
2608-
2609- typedef std::string(*exceptionTranslateFunction)();
2610-
2611- struct IExceptionTranslator;
2612- typedef std::vector<const IExceptionTranslator*> ExceptionTranslators;
2613-
2614- struct IExceptionTranslator {
2615- virtual ~IExceptionTranslator();
2616- virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
2617- };
2618-
2619- struct IExceptionTranslatorRegistry {
2620- virtual ~IExceptionTranslatorRegistry();
2621-
2622- virtual std::string translateActiveException() const = 0;
2623- };
2624-
2625- class ExceptionTranslatorRegistrar {
2626- template<typename T>
2627- class ExceptionTranslator : public IExceptionTranslator {
2628- public:
2629-
2630- ExceptionTranslator( std::string(*translateFunction)( T& ) )
2631- : m_translateFunction( translateFunction )
2632- {}
2633-
2634- virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE {
2635- try {
2636- if( it == itEnd )
2637- throw;
2638- else
2639- return (*it)->translate( it+1, itEnd );
2640- }
2641- catch( T& ex ) {
2642- return m_translateFunction( ex );
2643- }
2644- }
2645-
2646- protected:
2647- std::string(*m_translateFunction)( T& );
2648- };
2649-
2650- public:
2651- template<typename T>
2652- ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
2653- getMutableRegistryHub().registerTranslator
2654- ( new ExceptionTranslator<T>( translateFunction ) );
2655- }
2656- };
2657-}
2658-
2659-///////////////////////////////////////////////////////////////////////////////
2660-#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
2661- static std::string translatorName( signature ); \
2662- namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\
2663- static std::string translatorName( signature )
2664-
2665-#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
2666-
2667-// #included from: internal/catch_approx.hpp
2668-#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
2669-
2670-#include <cmath>
2671-#include <limits>
2672-
2673-namespace Catch {
2674-namespace Detail {
2675-
2676- class Approx {
2677- public:
2678- explicit Approx ( double value )
2679- : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
2680- m_scale( 1.0 ),
2681- m_value( value )
2682- {}
2683-
2684- Approx( Approx const& other )
2685- : m_epsilon( other.m_epsilon ),
2686- m_scale( other.m_scale ),
2687- m_value( other.m_value )
2688- {}
2689-
2690- static Approx custom() {
2691- return Approx( 0 );
2692- }
2693-
2694- Approx operator()( double value ) {
2695- Approx approx( value );
2696- approx.epsilon( m_epsilon );
2697- approx.scale( m_scale );
2698- return approx;
2699- }
2700-
2701- friend bool operator == ( double lhs, Approx const& rhs ) {
2702- // Thanks to Richard Harris for his help refining this formula
2703- return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );
2704- }
2705-
2706- friend bool operator == ( Approx const& lhs, double rhs ) {
2707- return operator==( rhs, lhs );
2708- }
2709-
2710- friend bool operator != ( double lhs, Approx const& rhs ) {
2711- return !operator==( lhs, rhs );
2712- }
2713-
2714- friend bool operator != ( Approx const& lhs, double rhs ) {
2715- return !operator==( rhs, lhs );
2716- }
2717-
2718- friend bool operator <= ( double lhs, Approx const& rhs )
2719- {
2720- return lhs < rhs.m_value || lhs == rhs;
2721- }
2722-
2723- friend bool operator <= ( Approx const& lhs, double rhs )
2724- {
2725- return lhs.m_value < rhs || lhs == rhs;
2726- }
2727-
2728- friend bool operator >= ( double lhs, Approx const& rhs )
2729- {
2730- return lhs > rhs.m_value || lhs == rhs;
2731- }
2732-
2733- friend bool operator >= ( Approx const& lhs, double rhs )
2734- {
2735- return lhs.m_value > rhs || lhs == rhs;
2736- }
2737-
2738- Approx& epsilon( double newEpsilon ) {
2739- m_epsilon = newEpsilon;
2740- return *this;
2741- }
2742-
2743- Approx& scale( double newScale ) {
2744- m_scale = newScale;
2745- return *this;
2746- }
2747-
2748- std::string toString() const {
2749- std::ostringstream oss;
2750- oss << "Approx( " << Catch::toString( m_value ) << " )";
2751- return oss.str();
2752- }
2753-
2754- private:
2755- double m_epsilon;
2756- double m_scale;
2757- double m_value;
2758- };
2759-}
2760-
2761-template<>
2762-inline std::string toString<Detail::Approx>( Detail::Approx const& value ) {
2763- return value.toString();
2764-}
2765-
2766-} // end namespace Catch
2767-
2768-// #included from: internal/catch_interfaces_tag_alias_registry.h
2769-#define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED
2770-
2771-// #included from: catch_tag_alias.h
2772-#define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED
2773-
2774-#include <string>
2775-
2776-namespace Catch {
2777-
2778- struct TagAlias {
2779- TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
2780-
2781- std::string tag;
2782- SourceLineInfo lineInfo;
2783- };
2784-
2785- struct RegistrarForTagAliases {
2786- RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
2787- };
2788-
2789-} // end namespace Catch
2790-
2791-#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }
2792-// #included from: catch_option.hpp
2793-#define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
2794-
2795-namespace Catch {
2796-
2797- // An optional type
2798- template<typename T>
2799- class Option {
2800- public:
2801- Option() : nullableValue( CATCH_NULL ) {}
2802- Option( T const& _value )
2803- : nullableValue( new( storage ) T( _value ) )
2804- {}
2805- Option( Option const& _other )
2806- : nullableValue( _other ? new( storage ) T( *_other ) : CATCH_NULL )
2807- {}
2808-
2809- ~Option() {
2810- reset();
2811- }
2812-
2813- Option& operator= ( Option const& _other ) {
2814- if( &_other != this ) {
2815- reset();
2816- if( _other )
2817- nullableValue = new( storage ) T( *_other );
2818- }
2819- return *this;
2820- }
2821- Option& operator = ( T const& _value ) {
2822- reset();
2823- nullableValue = new( storage ) T( _value );
2824- return *this;
2825- }
2826-
2827- void reset() {
2828- if( nullableValue )
2829- nullableValue->~T();
2830- nullableValue = CATCH_NULL;
2831- }
2832-
2833- T& operator*() { return *nullableValue; }
2834- T const& operator*() const { return *nullableValue; }
2835- T* operator->() { return nullableValue; }
2836- const T* operator->() const { return nullableValue; }
2837-
2838- T valueOr( T const& defaultValue ) const {
2839- return nullableValue ? *nullableValue : defaultValue;
2840- }
2841-
2842- bool some() const { return nullableValue != CATCH_NULL; }
2843- bool none() const { return nullableValue == CATCH_NULL; }
2844-
2845- bool operator !() const { return nullableValue == CATCH_NULL; }
2846- operator SafeBool::type() const {
2847- return SafeBool::makeSafe( some() );
2848- }
2849-
2850- private:
2851- T* nullableValue;
2852- char storage[sizeof(T)];
2853- };
2854-
2855-} // end namespace Catch
2856-
2857-namespace Catch {
2858-
2859- struct ITagAliasRegistry {
2860- virtual ~ITagAliasRegistry();
2861- virtual Option<TagAlias> find( std::string const& alias ) const = 0;
2862- virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
2863-
2864- static ITagAliasRegistry const& get();
2865- };
2866-
2867-} // end namespace Catch
2868-
2869-// These files are included here so the single_include script doesn't put them
2870-// in the conditionally compiled sections
2871-// #included from: internal/catch_test_case_info.h
2872-#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED
2873-
2874-#include <string>
2875-#include <set>
2876-
2877-#ifdef __clang__
2878-#pragma clang diagnostic push
2879-#pragma clang diagnostic ignored "-Wpadded"
2880-#endif
2881-
2882-namespace Catch {
2883-
2884- struct ITestCase;
2885-
2886- struct TestCaseInfo {
2887- enum SpecialProperties{
2888- None = 0,
2889- IsHidden = 1 << 1,
2890- ShouldFail = 1 << 2,
2891- MayFail = 1 << 3,
2892- Throws = 1 << 4
2893- };
2894-
2895- TestCaseInfo( std::string const& _name,
2896- std::string const& _className,
2897- std::string const& _description,
2898- std::set<std::string> const& _tags,
2899- SourceLineInfo const& _lineInfo );
2900-
2901- TestCaseInfo( TestCaseInfo const& other );
2902-
2903- friend void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags );
2904-
2905- bool isHidden() const;
2906- bool throws() const;
2907- bool okToFail() const;
2908- bool expectedToFail() const;
2909-
2910- std::string name;
2911- std::string className;
2912- std::string description;
2913- std::set<std::string> tags;
2914- std::set<std::string> lcaseTags;
2915- std::string tagsAsString;
2916- SourceLineInfo lineInfo;
2917- SpecialProperties properties;
2918- };
2919-
2920- class TestCase : public TestCaseInfo {
2921- public:
2922-
2923- TestCase( ITestCase* testCase, TestCaseInfo const& info );
2924- TestCase( TestCase const& other );
2925-
2926- TestCase withName( std::string const& _newName ) const;
2927-
2928- void invoke() const;
2929-
2930- TestCaseInfo const& getTestCaseInfo() const;
2931-
2932- void swap( TestCase& other );
2933- bool operator == ( TestCase const& other ) const;
2934- bool operator < ( TestCase const& other ) const;
2935- TestCase& operator = ( TestCase const& other );
2936-
2937- private:
2938- Ptr<ITestCase> test;
2939- };
2940-
2941- TestCase makeTestCase( ITestCase* testCase,
2942- std::string const& className,
2943- std::string const& name,
2944- std::string const& description,
2945- SourceLineInfo const& lineInfo );
2946-}
2947-
2948-#ifdef __clang__
2949-#pragma clang diagnostic pop
2950-#endif
2951-
2952-
2953-#ifdef __OBJC__
2954-// #included from: internal/catch_objc.hpp
2955-#define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
2956-
2957-#import <objc/runtime.h>
2958-
2959-#include <string>
2960-
2961-// NB. Any general catch headers included here must be included
2962-// in catch.hpp first to make sure they are included by the single
2963-// header for non obj-usage
2964-
2965-///////////////////////////////////////////////////////////////////////////////
2966-// This protocol is really only here for (self) documenting purposes, since
2967-// all its methods are optional.
2968-@protocol OcFixture
2969-
2970-@optional
2971-
2972--(void) setUp;
2973--(void) tearDown;
2974-
2975-@end
2976-
2977-namespace Catch {
2978-
2979- class OcMethod : public SharedImpl<ITestCase> {
2980-
2981- public:
2982- OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
2983-
2984- virtual void invoke() const {
2985- id obj = [[m_cls alloc] init];
2986-
2987- performOptionalSelector( obj, @selector(setUp) );
2988- performOptionalSelector( obj, m_sel );
2989- performOptionalSelector( obj, @selector(tearDown) );
2990-
2991- arcSafeRelease( obj );
2992- }
2993- private:
2994- virtual ~OcMethod() {}
2995-
2996- Class m_cls;
2997- SEL m_sel;
2998- };
2999-
3000- namespace Detail{
3001-
3002- inline std::string getAnnotation( Class cls,
3003- std::string const& annotationName,
3004- std::string const& testCaseName ) {
3005- NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
3006- SEL sel = NSSelectorFromString( selStr );
3007- arcSafeRelease( selStr );
3008- id value = performOptionalSelector( cls, sel );
3009- if( value )
3010- return [(NSString*)value UTF8String];
3011- return "";
3012- }
3013- }
3014-
3015- inline size_t registerTestMethods() {
3016- size_t noTestMethods = 0;
3017- int noClasses = objc_getClassList( CATCH_NULL, 0 );
3018-
3019- Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
3020- objc_getClassList( classes, noClasses );
3021-
3022- for( int c = 0; c < noClasses; c++ ) {
3023- Class cls = classes[c];
3024- {
3025- u_int count;
3026- Method* methods = class_copyMethodList( cls, &count );
3027- for( u_int m = 0; m < count ; m++ ) {
3028- SEL selector = method_getName(methods[m]);
3029- std::string methodName = sel_getName(selector);
3030- if( startsWith( methodName, "Catch_TestCase_" ) ) {
3031- std::string testCaseName = methodName.substr( 15 );
3032- std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
3033- std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
3034- const char* className = class_getName( cls );
3035-
3036- getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) );
3037- noTestMethods++;
3038- }
3039- }
3040- free(methods);
3041- }
3042- }
3043- return noTestMethods;
3044- }
3045-
3046- namespace Matchers {
3047- namespace Impl {
3048- namespace NSStringMatchers {
3049-
3050- template<typename MatcherT>
3051- struct StringHolder : MatcherImpl<MatcherT, NSString*>{
3052- StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
3053- StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
3054- StringHolder() {
3055- arcSafeRelease( m_substr );
3056- }
3057-
3058- NSString* m_substr;
3059- };
3060-
3061- struct Equals : StringHolder<Equals> {
3062- Equals( NSString* substr ) : StringHolder( substr ){}
3063-
3064- virtual bool match( ExpressionType const& str ) const {
3065- return (str != nil || m_substr == nil ) &&
3066- [str isEqualToString:m_substr];
3067- }
3068-
3069- virtual std::string toString() const {
3070- return "equals string: " + Catch::toString( m_substr );
3071- }
3072- };
3073-
3074- struct Contains : StringHolder<Contains> {
3075- Contains( NSString* substr ) : StringHolder( substr ){}
3076-
3077- virtual bool match( ExpressionType const& str ) const {
3078- return (str != nil || m_substr == nil ) &&
3079- [str rangeOfString:m_substr].location != NSNotFound;
3080- }
3081-
3082- virtual std::string toString() const {
3083- return "contains string: " + Catch::toString( m_substr );
3084- }
3085- };
3086-
3087- struct StartsWith : StringHolder<StartsWith> {
3088- StartsWith( NSString* substr ) : StringHolder( substr ){}
3089-
3090- virtual bool match( ExpressionType const& str ) const {
3091- return (str != nil || m_substr == nil ) &&
3092- [str rangeOfString:m_substr].location == 0;
3093- }
3094-
3095- virtual std::string toString() const {
3096- return "starts with: " + Catch::toString( m_substr );
3097- }
3098- };
3099- struct EndsWith : StringHolder<EndsWith> {
3100- EndsWith( NSString* substr ) : StringHolder( substr ){}
3101-
3102- virtual bool match( ExpressionType const& str ) const {
3103- return (str != nil || m_substr == nil ) &&
3104- [str rangeOfString:m_substr].location == [str length] - [m_substr length];
3105- }
3106-
3107- virtual std::string toString() const {
3108- return "ends with: " + Catch::toString( m_substr );
3109- }
3110- };
3111-
3112- } // namespace NSStringMatchers
3113- } // namespace Impl
3114-
3115- inline Impl::NSStringMatchers::Equals
3116- Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
3117-
3118- inline Impl::NSStringMatchers::Contains
3119- Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
3120-
3121- inline Impl::NSStringMatchers::StartsWith
3122- StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
3123-
3124- inline Impl::NSStringMatchers::EndsWith
3125- EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
3126-
3127- } // namespace Matchers
3128-
3129- using namespace Matchers;
3130-
3131-} // namespace Catch
3132-
3133-///////////////////////////////////////////////////////////////////////////////
3134-#define OC_TEST_CASE( name, desc )\
3135-+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
3136-{\
3137-return @ name; \
3138-}\
3139-+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
3140-{ \
3141-return @ desc; \
3142-} \
3143--(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
3144-
3145-#endif
3146-
3147-#ifdef CATCH_IMPL
3148-// #included from: internal/catch_impl.hpp
3149-#define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED
3150-
3151-// Collect all the implementation files together here
3152-// These are the equivalent of what would usually be cpp files
3153-
3154-#ifdef __clang__
3155-#pragma clang diagnostic push
3156-#pragma clang diagnostic ignored "-Wweak-vtables"
3157-#endif
3158-
3159-// #included from: ../catch_session.hpp
3160-#define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
3161-
3162-// #included from: internal/catch_commandline.hpp
3163-#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
3164-
3165-// #included from: catch_config.hpp
3166-#define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
3167-
3168-// #included from: catch_test_spec_parser.hpp
3169-#define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
3170-
3171-#ifdef __clang__
3172-#pragma clang diagnostic push
3173-#pragma clang diagnostic ignored "-Wpadded"
3174-#endif
3175-
3176-// #included from: catch_test_spec.hpp
3177-#define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
3178-
3179-#ifdef __clang__
3180-#pragma clang diagnostic push
3181-#pragma clang diagnostic ignored "-Wpadded"
3182-#endif
3183-
3184-// #included from: catch_wildcard_pattern.hpp
3185-#define TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED
3186-
3187-namespace Catch
3188-{
3189- class WildcardPattern {
3190- enum WildcardPosition {
3191- NoWildcard = 0,
3192- WildcardAtStart = 1,
3193- WildcardAtEnd = 2,
3194- WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
3195- };
3196-
3197- public:
3198-
3199- WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity )
3200- : m_caseSensitivity( caseSensitivity ),
3201- m_wildcard( NoWildcard ),
3202- m_pattern( adjustCase( pattern ) )
3203- {
3204- if( startsWith( m_pattern, "*" ) ) {
3205- m_pattern = m_pattern.substr( 1 );
3206- m_wildcard = WildcardAtStart;
3207- }
3208- if( endsWith( m_pattern, "*" ) ) {
3209- m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
3210- m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
3211- }
3212- }
3213- virtual ~WildcardPattern();
3214- virtual bool matches( std::string const& str ) const {
3215- switch( m_wildcard ) {
3216- case NoWildcard:
3217- return m_pattern == adjustCase( str );
3218- case WildcardAtStart:
3219- return endsWith( adjustCase( str ), m_pattern );
3220- case WildcardAtEnd:
3221- return startsWith( adjustCase( str ), m_pattern );
3222- case WildcardAtBothEnds:
3223- return contains( adjustCase( str ), m_pattern );
3224- }
3225-
3226-#ifdef __clang__
3227-#pragma clang diagnostic push
3228-#pragma clang diagnostic ignored "-Wunreachable-code"
3229-#endif
3230- throw std::logic_error( "Unknown enum" );
3231-#ifdef __clang__
3232-#pragma clang diagnostic pop
3233-#endif
3234- }
3235- private:
3236- std::string adjustCase( std::string const& str ) const {
3237- return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;
3238- }
3239- CaseSensitive::Choice m_caseSensitivity;
3240- WildcardPosition m_wildcard;
3241- std::string m_pattern;
3242- };
3243-}
3244-
3245-#include <string>
3246-#include <vector>
3247-
3248-namespace Catch {
3249-
3250- class TestSpec {
3251- struct Pattern : SharedImpl<> {
3252- virtual ~Pattern();
3253- virtual bool matches( TestCaseInfo const& testCase ) const = 0;
3254- };
3255- class NamePattern : public Pattern {
3256- public:
3257- NamePattern( std::string const& name )
3258- : m_wildcardPattern( toLower( name ), CaseSensitive::No )
3259- {}
3260- virtual ~NamePattern();
3261- virtual bool matches( TestCaseInfo const& testCase ) const {
3262- return m_wildcardPattern.matches( toLower( testCase.name ) );
3263- }
3264- private:
3265- WildcardPattern m_wildcardPattern;
3266- };
3267-
3268- class TagPattern : public Pattern {
3269- public:
3270- TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
3271- virtual ~TagPattern();
3272- virtual bool matches( TestCaseInfo const& testCase ) const {
3273- return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end();
3274- }
3275- private:
3276- std::string m_tag;
3277- };
3278-
3279- class ExcludedPattern : public Pattern {
3280- public:
3281- ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
3282- virtual ~ExcludedPattern();
3283- virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
3284- private:
3285- Ptr<Pattern> m_underlyingPattern;
3286- };
3287-
3288- struct Filter {
3289- std::vector<Ptr<Pattern> > m_patterns;
3290-
3291- bool matches( TestCaseInfo const& testCase ) const {
3292- // All patterns in a filter must match for the filter to be a match
3293- for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it ) {
3294- if( !(*it)->matches( testCase ) )
3295- return false;
3296- }
3297- return true;
3298- }
3299- };
3300-
3301- public:
3302- bool hasFilters() const {
3303- return !m_filters.empty();
3304- }
3305- bool matches( TestCaseInfo const& testCase ) const {
3306- // A TestSpec matches if any filter matches
3307- for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it )
3308- if( it->matches( testCase ) )
3309- return true;
3310- return false;
3311- }
3312-
3313- private:
3314- std::vector<Filter> m_filters;
3315-
3316- friend class TestSpecParser;
3317- };
3318-}
3319-
3320-#ifdef __clang__
3321-#pragma clang diagnostic pop
3322-#endif
3323-
3324-namespace Catch {
3325-
3326- class TestSpecParser {
3327- enum Mode{ None, Name, QuotedName, Tag, EscapedName };
3328- Mode m_mode;
3329- bool m_exclusion;
3330- std::size_t m_start, m_pos;
3331- std::string m_arg;
3332- std::vector<std::size_t> m_escapeChars;
3333- TestSpec::Filter m_currentFilter;
3334- TestSpec m_testSpec;
3335- ITagAliasRegistry const* m_tagAliases;
3336-
3337- public:
3338- TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
3339-
3340- TestSpecParser& parse( std::string const& arg ) {
3341- m_mode = None;
3342- m_exclusion = false;
3343- m_start = std::string::npos;
3344- m_arg = m_tagAliases->expandAliases( arg );
3345- m_escapeChars.clear();
3346- for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
3347- visitChar( m_arg[m_pos] );
3348- if( m_mode == Name )
3349- addPattern<TestSpec::NamePattern>();
3350- return *this;
3351- }
3352- TestSpec testSpec() {
3353- addFilter();
3354- return m_testSpec;
3355- }
3356- private:
3357- void visitChar( char c ) {
3358- if( m_mode == None ) {
3359- switch( c ) {
3360- case ' ': return;
3361- case '~': m_exclusion = true; return;
3362- case '[': return startNewMode( Tag, ++m_pos );
3363- case '"': return startNewMode( QuotedName, ++m_pos );
3364- case '\\': return escape();
3365- default: startNewMode( Name, m_pos ); break;
3366- }
3367- }
3368- if( m_mode == Name ) {
3369- if( c == ',' ) {
3370- addPattern<TestSpec::NamePattern>();
3371- addFilter();
3372- }
3373- else if( c == '[' ) {
3374- if( subString() == "exclude:" )
3375- m_exclusion = true;
3376- else
3377- addPattern<TestSpec::NamePattern>();
3378- startNewMode( Tag, ++m_pos );
3379- }
3380- else if( c == '\\' )
3381- escape();
3382- }
3383- else if( m_mode == EscapedName )
3384- m_mode = Name;
3385- else if( m_mode == QuotedName && c == '"' )
3386- addPattern<TestSpec::NamePattern>();
3387- else if( m_mode == Tag && c == ']' )
3388- addPattern<TestSpec::TagPattern>();
3389- }
3390- void startNewMode( Mode mode, std::size_t start ) {
3391- m_mode = mode;
3392- m_start = start;
3393- }
3394- void escape() {
3395- m_mode = EscapedName;
3396- m_escapeChars.push_back( m_pos );
3397- }
3398- std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
3399- template<typename T>
3400- void addPattern() {
3401- std::string token = subString();
3402- for( size_t i = 0; i < m_escapeChars.size(); ++i )
3403- token = token.substr( 0, m_escapeChars[i] ) + token.substr( m_escapeChars[i]+1 );
3404- m_escapeChars.clear();
3405- if( startsWith( token, "exclude:" ) ) {
3406- m_exclusion = true;
3407- token = token.substr( 8 );
3408- }
3409- if( !token.empty() ) {
3410- Ptr<TestSpec::Pattern> pattern = new T( token );
3411- if( m_exclusion )
3412- pattern = new TestSpec::ExcludedPattern( pattern );
3413- m_currentFilter.m_patterns.push_back( pattern );
3414- }
3415- m_exclusion = false;
3416- m_mode = None;
3417- }
3418- void addFilter() {
3419- if( !m_currentFilter.m_patterns.empty() ) {
3420- m_testSpec.m_filters.push_back( m_currentFilter );
3421- m_currentFilter = TestSpec::Filter();
3422- }
3423- }
3424- };
3425- inline TestSpec parseTestSpec( std::string const& arg ) {
3426- return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
3427- }
3428-
3429-} // namespace Catch
3430-
3431-#ifdef __clang__
3432-#pragma clang diagnostic pop
3433-#endif
3434-
3435-// #included from: catch_interfaces_config.h
3436-#define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
3437-
3438-#include <iostream>
3439-#include <string>
3440-#include <vector>
3441-
3442-namespace Catch {
3443-
3444- struct Verbosity { enum Level {
3445- NoOutput = 0,
3446- Quiet,
3447- Normal
3448- }; };
3449-
3450- struct WarnAbout { enum What {
3451- Nothing = 0x00,
3452- NoAssertions = 0x01
3453- }; };
3454-
3455- struct ShowDurations { enum OrNot {
3456- DefaultForReporter,
3457- Always,
3458- Never
3459- }; };
3460- struct RunTests { enum InWhatOrder {
3461- InDeclarationOrder,
3462- InLexicographicalOrder,
3463- InRandomOrder
3464- }; };
3465- struct UseColour { enum YesOrNo {
3466- Auto,
3467- Yes,
3468- No
3469- }; };
3470-
3471- class TestSpec;
3472-
3473- struct IConfig : IShared {
3474-
3475- virtual ~IConfig();
3476-
3477- virtual bool allowThrows() const = 0;
3478- virtual std::ostream& stream() const = 0;
3479- virtual std::string name() const = 0;
3480- virtual bool includeSuccessfulResults() const = 0;
3481- virtual bool shouldDebugBreak() const = 0;
3482- virtual bool warnAboutMissingAssertions() const = 0;
3483- virtual int abortAfter() const = 0;
3484- virtual bool showInvisibles() const = 0;
3485- virtual ShowDurations::OrNot showDurations() const = 0;
3486- virtual TestSpec const& testSpec() const = 0;
3487- virtual RunTests::InWhatOrder runOrder() const = 0;
3488- virtual unsigned int rngSeed() const = 0;
3489- virtual UseColour::YesOrNo useColour() const = 0;
3490- };
3491-}
3492-
3493-// #included from: catch_stream.h
3494-#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
3495-
3496-// #included from: catch_streambuf.h
3497-#define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED
3498-
3499-#include <streambuf>
3500-
3501-namespace Catch {
3502-
3503- class StreamBufBase : public std::streambuf {
3504- public:
3505- virtual ~StreamBufBase() CATCH_NOEXCEPT;
3506- };
3507-}
3508-
3509-#include <streambuf>
3510-#include <ostream>
3511-#include <fstream>
3512-#include <memory>
3513-
3514-namespace Catch {
3515-
3516- std::ostream& cout();
3517- std::ostream& cerr();
3518-
3519- struct IStream {
3520- virtual ~IStream() CATCH_NOEXCEPT;
3521- virtual std::ostream& stream() const = 0;
3522- };
3523-
3524- class FileStream : public IStream {
3525- mutable std::ofstream m_ofs;
3526- public:
3527- FileStream( std::string const& filename );
3528- virtual ~FileStream() CATCH_NOEXCEPT;
3529- public: // IStream
3530- virtual std::ostream& stream() const CATCH_OVERRIDE;
3531- };
3532-
3533- class CoutStream : public IStream {
3534- mutable std::ostream m_os;
3535- public:
3536- CoutStream();
3537- virtual ~CoutStream() CATCH_NOEXCEPT;
3538-
3539- public: // IStream
3540- virtual std::ostream& stream() const CATCH_OVERRIDE;
3541- };
3542-
3543- class DebugOutStream : public IStream {
3544- CATCH_AUTO_PTR( StreamBufBase ) m_streamBuf;
3545- mutable std::ostream m_os;
3546- public:
3547- DebugOutStream();
3548- virtual ~DebugOutStream() CATCH_NOEXCEPT;
3549-
3550- public: // IStream
3551- virtual std::ostream& stream() const CATCH_OVERRIDE;
3552- };
3553-}
3554-
3555-#include <memory>
3556-#include <vector>
3557-#include <string>
3558-#include <iostream>
3559-#include <ctime>
3560-
3561-#ifndef CATCH_CONFIG_CONSOLE_WIDTH
3562-#define CATCH_CONFIG_CONSOLE_WIDTH 80
3563-#endif
3564-
3565-namespace Catch {
3566-
3567- struct ConfigData {
3568-
3569- ConfigData()
3570- : listTests( false ),
3571- listTags( false ),
3572- listReporters( false ),
3573- listTestNamesOnly( false ),
3574- showSuccessfulTests( false ),
3575- shouldDebugBreak( false ),
3576- noThrow( false ),
3577- showHelp( false ),
3578- showInvisibles( false ),
3579- filenamesAsTags( false ),
3580- abortAfter( -1 ),
3581- rngSeed( 0 ),
3582- verbosity( Verbosity::Normal ),
3583- warnings( WarnAbout::Nothing ),
3584- showDurations( ShowDurations::DefaultForReporter ),
3585- runOrder( RunTests::InDeclarationOrder ),
3586- useColour( UseColour::Auto )
3587- {}
3588-
3589- bool listTests;
3590- bool listTags;
3591- bool listReporters;
3592- bool listTestNamesOnly;
3593-
3594- bool showSuccessfulTests;
3595- bool shouldDebugBreak;
3596- bool noThrow;
3597- bool showHelp;
3598- bool showInvisibles;
3599- bool filenamesAsTags;
3600-
3601- int abortAfter;
3602- unsigned int rngSeed;
3603-
3604- Verbosity::Level verbosity;
3605- WarnAbout::What warnings;
3606- ShowDurations::OrNot showDurations;
3607- RunTests::InWhatOrder runOrder;
3608- UseColour::YesOrNo useColour;
3609-
3610- std::string outputFilename;
3611- std::string name;
3612- std::string processName;
3613-
3614- std::vector<std::string> reporterNames;
3615- std::vector<std::string> testsOrTags;
3616- };
3617-
3618- class Config : public SharedImpl<IConfig> {
3619- private:
3620- Config( Config const& other );
3621- Config& operator = ( Config const& other );
3622- virtual void dummy();
3623- public:
3624-
3625- Config()
3626- {}
3627-
3628- Config( ConfigData const& data )
3629- : m_data( data ),
3630- m_stream( openStream() )
3631- {
3632- if( !data.testsOrTags.empty() ) {
3633- TestSpecParser parser( ITagAliasRegistry::get() );
3634- for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )
3635- parser.parse( data.testsOrTags[i] );
3636- m_testSpec = parser.testSpec();
3637- }
3638- }
3639-
3640- virtual ~Config() {
3641- }
3642-
3643- std::string const& getFilename() const {
3644- return m_data.outputFilename ;
3645- }
3646-
3647- bool listTests() const { return m_data.listTests; }
3648- bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }
3649- bool listTags() const { return m_data.listTags; }
3650- bool listReporters() const { return m_data.listReporters; }
3651-
3652- std::string getProcessName() const { return m_data.processName; }
3653-
3654- bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }
3655-
3656- std::vector<std::string> getReporterNames() const { return m_data.reporterNames; }
3657-
3658- int abortAfter() const { return m_data.abortAfter; }
3659-
3660- TestSpec const& testSpec() const { return m_testSpec; }
3661-
3662- bool showHelp() const { return m_data.showHelp; }
3663- bool showInvisibles() const { return m_data.showInvisibles; }
3664-
3665- // IConfig interface
3666- virtual bool allowThrows() const { return !m_data.noThrow; }
3667- virtual std::ostream& stream() const { return m_stream->stream(); }
3668- virtual std::string name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
3669- virtual bool includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
3670- virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
3671- virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }
3672- virtual RunTests::InWhatOrder runOrder() const { return m_data.runOrder; }
3673- virtual unsigned int rngSeed() const { return m_data.rngSeed; }
3674- virtual UseColour::YesOrNo useColour() const { return m_data.useColour; }
3675-
3676- private:
3677-
3678- IStream const* openStream() {
3679- if( m_data.outputFilename.empty() )
3680- return new CoutStream();
3681- else if( m_data.outputFilename[0] == '%' ) {
3682- if( m_data.outputFilename == "%debug" )
3683- return new DebugOutStream();
3684- else
3685- throw std::domain_error( "Unrecognised stream: " + m_data.outputFilename );
3686- }
3687- else
3688- return new FileStream( m_data.outputFilename );
3689- }
3690- ConfigData m_data;
3691-
3692- CATCH_AUTO_PTR( IStream const ) m_stream;
3693- TestSpec m_testSpec;
3694- };
3695-
3696-} // end namespace Catch
3697-
3698-// #included from: catch_clara.h
3699-#define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED
3700-
3701-// Use Catch's value for console width (store Clara's off to the side, if present)
3702-#ifdef CLARA_CONFIG_CONSOLE_WIDTH
3703-#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH
3704-#undef CLARA_CONFIG_CONSOLE_WIDTH
3705-#endif
3706-#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
3707-
3708-// Declare Clara inside the Catch namespace
3709-#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {
3710-// #included from: ../external/clara.h
3711-
3712-// Version 0.0.2.4
3713-
3714-// Only use header guard if we are not using an outer namespace
3715-#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
3716-
3717-#ifndef STITCH_CLARA_OPEN_NAMESPACE
3718-#define TWOBLUECUBES_CLARA_H_INCLUDED
3719-#define STITCH_CLARA_OPEN_NAMESPACE
3720-#define STITCH_CLARA_CLOSE_NAMESPACE
3721-#else
3722-#define STITCH_CLARA_CLOSE_NAMESPACE }
3723-#endif
3724-
3725-#define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE
3726-
3727-// ----------- #included from tbc_text_format.h -----------
3728-
3729-// Only use header guard if we are not using an outer namespace
3730-#if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE)
3731-#ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
3732-#define TBC_TEXT_FORMAT_H_INCLUDED
3733-#endif
3734-
3735-#include <string>
3736-#include <vector>
3737-#include <sstream>
3738-#include <algorithm>
3739-
3740-// Use optional outer namespace
3741-#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
3742-namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
3743-#endif
3744-
3745-namespace Tbc {
3746-
3747-#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
3748- const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
3749-#else
3750- const unsigned int consoleWidth = 80;
3751-#endif
3752-
3753- struct TextAttributes {
3754- TextAttributes()
3755- : initialIndent( std::string::npos ),
3756- indent( 0 ),
3757- width( consoleWidth-1 ),
3758- tabChar( '\t' )
3759- {}
3760-
3761- TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
3762- TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
3763- TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
3764- TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; }
3765-
3766- std::size_t initialIndent; // indent of first line, or npos
3767- std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos
3768- std::size_t width; // maximum width of text, including indent. Longer text will wrap
3769- char tabChar; // If this char is seen the indent is changed to current pos
3770- };
3771-
3772- class Text {
3773- public:
3774- Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
3775- : attr( _attr )
3776- {
3777- std::string wrappableChars = " [({.,/|\\-";
3778- std::size_t indent = _attr.initialIndent != std::string::npos
3779- ? _attr.initialIndent
3780- : _attr.indent;
3781- std::string remainder = _str;
3782-
3783- while( !remainder.empty() ) {
3784- if( lines.size() >= 1000 ) {
3785- lines.push_back( "... message truncated due to excessive size" );
3786- return;
3787- }
3788- std::size_t tabPos = std::string::npos;
3789- std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
3790- std::size_t pos = remainder.find_first_of( '\n' );
3791- if( pos <= width ) {
3792- width = pos;
3793- }
3794- pos = remainder.find_last_of( _attr.tabChar, width );
3795- if( pos != std::string::npos ) {
3796- tabPos = pos;
3797- if( remainder[width] == '\n' )
3798- width--;
3799- remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
3800- }
3801-
3802- if( width == remainder.size() ) {
3803- spliceLine( indent, remainder, width );
3804- }
3805- else if( remainder[width] == '\n' ) {
3806- spliceLine( indent, remainder, width );
3807- if( width <= 1 || remainder.size() != 1 )
3808- remainder = remainder.substr( 1 );
3809- indent = _attr.indent;
3810- }
3811- else {
3812- pos = remainder.find_last_of( wrappableChars, width );
3813- if( pos != std::string::npos && pos > 0 ) {
3814- spliceLine( indent, remainder, pos );
3815- if( remainder[0] == ' ' )
3816- remainder = remainder.substr( 1 );
3817- }
3818- else {
3819- spliceLine( indent, remainder, width-1 );
3820- lines.back() += "-";
3821- }
3822- if( lines.size() == 1 )
3823- indent = _attr.indent;
3824- if( tabPos != std::string::npos )
3825- indent += tabPos;
3826- }
3827- }
3828- }
3829-
3830- void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
3831- lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
3832- _remainder = _remainder.substr( _pos );
3833- }
3834-
3835- typedef std::vector<std::string>::const_iterator const_iterator;
3836-
3837- const_iterator begin() const { return lines.begin(); }
3838- const_iterator end() const { return lines.end(); }
3839- std::string const& last() const { return lines.back(); }
3840- std::size_t size() const { return lines.size(); }
3841- std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
3842- std::string toString() const {
3843- std::ostringstream oss;
3844- oss << *this;
3845- return oss.str();
3846- }
3847-
3848- inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
3849- for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
3850- it != itEnd; ++it ) {
3851- if( it != _text.begin() )
3852- _stream << "\n";
3853- _stream << *it;
3854- }
3855- return _stream;
3856- }
3857-
3858- private:
3859- std::string str;
3860- TextAttributes attr;
3861- std::vector<std::string> lines;
3862- };
3863-
3864-} // end namespace Tbc
3865-
3866-#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
3867-} // end outer namespace
3868-#endif
3869-
3870-#endif // TBC_TEXT_FORMAT_H_INCLUDED
3871-
3872-// ----------- end of #include from tbc_text_format.h -----------
3873-// ........... back in clara.h
3874-
3875-#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE
3876-
3877-// ----------- #included from clara_compilers.h -----------
3878-
3879-#ifndef TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
3880-#define TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
3881-
3882-// Detect a number of compiler features - mostly C++11/14 conformance - by compiler
3883-// The following features are defined:
3884-//
3885-// CLARA_CONFIG_CPP11_NULLPTR : is nullptr supported?
3886-// CLARA_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
3887-// CLARA_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
3888-// CLARA_CONFIG_CPP11_OVERRIDE : is override supported?
3889-// CLARA_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
3890-
3891-// CLARA_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
3892-
3893-// CLARA_CONFIG_VARIADIC_MACROS : are variadic macros supported?
3894-
3895-// In general each macro has a _NO_<feature name> form
3896-// (e.g. CLARA_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
3897-// Many features, at point of detection, define an _INTERNAL_ macro, so they
3898-// can be combined, en-mass, with the _NO_ forms later.
3899-
3900-// All the C++11 features can be disabled with CLARA_CONFIG_NO_CPP11
3901-
3902-#ifdef __clang__
3903-
3904-#if __has_feature(cxx_nullptr)
3905-#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
3906-#endif
3907-
3908-#if __has_feature(cxx_noexcept)
3909-#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
3910-#endif
3911-
3912-#endif // __clang__
3913-
3914-////////////////////////////////////////////////////////////////////////////////
3915-// GCC
3916-#ifdef __GNUC__
3917-
3918-#if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
3919-#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
3920-#endif
3921-
3922-// - otherwise more recent versions define __cplusplus >= 201103L
3923-// and will get picked up below
3924-
3925-#endif // __GNUC__
3926-
3927-////////////////////////////////////////////////////////////////////////////////
3928-// Visual C++
3929-#ifdef _MSC_VER
3930-
3931-#if (_MSC_VER >= 1600)
3932-#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
3933-#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
3934-#endif
3935-
3936-#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
3937-#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
3938-#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
3939-#endif
3940-
3941-#endif // _MSC_VER
3942-
3943-////////////////////////////////////////////////////////////////////////////////
3944-// C++ language feature support
3945-
3946-// catch all support for C++11
3947-#if defined(__cplusplus) && __cplusplus >= 201103L
3948-
3949-#define CLARA_CPP11_OR_GREATER
3950-
3951-#if !defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR)
3952-#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
3953-#endif
3954-
3955-#ifndef CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
3956-#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
3957-#endif
3958-
3959-#ifndef CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
3960-#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
3961-#endif
3962-
3963-#if !defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE)
3964-#define CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE
3965-#endif
3966-#if !defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
3967-#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
3968-#endif
3969-
3970-#endif // __cplusplus >= 201103L
3971-
3972-// Now set the actual defines based on the above + anything the user has configured
3973-#if defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NO_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_NO_CPP11)
3974-#define CLARA_CONFIG_CPP11_NULLPTR
3975-#endif
3976-#if defined(CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_NO_CPP11)
3977-#define CLARA_CONFIG_CPP11_NOEXCEPT
3978-#endif
3979-#if defined(CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_NO_CPP11)
3980-#define CLARA_CONFIG_CPP11_GENERATED_METHODS
3981-#endif
3982-#if defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_OVERRIDE) && !defined(CLARA_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_CPP11)
3983-#define CLARA_CONFIG_CPP11_OVERRIDE
3984-#endif
3985-#if defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_UNIQUE_PTR) && !defined(CLARA_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_CPP11)
3986-#define CLARA_CONFIG_CPP11_UNIQUE_PTR
3987-#endif
3988-
3989-// noexcept support:
3990-#if defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_NOEXCEPT)
3991-#define CLARA_NOEXCEPT noexcept
3992-# define CLARA_NOEXCEPT_IS(x) noexcept(x)
3993-#else
3994-#define CLARA_NOEXCEPT throw()
3995-# define CLARA_NOEXCEPT_IS(x)
3996-#endif
3997-
3998-// nullptr support
3999-#ifdef CLARA_CONFIG_CPP11_NULLPTR
4000-#define CLARA_NULL nullptr
4001-#else
4002-#define CLARA_NULL NULL
4003-#endif
4004-
4005-// override support
4006-#ifdef CLARA_CONFIG_CPP11_OVERRIDE
4007-#define CLARA_OVERRIDE override
4008-#else
4009-#define CLARA_OVERRIDE
4010-#endif
4011-
4012-// unique_ptr support
4013-#ifdef CLARA_CONFIG_CPP11_UNIQUE_PTR
4014-# define CLARA_AUTO_PTR( T ) std::unique_ptr<T>
4015-#else
4016-# define CLARA_AUTO_PTR( T ) std::auto_ptr<T>
4017-#endif
4018-
4019-#endif // TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
4020-
4021-// ----------- end of #include from clara_compilers.h -----------
4022-// ........... back in clara.h
4023-
4024-#include <map>
4025-#include <stdexcept>
4026-#include <memory>
4027-
4028-#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
4029-#define CLARA_PLATFORM_WINDOWS
4030-#endif
4031-
4032-// Use optional outer namespace
4033-#ifdef STITCH_CLARA_OPEN_NAMESPACE
4034-STITCH_CLARA_OPEN_NAMESPACE
4035-#endif
4036-
4037-namespace Clara {
4038-
4039- struct UnpositionalTag {};
4040-
4041- extern UnpositionalTag _;
4042-
4043-#ifdef CLARA_CONFIG_MAIN
4044- UnpositionalTag _;
4045-#endif
4046-
4047- namespace Detail {
4048-
4049-#ifdef CLARA_CONSOLE_WIDTH
4050- const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
4051-#else
4052- const unsigned int consoleWidth = 80;
4053-#endif
4054-
4055- using namespace Tbc;
4056-
4057- inline bool startsWith( std::string const& str, std::string const& prefix ) {
4058- return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;
4059- }
4060-
4061- template<typename T> struct RemoveConstRef{ typedef T type; };
4062- template<typename T> struct RemoveConstRef<T&>{ typedef T type; };
4063- template<typename T> struct RemoveConstRef<T const&>{ typedef T type; };
4064- template<typename T> struct RemoveConstRef<T const>{ typedef T type; };
4065-
4066- template<typename T> struct IsBool { static const bool value = false; };
4067- template<> struct IsBool<bool> { static const bool value = true; };
4068-
4069- template<typename T>
4070- void convertInto( std::string const& _source, T& _dest ) {
4071- std::stringstream ss;
4072- ss << _source;
4073- ss >> _dest;
4074- if( ss.fail() )
4075- throw std::runtime_error( "Unable to convert " + _source + " to destination type" );
4076- }
4077- inline void convertInto( std::string const& _source, std::string& _dest ) {
4078- _dest = _source;
4079- }
4080- char toLowerCh(char c) {
4081- return static_cast<char>( ::tolower( c ) );
4082- }
4083- inline void convertInto( std::string const& _source, bool& _dest ) {
4084- std::string sourceLC = _source;
4085- std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), toLowerCh );
4086- if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" )
4087- _dest = true;
4088- else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" )
4089- _dest = false;
4090- else
4091- throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" );
4092- }
4093-
4094- template<typename ConfigT>
4095- struct IArgFunction {
4096- virtual ~IArgFunction() {}
4097-#ifdef CLARA_CONFIG_CPP11_GENERATED_METHODS
4098- IArgFunction() = default;
4099- IArgFunction( IArgFunction const& ) = default;
4100-#endif
4101- virtual void set( ConfigT& config, std::string const& value ) const = 0;
4102- virtual bool takesArg() const = 0;
4103- virtual IArgFunction* clone() const = 0;
4104- };
4105-
4106- template<typename ConfigT>
4107- class BoundArgFunction {
4108- public:
4109- BoundArgFunction() : functionObj( CLARA_NULL ) {}
4110- BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
4111- BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CLARA_NULL ) {}
4112- BoundArgFunction& operator = ( BoundArgFunction const& other ) {
4113- IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : CLARA_NULL;
4114- delete functionObj;
4115- functionObj = newFunctionObj;
4116- return *this;
4117- }
4118- ~BoundArgFunction() { delete functionObj; }
4119-
4120- void set( ConfigT& config, std::string const& value ) const {
4121- functionObj->set( config, value );
4122- }
4123- bool takesArg() const { return functionObj->takesArg(); }
4124-
4125- bool isSet() const {
4126- return functionObj != CLARA_NULL;
4127- }
4128- private:
4129- IArgFunction<ConfigT>* functionObj;
4130- };
4131-
4132- template<typename C>
4133- struct NullBinder : IArgFunction<C>{
4134- virtual void set( C&, std::string const& ) const {}
4135- virtual bool takesArg() const { return true; }
4136- virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }
4137- };
4138-
4139- template<typename C, typename M>
4140- struct BoundDataMember : IArgFunction<C>{
4141- BoundDataMember( M C::* _member ) : member( _member ) {}
4142- virtual void set( C& p, std::string const& stringValue ) const {
4143- convertInto( stringValue, p.*member );
4144- }
4145- virtual bool takesArg() const { return !IsBool<M>::value; }
4146- virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }
4147- M C::* member;
4148- };
4149- template<typename C, typename M>
4150- struct BoundUnaryMethod : IArgFunction<C>{
4151- BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {}
4152- virtual void set( C& p, std::string const& stringValue ) const {
4153- typename RemoveConstRef<M>::type value;
4154- convertInto( stringValue, value );
4155- (p.*member)( value );
4156- }
4157- virtual bool takesArg() const { return !IsBool<M>::value; }
4158- virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }
4159- void (C::*member)( M );
4160- };
4161- template<typename C>
4162- struct BoundNullaryMethod : IArgFunction<C>{
4163- BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {}
4164- virtual void set( C& p, std::string const& stringValue ) const {
4165- bool value;
4166- convertInto( stringValue, value );
4167- if( value )
4168- (p.*member)();
4169- }
4170- virtual bool takesArg() const { return false; }
4171- virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }
4172- void (C::*member)();
4173- };
4174-
4175- template<typename C>
4176- struct BoundUnaryFunction : IArgFunction<C>{
4177- BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {}
4178- virtual void set( C& obj, std::string const& stringValue ) const {
4179- bool value;
4180- convertInto( stringValue, value );
4181- if( value )
4182- function( obj );
4183- }
4184- virtual bool takesArg() const { return false; }
4185- virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }
4186- void (*function)( C& );
4187- };
4188-
4189- template<typename C, typename T>
4190- struct BoundBinaryFunction : IArgFunction<C>{
4191- BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {}
4192- virtual void set( C& obj, std::string const& stringValue ) const {
4193- typename RemoveConstRef<T>::type value;
4194- convertInto( stringValue, value );
4195- function( obj, value );
4196- }
4197- virtual bool takesArg() const { return !IsBool<T>::value; }
4198- virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }
4199- void (*function)( C&, T );
4200- };
4201-
4202- } // namespace Detail
4203-
4204- inline std::vector<std::string> argsToVector( int argc, char const* const* const argv ) {
4205- std::vector<std::string> args( static_cast<std::size_t>( argc ) );
4206- for( std::size_t i = 0; i < static_cast<std::size_t>( argc ); ++i )
4207- args[i] = argv[i];
4208-
4209- return args;
4210- }
4211-
4212- class Parser {
4213- enum Mode { None, MaybeShortOpt, SlashOpt, ShortOpt, LongOpt, Positional };
4214- Mode mode;
4215- std::size_t from;
4216- bool inQuotes;
4217- public:
4218-
4219- struct Token {
4220- enum Type { Positional, ShortOpt, LongOpt };
4221- Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {}
4222- Type type;
4223- std::string data;
4224- };
4225-
4226- Parser() : mode( None ), from( 0 ), inQuotes( false ){}
4227-
4228- void parseIntoTokens( std::vector<std::string> const& args, std::vector<Token>& tokens ) {
4229- const std::string doubleDash = "--";
4230- for( std::size_t i = 1; i < args.size() && args[i] != doubleDash; ++i )
4231- parseIntoTokens( args[i], tokens);
4232- }
4233-
4234- void parseIntoTokens( std::string const& arg, std::vector<Token>& tokens ) {
4235- for( std::size_t i = 0; i <= arg.size(); ++i ) {
4236- char c = arg[i];
4237- if( c == '"' )
4238- inQuotes = !inQuotes;
4239- mode = handleMode( i, c, arg, tokens );
4240- }
4241- }
4242- Mode handleMode( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
4243- switch( mode ) {
4244- case None: return handleNone( i, c );
4245- case MaybeShortOpt: return handleMaybeShortOpt( i, c );
4246- case ShortOpt:
4247- case LongOpt:
4248- case SlashOpt: return handleOpt( i, c, arg, tokens );
4249- case Positional: return handlePositional( i, c, arg, tokens );
4250- default: throw std::logic_error( "Unknown mode" );
4251- }
4252- }
4253-
4254- Mode handleNone( std::size_t i, char c ) {
4255- if( inQuotes ) {
4256- from = i;
4257- return Positional;
4258- }
4259- switch( c ) {
4260- case '-': return MaybeShortOpt;
4261-#ifdef CLARA_PLATFORM_WINDOWS
4262- case '/': from = i+1; return SlashOpt;
4263-#endif
4264- default: from = i; return Positional;
4265- }
4266- }
4267- Mode handleMaybeShortOpt( std::size_t i, char c ) {
4268- switch( c ) {
4269- case '-': from = i+1; return LongOpt;
4270- default: from = i; return ShortOpt;
4271- }
4272- }
4273- Mode handleOpt( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
4274- if( std::string( ":=\0", 3 ).find( c ) == std::string::npos )
4275- return mode;
4276-
4277- std::string optName = arg.substr( from, i-from );
4278- if( mode == ShortOpt )
4279- for( std::size_t j = 0; j < optName.size(); ++j )
4280- tokens.push_back( Token( Token::ShortOpt, optName.substr( j, 1 ) ) );
4281- else if( mode == SlashOpt && optName.size() == 1 )
4282- tokens.push_back( Token( Token::ShortOpt, optName ) );
4283- else
4284- tokens.push_back( Token( Token::LongOpt, optName ) );
4285- return None;
4286- }
4287- Mode handlePositional( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
4288- if( inQuotes || std::string( "\0", 1 ).find( c ) == std::string::npos )
4289- return mode;
4290-
4291- std::string data = arg.substr( from, i-from );
4292- tokens.push_back( Token( Token::Positional, data ) );
4293- return None;
4294- }
4295- };
4296-
4297- template<typename ConfigT>
4298- struct CommonArgProperties {
4299- CommonArgProperties() {}
4300- CommonArgProperties( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ) {}
4301-
4302- Detail::BoundArgFunction<ConfigT> boundField;
4303- std::string description;
4304- std::string detail;
4305- std::string placeholder; // Only value if boundField takes an arg
4306-
4307- bool takesArg() const {
4308- return !placeholder.empty();
4309- }
4310- void validate() const {
4311- if( !boundField.isSet() )
4312- throw std::logic_error( "option not bound" );
4313- }
4314- };
4315- struct OptionArgProperties {
4316- std::vector<std::string> shortNames;
4317- std::string longName;
4318-
4319- bool hasShortName( std::string const& shortName ) const {
4320- return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end();
4321- }
4322- bool hasLongName( std::string const& _longName ) const {
4323- return _longName == longName;
4324- }
4325- };
4326- struct PositionalArgProperties {
4327- PositionalArgProperties() : position( -1 ) {}
4328- int position; // -1 means non-positional (floating)
4329-
4330- bool isFixedPositional() const {
4331- return position != -1;
4332- }
4333- };
4334-
4335- template<typename ConfigT>
4336- class CommandLine {
4337-
4338- struct Arg : CommonArgProperties<ConfigT>, OptionArgProperties, PositionalArgProperties {
4339- Arg() {}
4340- Arg( Detail::BoundArgFunction<ConfigT> const& _boundField ) : CommonArgProperties<ConfigT>( _boundField ) {}
4341-
4342- using CommonArgProperties<ConfigT>::placeholder; // !TBD
4343-
4344- std::string dbgName() const {
4345- if( !longName.empty() )
4346- return "--" + longName;
4347- if( !shortNames.empty() )
4348- return "-" + shortNames[0];
4349- return "positional args";
4350- }
4351- std::string commands() const {
4352- std::ostringstream oss;
4353- bool first = true;
4354- std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();
4355- for(; it != itEnd; ++it ) {
4356- if( first )
4357- first = false;
4358- else
4359- oss << ", ";
4360- oss << "-" << *it;
4361- }
4362- if( !longName.empty() ) {
4363- if( !first )
4364- oss << ", ";
4365- oss << "--" << longName;
4366- }
4367- if( !placeholder.empty() )
4368- oss << " <" << placeholder << ">";
4369- return oss.str();
4370- }
4371- };
4372-
4373- typedef CLARA_AUTO_PTR( Arg ) ArgAutoPtr;
4374-
4375- friend void addOptName( Arg& arg, std::string const& optName )
4376- {
4377- if( optName.empty() )
4378- return;
4379- if( Detail::startsWith( optName, "--" ) ) {
4380- if( !arg.longName.empty() )
4381- throw std::logic_error( "Only one long opt may be specified. '"
4382- + arg.longName
4383- + "' already specified, now attempting to add '"
4384- + optName + "'" );
4385- arg.longName = optName.substr( 2 );
4386- }
4387- else if( Detail::startsWith( optName, "-" ) )
4388- arg.shortNames.push_back( optName.substr( 1 ) );
4389- else
4390- throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" );
4391- }
4392- friend void setPositionalArg( Arg& arg, int position )
4393- {
4394- arg.position = position;
4395- }
4396-
4397- class ArgBuilder {
4398- public:
4399- ArgBuilder( Arg* arg ) : m_arg( arg ) {}
4400-
4401- // Bind a non-boolean data member (requires placeholder string)
4402- template<typename C, typename M>
4403- void bind( M C::* field, std::string const& placeholder ) {
4404- m_arg->boundField = new Detail::BoundDataMember<C,M>( field );
4405- m_arg->placeholder = placeholder;
4406- }
4407- // Bind a boolean data member (no placeholder required)
4408- template<typename C>
4409- void bind( bool C::* field ) {
4410- m_arg->boundField = new Detail::BoundDataMember<C,bool>( field );
4411- }
4412-
4413- // Bind a method taking a single, non-boolean argument (requires a placeholder string)
4414- template<typename C, typename M>
4415- void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) {
4416- m_arg->boundField = new Detail::BoundUnaryMethod<C,M>( unaryMethod );
4417- m_arg->placeholder = placeholder;
4418- }
4419-
4420- // Bind a method taking a single, boolean argument (no placeholder string required)
4421- template<typename C>
4422- void bind( void (C::* unaryMethod)( bool ) ) {
4423- m_arg->boundField = new Detail::BoundUnaryMethod<C,bool>( unaryMethod );
4424- }
4425-
4426- // Bind a method that takes no arguments (will be called if opt is present)
4427- template<typename C>
4428- void bind( void (C::* nullaryMethod)() ) {
4429- m_arg->boundField = new Detail::BoundNullaryMethod<C>( nullaryMethod );
4430- }
4431-
4432- // Bind a free function taking a single argument - the object to operate on (no placeholder string required)
4433- template<typename C>
4434- void bind( void (* unaryFunction)( C& ) ) {
4435- m_arg->boundField = new Detail::BoundUnaryFunction<C>( unaryFunction );
4436- }
4437-
4438- // Bind a free function taking a single argument - the object to operate on (requires a placeholder string)
4439- template<typename C, typename T>
4440- void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) {
4441- m_arg->boundField = new Detail::BoundBinaryFunction<C, T>( binaryFunction );
4442- m_arg->placeholder = placeholder;
4443- }
4444-
4445- ArgBuilder& describe( std::string const& description ) {
4446- m_arg->description = description;
4447- return *this;
4448- }
4449- ArgBuilder& detail( std::string const& detail ) {
4450- m_arg->detail = detail;
4451- return *this;
4452- }
4453-
4454- protected:
4455- Arg* m_arg;
4456- };
4457-
4458- class OptBuilder : public ArgBuilder {
4459- public:
4460- OptBuilder( Arg* arg ) : ArgBuilder( arg ) {}
4461- OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {}
4462-
4463- OptBuilder& operator[]( std::string const& optName ) {
4464- addOptName( *ArgBuilder::m_arg, optName );
4465- return *this;
4466- }
4467- };
4468-
4469- public:
4470-
4471- CommandLine()
4472- : m_boundProcessName( new Detail::NullBinder<ConfigT>() ),
4473- m_highestSpecifiedArgPosition( 0 ),
4474- m_throwOnUnrecognisedTokens( false )
4475- {}
4476- CommandLine( CommandLine const& other )
4477- : m_boundProcessName( other.m_boundProcessName ),
4478- m_options ( other.m_options ),
4479- m_positionalArgs( other.m_positionalArgs ),
4480- m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ),
4481- m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens )
4482- {
4483- if( other.m_floatingArg.get() )
4484- m_floatingArg.reset( new Arg( *other.m_floatingArg ) );
4485- }
4486-
4487- CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) {
4488- m_throwOnUnrecognisedTokens = shouldThrow;
4489- return *this;
4490- }
4491-
4492- OptBuilder operator[]( std::string const& optName ) {
4493- m_options.push_back( Arg() );
4494- addOptName( m_options.back(), optName );
4495- OptBuilder builder( &m_options.back() );
4496- return builder;
4497- }
4498-
4499- ArgBuilder operator[]( int position ) {
4500- m_positionalArgs.insert( std::make_pair( position, Arg() ) );
4501- if( position > m_highestSpecifiedArgPosition )
4502- m_highestSpecifiedArgPosition = position;
4503- setPositionalArg( m_positionalArgs[position], position );
4504- ArgBuilder builder( &m_positionalArgs[position] );
4505- return builder;
4506- }
4507-
4508- // Invoke this with the _ instance
4509- ArgBuilder operator[]( UnpositionalTag ) {
4510- if( m_floatingArg.get() )
4511- throw std::logic_error( "Only one unpositional argument can be added" );
4512- m_floatingArg.reset( new Arg() );
4513- ArgBuilder builder( m_floatingArg.get() );
4514- return builder;
4515- }
4516-
4517- template<typename C, typename M>
4518- void bindProcessName( M C::* field ) {
4519- m_boundProcessName = new Detail::BoundDataMember<C,M>( field );
4520- }
4521- template<typename C, typename M>
4522- void bindProcessName( void (C::*_unaryMethod)( M ) ) {
4523- m_boundProcessName = new Detail::BoundUnaryMethod<C,M>( _unaryMethod );
4524- }
4525-
4526- void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const {
4527- typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;
4528- std::size_t maxWidth = 0;
4529- for( it = itBegin; it != itEnd; ++it )
4530- maxWidth = (std::max)( maxWidth, it->commands().size() );
4531-
4532- for( it = itBegin; it != itEnd; ++it ) {
4533- Detail::Text usage( it->commands(), Detail::TextAttributes()
4534- .setWidth( maxWidth+indent )
4535- .setIndent( indent ) );
4536- Detail::Text desc( it->description, Detail::TextAttributes()
4537- .setWidth( width - maxWidth - 3 ) );
4538-
4539- for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) {
4540- std::string usageCol = i < usage.size() ? usage[i] : "";
4541- os << usageCol;
4542-
4543- if( i < desc.size() && !desc[i].empty() )
4544- os << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' )
4545- << desc[i];
4546- os << "\n";
4547- }
4548- }
4549- }
4550- std::string optUsage() const {
4551- std::ostringstream oss;
4552- optUsage( oss );
4553- return oss.str();
4554- }
4555-
4556- void argSynopsis( std::ostream& os ) const {
4557- for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {
4558- if( i > 1 )
4559- os << " ";
4560- typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
4561- if( it != m_positionalArgs.end() )
4562- os << "<" << it->second.placeholder << ">";
4563- else if( m_floatingArg.get() )
4564- os << "<" << m_floatingArg->placeholder << ">";
4565- else
4566- throw std::logic_error( "non consecutive positional arguments with no floating args" );
4567- }
4568- // !TBD No indication of mandatory args
4569- if( m_floatingArg.get() ) {
4570- if( m_highestSpecifiedArgPosition > 1 )
4571- os << " ";
4572- os << "[<" << m_floatingArg->placeholder << "> ...]";
4573- }
4574- }
4575- std::string argSynopsis() const {
4576- std::ostringstream oss;
4577- argSynopsis( oss );
4578- return oss.str();
4579- }
4580-
4581- void usage( std::ostream& os, std::string const& procName ) const {
4582- validate();
4583- os << "usage:\n " << procName << " ";
4584- argSynopsis( os );
4585- if( !m_options.empty() ) {
4586- os << " [options]\n\nwhere options are: \n";
4587- optUsage( os, 2 );
4588- }
4589- os << "\n";
4590- }
4591- std::string usage( std::string const& procName ) const {
4592- std::ostringstream oss;
4593- usage( oss, procName );
4594- return oss.str();
4595- }
4596-
4597- ConfigT parse( std::vector<std::string> const& args ) const {
4598- ConfigT config;
4599- parseInto( args, config );
4600- return config;
4601- }
4602-
4603- std::vector<Parser::Token> parseInto( std::vector<std::string> const& args, ConfigT& config ) const {
4604- std::string processName = args[0];
4605- std::size_t lastSlash = processName.find_last_of( "/\\" );
4606- if( lastSlash != std::string::npos )
4607- processName = processName.substr( lastSlash+1 );
4608- m_boundProcessName.set( config, processName );
4609- std::vector<Parser::Token> tokens;
4610- Parser parser;
4611- parser.parseIntoTokens( args, tokens );
4612- return populate( tokens, config );
4613- }
4614-
4615- std::vector<Parser::Token> populate( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
4616- validate();
4617- std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config );
4618- unusedTokens = populateFixedArgs( unusedTokens, config );
4619- unusedTokens = populateFloatingArgs( unusedTokens, config );
4620- return unusedTokens;
4621- }
4622-
4623- std::vector<Parser::Token> populateOptions( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
4624- std::vector<Parser::Token> unusedTokens;
4625- std::vector<std::string> errors;
4626- for( std::size_t i = 0; i < tokens.size(); ++i ) {
4627- Parser::Token const& token = tokens[i];
4628- typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();
4629- for(; it != itEnd; ++it ) {
4630- Arg const& arg = *it;
4631-
4632- try {
4633- if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||
4634- ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {
4635- if( arg.takesArg() ) {
4636- if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional )
4637- errors.push_back( "Expected argument to option: " + token.data );
4638- else
4639- arg.boundField.set( config, tokens[++i].data );
4640- }
4641- else {
4642- arg.boundField.set( config, "true" );
4643- }
4644- break;
4645- }
4646- }
4647- catch( std::exception& ex ) {
4648- errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" );
4649- }
4650- }
4651- if( it == itEnd ) {
4652- if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens )
4653- unusedTokens.push_back( token );
4654- else if( errors.empty() && m_throwOnUnrecognisedTokens )
4655- errors.push_back( "unrecognised option: " + token.data );
4656- }
4657- }
4658- if( !errors.empty() ) {
4659- std::ostringstream oss;
4660- for( std::vector<std::string>::const_iterator it = errors.begin(), itEnd = errors.end();
4661- it != itEnd;
4662- ++it ) {
4663- if( it != errors.begin() )
4664- oss << "\n";
4665- oss << *it;
4666- }
4667- throw std::runtime_error( oss.str() );
4668- }
4669- return unusedTokens;
4670- }
4671- std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
4672- std::vector<Parser::Token> unusedTokens;
4673- int position = 1;
4674- for( std::size_t i = 0; i < tokens.size(); ++i ) {
4675- Parser::Token const& token = tokens[i];
4676- typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );
4677- if( it != m_positionalArgs.end() )
4678- it->second.boundField.set( config, token.data );
4679- else
4680- unusedTokens.push_back( token );
4681- if( token.type == Parser::Token::Positional )
4682- position++;
4683- }
4684- return unusedTokens;
4685- }
4686- std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
4687- if( !m_floatingArg.get() )
4688- return tokens;
4689- std::vector<Parser::Token> unusedTokens;
4690- for( std::size_t i = 0; i < tokens.size(); ++i ) {
4691- Parser::Token const& token = tokens[i];
4692- if( token.type == Parser::Token::Positional )
4693- m_floatingArg->boundField.set( config, token.data );
4694- else
4695- unusedTokens.push_back( token );
4696- }
4697- return unusedTokens;
4698- }
4699-
4700- void validate() const
4701- {
4702- if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() )
4703- throw std::logic_error( "No options or arguments specified" );
4704-
4705- for( typename std::vector<Arg>::const_iterator it = m_options.begin(),
4706- itEnd = m_options.end();
4707- it != itEnd; ++it )
4708- it->validate();
4709- }
4710-
4711- private:
4712- Detail::BoundArgFunction<ConfigT> m_boundProcessName;
4713- std::vector<Arg> m_options;
4714- std::map<int, Arg> m_positionalArgs;
4715- ArgAutoPtr m_floatingArg;
4716- int m_highestSpecifiedArgPosition;
4717- bool m_throwOnUnrecognisedTokens;
4718- };
4719-
4720-} // end namespace Clara
4721-
4722-STITCH_CLARA_CLOSE_NAMESPACE
4723-#undef STITCH_CLARA_OPEN_NAMESPACE
4724-#undef STITCH_CLARA_CLOSE_NAMESPACE
4725-
4726-#endif // TWOBLUECUBES_CLARA_H_INCLUDED
4727-#undef STITCH_CLARA_OPEN_NAMESPACE
4728-
4729-// Restore Clara's value for console width, if present
4730-#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
4731-#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
4732-#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
4733-#endif
4734-
4735-#include <fstream>
4736-
4737-namespace Catch {
4738-
4739- inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }
4740- inline void abortAfterX( ConfigData& config, int x ) {
4741- if( x < 1 )
4742- throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" );
4743- config.abortAfter = x;
4744- }
4745- inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
4746- inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); }
4747-
4748- inline void addWarning( ConfigData& config, std::string const& _warning ) {
4749- if( _warning == "NoAssertions" )
4750- config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );
4751- else
4752- throw std::runtime_error( "Unrecognised warning: '" + _warning + "'" );
4753- }
4754- inline void setOrder( ConfigData& config, std::string const& order ) {
4755- if( startsWith( "declared", order ) )
4756- config.runOrder = RunTests::InDeclarationOrder;
4757- else if( startsWith( "lexical", order ) )
4758- config.runOrder = RunTests::InLexicographicalOrder;
4759- else if( startsWith( "random", order ) )
4760- config.runOrder = RunTests::InRandomOrder;
4761- else
4762- throw std::runtime_error( "Unrecognised ordering: '" + order + "'" );
4763- }
4764- inline void setRngSeed( ConfigData& config, std::string const& seed ) {
4765- if( seed == "time" ) {
4766- config.rngSeed = static_cast<unsigned int>( std::time(0) );
4767- }
4768- else {
4769- std::stringstream ss;
4770- ss << seed;
4771- ss >> config.rngSeed;
4772- if( ss.fail() )
4773- throw std::runtime_error( "Argment to --rng-seed should be the word 'time' or a number" );
4774- }
4775- }
4776- inline void setVerbosity( ConfigData& config, int level ) {
4777- // !TBD: accept strings?
4778- config.verbosity = static_cast<Verbosity::Level>( level );
4779- }
4780- inline void setShowDurations( ConfigData& config, bool _showDurations ) {
4781- config.showDurations = _showDurations
4782- ? ShowDurations::Always
4783- : ShowDurations::Never;
4784- }
4785- inline void setUseColour( ConfigData& config, std::string const& value ) {
4786- std::string mode = toLower( value );
4787-
4788- if( mode == "yes" )
4789- config.useColour = UseColour::Yes;
4790- else if( mode == "no" )
4791- config.useColour = UseColour::No;
4792- else if( mode == "auto" )
4793- config.useColour = UseColour::Auto;
4794- else
4795- throw std::runtime_error( "colour mode must be one of: auto, yes or no" );
4796- }
4797- inline void forceColour( ConfigData& config ) {
4798- config.useColour = UseColour::Yes;
4799- }
4800- inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {
4801- std::ifstream f( _filename.c_str() );
4802- if( !f.is_open() )
4803- throw std::domain_error( "Unable to load input file: " + _filename );
4804-
4805- std::string line;
4806- while( std::getline( f, line ) ) {
4807- line = trim(line);
4808- if( !line.empty() && !startsWith( line, "#" ) ) {
4809- if( !startsWith( line, "\"" ) )
4810- line = "\"" + line + "\"";
4811- addTestOrTags( config, line + "," );
4812- }
4813- }
4814- }
4815-
4816- inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
4817-
4818- using namespace Clara;
4819- CommandLine<ConfigData> cli;
4820-
4821- cli.bindProcessName( &ConfigData::processName );
4822-
4823- cli["-?"]["-h"]["--help"]
4824- .describe( "display usage information" )
4825- .bind( &ConfigData::showHelp );
4826-
4827- cli["-l"]["--list-tests"]
4828- .describe( "list all/matching test cases" )
4829- .bind( &ConfigData::listTests );
4830-
4831- cli["-t"]["--list-tags"]
4832- .describe( "list all/matching tags" )
4833- .bind( &ConfigData::listTags );
4834-
4835- cli["-s"]["--success"]
4836- .describe( "include successful tests in output" )
4837- .bind( &ConfigData::showSuccessfulTests );
4838-
4839- cli["-b"]["--break"]
4840- .describe( "break into debugger on failure" )
4841- .bind( &ConfigData::shouldDebugBreak );
4842-
4843- cli["-e"]["--nothrow"]
4844- .describe( "skip exception tests" )
4845- .bind( &ConfigData::noThrow );
4846-
4847- cli["-i"]["--invisibles"]
4848- .describe( "show invisibles (tabs, newlines)" )
4849- .bind( &ConfigData::showInvisibles );
4850-
4851- cli["-o"]["--out"]
4852- .describe( "output filename" )
4853- .bind( &ConfigData::outputFilename, "filename" );
4854-
4855- cli["-r"]["--reporter"]
4856-// .placeholder( "name[:filename]" )
4857- .describe( "reporter to use (defaults to console)" )
4858- .bind( &addReporterName, "name" );
4859-
4860- cli["-n"]["--name"]
4861- .describe( "suite name" )
4862- .bind( &ConfigData::name, "name" );
4863-
4864- cli["-a"]["--abort"]
4865- .describe( "abort at first failure" )
4866- .bind( &abortAfterFirst );
4867-
4868- cli["-x"]["--abortx"]
4869- .describe( "abort after x failures" )
4870- .bind( &abortAfterX, "no. failures" );
4871-
4872- cli["-w"]["--warn"]
4873- .describe( "enable warnings" )
4874- .bind( &addWarning, "warning name" );
4875-
4876-// - needs updating if reinstated
4877-// cli.into( &setVerbosity )
4878-// .describe( "level of verbosity (0=no output)" )
4879-// .shortOpt( "v")
4880-// .longOpt( "verbosity" )
4881-// .placeholder( "level" );
4882-
4883- cli[_]
4884- .describe( "which test or tests to use" )
4885- .bind( &addTestOrTags, "test name, pattern or tags" );
4886-
4887- cli["-d"]["--durations"]
4888- .describe( "show test durations" )
4889- .bind( &setShowDurations, "yes|no" );
4890-
4891- cli["-f"]["--input-file"]
4892- .describe( "load test names to run from a file" )
4893- .bind( &loadTestNamesFromFile, "filename" );
4894-
4895- cli["-#"]["--filenames-as-tags"]
4896- .describe( "adds a tag for the filename" )
4897- .bind( &ConfigData::filenamesAsTags );
4898-
4899- // Less common commands which don't have a short form
4900- cli["--list-test-names-only"]
4901- .describe( "list all/matching test cases names only" )
4902- .bind( &ConfigData::listTestNamesOnly );
4903-
4904- cli["--list-reporters"]
4905- .describe( "list all reporters" )
4906- .bind( &ConfigData::listReporters );
4907-
4908- cli["--order"]
4909- .describe( "test case order (defaults to decl)" )
4910- .bind( &setOrder, "decl|lex|rand" );
4911-
4912- cli["--rng-seed"]
4913- .describe( "set a specific seed for random numbers" )
4914- .bind( &setRngSeed, "'time'|number" );
4915-
4916- cli["--force-colour"]
4917- .describe( "force colourised output (deprecated)" )
4918- .bind( &forceColour );
4919-
4920- cli["--use-colour"]
4921- .describe( "should output be colourised" )
4922- .bind( &setUseColour, "yes|no" );
4923-
4924- return cli;
4925- }
4926-
4927-} // end namespace Catch
4928-
4929-// #included from: internal/catch_list.hpp
4930-#define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED
4931-
4932-// #included from: catch_text.h
4933-#define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED
4934-
4935-#define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
4936-
4937-#define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch
4938-// #included from: ../external/tbc_text_format.h
4939-// Only use header guard if we are not using an outer namespace
4940-#ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
4941-# ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
4942-# ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
4943-# define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
4944-# endif
4945-# else
4946-# define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
4947-# endif
4948-#endif
4949-#ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
4950-#include <string>
4951-#include <vector>
4952-#include <sstream>
4953-
4954-// Use optional outer namespace
4955-#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
4956-namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
4957-#endif
4958-
4959-namespace Tbc {
4960-
4961-#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
4962- const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
4963-#else
4964- const unsigned int consoleWidth = 80;
4965-#endif
4966-
4967- struct TextAttributes {
4968- TextAttributes()
4969- : initialIndent( std::string::npos ),
4970- indent( 0 ),
4971- width( consoleWidth-1 ),
4972- tabChar( '\t' )
4973- {}
4974-
4975- TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
4976- TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
4977- TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
4978- TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; }
4979-
4980- std::size_t initialIndent; // indent of first line, or npos
4981- std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos
4982- std::size_t width; // maximum width of text, including indent. Longer text will wrap
4983- char tabChar; // If this char is seen the indent is changed to current pos
4984- };
4985-
4986- class Text {
4987- public:
4988- Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
4989- : attr( _attr )
4990- {
4991- std::string wrappableChars = " [({.,/|\\-";
4992- std::size_t indent = _attr.initialIndent != std::string::npos
4993- ? _attr.initialIndent
4994- : _attr.indent;
4995- std::string remainder = _str;
4996-
4997- while( !remainder.empty() ) {
4998- if( lines.size() >= 1000 ) {
4999- lines.push_back( "... message truncated due to excessive size" );
5000- return;
5001- }
5002- std::size_t tabPos = std::string::npos;
5003- std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
5004- std::size_t pos = remainder.find_first_of( '\n' );
5005- if( pos <= width ) {
5006- width = pos;
5007- }
5008- pos = remainder.find_last_of( _attr.tabChar, width );
5009- if( pos != std::string::npos ) {
5010- tabPos = pos;
5011- if( remainder[width] == '\n' )
5012- width--;
5013- remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
5014- }
5015-
5016- if( width == remainder.size() ) {
5017- spliceLine( indent, remainder, width );
5018- }
5019- else if( remainder[width] == '\n' ) {
5020- spliceLine( indent, remainder, width );
5021- if( width <= 1 || remainder.size() != 1 )
5022- remainder = remainder.substr( 1 );
5023- indent = _attr.indent;
5024- }
5025- else {
5026- pos = remainder.find_last_of( wrappableChars, width );
5027- if( pos != std::string::npos && pos > 0 ) {
5028- spliceLine( indent, remainder, pos );
5029- if( remainder[0] == ' ' )
5030- remainder = remainder.substr( 1 );
5031- }
5032- else {
5033- spliceLine( indent, remainder, width-1 );
5034- lines.back() += "-";
5035- }
5036- if( lines.size() == 1 )
5037- indent = _attr.indent;
5038- if( tabPos != std::string::npos )
5039- indent += tabPos;
5040- }
5041- }
5042- }
5043-
5044- void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
5045- lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
5046- _remainder = _remainder.substr( _pos );
5047- }
5048-
5049- typedef std::vector<std::string>::const_iterator const_iterator;
5050-
5051- const_iterator begin() const { return lines.begin(); }
5052- const_iterator end() const { return lines.end(); }
5053- std::string const& last() const { return lines.back(); }
5054- std::size_t size() const { return lines.size(); }
5055- std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
5056- std::string toString() const {
5057- std::ostringstream oss;
5058- oss << *this;
5059- return oss.str();
5060- }
5061-
5062- inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
5063- for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
5064- it != itEnd; ++it ) {
5065- if( it != _text.begin() )
5066- _stream << "\n";
5067- _stream << *it;
5068- }
5069- return _stream;
5070- }
5071-
5072- private:
5073- std::string str;
5074- TextAttributes attr;
5075- std::vector<std::string> lines;
5076- };
5077-
5078-} // end namespace Tbc
5079-
5080-#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
5081-} // end outer namespace
5082-#endif
5083-
5084-#endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
5085-#undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
5086-
5087-namespace Catch {
5088- using Tbc::Text;
5089- using Tbc::TextAttributes;
5090-}
5091-
5092-// #included from: catch_console_colour.hpp
5093-#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED
5094-
5095-namespace Catch {
5096-
5097- struct Colour {
5098- enum Code {
5099- None = 0,
5100-
5101- White,
5102- Red,
5103- Green,
5104- Blue,
5105- Cyan,
5106- Yellow,
5107- Grey,
5108-
5109- Bright = 0x10,
5110-
5111- BrightRed = Bright | Red,
5112- BrightGreen = Bright | Green,
5113- LightGrey = Bright | Grey,
5114- BrightWhite = Bright | White,
5115-
5116- // By intention
5117- FileName = LightGrey,
5118- Warning = Yellow,
5119- ResultError = BrightRed,
5120- ResultSuccess = BrightGreen,
5121- ResultExpectedFailure = Warning,
5122-
5123- Error = BrightRed,
5124- Success = Green,
5125-
5126- OriginalExpression = Cyan,
5127- ReconstructedExpression = Yellow,
5128-
5129- SecondaryText = LightGrey,
5130- Headers = White
5131- };
5132-
5133- // Use constructed object for RAII guard
5134- Colour( Code _colourCode );
5135- Colour( Colour const& other );
5136- ~Colour();
5137-
5138- // Use static method for one-shot changes
5139- static void use( Code _colourCode );
5140-
5141- private:
5142- bool m_moved;
5143- };
5144-
5145- inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; }
5146-
5147-} // end namespace Catch
5148-
5149-// #included from: catch_interfaces_reporter.h
5150-#define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
5151-
5152-#include <string>
5153-#include <ostream>
5154-#include <map>
5155-#include <assert.h>
5156-
5157-namespace Catch
5158-{
5159- struct ReporterConfig {
5160- explicit ReporterConfig( Ptr<IConfig const> const& _fullConfig )
5161- : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
5162-
5163- ReporterConfig( Ptr<IConfig const> const& _fullConfig, std::ostream& _stream )
5164- : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
5165-
5166- std::ostream& stream() const { return *m_stream; }
5167- Ptr<IConfig const> fullConfig() const { return m_fullConfig; }
5168-
5169- private:
5170- std::ostream* m_stream;
5171- Ptr<IConfig const> m_fullConfig;
5172- };
5173-
5174- struct ReporterPreferences {
5175- ReporterPreferences()
5176- : shouldRedirectStdOut( false )
5177- {}
5178-
5179- bool shouldRedirectStdOut;
5180- };
5181-
5182- template<typename T>
5183- struct LazyStat : Option<T> {
5184- LazyStat() : used( false ) {}
5185- LazyStat& operator=( T const& _value ) {
5186- Option<T>::operator=( _value );
5187- used = false;
5188- return *this;
5189- }
5190- void reset() {
5191- Option<T>::reset();
5192- used = false;
5193- }
5194- bool used;
5195- };
5196-
5197- struct TestRunInfo {
5198- TestRunInfo( std::string const& _name ) : name( _name ) {}
5199- std::string name;
5200- };
5201- struct GroupInfo {
5202- GroupInfo( std::string const& _name,
5203- std::size_t _groupIndex,
5204- std::size_t _groupsCount )
5205- : name( _name ),
5206- groupIndex( _groupIndex ),
5207- groupsCounts( _groupsCount )
5208- {}
5209-
5210- std::string name;
5211- std::size_t groupIndex;
5212- std::size_t groupsCounts;
5213- };
5214-
5215- struct AssertionStats {
5216- AssertionStats( AssertionResult const& _assertionResult,
5217- std::vector<MessageInfo> const& _infoMessages,
5218- Totals const& _totals )
5219- : assertionResult( _assertionResult ),
5220- infoMessages( _infoMessages ),
5221- totals( _totals )
5222- {
5223- if( assertionResult.hasMessage() ) {
5224- // Copy message into messages list.
5225- // !TBD This should have been done earlier, somewhere
5226- MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
5227- builder << assertionResult.getMessage();
5228- builder.m_info.message = builder.m_stream.str();
5229-
5230- infoMessages.push_back( builder.m_info );
5231- }
5232- }
5233- virtual ~AssertionStats();
5234-
5235-# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
5236- AssertionStats( AssertionStats const& ) = default;
5237- AssertionStats( AssertionStats && ) = default;
5238- AssertionStats& operator = ( AssertionStats const& ) = default;
5239- AssertionStats& operator = ( AssertionStats && ) = default;
5240-# endif
5241-
5242- AssertionResult assertionResult;
5243- std::vector<MessageInfo> infoMessages;
5244- Totals totals;
5245- };
5246-
5247- struct SectionStats {
5248- SectionStats( SectionInfo const& _sectionInfo,
5249- Counts const& _assertions,
5250- double _durationInSeconds,
5251- bool _missingAssertions )
5252- : sectionInfo( _sectionInfo ),
5253- assertions( _assertions ),
5254- durationInSeconds( _durationInSeconds ),
5255- missingAssertions( _missingAssertions )
5256- {}
5257- virtual ~SectionStats();
5258-# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
5259- SectionStats( SectionStats const& ) = default;
5260- SectionStats( SectionStats && ) = default;
5261- SectionStats& operator = ( SectionStats const& ) = default;
5262- SectionStats& operator = ( SectionStats && ) = default;
5263-# endif
5264-
5265- SectionInfo sectionInfo;
5266- Counts assertions;
5267- double durationInSeconds;
5268- bool missingAssertions;
5269- };
5270-
5271- struct TestCaseStats {
5272- TestCaseStats( TestCaseInfo const& _testInfo,
5273- Totals const& _totals,
5274- std::string const& _stdOut,
5275- std::string const& _stdErr,
5276- bool _aborting )
5277- : testInfo( _testInfo ),
5278- totals( _totals ),
5279- stdOut( _stdOut ),
5280- stdErr( _stdErr ),
5281- aborting( _aborting )
5282- {}
5283- virtual ~TestCaseStats();
5284-
5285-# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
5286- TestCaseStats( TestCaseStats const& ) = default;
5287- TestCaseStats( TestCaseStats && ) = default;
5288- TestCaseStats& operator = ( TestCaseStats const& ) = default;
5289- TestCaseStats& operator = ( TestCaseStats && ) = default;
5290-# endif
5291-
5292- TestCaseInfo testInfo;
5293- Totals totals;
5294- std::string stdOut;
5295- std::string stdErr;
5296- bool aborting;
5297- };
5298-
5299- struct TestGroupStats {
5300- TestGroupStats( GroupInfo const& _groupInfo,
5301- Totals const& _totals,
5302- bool _aborting )
5303- : groupInfo( _groupInfo ),
5304- totals( _totals ),
5305- aborting( _aborting )
5306- {}
5307- TestGroupStats( GroupInfo const& _groupInfo )
5308- : groupInfo( _groupInfo ),
5309- aborting( false )
5310- {}
5311- virtual ~TestGroupStats();
5312-
5313-# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
5314- TestGroupStats( TestGroupStats const& ) = default;
5315- TestGroupStats( TestGroupStats && ) = default;
5316- TestGroupStats& operator = ( TestGroupStats const& ) = default;
5317- TestGroupStats& operator = ( TestGroupStats && ) = default;
5318-# endif
5319-
5320- GroupInfo groupInfo;
5321- Totals totals;
5322- bool aborting;
5323- };
5324-
5325- struct TestRunStats {
5326- TestRunStats( TestRunInfo const& _runInfo,
5327- Totals const& _totals,
5328- bool _aborting )
5329- : runInfo( _runInfo ),
5330- totals( _totals ),
5331- aborting( _aborting )
5332- {}
5333- virtual ~TestRunStats();
5334-
5335-# ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS
5336- TestRunStats( TestRunStats const& _other )
5337- : runInfo( _other.runInfo ),
5338- totals( _other.totals ),
5339- aborting( _other.aborting )
5340- {}
5341-# else
5342- TestRunStats( TestRunStats const& ) = default;
5343- TestRunStats( TestRunStats && ) = default;
5344- TestRunStats& operator = ( TestRunStats const& ) = default;
5345- TestRunStats& operator = ( TestRunStats && ) = default;
5346-# endif
5347-
5348- TestRunInfo runInfo;
5349- Totals totals;
5350- bool aborting;
5351- };
5352-
5353- class MultipleReporters;
5354-
5355- struct IStreamingReporter : IShared {
5356- virtual ~IStreamingReporter();
5357-
5358- // Implementing class must also provide the following static method:
5359- // static std::string getDescription();
5360-
5361- virtual ReporterPreferences getPreferences() const = 0;
5362-
5363- virtual void noMatchingTestCases( std::string const& spec ) = 0;
5364-
5365- virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
5366- virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
5367-
5368- virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
5369- virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
5370-
5371- virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
5372-
5373- // The return value indicates if the messages buffer should be cleared:
5374- virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
5375-
5376- virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
5377- virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
5378- virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
5379- virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
5380-
5381- virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
5382-
5383- virtual MultipleReporters* tryAsMulti() { return CATCH_NULL; }
5384- };
5385-
5386- struct IReporterFactory : IShared {
5387- virtual ~IReporterFactory();
5388- virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0;
5389- virtual std::string getDescription() const = 0;
5390- };
5391-
5392- struct IReporterRegistry {
5393- typedef std::map<std::string, Ptr<IReporterFactory> > FactoryMap;
5394- typedef std::vector<Ptr<IReporterFactory> > Listeners;
5395-
5396- virtual ~IReporterRegistry();
5397- virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const = 0;
5398- virtual FactoryMap const& getFactories() const = 0;
5399- virtual Listeners const& getListeners() const = 0;
5400- };
5401-
5402- Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter );
5403-
5404-}
5405-
5406-#include <limits>
5407-#include <algorithm>
5408-
5409-namespace Catch {
5410-
5411- inline std::size_t listTests( Config const& config ) {
5412-
5413- TestSpec testSpec = config.testSpec();
5414- if( config.testSpec().hasFilters() )
5415- Catch::cout() << "Matching test cases:\n";
5416- else {
5417- Catch::cout() << "All available test cases:\n";
5418- testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
5419- }
5420-
5421- std::size_t matchedTests = 0;
5422- TextAttributes nameAttr, tagsAttr;
5423- nameAttr.setInitialIndent( 2 ).setIndent( 4 );
5424- tagsAttr.setIndent( 6 );
5425-
5426- std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
5427- for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
5428- it != itEnd;
5429- ++it ) {
5430- matchedTests++;
5431- TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
5432- Colour::Code colour = testCaseInfo.isHidden()
5433- ? Colour::SecondaryText
5434- : Colour::None;
5435- Colour colourGuard( colour );
5436-
5437- Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl;
5438- if( !testCaseInfo.tags.empty() )
5439- Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl;
5440- }
5441-
5442- if( !config.testSpec().hasFilters() )
5443- Catch::cout() << pluralise( matchedTests, "test case" ) << "\n" << std::endl;
5444- else
5445- Catch::cout() << pluralise( matchedTests, "matching test case" ) << "\n" << std::endl;
5446- return matchedTests;
5447- }
5448-
5449- inline std::size_t listTestsNamesOnly( Config const& config ) {
5450- TestSpec testSpec = config.testSpec();
5451- if( !config.testSpec().hasFilters() )
5452- testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
5453- std::size_t matchedTests = 0;
5454- std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
5455- for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
5456- it != itEnd;
5457- ++it ) {
5458- matchedTests++;
5459- TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
5460- if( startsWith( testCaseInfo.name, "#" ) )
5461- Catch::cout() << "\"" << testCaseInfo.name << "\"" << std::endl;
5462- else
5463- Catch::cout() << testCaseInfo.name << std::endl;
5464- }
5465- return matchedTests;
5466- }
5467-
5468- struct TagInfo {
5469- TagInfo() : count ( 0 ) {}
5470- void add( std::string const& spelling ) {
5471- ++count;
5472- spellings.insert( spelling );
5473- }
5474- std::string all() const {
5475- std::string out;
5476- for( std::set<std::string>::const_iterator it = spellings.begin(), itEnd = spellings.end();
5477- it != itEnd;
5478- ++it )
5479- out += "[" + *it + "]";
5480- return out;
5481- }
5482- std::set<std::string> spellings;
5483- std::size_t count;
5484- };
5485-
5486- inline std::size_t listTags( Config const& config ) {
5487- TestSpec testSpec = config.testSpec();
5488- if( config.testSpec().hasFilters() )
5489- Catch::cout() << "Tags for matching test cases:\n";
5490- else {
5491- Catch::cout() << "All available tags:\n";
5492- testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
5493- }
5494-
5495- std::map<std::string, TagInfo> tagCounts;
5496-
5497- std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
5498- for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
5499- it != itEnd;
5500- ++it ) {
5501- for( std::set<std::string>::const_iterator tagIt = it->getTestCaseInfo().tags.begin(),
5502- tagItEnd = it->getTestCaseInfo().tags.end();
5503- tagIt != tagItEnd;
5504- ++tagIt ) {
5505- std::string tagName = *tagIt;
5506- std::string lcaseTagName = toLower( tagName );
5507- std::map<std::string, TagInfo>::iterator countIt = tagCounts.find( lcaseTagName );
5508- if( countIt == tagCounts.end() )
5509- countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
5510- countIt->second.add( tagName );
5511- }
5512- }
5513-
5514- for( std::map<std::string, TagInfo>::const_iterator countIt = tagCounts.begin(),
5515- countItEnd = tagCounts.end();
5516- countIt != countItEnd;
5517- ++countIt ) {
5518- std::ostringstream oss;
5519- oss << " " << std::setw(2) << countIt->second.count << " ";
5520- Text wrapper( countIt->second.all(), TextAttributes()
5521- .setInitialIndent( 0 )
5522- .setIndent( oss.str().size() )
5523- .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) );
5524- Catch::cout() << oss.str() << wrapper << "\n";
5525- }
5526- Catch::cout() << pluralise( tagCounts.size(), "tag" ) << "\n" << std::endl;
5527- return tagCounts.size();
5528- }
5529-
5530- inline std::size_t listReporters( Config const& /*config*/ ) {
5531- Catch::cout() << "Available reporters:\n";
5532- IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
5533- IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;
5534- std::size_t maxNameLen = 0;
5535- for(it = itBegin; it != itEnd; ++it )
5536- maxNameLen = (std::max)( maxNameLen, it->first.size() );
5537-
5538- for(it = itBegin; it != itEnd; ++it ) {
5539- Text wrapper( it->second->getDescription(), TextAttributes()
5540- .setInitialIndent( 0 )
5541- .setIndent( 7+maxNameLen )
5542- .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );
5543- Catch::cout() << " "
5544- << it->first
5545- << ":"
5546- << std::string( maxNameLen - it->first.size() + 2, ' ' )
5547- << wrapper << "\n";
5548- }
5549- Catch::cout() << std::endl;
5550- return factories.size();
5551- }
5552-
5553- inline Option<std::size_t> list( Config const& config ) {
5554- Option<std::size_t> listedCount;
5555- if( config.listTests() )
5556- listedCount = listedCount.valueOr(0) + listTests( config );
5557- if( config.listTestNamesOnly() )
5558- listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
5559- if( config.listTags() )
5560- listedCount = listedCount.valueOr(0) + listTags( config );
5561- if( config.listReporters() )
5562- listedCount = listedCount.valueOr(0) + listReporters( config );
5563- return listedCount;
5564- }
5565-
5566-} // end namespace Catch
5567-
5568-// #included from: internal/catch_run_context.hpp
5569-#define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
5570-
5571-// #included from: catch_test_case_tracker.hpp
5572-#define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
5573-
5574-#include <map>
5575-#include <string>
5576-#include <assert.h>
5577-#include <vector>
5578-
5579-namespace Catch {
5580-namespace TestCaseTracking {
5581-
5582- struct ITracker : SharedImpl<> {
5583- virtual ~ITracker();
5584-
5585- // static queries
5586- virtual std::string name() const = 0;
5587-
5588- // dynamic queries
5589- virtual bool isComplete() const = 0; // Successfully completed or failed
5590- virtual bool isSuccessfullyCompleted() const = 0;
5591- virtual bool isOpen() const = 0; // Started but not complete
5592- virtual bool hasChildren() const = 0;
5593-
5594- virtual ITracker& parent() = 0;
5595-
5596- // actions
5597- virtual void close() = 0; // Successfully complete
5598- virtual void fail() = 0;
5599- virtual void markAsNeedingAnotherRun() = 0;
5600-
5601- virtual void addChild( Ptr<ITracker> const& child ) = 0;
5602- virtual ITracker* findChild( std::string const& name ) = 0;
5603- virtual void openChild() = 0;
5604-
5605- // Debug/ checking
5606- virtual bool isSectionTracker() const = 0;
5607- virtual bool isIndexTracker() const = 0;
5608- };
5609-
5610- class TrackerContext {
5611-
5612- enum RunState {
5613- NotStarted,
5614- Executing,
5615- CompletedCycle
5616- };
5617-
5618- Ptr<ITracker> m_rootTracker;
5619- ITracker* m_currentTracker;
5620- RunState m_runState;
5621-
5622- public:
5623-
5624- static TrackerContext& instance() {
5625- static TrackerContext s_instance;
5626- return s_instance;
5627- }
5628-
5629- TrackerContext()
5630- : m_currentTracker( CATCH_NULL ),
5631- m_runState( NotStarted )
5632- {}
5633-
5634- ITracker& startRun();
5635-
5636- void endRun() {
5637- m_rootTracker.reset();
5638- m_currentTracker = CATCH_NULL;
5639- m_runState = NotStarted;
5640- }
5641-
5642- void startCycle() {
5643- m_currentTracker = m_rootTracker.get();
5644- m_runState = Executing;
5645- }
5646- void completeCycle() {
5647- m_runState = CompletedCycle;
5648- }
5649-
5650- bool completedCycle() const {
5651- return m_runState == CompletedCycle;
5652- }
5653- ITracker& currentTracker() {
5654- return *m_currentTracker;
5655- }
5656- void setCurrentTracker( ITracker* tracker ) {
5657- m_currentTracker = tracker;
5658- }
5659- };
5660-
5661- class TrackerBase : public ITracker {
5662- protected:
5663- enum CycleState {
5664- NotStarted,
5665- Executing,
5666- ExecutingChildren,
5667- NeedsAnotherRun,
5668- CompletedSuccessfully,
5669- Failed
5670- };
5671- class TrackerHasName {
5672- std::string m_name;
5673- public:
5674- TrackerHasName( std::string const& name ) : m_name( name ) {}
5675- bool operator ()( Ptr<ITracker> const& tracker ) {
5676- return tracker->name() == m_name;
5677- }
5678- };
5679- typedef std::vector<Ptr<ITracker> > Children;
5680- std::string m_name;
5681- TrackerContext& m_ctx;
5682- ITracker* m_parent;
5683- Children m_children;
5684- CycleState m_runState;
5685- public:
5686- TrackerBase( std::string const& name, TrackerContext& ctx, ITracker* parent )
5687- : m_name( name ),
5688- m_ctx( ctx ),
5689- m_parent( parent ),
5690- m_runState( NotStarted )
5691- {}
5692- virtual ~TrackerBase();
5693-
5694- virtual std::string name() const CATCH_OVERRIDE {
5695- return m_name;
5696- }
5697- virtual bool isComplete() const CATCH_OVERRIDE {
5698- return m_runState == CompletedSuccessfully || m_runState == Failed;
5699- }
5700- virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE {
5701- return m_runState == CompletedSuccessfully;
5702- }
5703- virtual bool isOpen() const CATCH_OVERRIDE {
5704- return m_runState != NotStarted && !isComplete();
5705- }
5706- virtual bool hasChildren() const CATCH_OVERRIDE {
5707- return !m_children.empty();
5708- }
5709-
5710- virtual void addChild( Ptr<ITracker> const& child ) CATCH_OVERRIDE {
5711- m_children.push_back( child );
5712- }
5713-
5714- virtual ITracker* findChild( std::string const& name ) CATCH_OVERRIDE {
5715- Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( name ) );
5716- return( it != m_children.end() )
5717- ? it->get()
5718- : CATCH_NULL;
5719- }
5720- virtual ITracker& parent() CATCH_OVERRIDE {
5721- assert( m_parent ); // Should always be non-null except for root
5722- return *m_parent;
5723- }
5724-
5725- virtual void openChild() CATCH_OVERRIDE {
5726- if( m_runState != ExecutingChildren ) {
5727- m_runState = ExecutingChildren;
5728- if( m_parent )
5729- m_parent->openChild();
5730- }
5731- }
5732-
5733- virtual bool isSectionTracker() const CATCH_OVERRIDE { return false; }
5734- virtual bool isIndexTracker() const CATCH_OVERRIDE { return false; }
5735-
5736- void open() {
5737- m_runState = Executing;
5738- moveToThis();
5739- if( m_parent )
5740- m_parent->openChild();
5741- }
5742-
5743- virtual void close() CATCH_OVERRIDE {
5744-
5745- // Close any still open children (e.g. generators)
5746- while( &m_ctx.currentTracker() != this )
5747- m_ctx.currentTracker().close();
5748-
5749- switch( m_runState ) {
5750- case NotStarted:
5751- case CompletedSuccessfully:
5752- case Failed:
5753- throw std::logic_error( "Illogical state" );
5754-
5755- case NeedsAnotherRun:
5756- break;;
5757-
5758- case Executing:
5759- m_runState = CompletedSuccessfully;
5760- break;
5761- case ExecutingChildren:
5762- if( m_children.empty() || m_children.back()->isComplete() )
5763- m_runState = CompletedSuccessfully;
5764- break;
5765-
5766- default:
5767- throw std::logic_error( "Unexpected state" );
5768- }
5769- moveToParent();
5770- m_ctx.completeCycle();
5771- }
5772- virtual void fail() CATCH_OVERRIDE {
5773- m_runState = Failed;
5774- if( m_parent )
5775- m_parent->markAsNeedingAnotherRun();
5776- moveToParent();
5777- m_ctx.completeCycle();
5778- }
5779- virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE {
5780- m_runState = NeedsAnotherRun;
5781- }
5782- private:
5783- void moveToParent() {
5784- assert( m_parent );
5785- m_ctx.setCurrentTracker( m_parent );
5786- }
5787- void moveToThis() {
5788- m_ctx.setCurrentTracker( this );
5789- }
5790- };
5791-
5792- class SectionTracker : public TrackerBase {
5793- public:
5794- SectionTracker( std::string const& name, TrackerContext& ctx, ITracker* parent )
5795- : TrackerBase( name, ctx, parent )
5796- {}
5797- virtual ~SectionTracker();
5798-
5799- virtual bool isSectionTracker() const CATCH_OVERRIDE { return true; }
5800-
5801- static SectionTracker& acquire( TrackerContext& ctx, std::string const& name ) {
5802- SectionTracker* section = CATCH_NULL;
5803-
5804- ITracker& currentTracker = ctx.currentTracker();
5805- if( ITracker* childTracker = currentTracker.findChild( name ) ) {
5806- assert( childTracker );
5807- assert( childTracker->isSectionTracker() );
5808- section = static_cast<SectionTracker*>( childTracker );
5809- }
5810- else {
5811- section = new SectionTracker( name, ctx, &currentTracker );
5812- currentTracker.addChild( section );
5813- }
5814- if( !ctx.completedCycle() && !section->isComplete() ) {
5815-
5816- section->open();
5817- }
5818- return *section;
5819- }
5820- };
5821-
5822- class IndexTracker : public TrackerBase {
5823- int m_size;
5824- int m_index;
5825- public:
5826- IndexTracker( std::string const& name, TrackerContext& ctx, ITracker* parent, int size )
5827- : TrackerBase( name, ctx, parent ),
5828- m_size( size ),
5829- m_index( -1 )
5830- {}
5831- virtual ~IndexTracker();
5832-
5833- virtual bool isIndexTracker() const CATCH_OVERRIDE { return true; }
5834-
5835- static IndexTracker& acquire( TrackerContext& ctx, std::string const& name, int size ) {
5836- IndexTracker* tracker = CATCH_NULL;
5837-
5838- ITracker& currentTracker = ctx.currentTracker();
5839- if( ITracker* childTracker = currentTracker.findChild( name ) ) {
5840- assert( childTracker );
5841- assert( childTracker->isIndexTracker() );
5842- tracker = static_cast<IndexTracker*>( childTracker );
5843- }
5844- else {
5845- tracker = new IndexTracker( name, ctx, &currentTracker, size );
5846- currentTracker.addChild( tracker );
5847- }
5848-
5849- if( !ctx.completedCycle() && !tracker->isComplete() ) {
5850- if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
5851- tracker->moveNext();
5852- tracker->open();
5853- }
5854-
5855- return *tracker;
5856- }
5857-
5858- int index() const { return m_index; }
5859-
5860- void moveNext() {
5861- m_index++;
5862- m_children.clear();
5863- }
5864-
5865- virtual void close() CATCH_OVERRIDE {
5866- TrackerBase::close();
5867- if( m_runState == CompletedSuccessfully && m_index < m_size-1 )
5868- m_runState = Executing;
5869- }
5870- };
5871-
5872- inline ITracker& TrackerContext::startRun() {
5873- m_rootTracker = new SectionTracker( "{root}", *this, CATCH_NULL );
5874- m_currentTracker = CATCH_NULL;
5875- m_runState = Executing;
5876- return *m_rootTracker;
5877- }
5878-
5879-} // namespace TestCaseTracking
5880-
5881-using TestCaseTracking::ITracker;
5882-using TestCaseTracking::TrackerContext;
5883-using TestCaseTracking::SectionTracker;
5884-using TestCaseTracking::IndexTracker;
5885-
5886-} // namespace Catch
5887-
5888-// #included from: catch_fatal_condition.hpp
5889-#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
5890-
5891-namespace Catch {
5892-
5893- // Report the error condition then exit the process
5894- inline void fatal( std::string const& message, int exitCode ) {
5895- IContext& context = Catch::getCurrentContext();
5896- IResultCapture* resultCapture = context.getResultCapture();
5897- resultCapture->handleFatalErrorCondition( message );
5898-
5899- if( Catch::alwaysTrue() ) // avoids "no return" warnings
5900- exit( exitCode );
5901- }
5902-
5903-} // namespace Catch
5904-
5905-#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
5906-
5907-namespace Catch {
5908-
5909- struct FatalConditionHandler {
5910- void reset() {}
5911- };
5912-
5913-} // namespace Catch
5914-
5915-#else // Not Windows - assumed to be POSIX compatible //////////////////////////
5916-
5917-#include <signal.h>
5918-
5919-namespace Catch {
5920-
5921- struct SignalDefs { int id; const char* name; };
5922- extern SignalDefs signalDefs[];
5923- SignalDefs signalDefs[] = {
5924- { SIGINT, "SIGINT - Terminal interrupt signal" },
5925- { SIGILL, "SIGILL - Illegal instruction signal" },
5926- { SIGFPE, "SIGFPE - Floating point error signal" },
5927- { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
5928- { SIGTERM, "SIGTERM - Termination request signal" },
5929- { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
5930- };
5931-
5932- struct FatalConditionHandler {
5933-
5934- static void handleSignal( int sig ) {
5935- for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
5936- if( sig == signalDefs[i].id )
5937- fatal( signalDefs[i].name, -sig );
5938- fatal( "<unknown signal>", -sig );
5939- }
5940-
5941- FatalConditionHandler() : m_isSet( true ) {
5942- for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
5943- signal( signalDefs[i].id, handleSignal );
5944- }
5945- ~FatalConditionHandler() {
5946- reset();
5947- }
5948- void reset() {
5949- if( m_isSet ) {
5950- for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
5951- signal( signalDefs[i].id, SIG_DFL );
5952- m_isSet = false;
5953- }
5954- }
5955-
5956- bool m_isSet;
5957- };
5958-
5959-} // namespace Catch
5960-
5961-#endif // not Windows
5962-
5963-#include <set>
5964-#include <string>
5965-
5966-namespace Catch {
5967-
5968- class StreamRedirect {
5969-
5970- public:
5971- StreamRedirect( std::ostream& stream, std::string& targetString )
5972- : m_stream( stream ),
5973- m_prevBuf( stream.rdbuf() ),
5974- m_targetString( targetString )
5975- {
5976- stream.rdbuf( m_oss.rdbuf() );
5977- }
5978-
5979- ~StreamRedirect() {
5980- m_targetString += m_oss.str();
5981- m_stream.rdbuf( m_prevBuf );
5982- }
5983-
5984- private:
5985- std::ostream& m_stream;
5986- std::streambuf* m_prevBuf;
5987- std::ostringstream m_oss;
5988- std::string& m_targetString;
5989- };
5990-
5991- ///////////////////////////////////////////////////////////////////////////
5992-
5993- class RunContext : public IResultCapture, public IRunner {
5994-
5995- RunContext( RunContext const& );
5996- void operator =( RunContext const& );
5997-
5998- public:
5999-
6000- explicit RunContext( Ptr<IConfig const> const& _config, Ptr<IStreamingReporter> const& reporter )
6001- : m_runInfo( _config->name() ),
6002- m_context( getCurrentMutableContext() ),
6003- m_activeTestCase( CATCH_NULL ),
6004- m_config( _config ),
6005- m_reporter( reporter )
6006- {
6007- m_context.setRunner( this );
6008- m_context.setConfig( m_config );
6009- m_context.setResultCapture( this );
6010- m_reporter->testRunStarting( m_runInfo );
6011- }
6012-
6013- virtual ~RunContext() {
6014- m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );
6015- }
6016-
6017- void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
6018- m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) );
6019- }
6020- void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) {
6021- m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );
6022- }
6023-
6024- Totals runTest( TestCase const& testCase ) {
6025- Totals prevTotals = m_totals;
6026-
6027- std::string redirectedCout;
6028- std::string redirectedCerr;
6029-
6030- TestCaseInfo testInfo = testCase.getTestCaseInfo();
6031-
6032- m_reporter->testCaseStarting( testInfo );
6033-
6034- m_activeTestCase = &testCase;
6035-
6036- do {
6037- m_trackerContext.startRun();
6038- do {
6039- m_trackerContext.startCycle();
6040- m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, testInfo.name );
6041- runCurrentTest( redirectedCout, redirectedCerr );
6042- }
6043- while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() );
6044- }
6045- // !TBD: deprecated - this will be replaced by indexed trackers
6046- while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
6047-
6048- Totals deltaTotals = m_totals.delta( prevTotals );
6049- if( testInfo.expectedToFail() && deltaTotals.testCases.passed > 0 ) {
6050- deltaTotals.assertions.failed++;
6051- deltaTotals.testCases.passed--;
6052- deltaTotals.testCases.failed++;
6053- }
6054- m_totals.testCases += deltaTotals.testCases;
6055- m_reporter->testCaseEnded( TestCaseStats( testInfo,
6056- deltaTotals,
6057- redirectedCout,
6058- redirectedCerr,
6059- aborting() ) );
6060-
6061- m_activeTestCase = CATCH_NULL;
6062- m_testCaseTracker = CATCH_NULL;
6063-
6064- return deltaTotals;
6065- }
6066-
6067- Ptr<IConfig const> config() const {
6068- return m_config;
6069- }
6070-
6071- private: // IResultCapture
6072-
6073- virtual void assertionEnded( AssertionResult const& result ) {
6074- if( result.getResultType() == ResultWas::Ok ) {
6075- m_totals.assertions.passed++;
6076- }
6077- else if( !result.isOk() ) {
6078- m_totals.assertions.failed++;
6079- }
6080-
6081- if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) )
6082- m_messages.clear();
6083-
6084- // Reset working state
6085- m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
6086- m_lastResult = result;
6087- }
6088-
6089- virtual bool sectionStarted (
6090- SectionInfo const& sectionInfo,
6091- Counts& assertions
6092- )
6093- {
6094- std::ostringstream oss;
6095- oss << sectionInfo.name << "@" << sectionInfo.lineInfo;
6096-
6097- ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, oss.str() );
6098- if( !sectionTracker.isOpen() )
6099- return false;
6100- m_activeSections.push_back( &sectionTracker );
6101-
6102- m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
6103-
6104- m_reporter->sectionStarting( sectionInfo );
6105-
6106- assertions = m_totals.assertions;
6107-
6108- return true;
6109- }
6110- bool testForMissingAssertions( Counts& assertions ) {
6111- if( assertions.total() != 0 )
6112- return false;
6113- if( !m_config->warnAboutMissingAssertions() )
6114- return false;
6115- if( m_trackerContext.currentTracker().hasChildren() )
6116- return false;
6117- m_totals.assertions.failed++;
6118- assertions.failed++;
6119- return true;
6120- }
6121-
6122- virtual void sectionEnded( SectionEndInfo const& endInfo ) {
6123- Counts assertions = m_totals.assertions - endInfo.prevAssertions;
6124- bool missingAssertions = testForMissingAssertions( assertions );
6125-
6126- if( !m_activeSections.empty() ) {
6127- m_activeSections.back()->close();
6128- m_activeSections.pop_back();
6129- }
6130-
6131- m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) );
6132- m_messages.clear();
6133- }
6134-
6135- virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) {
6136- if( m_unfinishedSections.empty() )
6137- m_activeSections.back()->fail();
6138- else
6139- m_activeSections.back()->close();
6140- m_activeSections.pop_back();
6141-
6142- m_unfinishedSections.push_back( endInfo );
6143- }
6144-
6145- virtual void pushScopedMessage( MessageInfo const& message ) {
6146- m_messages.push_back( message );
6147- }
6148-
6149- virtual void popScopedMessage( MessageInfo const& message ) {
6150- m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() );
6151- }
6152-
6153- virtual std::string getCurrentTestName() const {
6154- return m_activeTestCase
6155- ? m_activeTestCase->getTestCaseInfo().name
6156- : "";
6157- }
6158-
6159- virtual const AssertionResult* getLastResult() const {
6160- return &m_lastResult;
6161- }
6162-
6163- virtual void handleFatalErrorCondition( std::string const& message ) {
6164- ResultBuilder resultBuilder = makeUnexpectedResultBuilder();
6165- resultBuilder.setResultType( ResultWas::FatalErrorCondition );
6166- resultBuilder << message;
6167- resultBuilder.captureExpression();
6168-
6169- handleUnfinishedSections();
6170-
6171- // Recreate section for test case (as we will lose the one that was in scope)
6172- TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
6173- SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
6174-
6175- Counts assertions;
6176- assertions.failed = 1;
6177- SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false );
6178- m_reporter->sectionEnded( testCaseSectionStats );
6179-
6180- TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo();
6181-
6182- Totals deltaTotals;
6183- deltaTotals.testCases.failed = 1;
6184- m_reporter->testCaseEnded( TestCaseStats( testInfo,
6185- deltaTotals,
6186- "",
6187- "",
6188- false ) );
6189- m_totals.testCases.failed++;
6190- testGroupEnded( "", m_totals, 1, 1 );
6191- m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) );
6192- }
6193-
6194- public:
6195- // !TBD We need to do this another way!
6196- bool aborting() const {
6197- return m_totals.assertions.failed == static_cast<std::size_t>( m_config->abortAfter() );
6198- }
6199-
6200- private:
6201-
6202- void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
6203- TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
6204- SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
6205- m_reporter->sectionStarting( testCaseSection );
6206- Counts prevAssertions = m_totals.assertions;
6207- double duration = 0;
6208- try {
6209- m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
6210-
6211- seedRng( *m_config );
6212-
6213- Timer timer;
6214- timer.start();
6215- if( m_reporter->getPreferences().shouldRedirectStdOut ) {
6216- StreamRedirect coutRedir( Catch::cout(), redirectedCout );
6217- StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr );
6218- invokeActiveTestCase();
6219- }
6220- else {
6221- invokeActiveTestCase();
6222- }
6223- duration = timer.getElapsedSeconds();
6224- }
6225- catch( TestFailureException& ) {
6226- // This just means the test was aborted due to failure
6227- }
6228- catch(...) {
6229- makeUnexpectedResultBuilder().useActiveException();
6230- }
6231- m_testCaseTracker->close();
6232- handleUnfinishedSections();
6233- m_messages.clear();
6234-
6235- Counts assertions = m_totals.assertions - prevAssertions;
6236- bool missingAssertions = testForMissingAssertions( assertions );
6237-
6238- if( testCaseInfo.okToFail() ) {
6239- std::swap( assertions.failedButOk, assertions.failed );
6240- m_totals.assertions.failed -= assertions.failedButOk;
6241- m_totals.assertions.failedButOk += assertions.failedButOk;
6242- }
6243-
6244- SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );
6245- m_reporter->sectionEnded( testCaseSectionStats );
6246- }
6247-
6248- void invokeActiveTestCase() {
6249- FatalConditionHandler fatalConditionHandler; // Handle signals
6250- m_activeTestCase->invoke();
6251- fatalConditionHandler.reset();
6252- }
6253-
6254- private:
6255-
6256- ResultBuilder makeUnexpectedResultBuilder() const {
6257- return ResultBuilder( m_lastAssertionInfo.macroName.c_str(),
6258- m_lastAssertionInfo.lineInfo,
6259- m_lastAssertionInfo.capturedExpression.c_str(),
6260- m_lastAssertionInfo.resultDisposition );
6261- }
6262-
6263- void handleUnfinishedSections() {
6264- // If sections ended prematurely due to an exception we stored their
6265- // infos here so we can tear them down outside the unwind process.
6266- for( std::vector<SectionEndInfo>::const_reverse_iterator it = m_unfinishedSections.rbegin(),
6267- itEnd = m_unfinishedSections.rend();
6268- it != itEnd;
6269- ++it )
6270- sectionEnded( *it );
6271- m_unfinishedSections.clear();
6272- }
6273-
6274- TestRunInfo m_runInfo;
6275- IMutableContext& m_context;
6276- TestCase const* m_activeTestCase;
6277- ITracker* m_testCaseTracker;
6278- ITracker* m_currentSectionTracker;
6279- AssertionResult m_lastResult;
6280-
6281- Ptr<IConfig const> m_config;
6282- Totals m_totals;
6283- Ptr<IStreamingReporter> m_reporter;
6284- std::vector<MessageInfo> m_messages;
6285- AssertionInfo m_lastAssertionInfo;
6286- std::vector<SectionEndInfo> m_unfinishedSections;
6287- std::vector<ITracker*> m_activeSections;
6288- TrackerContext m_trackerContext;
6289- };
6290-
6291- IResultCapture& getResultCapture() {
6292- if( IResultCapture* capture = getCurrentContext().getResultCapture() )
6293- return *capture;
6294- else
6295- throw std::logic_error( "No result capture instance" );
6296- }
6297-
6298-} // end namespace Catch
6299-
6300-// #included from: internal/catch_version.h
6301-#define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED
6302-
6303-namespace Catch {
6304-
6305- // Versioning information
6306- struct Version {
6307- Version( unsigned int _majorVersion,
6308- unsigned int _minorVersion,
6309- unsigned int _patchNumber,
6310- std::string const& _branchName,
6311- unsigned int _buildNumber );
6312-
6313- unsigned int const majorVersion;
6314- unsigned int const minorVersion;
6315- unsigned int const patchNumber;
6316-
6317- // buildNumber is only used if branchName is not null
6318- std::string const branchName;
6319- unsigned int const buildNumber;
6320-
6321- friend std::ostream& operator << ( std::ostream& os, Version const& version );
6322-
6323- private:
6324- void operator=( Version const& );
6325- };
6326-
6327- extern Version libraryVersion;
6328-}
6329-
6330-#include <fstream>
6331-#include <stdlib.h>
6332-#include <limits>
6333-
6334-namespace Catch {
6335-
6336- Ptr<IStreamingReporter> createReporter( std::string const& reporterName, Ptr<Config> const& config ) {
6337- Ptr<IStreamingReporter> reporter = getRegistryHub().getReporterRegistry().create( reporterName, config.get() );
6338- if( !reporter ) {
6339- std::ostringstream oss;
6340- oss << "No reporter registered with name: '" << reporterName << "'";
6341- throw std::domain_error( oss.str() );
6342- }
6343- return reporter;
6344- }
6345-
6346- Ptr<IStreamingReporter> makeReporter( Ptr<Config> const& config ) {
6347- std::vector<std::string> reporters = config->getReporterNames();
6348- if( reporters.empty() )
6349- reporters.push_back( "console" );
6350-
6351- Ptr<IStreamingReporter> reporter;
6352- for( std::vector<std::string>::const_iterator it = reporters.begin(), itEnd = reporters.end();
6353- it != itEnd;
6354- ++it )
6355- reporter = addReporter( reporter, createReporter( *it, config ) );
6356- return reporter;
6357- }
6358- Ptr<IStreamingReporter> addListeners( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> reporters ) {
6359- IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners();
6360- for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end();
6361- it != itEnd;
6362- ++it )
6363- reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) );
6364- return reporters;
6365- }
6366-
6367- Totals runTests( Ptr<Config> const& config ) {
6368-
6369- Ptr<IConfig const> iconfig = config.get();
6370-
6371- Ptr<IStreamingReporter> reporter = makeReporter( config );
6372- reporter = addListeners( iconfig, reporter );
6373-
6374- RunContext context( iconfig, reporter );
6375-
6376- Totals totals;
6377-
6378- context.testGroupStarting( config->name(), 1, 1 );
6379-
6380- TestSpec testSpec = config->testSpec();
6381- if( !testSpec.hasFilters() )
6382- testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests
6383-
6384- std::vector<TestCase> const& allTestCases = getAllTestCasesSorted( *iconfig );
6385- for( std::vector<TestCase>::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end();
6386- it != itEnd;
6387- ++it ) {
6388- if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) )
6389- totals += context.runTest( *it );
6390- else
6391- reporter->skipTest( *it );
6392- }
6393-
6394- context.testGroupEnded( iconfig->name(), totals, 1, 1 );
6395- return totals;
6396- }
6397-
6398- void applyFilenamesAsTags( IConfig const& config ) {
6399- std::vector<TestCase> const& tests = getAllTestCasesSorted( config );
6400- for(std::size_t i = 0; i < tests.size(); ++i ) {
6401- TestCase& test = const_cast<TestCase&>( tests[i] );
6402- std::set<std::string> tags = test.tags;
6403-
6404- std::string filename = test.lineInfo.file;
6405- std::string::size_type lastSlash = filename.find_last_of( "\\/" );
6406- if( lastSlash != std::string::npos )
6407- filename = filename.substr( lastSlash+1 );
6408-
6409- std::string::size_type lastDot = filename.find_last_of( "." );
6410- if( lastDot != std::string::npos )
6411- filename = filename.substr( 0, lastDot );
6412-
6413- tags.insert( "#" + filename );
6414- setTags( test, tags );
6415- }
6416- }
6417-
6418- class Session : NonCopyable {
6419- static bool alreadyInstantiated;
6420-
6421- public:
6422-
6423- struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; };
6424-
6425- Session()
6426- : m_cli( makeCommandLineParser() ) {
6427- if( alreadyInstantiated ) {
6428- std::string msg = "Only one instance of Catch::Session can ever be used";
6429- Catch::cerr() << msg << std::endl;
6430- throw std::logic_error( msg );
6431- }
6432- alreadyInstantiated = true;
6433- }
6434- ~Session() {
6435- Catch::cleanUp();
6436- }
6437-
6438- void showHelp( std::string const& processName ) {
6439- Catch::cout() << "\nCatch v" << libraryVersion << "\n";
6440-
6441- m_cli.usage( Catch::cout(), processName );
6442- Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
6443- }
6444-
6445- int applyCommandLine( int argc, char const* const* const argv, OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
6446- try {
6447- m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
6448- m_unusedTokens = m_cli.parseInto( Clara::argsToVector( argc, argv ), m_configData );
6449- if( m_configData.showHelp )
6450- showHelp( m_configData.processName );
6451- m_config.reset();
6452- }
6453- catch( std::exception& ex ) {
6454- {
6455- Colour colourGuard( Colour::Red );
6456- Catch::cerr()
6457- << "\nError(s) in input:\n"
6458- << Text( ex.what(), TextAttributes().setIndent(2) )
6459- << "\n\n";
6460- }
6461- m_cli.usage( Catch::cout(), m_configData.processName );
6462- return (std::numeric_limits<int>::max)();
6463- }
6464- return 0;
6465- }
6466-
6467- void useConfigData( ConfigData const& _configData ) {
6468- m_configData = _configData;
6469- m_config.reset();
6470- }
6471-
6472- int run( int argc, char const* const* const argv ) {
6473-
6474- int returnCode = applyCommandLine( argc, argv );
6475- if( returnCode == 0 )
6476- returnCode = run();
6477- return returnCode;
6478- }
6479-
6480- int run() {
6481- if( m_configData.showHelp )
6482- return 0;
6483-
6484- try
6485- {
6486- config(); // Force config to be constructed
6487-
6488- seedRng( *m_config );
6489-
6490- if( m_configData.filenamesAsTags )
6491- applyFilenamesAsTags( *m_config );
6492-
6493- // Handle list request
6494- if( Option<std::size_t> listed = list( config() ) )
6495- return static_cast<int>( *listed );
6496-
6497- return static_cast<int>( runTests( m_config ).assertions.failed );
6498- }
6499- catch( std::exception& ex ) {
6500- Catch::cerr() << ex.what() << std::endl;
6501- return (std::numeric_limits<int>::max)();
6502- }
6503- }
6504-
6505- Clara::CommandLine<ConfigData> const& cli() const {
6506- return m_cli;
6507- }
6508- std::vector<Clara::Parser::Token> const& unusedTokens() const {
6509- return m_unusedTokens;
6510- }
6511- ConfigData& configData() {
6512- return m_configData;
6513- }
6514- Config& config() {
6515- if( !m_config )
6516- m_config = new Config( m_configData );
6517- return *m_config;
6518- }
6519- private:
6520- Clara::CommandLine<ConfigData> m_cli;
6521- std::vector<Clara::Parser::Token> m_unusedTokens;
6522- ConfigData m_configData;
6523- Ptr<Config> m_config;
6524- };
6525-
6526- bool Session::alreadyInstantiated = false;
6527-
6528-} // end namespace Catch
6529-
6530-// #included from: catch_registry_hub.hpp
6531-#define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED
6532-
6533-// #included from: catch_test_case_registry_impl.hpp
6534-#define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
6535-
6536-#include <vector>
6537-#include <set>
6538-#include <sstream>
6539-#include <iostream>
6540-#include <algorithm>
6541-
6542-namespace Catch {
6543-
6544- struct RandomNumberGenerator {
6545- typedef std::ptrdiff_t result_type;
6546-
6547- result_type operator()( result_type n ) const { return std::rand() % n; }
6548-
6549-#ifdef CATCH_CONFIG_CPP11_SHUFFLE
6550- static constexpr result_type min() { return 0; }
6551- static constexpr result_type max() { return 1000000; }
6552- result_type operator()() const { return std::rand() % max(); }
6553-#endif
6554- template<typename V>
6555- static void shuffle( V& vector ) {
6556- RandomNumberGenerator rng;
6557-#ifdef CATCH_CONFIG_CPP11_SHUFFLE
6558- std::shuffle( vector.begin(), vector.end(), rng );
6559-#else
6560- std::random_shuffle( vector.begin(), vector.end(), rng );
6561-#endif
6562- }
6563- };
6564-
6565- inline std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
6566-
6567- std::vector<TestCase> sorted = unsortedTestCases;
6568-
6569- switch( config.runOrder() ) {
6570- case RunTests::InLexicographicalOrder:
6571- std::sort( sorted.begin(), sorted.end() );
6572- break;
6573- case RunTests::InRandomOrder:
6574- {
6575- seedRng( config );
6576- RandomNumberGenerator::shuffle( sorted );
6577- }
6578- break;
6579- case RunTests::InDeclarationOrder:
6580- // already in declaration order
6581- break;
6582- }
6583- return sorted;
6584- }
6585- bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
6586- return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
6587- }
6588-
6589- void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
6590- std::set<TestCase> seenFunctions;
6591- for( std::vector<TestCase>::const_iterator it = functions.begin(), itEnd = functions.end();
6592- it != itEnd;
6593- ++it ) {
6594- std::pair<std::set<TestCase>::const_iterator, bool> prev = seenFunctions.insert( *it );
6595- if( !prev.second ) {
6596- std::ostringstream ss;
6597-
6598- ss << Colour( Colour::Red )
6599- << "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n"
6600- << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
6601- << "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl;
6602-
6603- throw std::runtime_error(ss.str());
6604- }
6605- }
6606- }
6607-
6608- std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
6609- std::vector<TestCase> filtered;
6610- filtered.reserve( testCases.size() );
6611- for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end();
6612- it != itEnd;
6613- ++it )
6614- if( matchTest( *it, testSpec, config ) )
6615- filtered.push_back( *it );
6616- return filtered;
6617- }
6618- std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
6619- return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
6620- }
6621-
6622- class TestRegistry : public ITestCaseRegistry {
6623- public:
6624- TestRegistry()
6625- : m_currentSortOrder( RunTests::InDeclarationOrder ),
6626- m_unnamedCount( 0 )
6627- {}
6628- virtual ~TestRegistry();
6629-
6630- virtual void registerTest( TestCase const& testCase ) {
6631- std::string name = testCase.getTestCaseInfo().name;
6632- if( name == "" ) {
6633- std::ostringstream oss;
6634- oss << "Anonymous test case " << ++m_unnamedCount;
6635- return registerTest( testCase.withName( oss.str() ) );
6636- }
6637- m_functions.push_back( testCase );
6638- }
6639-
6640- virtual std::vector<TestCase> const& getAllTests() const {
6641- return m_functions;
6642- }
6643- virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const {
6644- if( m_sortedFunctions.empty() )
6645- enforceNoDuplicateTestCases( m_functions );
6646-
6647- if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
6648- m_sortedFunctions = sortTests( config, m_functions );
6649- m_currentSortOrder = config.runOrder();
6650- }
6651- return m_sortedFunctions;
6652- }
6653-
6654- private:
6655- std::vector<TestCase> m_functions;
6656- mutable RunTests::InWhatOrder m_currentSortOrder;
6657- mutable std::vector<TestCase> m_sortedFunctions;
6658- size_t m_unnamedCount;
6659- std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
6660- };
6661-
6662- ///////////////////////////////////////////////////////////////////////////
6663-
6664- class FreeFunctionTestCase : public SharedImpl<ITestCase> {
6665- public:
6666-
6667- FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}
6668-
6669- virtual void invoke() const {
6670- m_fun();
6671- }
6672-
6673- private:
6674- virtual ~FreeFunctionTestCase();
6675-
6676- TestFunction m_fun;
6677- };
6678-
6679- inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) {
6680- std::string className = classOrQualifiedMethodName;
6681- if( startsWith( className, "&" ) )
6682- {
6683- std::size_t lastColons = className.rfind( "::" );
6684- std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
6685- if( penultimateColons == std::string::npos )
6686- penultimateColons = 1;
6687- className = className.substr( penultimateColons, lastColons-penultimateColons );
6688- }
6689- return className;
6690- }
6691-
6692- void registerTestCase
6693- ( ITestCase* testCase,
6694- char const* classOrQualifiedMethodName,
6695- NameAndDesc const& nameAndDesc,
6696- SourceLineInfo const& lineInfo ) {
6697-
6698- getMutableRegistryHub().registerTest
6699- ( makeTestCase
6700- ( testCase,
6701- extractClassName( classOrQualifiedMethodName ),
6702- nameAndDesc.name,
6703- nameAndDesc.description,
6704- lineInfo ) );
6705- }
6706- void registerTestCaseFunction
6707- ( TestFunction function,
6708- SourceLineInfo const& lineInfo,
6709- NameAndDesc const& nameAndDesc ) {
6710- registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
6711- }
6712-
6713- ///////////////////////////////////////////////////////////////////////////
6714-
6715- AutoReg::AutoReg
6716- ( TestFunction function,
6717- SourceLineInfo const& lineInfo,
6718- NameAndDesc const& nameAndDesc ) {
6719- registerTestCaseFunction( function, lineInfo, nameAndDesc );
6720- }
6721-
6722- AutoReg::~AutoReg() {}
6723-
6724-} // end namespace Catch
6725-
6726-// #included from: catch_reporter_registry.hpp
6727-#define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED
6728-
6729-#include <map>
6730-
6731-namespace Catch {
6732-
6733- class ReporterRegistry : public IReporterRegistry {
6734-
6735- public:
6736-
6737- virtual ~ReporterRegistry() CATCH_OVERRIDE {}
6738-
6739- virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const CATCH_OVERRIDE {
6740- FactoryMap::const_iterator it = m_factories.find( name );
6741- if( it == m_factories.end() )
6742- return CATCH_NULL;
6743- return it->second->create( ReporterConfig( config ) );
6744- }
6745-
6746- void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) {
6747- m_factories.insert( std::make_pair( name, factory ) );
6748- }
6749- void registerListener( Ptr<IReporterFactory> const& factory ) {
6750- m_listeners.push_back( factory );
6751- }
6752-
6753- virtual FactoryMap const& getFactories() const CATCH_OVERRIDE {
6754- return m_factories;
6755- }
6756- virtual Listeners const& getListeners() const CATCH_OVERRIDE {
6757- return m_listeners;
6758- }
6759-
6760- private:
6761- FactoryMap m_factories;
6762- Listeners m_listeners;
6763- };
6764-}
6765-
6766-// #included from: catch_exception_translator_registry.hpp
6767-#define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
6768-
6769-#ifdef __OBJC__
6770-#import "Foundation/Foundation.h"
6771-#endif
6772-
6773-namespace Catch {
6774-
6775- class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
6776- public:
6777- ~ExceptionTranslatorRegistry() {
6778- deleteAll( m_translators );
6779- }
6780-
6781- virtual void registerTranslator( const IExceptionTranslator* translator ) {
6782- m_translators.push_back( translator );
6783- }
6784-
6785- virtual std::string translateActiveException() const {
6786- try {
6787-#ifdef __OBJC__
6788- // In Objective-C try objective-c exceptions first
6789- @try {
6790- return tryTranslators();
6791- }
6792- @catch (NSException *exception) {
6793- return Catch::toString( [exception description] );
6794- }
6795-#else
6796- return tryTranslators();
6797-#endif
6798- }
6799- catch( TestFailureException& ) {
6800- throw;
6801- }
6802- catch( std::exception& ex ) {
6803- return ex.what();
6804- }
6805- catch( std::string& msg ) {
6806- return msg;
6807- }
6808- catch( const char* msg ) {
6809- return msg;
6810- }
6811- catch(...) {
6812- return "Unknown exception";
6813- }
6814- }
6815-
6816- std::string tryTranslators() const {
6817- if( m_translators.empty() )
6818- throw;
6819- else
6820- return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );
6821- }
6822-
6823- private:
6824- std::vector<const IExceptionTranslator*> m_translators;
6825- };
6826-}
6827-
6828-namespace Catch {
6829-
6830- namespace {
6831-
6832- class RegistryHub : public IRegistryHub, public IMutableRegistryHub {
6833-
6834- RegistryHub( RegistryHub const& );
6835- void operator=( RegistryHub const& );
6836-
6837- public: // IRegistryHub
6838- RegistryHub() {
6839- }
6840- virtual IReporterRegistry const& getReporterRegistry() const CATCH_OVERRIDE {
6841- return m_reporterRegistry;
6842- }
6843- virtual ITestCaseRegistry const& getTestCaseRegistry() const CATCH_OVERRIDE {
6844- return m_testCaseRegistry;
6845- }
6846- virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE {
6847- return m_exceptionTranslatorRegistry;
6848- }
6849-
6850- public: // IMutableRegistryHub
6851- virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
6852- m_reporterRegistry.registerReporter( name, factory );
6853- }
6854- virtual void registerListener( Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
6855- m_reporterRegistry.registerListener( factory );
6856- }
6857- virtual void registerTest( TestCase const& testInfo ) CATCH_OVERRIDE {
6858- m_testCaseRegistry.registerTest( testInfo );
6859- }
6860- virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE {
6861- m_exceptionTranslatorRegistry.registerTranslator( translator );
6862- }
6863-
6864- private:
6865- TestRegistry m_testCaseRegistry;
6866- ReporterRegistry m_reporterRegistry;
6867- ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
6868- };
6869-
6870- // Single, global, instance
6871- inline RegistryHub*& getTheRegistryHub() {
6872- static RegistryHub* theRegistryHub = CATCH_NULL;
6873- if( !theRegistryHub )
6874- theRegistryHub = new RegistryHub();
6875- return theRegistryHub;
6876- }
6877- }
6878-
6879- IRegistryHub& getRegistryHub() {
6880- return *getTheRegistryHub();
6881- }
6882- IMutableRegistryHub& getMutableRegistryHub() {
6883- return *getTheRegistryHub();
6884- }
6885- void cleanUp() {
6886- delete getTheRegistryHub();
6887- getTheRegistryHub() = CATCH_NULL;
6888- cleanUpContext();
6889- }
6890- std::string translateActiveException() {
6891- return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
6892- }
6893-
6894-} // end namespace Catch
6895-
6896-// #included from: catch_notimplemented_exception.hpp
6897-#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED
6898-
6899-#include <ostream>
6900-
6901-namespace Catch {
6902-
6903- NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo )
6904- : m_lineInfo( lineInfo ) {
6905- std::ostringstream oss;
6906- oss << lineInfo << ": function ";
6907- oss << "not implemented";
6908- m_what = oss.str();
6909- }
6910-
6911- const char* NotImplementedException::what() const CATCH_NOEXCEPT {
6912- return m_what.c_str();
6913- }
6914-
6915-} // end namespace Catch
6916-
6917-// #included from: catch_context_impl.hpp
6918-#define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
6919-
6920-// #included from: catch_stream.hpp
6921-#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
6922-
6923-#include <stdexcept>
6924-#include <cstdio>
6925-#include <iostream>
6926-
6927-namespace Catch {
6928-
6929- template<typename WriterF, size_t bufferSize=256>
6930- class StreamBufImpl : public StreamBufBase {
6931- char data[bufferSize];
6932- WriterF m_writer;
6933-
6934- public:
6935- StreamBufImpl() {
6936- setp( data, data + sizeof(data) );
6937- }
6938-
6939- ~StreamBufImpl() CATCH_NOEXCEPT {
6940- sync();
6941- }
6942-
6943- private:
6944- int overflow( int c ) {
6945- sync();
6946-
6947- if( c != EOF ) {
6948- if( pbase() == epptr() )
6949- m_writer( std::string( 1, static_cast<char>( c ) ) );
6950- else
6951- sputc( static_cast<char>( c ) );
6952- }
6953- return 0;
6954- }
6955-
6956- int sync() {
6957- if( pbase() != pptr() ) {
6958- m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
6959- setp( pbase(), epptr() );
6960- }
6961- return 0;
6962- }
6963- };
6964-
6965- ///////////////////////////////////////////////////////////////////////////
6966-
6967- FileStream::FileStream( std::string const& filename ) {
6968- m_ofs.open( filename.c_str() );
6969- if( m_ofs.fail() ) {
6970- std::ostringstream oss;
6971- oss << "Unable to open file: '" << filename << "'";
6972- throw std::domain_error( oss.str() );
6973- }
6974- }
6975-
6976- std::ostream& FileStream::stream() const {
6977- return m_ofs;
6978- }
6979-
6980- struct OutputDebugWriter {
6981-
6982- void operator()( std::string const&str ) {
6983- writeToDebugConsole( str );
6984- }
6985- };
6986-
6987- DebugOutStream::DebugOutStream()
6988- : m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
6989- m_os( m_streamBuf.get() )
6990- {}
6991-
6992- std::ostream& DebugOutStream::stream() const {
6993- return m_os;
6994- }
6995-
6996- // Store the streambuf from cout up-front because
6997- // cout may get redirected when running tests
6998- CoutStream::CoutStream()
6999- : m_os( Catch::cout().rdbuf() )
7000- {}
7001-
7002- std::ostream& CoutStream::stream() const {
7003- return m_os;
7004- }
7005-
7006-#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
7007- std::ostream& cout() {
7008- return std::cout;
7009- }
7010- std::ostream& cerr() {
7011- return std::cerr;
7012- }
7013-#endif
7014-}
7015-
7016-namespace Catch {
7017-
7018- class Context : public IMutableContext {
7019-
7020- Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {}
7021- Context( Context const& );
7022- void operator=( Context const& );
7023-
7024- public:
7025- virtual ~Context() {
7026- deleteAllValues( m_generatorsByTestName );
7027- }
7028-
7029- public: // IContext
7030- virtual IResultCapture* getResultCapture() {
7031- return m_resultCapture;
7032- }
7033- virtual IRunner* getRunner() {
7034- return m_runner;
7035- }
7036- virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) {
7037- return getGeneratorsForCurrentTest()
7038- .getGeneratorInfo( fileInfo, totalSize )
7039- .getCurrentIndex();
7040- }
7041- virtual bool advanceGeneratorsForCurrentTest() {
7042- IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
7043- return generators && generators->moveNext();
7044- }
7045-
7046- virtual Ptr<IConfig const> getConfig() const {
7047- return m_config;
7048- }
7049-
7050- public: // IMutableContext
7051- virtual void setResultCapture( IResultCapture* resultCapture ) {
7052- m_resultCapture = resultCapture;
7053- }
7054- virtual void setRunner( IRunner* runner ) {
7055- m_runner = runner;
7056- }
7057- virtual void setConfig( Ptr<IConfig const> const& config ) {
7058- m_config = config;
7059- }
7060-
7061- friend IMutableContext& getCurrentMutableContext();
7062-
7063- private:
7064- IGeneratorsForTest* findGeneratorsForCurrentTest() {
7065- std::string testName = getResultCapture()->getCurrentTestName();
7066-
7067- std::map<std::string, IGeneratorsForTest*>::const_iterator it =
7068- m_generatorsByTestName.find( testName );
7069- return it != m_generatorsByTestName.end()
7070- ? it->second
7071- : CATCH_NULL;
7072- }
7073-
7074- IGeneratorsForTest& getGeneratorsForCurrentTest() {
7075- IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
7076- if( !generators ) {
7077- std::string testName = getResultCapture()->getCurrentTestName();
7078- generators = createGeneratorsForTest();
7079- m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
7080- }
7081- return *generators;
7082- }
7083-
7084- private:
7085- Ptr<IConfig const> m_config;
7086- IRunner* m_runner;
7087- IResultCapture* m_resultCapture;
7088- std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
7089- };
7090-
7091- namespace {
7092- Context* currentContext = CATCH_NULL;
7093- }
7094- IMutableContext& getCurrentMutableContext() {
7095- if( !currentContext )
7096- currentContext = new Context();
7097- return *currentContext;
7098- }
7099- IContext& getCurrentContext() {
7100- return getCurrentMutableContext();
7101- }
7102-
7103- void cleanUpContext() {
7104- delete currentContext;
7105- currentContext = CATCH_NULL;
7106- }
7107-}
7108-
7109-// #included from: catch_console_colour_impl.hpp
7110-#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
7111-
7112-namespace Catch {
7113- namespace {
7114-
7115- struct IColourImpl {
7116- virtual ~IColourImpl() {}
7117- virtual void use( Colour::Code _colourCode ) = 0;
7118- };
7119-
7120- struct NoColourImpl : IColourImpl {
7121- void use( Colour::Code ) {}
7122-
7123- static IColourImpl* instance() {
7124- static NoColourImpl s_instance;
7125- return &s_instance;
7126- }
7127- };
7128-
7129- } // anon namespace
7130-} // namespace Catch
7131-
7132-#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
7133-# ifdef CATCH_PLATFORM_WINDOWS
7134-# define CATCH_CONFIG_COLOUR_WINDOWS
7135-# else
7136-# define CATCH_CONFIG_COLOUR_ANSI
7137-# endif
7138-#endif
7139-
7140-#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
7141-
7142-// #included from: catch_windows_h_proxy.h
7143-
7144-#define TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED
7145-
7146-#ifdef CATCH_DEFINES_NOMINMAX
7147-# define NOMINMAX
7148-#endif
7149-#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN
7150-# define WIN32_LEAN_AND_MEAN
7151-#endif
7152-
7153-#ifdef __AFXDLL
7154-#include <AfxWin.h>
7155-#else
7156-#include <windows.h>
7157-#endif
7158-
7159-#ifdef CATCH_DEFINES_NOMINMAX
7160-# undef NOMINMAX
7161-#endif
7162-#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN
7163-# undef WIN32_LEAN_AND_MEAN
7164-#endif
7165-
7166-namespace Catch {
7167-namespace {
7168-
7169- class Win32ColourImpl : public IColourImpl {
7170- public:
7171- Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
7172- {
7173- CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
7174- GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
7175- originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
7176- originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
7177- }
7178-
7179- virtual void use( Colour::Code _colourCode ) {
7180- switch( _colourCode ) {
7181- case Colour::None: return setTextAttribute( originalForegroundAttributes );
7182- case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
7183- case Colour::Red: return setTextAttribute( FOREGROUND_RED );
7184- case Colour::Green: return setTextAttribute( FOREGROUND_GREEN );
7185- case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE );
7186- case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
7187- case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
7188- case Colour::Grey: return setTextAttribute( 0 );
7189-
7190- case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY );
7191- case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
7192- case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
7193- case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
7194-
7195- case Colour::Bright: throw std::logic_error( "not a colour" );
7196- }
7197- }
7198-
7199- private:
7200- void setTextAttribute( WORD _textAttribute ) {
7201- SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
7202- }
7203- HANDLE stdoutHandle;
7204- WORD originalForegroundAttributes;
7205- WORD originalBackgroundAttributes;
7206- };
7207-
7208- IColourImpl* platformColourInstance() {
7209- static Win32ColourImpl s_instance;
7210-
7211- Ptr<IConfig const> config = getCurrentContext().getConfig();
7212- UseColour::YesOrNo colourMode = config
7213- ? config->useColour()
7214- : UseColour::Auto;
7215- if( colourMode == UseColour::Auto )
7216- colourMode = !isDebuggerActive()
7217- ? UseColour::Yes
7218- : UseColour::No;
7219- return colourMode == UseColour::Yes
7220- ? &s_instance
7221- : NoColourImpl::instance();
7222- }
7223-
7224-} // end anon namespace
7225-} // end namespace Catch
7226-
7227-#elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
7228-
7229-#include <unistd.h>
7230-
7231-namespace Catch {
7232-namespace {
7233-
7234- // use POSIX/ ANSI console terminal codes
7235- // Thanks to Adam Strzelecki for original contribution
7236- // (http://github.com/nanoant)
7237- // https://github.com/philsquared/Catch/pull/131
7238- class PosixColourImpl : public IColourImpl {
7239- public:
7240- virtual void use( Colour::Code _colourCode ) {
7241- switch( _colourCode ) {
7242- case Colour::None:
7243- case Colour::White: return setColour( "[0m" );
7244- case Colour::Red: return setColour( "[0;31m" );
7245- case Colour::Green: return setColour( "[0;32m" );
7246- case Colour::Blue: return setColour( "[0;34m" );
7247- case Colour::Cyan: return setColour( "[0;36m" );
7248- case Colour::Yellow: return setColour( "[0;33m" );
7249- case Colour::Grey: return setColour( "[1;30m" );
7250-
7251- case Colour::LightGrey: return setColour( "[0;37m" );
7252- case Colour::BrightRed: return setColour( "[1;31m" );
7253- case Colour::BrightGreen: return setColour( "[1;32m" );
7254- case Colour::BrightWhite: return setColour( "[1;37m" );
7255-
7256- case Colour::Bright: throw std::logic_error( "not a colour" );
7257- }
7258- }
7259- static IColourImpl* instance() {
7260- static PosixColourImpl s_instance;
7261- return &s_instance;
7262- }
7263-
7264- private:
7265- void setColour( const char* _escapeCode ) {
7266- Catch::cout() << '\033' << _escapeCode;
7267- }
7268- };
7269-
7270- IColourImpl* platformColourInstance() {
7271- Ptr<IConfig const> config = getCurrentContext().getConfig();
7272- UseColour::YesOrNo colourMode = config
7273- ? config->useColour()
7274- : UseColour::Auto;
7275- if( colourMode == UseColour::Auto )
7276- colourMode = (!isDebuggerActive() && isatty(STDOUT_FILENO) )
7277- ? UseColour::Yes
7278- : UseColour::No;
7279- return colourMode == UseColour::Yes
7280- ? PosixColourImpl::instance()
7281- : NoColourImpl::instance();
7282- }
7283-
7284-} // end anon namespace
7285-} // end namespace Catch
7286-
7287-#else // not Windows or ANSI ///////////////////////////////////////////////
7288-
7289-namespace Catch {
7290-
7291- static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
7292-
7293-} // end namespace Catch
7294-
7295-#endif // Windows/ ANSI/ None
7296-
7297-namespace Catch {
7298-
7299- Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); }
7300- Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast<Colour&>( _other ).m_moved = true; }
7301- Colour::~Colour(){ if( !m_moved ) use( None ); }
7302-
7303- void Colour::use( Code _colourCode ) {
7304- static IColourImpl* impl = platformColourInstance();
7305- impl->use( _colourCode );
7306- }
7307-
7308-} // end namespace Catch
7309-
7310-// #included from: catch_generators_impl.hpp
7311-#define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED
7312-
7313-#include <vector>
7314-#include <string>
7315-#include <map>
7316-
7317-namespace Catch {
7318-
7319- struct GeneratorInfo : IGeneratorInfo {
7320-
7321- GeneratorInfo( std::size_t size )
7322- : m_size( size ),
7323- m_currentIndex( 0 )
7324- {}
7325-
7326- bool moveNext() {
7327- if( ++m_currentIndex == m_size ) {
7328- m_currentIndex = 0;
7329- return false;
7330- }
7331- return true;
7332- }
7333-
7334- std::size_t getCurrentIndex() const {
7335- return m_currentIndex;
7336- }
7337-
7338- std::size_t m_size;
7339- std::size_t m_currentIndex;
7340- };
7341-
7342- ///////////////////////////////////////////////////////////////////////////
7343-
7344- class GeneratorsForTest : public IGeneratorsForTest {
7345-
7346- public:
7347- ~GeneratorsForTest() {
7348- deleteAll( m_generatorsInOrder );
7349- }
7350-
7351- IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) {
7352- std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );
7353- if( it == m_generatorsByName.end() ) {
7354- IGeneratorInfo* info = new GeneratorInfo( size );
7355- m_generatorsByName.insert( std::make_pair( fileInfo, info ) );
7356- m_generatorsInOrder.push_back( info );
7357- return *info;
7358- }
7359- return *it->second;
7360- }
7361-
7362- bool moveNext() {
7363- std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
7364- std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();
7365- for(; it != itEnd; ++it ) {
7366- if( (*it)->moveNext() )
7367- return true;
7368- }
7369- return false;
7370- }
7371-
7372- private:
7373- std::map<std::string, IGeneratorInfo*> m_generatorsByName;
7374- std::vector<IGeneratorInfo*> m_generatorsInOrder;
7375- };
7376-
7377- IGeneratorsForTest* createGeneratorsForTest()
7378- {
7379- return new GeneratorsForTest();
7380- }
7381-
7382-} // end namespace Catch
7383-
7384-// #included from: catch_assertionresult.hpp
7385-#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED
7386-
7387-namespace Catch {
7388-
7389- AssertionInfo::AssertionInfo( std::string const& _macroName,
7390- SourceLineInfo const& _lineInfo,
7391- std::string const& _capturedExpression,
7392- ResultDisposition::Flags _resultDisposition )
7393- : macroName( _macroName ),
7394- lineInfo( _lineInfo ),
7395- capturedExpression( _capturedExpression ),
7396- resultDisposition( _resultDisposition )
7397- {}
7398-
7399- AssertionResult::AssertionResult() {}
7400-
7401- AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
7402- : m_info( info ),
7403- m_resultData( data )
7404- {}
7405-
7406- AssertionResult::~AssertionResult() {}
7407-
7408- // Result was a success
7409- bool AssertionResult::succeeded() const {
7410- return Catch::isOk( m_resultData.resultType );
7411- }
7412-
7413- // Result was a success, or failure is suppressed
7414- bool AssertionResult::isOk() const {
7415- return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
7416- }
7417-
7418- ResultWas::OfType AssertionResult::getResultType() const {
7419- return m_resultData.resultType;
7420- }
7421-
7422- bool AssertionResult::hasExpression() const {
7423- return !m_info.capturedExpression.empty();
7424- }
7425-
7426- bool AssertionResult::hasMessage() const {
7427- return !m_resultData.message.empty();
7428- }
7429-
7430- std::string AssertionResult::getExpression() const {
7431- if( isFalseTest( m_info.resultDisposition ) )
7432- return "!" + m_info.capturedExpression;
7433- else
7434- return m_info.capturedExpression;
7435- }
7436- std::string AssertionResult::getExpressionInMacro() const {
7437- if( m_info.macroName.empty() )
7438- return m_info.capturedExpression;
7439- else
7440- return m_info.macroName + "( " + m_info.capturedExpression + " )";
7441- }
7442-
7443- bool AssertionResult::hasExpandedExpression() const {
7444- return hasExpression() && getExpandedExpression() != getExpression();
7445- }
7446-
7447- std::string AssertionResult::getExpandedExpression() const {
7448- return m_resultData.reconstructedExpression;
7449- }
7450-
7451- std::string AssertionResult::getMessage() const {
7452- return m_resultData.message;
7453- }
7454- SourceLineInfo AssertionResult::getSourceInfo() const {
7455- return m_info.lineInfo;
7456- }
7457-
7458- std::string AssertionResult::getTestMacroName() const {
7459- return m_info.macroName;
7460- }
7461-
7462-} // end namespace Catch
7463-
7464-// #included from: catch_test_case_info.hpp
7465-#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED
7466-
7467-namespace Catch {
7468-
7469- inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
7470- if( startsWith( tag, "." ) ||
7471- tag == "hide" ||
7472- tag == "!hide" )
7473- return TestCaseInfo::IsHidden;
7474- else if( tag == "!throws" )
7475- return TestCaseInfo::Throws;
7476- else if( tag == "!shouldfail" )
7477- return TestCaseInfo::ShouldFail;
7478- else if( tag == "!mayfail" )
7479- return TestCaseInfo::MayFail;
7480- else
7481- return TestCaseInfo::None;
7482- }
7483- inline bool isReservedTag( std::string const& tag ) {
7484- return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !isalnum( tag[0] );
7485- }
7486- inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
7487- if( isReservedTag( tag ) ) {
7488- {
7489- Colour colourGuard( Colour::Red );
7490- Catch::cerr()
7491- << "Tag name [" << tag << "] not allowed.\n"
7492- << "Tag names starting with non alpha-numeric characters are reserved\n";
7493- }
7494- {
7495- Colour colourGuard( Colour::FileName );
7496- Catch::cerr() << _lineInfo << std::endl;
7497- }
7498- exit(1);
7499- }
7500- }
7501-
7502- TestCase makeTestCase( ITestCase* _testCase,
7503- std::string const& _className,
7504- std::string const& _name,
7505- std::string const& _descOrTags,
7506- SourceLineInfo const& _lineInfo )
7507- {
7508- bool isHidden( startsWith( _name, "./" ) ); // Legacy support
7509-
7510- // Parse out tags
7511- std::set<std::string> tags;
7512- std::string desc, tag;
7513- bool inTag = false;
7514- for( std::size_t i = 0; i < _descOrTags.size(); ++i ) {
7515- char c = _descOrTags[i];
7516- if( !inTag ) {
7517- if( c == '[' )
7518- inTag = true;
7519- else
7520- desc += c;
7521- }
7522- else {
7523- if( c == ']' ) {
7524- TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
7525- if( prop == TestCaseInfo::IsHidden )
7526- isHidden = true;
7527- else if( prop == TestCaseInfo::None )
7528- enforceNotReservedTag( tag, _lineInfo );
7529-
7530- tags.insert( tag );
7531- tag.clear();
7532- inTag = false;
7533- }
7534- else
7535- tag += c;
7536- }
7537- }
7538- if( isHidden ) {
7539- tags.insert( "hide" );
7540- tags.insert( "." );
7541- }
7542-
7543- TestCaseInfo info( _name, _className, desc, tags, _lineInfo );
7544- return TestCase( _testCase, info );
7545- }
7546-
7547- void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags )
7548- {
7549- testCaseInfo.tags = tags;
7550- testCaseInfo.lcaseTags.clear();
7551-
7552- std::ostringstream oss;
7553- for( std::set<std::string>::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) {
7554- oss << "[" << *it << "]";
7555- std::string lcaseTag = toLower( *it );
7556- testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
7557- testCaseInfo.lcaseTags.insert( lcaseTag );
7558- }
7559- testCaseInfo.tagsAsString = oss.str();
7560- }
7561-
7562- TestCaseInfo::TestCaseInfo( std::string const& _name,
7563- std::string const& _className,
7564- std::string const& _description,
7565- std::set<std::string> const& _tags,
7566- SourceLineInfo const& _lineInfo )
7567- : name( _name ),
7568- className( _className ),
7569- description( _description ),
7570- lineInfo( _lineInfo ),
7571- properties( None )
7572- {
7573- setTags( *this, _tags );
7574- }
7575-
7576- TestCaseInfo::TestCaseInfo( TestCaseInfo const& other )
7577- : name( other.name ),
7578- className( other.className ),
7579- description( other.description ),
7580- tags( other.tags ),
7581- lcaseTags( other.lcaseTags ),
7582- tagsAsString( other.tagsAsString ),
7583- lineInfo( other.lineInfo ),
7584- properties( other.properties )
7585- {}
7586-
7587- bool TestCaseInfo::isHidden() const {
7588- return ( properties & IsHidden ) != 0;
7589- }
7590- bool TestCaseInfo::throws() const {
7591- return ( properties & Throws ) != 0;
7592- }
7593- bool TestCaseInfo::okToFail() const {
7594- return ( properties & (ShouldFail | MayFail ) ) != 0;
7595- }
7596- bool TestCaseInfo::expectedToFail() const {
7597- return ( properties & (ShouldFail ) ) != 0;
7598- }
7599-
7600- TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}
7601-
7602- TestCase::TestCase( TestCase const& other )
7603- : TestCaseInfo( other ),
7604- test( other.test )
7605- {}
7606-
7607- TestCase TestCase::withName( std::string const& _newName ) const {
7608- TestCase other( *this );
7609- other.name = _newName;
7610- return other;
7611- }
7612-
7613- void TestCase::swap( TestCase& other ) {
7614- test.swap( other.test );
7615- name.swap( other.name );
7616- className.swap( other.className );
7617- description.swap( other.description );
7618- tags.swap( other.tags );
7619- lcaseTags.swap( other.lcaseTags );
7620- tagsAsString.swap( other.tagsAsString );
7621- std::swap( TestCaseInfo::properties, static_cast<TestCaseInfo&>( other ).properties );
7622- std::swap( lineInfo, other.lineInfo );
7623- }
7624-
7625- void TestCase::invoke() const {
7626- test->invoke();
7627- }
7628-
7629- bool TestCase::operator == ( TestCase const& other ) const {
7630- return test.get() == other.test.get() &&
7631- name == other.name &&
7632- className == other.className;
7633- }
7634-
7635- bool TestCase::operator < ( TestCase const& other ) const {
7636- return name < other.name;
7637- }
7638- TestCase& TestCase::operator = ( TestCase const& other ) {
7639- TestCase temp( other );
7640- swap( temp );
7641- return *this;
7642- }
7643-
7644- TestCaseInfo const& TestCase::getTestCaseInfo() const
7645- {
7646- return *this;
7647- }
7648-
7649-} // end namespace Catch
7650-
7651-// #included from: catch_version.hpp
7652-#define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED
7653-
7654-namespace Catch {
7655-
7656- Version::Version
7657- ( unsigned int _majorVersion,
7658- unsigned int _minorVersion,
7659- unsigned int _patchNumber,
7660- std::string const& _branchName,
7661- unsigned int _buildNumber )
7662- : majorVersion( _majorVersion ),
7663- minorVersion( _minorVersion ),
7664- patchNumber( _patchNumber ),
7665- branchName( _branchName ),
7666- buildNumber( _buildNumber )
7667- {}
7668-
7669- std::ostream& operator << ( std::ostream& os, Version const& version ) {
7670- os << version.majorVersion << "."
7671- << version.minorVersion << "."
7672- << version.patchNumber;
7673-
7674- if( !version.branchName.empty() ) {
7675- os << "-" << version.branchName
7676- << "." << version.buildNumber;
7677- }
7678- return os;
7679- }
7680-
7681- Version libraryVersion( 1, 6, 1, "", 0 );
7682-
7683-}
7684-
7685-// #included from: catch_message.hpp
7686-#define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED
7687-
7688-namespace Catch {
7689-
7690- MessageInfo::MessageInfo( std::string const& _macroName,
7691- SourceLineInfo const& _lineInfo,
7692- ResultWas::OfType _type )
7693- : macroName( _macroName ),
7694- lineInfo( _lineInfo ),
7695- type( _type ),
7696- sequence( ++globalCount )
7697- {}
7698-
7699- // This may need protecting if threading support is added
7700- unsigned int MessageInfo::globalCount = 0;
7701-
7702- ////////////////////////////////////////////////////////////////////////////
7703-
7704- ScopedMessage::ScopedMessage( MessageBuilder const& builder )
7705- : m_info( builder.m_info )
7706- {
7707- m_info.message = builder.m_stream.str();
7708- getResultCapture().pushScopedMessage( m_info );
7709- }
7710- ScopedMessage::ScopedMessage( ScopedMessage const& other )
7711- : m_info( other.m_info )
7712- {}
7713-
7714- ScopedMessage::~ScopedMessage() {
7715- getResultCapture().popScopedMessage( m_info );
7716- }
7717-
7718-} // end namespace Catch
7719-
7720-// #included from: catch_legacy_reporter_adapter.hpp
7721-#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED
7722-
7723-// #included from: catch_legacy_reporter_adapter.h
7724-#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED
7725-
7726-namespace Catch
7727-{
7728- // Deprecated
7729- struct IReporter : IShared {
7730- virtual ~IReporter();
7731-
7732- virtual bool shouldRedirectStdout() const = 0;
7733-
7734- virtual void StartTesting() = 0;
7735- virtual void EndTesting( Totals const& totals ) = 0;
7736- virtual void StartGroup( std::string const& groupName ) = 0;
7737- virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0;
7738- virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0;
7739- virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0;
7740- virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0;
7741- virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0;
7742- virtual void NoAssertionsInSection( std::string const& sectionName ) = 0;
7743- virtual void NoAssertionsInTestCase( std::string const& testName ) = 0;
7744- virtual void Aborted() = 0;
7745- virtual void Result( AssertionResult const& result ) = 0;
7746- };
7747-
7748- class LegacyReporterAdapter : public SharedImpl<IStreamingReporter>
7749- {
7750- public:
7751- LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter );
7752- virtual ~LegacyReporterAdapter();
7753-
7754- virtual ReporterPreferences getPreferences() const;
7755- virtual void noMatchingTestCases( std::string const& );
7756- virtual void testRunStarting( TestRunInfo const& );
7757- virtual void testGroupStarting( GroupInfo const& groupInfo );
7758- virtual void testCaseStarting( TestCaseInfo const& testInfo );
7759- virtual void sectionStarting( SectionInfo const& sectionInfo );
7760- virtual void assertionStarting( AssertionInfo const& );
7761- virtual bool assertionEnded( AssertionStats const& assertionStats );
7762- virtual void sectionEnded( SectionStats const& sectionStats );
7763- virtual void testCaseEnded( TestCaseStats const& testCaseStats );
7764- virtual void testGroupEnded( TestGroupStats const& testGroupStats );
7765- virtual void testRunEnded( TestRunStats const& testRunStats );
7766- virtual void skipTest( TestCaseInfo const& );
7767-
7768- private:
7769- Ptr<IReporter> m_legacyReporter;
7770- };
7771-}
7772-
7773-namespace Catch
7774-{
7775- LegacyReporterAdapter::LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter )
7776- : m_legacyReporter( legacyReporter )
7777- {}
7778- LegacyReporterAdapter::~LegacyReporterAdapter() {}
7779-
7780- ReporterPreferences LegacyReporterAdapter::getPreferences() const {
7781- ReporterPreferences prefs;
7782- prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout();
7783- return prefs;
7784- }
7785-
7786- void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {}
7787- void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) {
7788- m_legacyReporter->StartTesting();
7789- }
7790- void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) {
7791- m_legacyReporter->StartGroup( groupInfo.name );
7792- }
7793- void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) {
7794- m_legacyReporter->StartTestCase( testInfo );
7795- }
7796- void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) {
7797- m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description );
7798- }
7799- void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) {
7800- // Not on legacy interface
7801- }
7802-
7803- bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) {
7804- if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
7805- for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
7806- it != itEnd;
7807- ++it ) {
7808- if( it->type == ResultWas::Info ) {
7809- ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal );
7810- rb << it->message;
7811- rb.setResultType( ResultWas::Info );
7812- AssertionResult result = rb.build();
7813- m_legacyReporter->Result( result );
7814- }
7815- }
7816- }
7817- m_legacyReporter->Result( assertionStats.assertionResult );
7818- return true;
7819- }
7820- void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) {
7821- if( sectionStats.missingAssertions )
7822- m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name );
7823- m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions );
7824- }
7825- void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) {
7826- m_legacyReporter->EndTestCase
7827- ( testCaseStats.testInfo,
7828- testCaseStats.totals,
7829- testCaseStats.stdOut,
7830- testCaseStats.stdErr );
7831- }
7832- void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) {
7833- if( testGroupStats.aborting )
7834- m_legacyReporter->Aborted();
7835- m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals );
7836- }
7837- void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) {
7838- m_legacyReporter->EndTesting( testRunStats.totals );
7839- }
7840- void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) {
7841- }
7842-}
7843-
7844-// #included from: catch_timer.hpp
7845-
7846-#ifdef __clang__
7847-#pragma clang diagnostic push
7848-#pragma clang diagnostic ignored "-Wc++11-long-long"
7849-#endif
7850-
7851-#ifdef CATCH_PLATFORM_WINDOWS
7852-#else
7853-#include <sys/time.h>
7854-#endif
7855-
7856-namespace Catch {
7857-
7858- namespace {
7859-#ifdef CATCH_PLATFORM_WINDOWS
7860- uint64_t getCurrentTicks() {
7861- static uint64_t hz=0, hzo=0;
7862- if (!hz) {
7863- QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>( &hz ) );
7864- QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &hzo ) );
7865- }
7866- uint64_t t;
7867- QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &t ) );
7868- return ((t-hzo)*1000000)/hz;
7869- }
7870-#else
7871- uint64_t getCurrentTicks() {
7872- timeval t;
7873- gettimeofday(&t,CATCH_NULL);
7874- return static_cast<uint64_t>( t.tv_sec ) * 1000000ull + static_cast<uint64_t>( t.tv_usec );
7875- }
7876-#endif
7877- }
7878-
7879- void Timer::start() {
7880- m_ticks = getCurrentTicks();
7881- }
7882- unsigned int Timer::getElapsedMicroseconds() const {
7883- return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
7884- }
7885- unsigned int Timer::getElapsedMilliseconds() const {
7886- return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
7887- }
7888- double Timer::getElapsedSeconds() const {
7889- return getElapsedMicroseconds()/1000000.0;
7890- }
7891-
7892-} // namespace Catch
7893-
7894-#ifdef __clang__
7895-#pragma clang diagnostic pop
7896-#endif
7897-// #included from: catch_common.hpp
7898-#define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED
7899-
7900-namespace Catch {
7901-
7902- bool startsWith( std::string const& s, std::string const& prefix ) {
7903- return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
7904- }
7905- bool endsWith( std::string const& s, std::string const& suffix ) {
7906- return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
7907- }
7908- bool contains( std::string const& s, std::string const& infix ) {
7909- return s.find( infix ) != std::string::npos;
7910- }
7911- char toLowerCh(char c) {
7912- return static_cast<char>( ::tolower( c ) );
7913- }
7914- void toLowerInPlace( std::string& s ) {
7915- std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
7916- }
7917- std::string toLower( std::string const& s ) {
7918- std::string lc = s;
7919- toLowerInPlace( lc );
7920- return lc;
7921- }
7922- std::string trim( std::string const& str ) {
7923- static char const* whitespaceChars = "\n\r\t ";
7924- std::string::size_type start = str.find_first_not_of( whitespaceChars );
7925- std::string::size_type end = str.find_last_not_of( whitespaceChars );
7926-
7927- return start != std::string::npos ? str.substr( start, 1+end-start ) : "";
7928- }
7929-
7930- bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
7931- bool replaced = false;
7932- std::size_t i = str.find( replaceThis );
7933- while( i != std::string::npos ) {
7934- replaced = true;
7935- str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
7936- if( i < str.size()-withThis.size() )
7937- i = str.find( replaceThis, i+withThis.size() );
7938- else
7939- i = std::string::npos;
7940- }
7941- return replaced;
7942- }
7943-
7944- pluralise::pluralise( std::size_t count, std::string const& label )
7945- : m_count( count ),
7946- m_label( label )
7947- {}
7948-
7949- std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
7950- os << pluraliser.m_count << " " << pluraliser.m_label;
7951- if( pluraliser.m_count != 1 )
7952- os << "s";
7953- return os;
7954- }
7955-
7956- SourceLineInfo::SourceLineInfo() : line( 0 ){}
7957- SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )
7958- : file( _file ),
7959- line( _line )
7960- {}
7961- SourceLineInfo::SourceLineInfo( SourceLineInfo const& other )
7962- : file( other.file ),
7963- line( other.line )
7964- {}
7965- bool SourceLineInfo::empty() const {
7966- return file.empty();
7967- }
7968- bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {
7969- return line == other.line && file == other.file;
7970- }
7971- bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const {
7972- return line < other.line || ( line == other.line && file < other.file );
7973- }
7974-
7975- void seedRng( IConfig const& config ) {
7976- if( config.rngSeed() != 0 )
7977- std::srand( config.rngSeed() );
7978- }
7979- unsigned int rngSeed() {
7980- return getCurrentContext().getConfig()->rngSeed();
7981- }
7982-
7983- std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
7984-#ifndef __GNUG__
7985- os << info.file << "(" << info.line << ")";
7986-#else
7987- os << info.file << ":" << info.line;
7988-#endif
7989- return os;
7990- }
7991-
7992- void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
7993- std::ostringstream oss;
7994- oss << locationInfo << ": Internal Catch error: '" << message << "'";
7995- if( alwaysTrue() )
7996- throw std::logic_error( oss.str() );
7997- }
7998-}
7999-
8000-// #included from: catch_section.hpp
8001-#define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
8002-
8003-namespace Catch {
8004-
8005- SectionInfo::SectionInfo
8006- ( SourceLineInfo const& _lineInfo,
8007- std::string const& _name,
8008- std::string const& _description )
8009- : name( _name ),
8010- description( _description ),
8011- lineInfo( _lineInfo )
8012- {}
8013-
8014- Section::Section( SectionInfo const& info )
8015- : m_info( info ),
8016- m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
8017- {
8018- m_timer.start();
8019- }
8020-
8021- Section::~Section() {
8022- if( m_sectionIncluded ) {
8023- SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
8024- if( std::uncaught_exception() )
8025- getResultCapture().sectionEndedEarly( endInfo );
8026- else
8027- getResultCapture().sectionEnded( endInfo );
8028- }
8029- }
8030-
8031- // This indicates whether the section should be executed or not
8032- Section::operator bool() const {
8033- return m_sectionIncluded;
8034- }
8035-
8036-} // end namespace Catch
8037-
8038-// #included from: catch_debugger.hpp
8039-#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
8040-
8041-#include <iostream>
8042-
8043-#ifdef CATCH_PLATFORM_MAC
8044-
8045- #include <assert.h>
8046- #include <stdbool.h>
8047- #include <sys/types.h>
8048- #include <unistd.h>
8049- #include <sys/sysctl.h>
8050-
8051- namespace Catch{
8052-
8053- // The following function is taken directly from the following technical note:
8054- // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
8055-
8056- // Returns true if the current process is being debugged (either
8057- // running under the debugger or has a debugger attached post facto).
8058- bool isDebuggerActive(){
8059-
8060- int mib[4];
8061- struct kinfo_proc info;
8062- size_t size;
8063-
8064- // Initialize the flags so that, if sysctl fails for some bizarre
8065- // reason, we get a predictable result.
8066-
8067- info.kp_proc.p_flag = 0;
8068-
8069- // Initialize mib, which tells sysctl the info we want, in this case
8070- // we're looking for information about a specific process ID.
8071-
8072- mib[0] = CTL_KERN;
8073- mib[1] = KERN_PROC;
8074- mib[2] = KERN_PROC_PID;
8075- mib[3] = getpid();
8076-
8077- // Call sysctl.
8078-
8079- size = sizeof(info);
8080- if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) {
8081- Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
8082- return false;
8083- }
8084-
8085- // We're being debugged if the P_TRACED flag is set.
8086-
8087- return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
8088- }
8089- } // namespace Catch
8090-
8091-#elif defined(CATCH_PLATFORM_LINUX)
8092- #include <fstream>
8093- #include <string>
8094-
8095- namespace Catch{
8096- // The standard POSIX way of detecting a debugger is to attempt to
8097- // ptrace() the process, but this needs to be done from a child and not
8098- // this process itself to still allow attaching to this process later
8099- // if wanted, so is rather heavy. Under Linux we have the PID of the
8100- // "debugger" (which doesn't need to be gdb, of course, it could also
8101- // be strace, for example) in /proc/$PID/status, so just get it from
8102- // there instead.
8103- bool isDebuggerActive(){
8104- std::ifstream in("/proc/self/status");
8105- for( std::string line; std::getline(in, line); ) {
8106- static const int PREFIX_LEN = 11;
8107- if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
8108- // We're traced if the PID is not 0 and no other PID starts
8109- // with 0 digit, so it's enough to check for just a single
8110- // character.
8111- return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
8112- }
8113- }
8114-
8115- return false;
8116- }
8117- } // namespace Catch
8118-#elif defined(_MSC_VER)
8119- extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
8120- namespace Catch {
8121- bool isDebuggerActive() {
8122- return IsDebuggerPresent() != 0;
8123- }
8124- }
8125-#elif defined(__MINGW32__)
8126- extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
8127- namespace Catch {
8128- bool isDebuggerActive() {
8129- return IsDebuggerPresent() != 0;
8130- }
8131- }
8132-#else
8133- namespace Catch {
8134- inline bool isDebuggerActive() { return false; }
8135- }
8136-#endif // Platform
8137-
8138-#ifdef CATCH_PLATFORM_WINDOWS
8139- extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* );
8140- namespace Catch {
8141- void writeToDebugConsole( std::string const& text ) {
8142- ::OutputDebugStringA( text.c_str() );
8143- }
8144- }
8145-#else
8146- namespace Catch {
8147- void writeToDebugConsole( std::string const& text ) {
8148- // !TBD: Need a version for Mac/ XCode and other IDEs
8149- Catch::cout() << text;
8150- }
8151- }
8152-#endif // Platform
8153-
8154-// #included from: catch_tostring.hpp
8155-#define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED
8156-
8157-namespace Catch {
8158-
8159-namespace Detail {
8160-
8161- const std::string unprintableString = "{?}";
8162-
8163- namespace {
8164- const int hexThreshold = 255;
8165-
8166- struct Endianness {
8167- enum Arch { Big, Little };
8168-
8169- static Arch which() {
8170- union _{
8171- int asInt;
8172- char asChar[sizeof (int)];
8173- } u;
8174-
8175- u.asInt = 1;
8176- return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
8177- }
8178- };
8179- }
8180-
8181- std::string rawMemoryToString( const void *object, std::size_t size )
8182- {
8183- // Reverse order for little endian architectures
8184- int i = 0, end = static_cast<int>( size ), inc = 1;
8185- if( Endianness::which() == Endianness::Little ) {
8186- i = end-1;
8187- end = inc = -1;
8188- }
8189-
8190- unsigned char const *bytes = static_cast<unsigned char const *>(object);
8191- std::ostringstream os;
8192- os << "0x" << std::setfill('0') << std::hex;
8193- for( ; i != end; i += inc )
8194- os << std::setw(2) << static_cast<unsigned>(bytes[i]);
8195- return os.str();
8196- }
8197-}
8198-
8199-std::string toString( std::string const& value ) {
8200- std::string s = value;
8201- if( getCurrentContext().getConfig()->showInvisibles() ) {
8202- for(size_t i = 0; i < s.size(); ++i ) {
8203- std::string subs;
8204- switch( s[i] ) {
8205- case '\n': subs = "\\n"; break;
8206- case '\t': subs = "\\t"; break;
8207- default: break;
8208- }
8209- if( !subs.empty() ) {
8210- s = s.substr( 0, i ) + subs + s.substr( i+1 );
8211- ++i;
8212- }
8213- }
8214- }
8215- return "\"" + s + "\"";
8216-}
8217-std::string toString( std::wstring const& value ) {
8218-
8219- std::string s;
8220- s.reserve( value.size() );
8221- for(size_t i = 0; i < value.size(); ++i )
8222- s += value[i] <= 0xff ? static_cast<char>( value[i] ) : '?';
8223- return Catch::toString( s );
8224-}
8225-
8226-std::string toString( const char* const value ) {
8227- return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" );
8228-}
8229-
8230-std::string toString( char* const value ) {
8231- return Catch::toString( static_cast<const char*>( value ) );
8232-}
8233-
8234-std::string toString( const wchar_t* const value )
8235-{
8236- return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" );
8237-}
8238-
8239-std::string toString( wchar_t* const value )
8240-{
8241- return Catch::toString( static_cast<const wchar_t*>( value ) );
8242-}
8243-
8244-std::string toString( int value ) {
8245- std::ostringstream oss;
8246- oss << value;
8247- if( value > Detail::hexThreshold )
8248- oss << " (0x" << std::hex << value << ")";
8249- return oss.str();
8250-}
8251-
8252-std::string toString( unsigned long value ) {
8253- std::ostringstream oss;
8254- oss << value;
8255- if( value > Detail::hexThreshold )
8256- oss << " (0x" << std::hex << value << ")";
8257- return oss.str();
8258-}
8259-
8260-std::string toString( unsigned int value ) {
8261- return Catch::toString( static_cast<unsigned long>( value ) );
8262-}
8263-
8264-template<typename T>
8265-std::string fpToString( T value, int precision ) {
8266- std::ostringstream oss;
8267- oss << std::setprecision( precision )
8268- << std::fixed
8269- << value;
8270- std::string d = oss.str();
8271- std::size_t i = d.find_last_not_of( '0' );
8272- if( i != std::string::npos && i != d.size()-1 ) {
8273- if( d[i] == '.' )
8274- i++;
8275- d = d.substr( 0, i+1 );
8276- }
8277- return d;
8278-}
8279-
8280-std::string toString( const double value ) {
8281- return fpToString( value, 10 );
8282-}
8283-std::string toString( const float value ) {
8284- return fpToString( value, 5 ) + "f";
8285-}
8286-
8287-std::string toString( bool value ) {
8288- return value ? "true" : "false";
8289-}
8290-
8291-std::string toString( char value ) {
8292- return value < ' '
8293- ? toString( static_cast<unsigned int>( value ) )
8294- : Detail::makeString( value );
8295-}
8296-
8297-std::string toString( signed char value ) {
8298- return toString( static_cast<char>( value ) );
8299-}
8300-
8301-std::string toString( unsigned char value ) {
8302- return toString( static_cast<char>( value ) );
8303-}
8304-
8305-#ifdef CATCH_CONFIG_CPP11_LONG_LONG
8306-std::string toString( long long value ) {
8307- std::ostringstream oss;
8308- oss << value;
8309- if( value > Detail::hexThreshold )
8310- oss << " (0x" << std::hex << value << ")";
8311- return oss.str();
8312-}
8313-std::string toString( unsigned long long value ) {
8314- std::ostringstream oss;
8315- oss << value;
8316- if( value > Detail::hexThreshold )
8317- oss << " (0x" << std::hex << value << ")";
8318- return oss.str();
8319-}
8320-#endif
8321-
8322-#ifdef CATCH_CONFIG_CPP11_NULLPTR
8323-std::string toString( std::nullptr_t ) {
8324- return "nullptr";
8325-}
8326-#endif
8327-
8328-#ifdef __OBJC__
8329- std::string toString( NSString const * const& nsstring ) {
8330- if( !nsstring )
8331- return "nil";
8332- return "@" + toString([nsstring UTF8String]);
8333- }
8334- std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) {
8335- if( !nsstring )
8336- return "nil";
8337- return "@" + toString([nsstring UTF8String]);
8338- }
8339- std::string toString( NSObject* const& nsObject ) {
8340- return toString( [nsObject description] );
8341- }
8342-#endif
8343-
8344-} // end namespace Catch
8345-
8346-// #included from: catch_result_builder.hpp
8347-#define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED
8348-
8349-namespace Catch {
8350-
8351- std::string capturedExpressionWithSecondArgument( std::string const& capturedExpression, std::string const& secondArg ) {
8352- return secondArg.empty() || secondArg == "\"\""
8353- ? capturedExpression
8354- : capturedExpression + ", " + secondArg;
8355- }
8356- ResultBuilder::ResultBuilder( char const* macroName,
8357- SourceLineInfo const& lineInfo,
8358- char const* capturedExpression,
8359- ResultDisposition::Flags resultDisposition,
8360- char const* secondArg )
8361- : m_assertionInfo( macroName, lineInfo, capturedExpressionWithSecondArgument( capturedExpression, secondArg ), resultDisposition ),
8362- m_shouldDebugBreak( false ),
8363- m_shouldThrow( false )
8364- {}
8365-
8366- ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) {
8367- m_data.resultType = result;
8368- return *this;
8369- }
8370- ResultBuilder& ResultBuilder::setResultType( bool result ) {
8371- m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;
8372- return *this;
8373- }
8374- ResultBuilder& ResultBuilder::setLhs( std::string const& lhs ) {
8375- m_exprComponents.lhs = lhs;
8376- return *this;
8377- }
8378- ResultBuilder& ResultBuilder::setRhs( std::string const& rhs ) {
8379- m_exprComponents.rhs = rhs;
8380- return *this;
8381- }
8382- ResultBuilder& ResultBuilder::setOp( std::string const& op ) {
8383- m_exprComponents.op = op;
8384- return *this;
8385- }
8386-
8387- void ResultBuilder::endExpression() {
8388- m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition );
8389- captureExpression();
8390- }
8391-
8392- void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) {
8393- m_assertionInfo.resultDisposition = resultDisposition;
8394- m_stream.oss << Catch::translateActiveException();
8395- captureResult( ResultWas::ThrewException );
8396- }
8397-
8398- void ResultBuilder::captureResult( ResultWas::OfType resultType ) {
8399- setResultType( resultType );
8400- captureExpression();
8401- }
8402- void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) {
8403- if( expectedMessage.empty() )
8404- captureExpectedException( Matchers::Impl::Generic::AllOf<std::string>() );
8405- else
8406- captureExpectedException( Matchers::Equals( expectedMessage ) );
8407- }
8408-
8409- void ResultBuilder::captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher ) {
8410-
8411- assert( m_exprComponents.testFalse == false );
8412- AssertionResultData data = m_data;
8413- data.resultType = ResultWas::Ok;
8414- data.reconstructedExpression = m_assertionInfo.capturedExpression;
8415-
8416- std::string actualMessage = Catch::translateActiveException();
8417- if( !matcher.match( actualMessage ) ) {
8418- data.resultType = ResultWas::ExpressionFailed;
8419- data.reconstructedExpression = actualMessage;
8420- }
8421- AssertionResult result( m_assertionInfo, data );
8422- handleResult( result );
8423- }
8424-
8425- void ResultBuilder::captureExpression() {
8426- AssertionResult result = build();
8427- handleResult( result );
8428- }
8429- void ResultBuilder::handleResult( AssertionResult const& result )
8430- {
8431- getResultCapture().assertionEnded( result );
8432-
8433- if( !result.isOk() ) {
8434- if( getCurrentContext().getConfig()->shouldDebugBreak() )
8435- m_shouldDebugBreak = true;
8436- if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) )
8437- m_shouldThrow = true;
8438- }
8439- }
8440- void ResultBuilder::react() {
8441- if( m_shouldThrow )
8442- throw Catch::TestFailureException();
8443- }
8444-
8445- bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; }
8446- bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); }
8447-
8448- AssertionResult ResultBuilder::build() const
8449- {
8450- assert( m_data.resultType != ResultWas::Unknown );
8451-
8452- AssertionResultData data = m_data;
8453-
8454- // Flip bool results if testFalse is set
8455- if( m_exprComponents.testFalse ) {
8456- if( data.resultType == ResultWas::Ok )
8457- data.resultType = ResultWas::ExpressionFailed;
8458- else if( data.resultType == ResultWas::ExpressionFailed )
8459- data.resultType = ResultWas::Ok;
8460- }
8461-
8462- data.message = m_stream.oss.str();
8463- data.reconstructedExpression = reconstructExpression();
8464- if( m_exprComponents.testFalse ) {
8465- if( m_exprComponents.op == "" )
8466- data.reconstructedExpression = "!" + data.reconstructedExpression;
8467- else
8468- data.reconstructedExpression = "!(" + data.reconstructedExpression + ")";
8469- }
8470- return AssertionResult( m_assertionInfo, data );
8471- }
8472- std::string ResultBuilder::reconstructExpression() const {
8473- if( m_exprComponents.op == "" )
8474- return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.lhs;
8475- else if( m_exprComponents.op == "matches" )
8476- return m_exprComponents.lhs + " " + m_exprComponents.rhs;
8477- else if( m_exprComponents.op != "!" ) {
8478- if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 &&
8479- m_exprComponents.lhs.find("\n") == std::string::npos &&
8480- m_exprComponents.rhs.find("\n") == std::string::npos )
8481- return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs;
8482- else
8483- return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs;
8484- }
8485- else
8486- return "{can't expand - use " + m_assertionInfo.macroName + "_FALSE( " + m_assertionInfo.capturedExpression.substr(1) + " ) instead of " + m_assertionInfo.macroName + "( " + m_assertionInfo.capturedExpression + " ) for better diagnostics}";
8487- }
8488-
8489-} // end namespace Catch
8490-
8491-// #included from: catch_tag_alias_registry.hpp
8492-#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
8493-
8494-// #included from: catch_tag_alias_registry.h
8495-#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED
8496-
8497-#include <map>
8498-
8499-namespace Catch {
8500-
8501- class TagAliasRegistry : public ITagAliasRegistry {
8502- public:
8503- virtual ~TagAliasRegistry();
8504- virtual Option<TagAlias> find( std::string const& alias ) const;
8505- virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const;
8506- void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
8507- static TagAliasRegistry& get();
8508-
8509- private:
8510- std::map<std::string, TagAlias> m_registry;
8511- };
8512-
8513-} // end namespace Catch
8514-
8515-#include <map>
8516-#include <iostream>
8517-
8518-namespace Catch {
8519-
8520- TagAliasRegistry::~TagAliasRegistry() {}
8521-
8522- Option<TagAlias> TagAliasRegistry::find( std::string const& alias ) const {
8523- std::map<std::string, TagAlias>::const_iterator it = m_registry.find( alias );
8524- if( it != m_registry.end() )
8525- return it->second;
8526- else
8527- return Option<TagAlias>();
8528- }
8529-
8530- std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
8531- std::string expandedTestSpec = unexpandedTestSpec;
8532- for( std::map<std::string, TagAlias>::const_iterator it = m_registry.begin(), itEnd = m_registry.end();
8533- it != itEnd;
8534- ++it ) {
8535- std::size_t pos = expandedTestSpec.find( it->first );
8536- if( pos != std::string::npos ) {
8537- expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
8538- it->second.tag +
8539- expandedTestSpec.substr( pos + it->first.size() );
8540- }
8541- }
8542- return expandedTestSpec;
8543- }
8544-
8545- void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
8546-
8547- if( !startsWith( alias, "[@" ) || !endsWith( alias, "]" ) ) {
8548- std::ostringstream oss;
8549- oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo;
8550- throw std::domain_error( oss.str().c_str() );
8551- }
8552- if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) {
8553- std::ostringstream oss;
8554- oss << "error: tag alias, \"" << alias << "\" already registered.\n"
8555- << "\tFirst seen at " << find(alias)->lineInfo << "\n"
8556- << "\tRedefined at " << lineInfo;
8557- throw std::domain_error( oss.str().c_str() );
8558- }
8559- }
8560-
8561- TagAliasRegistry& TagAliasRegistry::get() {
8562- static TagAliasRegistry instance;
8563- return instance;
8564-
8565- }
8566-
8567- ITagAliasRegistry::~ITagAliasRegistry() {}
8568- ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); }
8569-
8570- RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
8571- try {
8572- TagAliasRegistry::get().add( alias, tag, lineInfo );
8573- }
8574- catch( std::exception& ex ) {
8575- Colour colourGuard( Colour::Red );
8576- Catch::cerr() << ex.what() << std::endl;
8577- exit(1);
8578- }
8579- }
8580-
8581-} // end namespace Catch
8582-
8583-// #included from: ../reporters/catch_reporter_multi.hpp
8584-#define TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED
8585-
8586-namespace Catch {
8587-
8588-class MultipleReporters : public SharedImpl<IStreamingReporter> {
8589- typedef std::vector<Ptr<IStreamingReporter> > Reporters;
8590- Reporters m_reporters;
8591-
8592-public:
8593- void add( Ptr<IStreamingReporter> const& reporter ) {
8594- m_reporters.push_back( reporter );
8595- }
8596-
8597-public: // IStreamingReporter
8598-
8599- virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
8600- return m_reporters[0]->getPreferences();
8601- }
8602-
8603- virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
8604- for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8605- it != itEnd;
8606- ++it )
8607- (*it)->noMatchingTestCases( spec );
8608- }
8609-
8610- virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE {
8611- for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8612- it != itEnd;
8613- ++it )
8614- (*it)->testRunStarting( testRunInfo );
8615- }
8616-
8617- virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
8618- for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8619- it != itEnd;
8620- ++it )
8621- (*it)->testGroupStarting( groupInfo );
8622- }
8623-
8624- virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
8625- for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8626- it != itEnd;
8627- ++it )
8628- (*it)->testCaseStarting( testInfo );
8629- }
8630-
8631- virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
8632- for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8633- it != itEnd;
8634- ++it )
8635- (*it)->sectionStarting( sectionInfo );
8636- }
8637-
8638- virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE {
8639- for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8640- it != itEnd;
8641- ++it )
8642- (*it)->assertionStarting( assertionInfo );
8643- }
8644-
8645- // The return value indicates if the messages buffer should be cleared:
8646- virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
8647- bool clearBuffer = false;
8648- for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8649- it != itEnd;
8650- ++it )
8651- clearBuffer |= (*it)->assertionEnded( assertionStats );
8652- return clearBuffer;
8653- }
8654-
8655- virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
8656- for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8657- it != itEnd;
8658- ++it )
8659- (*it)->sectionEnded( sectionStats );
8660- }
8661-
8662- virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
8663- for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8664- it != itEnd;
8665- ++it )
8666- (*it)->testCaseEnded( testCaseStats );
8667- }
8668-
8669- virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
8670- for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8671- it != itEnd;
8672- ++it )
8673- (*it)->testGroupEnded( testGroupStats );
8674- }
8675-
8676- virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
8677- for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8678- it != itEnd;
8679- ++it )
8680- (*it)->testRunEnded( testRunStats );
8681- }
8682-
8683- virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
8684- for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8685- it != itEnd;
8686- ++it )
8687- (*it)->skipTest( testInfo );
8688- }
8689-
8690- virtual MultipleReporters* tryAsMulti() CATCH_OVERRIDE {
8691- return this;
8692- }
8693-
8694-};
8695-
8696-Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter ) {
8697- Ptr<IStreamingReporter> resultingReporter;
8698-
8699- if( existingReporter ) {
8700- MultipleReporters* multi = existingReporter->tryAsMulti();
8701- if( !multi ) {
8702- multi = new MultipleReporters;
8703- resultingReporter = Ptr<IStreamingReporter>( multi );
8704- if( existingReporter )
8705- multi->add( existingReporter );
8706- }
8707- else
8708- resultingReporter = existingReporter;
8709- multi->add( additionalReporter );
8710- }
8711- else
8712- resultingReporter = additionalReporter;
8713-
8714- return resultingReporter;
8715-}
8716-
8717-} // end namespace Catch
8718-
8719-// #included from: ../reporters/catch_reporter_xml.hpp
8720-#define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED
8721-
8722-// #included from: catch_reporter_bases.hpp
8723-#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
8724-
8725-#include <cstring>
8726-
8727-namespace Catch {
8728-
8729- struct StreamingReporterBase : SharedImpl<IStreamingReporter> {
8730-
8731- StreamingReporterBase( ReporterConfig const& _config )
8732- : m_config( _config.fullConfig() ),
8733- stream( _config.stream() )
8734- {
8735- m_reporterPrefs.shouldRedirectStdOut = false;
8736- }
8737-
8738- virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
8739- return m_reporterPrefs;
8740- }
8741-
8742- virtual ~StreamingReporterBase() CATCH_OVERRIDE;
8743-
8744- virtual void noMatchingTestCases( std::string const& ) CATCH_OVERRIDE {}
8745-
8746- virtual void testRunStarting( TestRunInfo const& _testRunInfo ) CATCH_OVERRIDE {
8747- currentTestRunInfo = _testRunInfo;
8748- }
8749- virtual void testGroupStarting( GroupInfo const& _groupInfo ) CATCH_OVERRIDE {
8750- currentGroupInfo = _groupInfo;
8751- }
8752-
8753- virtual void testCaseStarting( TestCaseInfo const& _testInfo ) CATCH_OVERRIDE {
8754- currentTestCaseInfo = _testInfo;
8755- }
8756- virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
8757- m_sectionStack.push_back( _sectionInfo );
8758- }
8759-
8760- virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) CATCH_OVERRIDE {
8761- m_sectionStack.pop_back();
8762- }
8763- virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) CATCH_OVERRIDE {
8764- currentTestCaseInfo.reset();
8765- }
8766- virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) CATCH_OVERRIDE {
8767- currentGroupInfo.reset();
8768- }
8769- virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) CATCH_OVERRIDE {
8770- currentTestCaseInfo.reset();
8771- currentGroupInfo.reset();
8772- currentTestRunInfo.reset();
8773- }
8774-
8775- virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {
8776- // Don't do anything with this by default.
8777- // It can optionally be overridden in the derived class.
8778- }
8779-
8780- Ptr<IConfig const> m_config;
8781- std::ostream& stream;
8782-
8783- LazyStat<TestRunInfo> currentTestRunInfo;
8784- LazyStat<GroupInfo> currentGroupInfo;
8785- LazyStat<TestCaseInfo> currentTestCaseInfo;
8786-
8787- std::vector<SectionInfo> m_sectionStack;
8788- ReporterPreferences m_reporterPrefs;
8789- };
8790-
8791- struct CumulativeReporterBase : SharedImpl<IStreamingReporter> {
8792- template<typename T, typename ChildNodeT>
8793- struct Node : SharedImpl<> {
8794- explicit Node( T const& _value ) : value( _value ) {}
8795- virtual ~Node() {}
8796-
8797- typedef std::vector<Ptr<ChildNodeT> > ChildNodes;
8798- T value;
8799- ChildNodes children;
8800- };
8801- struct SectionNode : SharedImpl<> {
8802- explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {}
8803- virtual ~SectionNode();
8804-
8805- bool operator == ( SectionNode const& other ) const {
8806- return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
8807- }
8808- bool operator == ( Ptr<SectionNode> const& other ) const {
8809- return operator==( *other );
8810- }
8811-
8812- SectionStats stats;
8813- typedef std::vector<Ptr<SectionNode> > ChildSections;
8814- typedef std::vector<AssertionStats> Assertions;
8815- ChildSections childSections;
8816- Assertions assertions;
8817- std::string stdOut;
8818- std::string stdErr;
8819- };
8820-
8821- struct BySectionInfo {
8822- BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
8823- BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
8824- bool operator() ( Ptr<SectionNode> const& node ) const {
8825- return node->stats.sectionInfo.lineInfo == m_other.lineInfo;
8826- }
8827- private:
8828- void operator=( BySectionInfo const& );
8829- SectionInfo const& m_other;
8830- };
8831-
8832- typedef Node<TestCaseStats, SectionNode> TestCaseNode;
8833- typedef Node<TestGroupStats, TestCaseNode> TestGroupNode;
8834- typedef Node<TestRunStats, TestGroupNode> TestRunNode;
8835-
8836- CumulativeReporterBase( ReporterConfig const& _config )
8837- : m_config( _config.fullConfig() ),
8838- stream( _config.stream() )
8839- {
8840- m_reporterPrefs.shouldRedirectStdOut = false;
8841- }
8842- ~CumulativeReporterBase();
8843-
8844- virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
8845- return m_reporterPrefs;
8846- }
8847-
8848- virtual void testRunStarting( TestRunInfo const& ) CATCH_OVERRIDE {}
8849- virtual void testGroupStarting( GroupInfo const& ) CATCH_OVERRIDE {}
8850-
8851- virtual void testCaseStarting( TestCaseInfo const& ) CATCH_OVERRIDE {}
8852-
8853- virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
8854- SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
8855- Ptr<SectionNode> node;
8856- if( m_sectionStack.empty() ) {
8857- if( !m_rootSection )
8858- m_rootSection = new SectionNode( incompleteStats );
8859- node = m_rootSection;
8860- }
8861- else {
8862- SectionNode& parentNode = *m_sectionStack.back();
8863- SectionNode::ChildSections::const_iterator it =
8864- std::find_if( parentNode.childSections.begin(),
8865- parentNode.childSections.end(),
8866- BySectionInfo( sectionInfo ) );
8867- if( it == parentNode.childSections.end() ) {
8868- node = new SectionNode( incompleteStats );
8869- parentNode.childSections.push_back( node );
8870- }
8871- else
8872- node = *it;
8873- }
8874- m_sectionStack.push_back( node );
8875- m_deepestSection = node;
8876- }
8877-
8878- virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
8879-
8880- virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
8881- assert( !m_sectionStack.empty() );
8882- SectionNode& sectionNode = *m_sectionStack.back();
8883- sectionNode.assertions.push_back( assertionStats );
8884- return true;
8885- }
8886- virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
8887- assert( !m_sectionStack.empty() );
8888- SectionNode& node = *m_sectionStack.back();
8889- node.stats = sectionStats;
8890- m_sectionStack.pop_back();
8891- }
8892- virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
8893- Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats );
8894- assert( m_sectionStack.size() == 0 );
8895- node->children.push_back( m_rootSection );
8896- m_testCases.push_back( node );
8897- m_rootSection.reset();
8898-
8899- assert( m_deepestSection );
8900- m_deepestSection->stdOut = testCaseStats.stdOut;
8901- m_deepestSection->stdErr = testCaseStats.stdErr;
8902- }
8903- virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
8904- Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats );
8905- node->children.swap( m_testCases );
8906- m_testGroups.push_back( node );
8907- }
8908- virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
8909- Ptr<TestRunNode> node = new TestRunNode( testRunStats );
8910- node->children.swap( m_testGroups );
8911- m_testRuns.push_back( node );
8912- testRunEndedCumulative();
8913- }
8914- virtual void testRunEndedCumulative() = 0;
8915-
8916- virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {}
8917-
8918- Ptr<IConfig const> m_config;
8919- std::ostream& stream;
8920- std::vector<AssertionStats> m_assertions;
8921- std::vector<std::vector<Ptr<SectionNode> > > m_sections;
8922- std::vector<Ptr<TestCaseNode> > m_testCases;
8923- std::vector<Ptr<TestGroupNode> > m_testGroups;
8924-
8925- std::vector<Ptr<TestRunNode> > m_testRuns;
8926-
8927- Ptr<SectionNode> m_rootSection;
8928- Ptr<SectionNode> m_deepestSection;
8929- std::vector<Ptr<SectionNode> > m_sectionStack;
8930- ReporterPreferences m_reporterPrefs;
8931-
8932- };
8933-
8934- template<char C>
8935- char const* getLineOfChars() {
8936- static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
8937- if( !*line ) {
8938- memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
8939- line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
8940- }
8941- return line;
8942- }
8943-
8944- struct TestEventListenerBase : StreamingReporterBase {
8945- TestEventListenerBase( ReporterConfig const& _config )
8946- : StreamingReporterBase( _config )
8947- {}
8948-
8949- virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
8950- virtual bool assertionEnded( AssertionStats const& ) CATCH_OVERRIDE {
8951- return false;
8952- }
8953- };
8954-
8955-} // end namespace Catch
8956-
8957-// #included from: ../internal/catch_reporter_registrars.hpp
8958-#define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
8959-
8960-namespace Catch {
8961-
8962- template<typename T>
8963- class LegacyReporterRegistrar {
8964-
8965- class ReporterFactory : public IReporterFactory {
8966- virtual IStreamingReporter* create( ReporterConfig const& config ) const {
8967- return new LegacyReporterAdapter( new T( config ) );
8968- }
8969-
8970- virtual std::string getDescription() const {
8971- return T::getDescription();
8972- }
8973- };
8974-
8975- public:
8976-
8977- LegacyReporterRegistrar( std::string const& name ) {
8978- getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
8979- }
8980- };
8981-
8982- template<typename T>
8983- class ReporterRegistrar {
8984-
8985- class ReporterFactory : public SharedImpl<IReporterFactory> {
8986-
8987- // *** Please Note ***:
8988- // - If you end up here looking at a compiler error because it's trying to register
8989- // your custom reporter class be aware that the native reporter interface has changed
8990- // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via
8991- // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter.
8992- // However please consider updating to the new interface as the old one is now
8993- // deprecated and will probably be removed quite soon!
8994- // Please contact me via github if you have any questions at all about this.
8995- // In fact, ideally, please contact me anyway to let me know you've hit this - as I have
8996- // no idea who is actually using custom reporters at all (possibly no-one!).
8997- // The new interface is designed to minimise exposure to interface changes in the future.
8998- virtual IStreamingReporter* create( ReporterConfig const& config ) const {
8999- return new T( config );
9000- }
9001-
9002- virtual std::string getDescription() const {
9003- return T::getDescription();
9004- }
9005- };
9006-
9007- public:
9008-
9009- ReporterRegistrar( std::string const& name ) {
9010- getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
9011- }
9012- };
9013-
9014- template<typename T>
9015- class ListenerRegistrar {
9016-
9017- class ListenerFactory : public SharedImpl<IReporterFactory> {
9018-
9019- virtual IStreamingReporter* create( ReporterConfig const& config ) const {
9020- return new T( config );
9021- }
9022- virtual std::string getDescription() const {
9023- return "";
9024- }
9025- };
9026-
9027- public:
9028-
9029- ListenerRegistrar() {
9030- getMutableRegistryHub().registerListener( new ListenerFactory() );
9031- }
9032- };
9033-}
9034-
9035-#define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \
9036- namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
9037-
9038-#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
9039- namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
9040-
9041-#define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \
9042- namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }
9043-
9044-// #included from: ../internal/catch_xmlwriter.hpp
9045-#define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED
9046-
9047-#include <sstream>
9048-#include <string>
9049-#include <vector>
9050-#include <iomanip>
9051-
9052-namespace Catch {
9053-
9054- class XmlEncode {
9055- public:
9056- enum ForWhat { ForTextNodes, ForAttributes };
9057-
9058- XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes )
9059- : m_str( str ),
9060- m_forWhat( forWhat )
9061- {}
9062-
9063- void encodeTo( std::ostream& os ) const {
9064-
9065- // Apostrophe escaping not necessary if we always use " to write attributes
9066- // (see: http://www.w3.org/TR/xml/#syntax)
9067-
9068- for( std::size_t i = 0; i < m_str.size(); ++ i ) {
9069- char c = m_str[i];
9070- switch( c ) {
9071- case '<': os << "&lt;"; break;
9072- case '&': os << "&amp;"; break;
9073-
9074- case '>':
9075- // See: http://www.w3.org/TR/xml/#syntax
9076- if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' )
9077- os << "&gt;";
9078- else
9079- os << c;
9080- break;
9081-
9082- case '\"':
9083- if( m_forWhat == ForAttributes )
9084- os << "&quot;";
9085- else
9086- os << c;
9087- break;
9088-
9089- default:
9090- // Escape control chars - based on contribution by @espenalb in PR #465 and
9091- // by @mrpi PR #588
9092- if ( ( c >= 0 && c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' )
9093- os << "&#x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>( c ) << ';';
9094- else
9095- os << c;
9096- }
9097- }
9098- }
9099-
9100- friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
9101- xmlEncode.encodeTo( os );
9102- return os;
9103- }
9104-
9105- private:
9106- std::string m_str;
9107- ForWhat m_forWhat;
9108- };
9109-
9110- class XmlWriter {
9111- public:
9112-
9113- class ScopedElement {
9114- public:
9115- ScopedElement( XmlWriter* writer )
9116- : m_writer( writer )
9117- {}
9118-
9119- ScopedElement( ScopedElement const& other )
9120- : m_writer( other.m_writer ){
9121- other.m_writer = CATCH_NULL;
9122- }
9123-
9124- ~ScopedElement() {
9125- if( m_writer )
9126- m_writer->endElement();
9127- }
9128-
9129- ScopedElement& writeText( std::string const& text, bool indent = true ) {
9130- m_writer->writeText( text, indent );
9131- return *this;
9132- }
9133-
9134- template<typename T>
9135- ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
9136- m_writer->writeAttribute( name, attribute );
9137- return *this;
9138- }
9139-
9140- private:
9141- mutable XmlWriter* m_writer;
9142- };
9143-
9144- XmlWriter()
9145- : m_tagIsOpen( false ),
9146- m_needsNewline( false ),
9147- m_os( &Catch::cout() )
9148- {
9149- // We encode control characters, which requires
9150- // XML 1.1
9151- // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
9152- *m_os << "<?xml version=\"1.1\" encoding=\"UTF-8\"?>\n";
9153- }
9154-
9155- XmlWriter( std::ostream& os )
9156- : m_tagIsOpen( false ),
9157- m_needsNewline( false ),
9158- m_os( &os )
9159- {
9160- *m_os << "<?xml version=\"1.1\" encoding=\"UTF-8\"?>\n";
9161- }
9162-
9163- ~XmlWriter() {
9164- while( !m_tags.empty() )
9165- endElement();
9166- }
9167-
9168- XmlWriter& startElement( std::string const& name ) {
9169- ensureTagClosed();
9170- newlineIfNecessary();
9171- stream() << m_indent << "<" << name;
9172- m_tags.push_back( name );
9173- m_indent += " ";
9174- m_tagIsOpen = true;
9175- return *this;
9176- }
9177-
9178- ScopedElement scopedElement( std::string const& name ) {
9179- ScopedElement scoped( this );
9180- startElement( name );
9181- return scoped;
9182- }
9183-
9184- XmlWriter& endElement() {
9185- newlineIfNecessary();
9186- m_indent = m_indent.substr( 0, m_indent.size()-2 );
9187- if( m_tagIsOpen ) {
9188- stream() << "/>\n";
9189- m_tagIsOpen = false;
9190- }
9191- else {
9192- stream() << m_indent << "</" << m_tags.back() << ">\n";
9193- }
9194- m_tags.pop_back();
9195- return *this;
9196- }
9197-
9198- XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {
9199- if( !name.empty() && !attribute.empty() )
9200- stream() << " " << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << "\"";
9201- return *this;
9202- }
9203-
9204- XmlWriter& writeAttribute( std::string const& name, bool attribute ) {
9205- stream() << " " << name << "=\"" << ( attribute ? "true" : "false" ) << "\"";
9206- return *this;
9207- }
9208-
9209- template<typename T>
9210- XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
9211- std::ostringstream oss;
9212- oss << attribute;
9213- return writeAttribute( name, oss.str() );
9214- }
9215-
9216- XmlWriter& writeText( std::string const& text, bool indent = true ) {
9217- if( !text.empty() ){
9218- bool tagWasOpen = m_tagIsOpen;
9219- ensureTagClosed();
9220- if( tagWasOpen && indent )
9221- stream() << m_indent;
9222- stream() << XmlEncode( text );
9223- m_needsNewline = true;
9224- }
9225- return *this;
9226- }
9227-
9228- XmlWriter& writeComment( std::string const& text ) {
9229- ensureTagClosed();
9230- stream() << m_indent << "<!--" << text << "-->";
9231- m_needsNewline = true;
9232- return *this;
9233- }
9234-
9235- XmlWriter& writeBlankLine() {
9236- ensureTagClosed();
9237- stream() << "\n";
9238- return *this;
9239- }
9240-
9241- void setStream( std::ostream& os ) {
9242- m_os = &os;
9243- }
9244-
9245- private:
9246- XmlWriter( XmlWriter const& );
9247- void operator=( XmlWriter const& );
9248-
9249- std::ostream& stream() {
9250- return *m_os;
9251- }
9252-
9253- void ensureTagClosed() {
9254- if( m_tagIsOpen ) {
9255- stream() << ">\n";
9256- m_tagIsOpen = false;
9257- }
9258- }
9259-
9260- void newlineIfNecessary() {
9261- if( m_needsNewline ) {
9262- stream() << "\n";
9263- m_needsNewline = false;
9264- }
9265- }
9266-
9267- bool m_tagIsOpen;
9268- bool m_needsNewline;
9269- std::vector<std::string> m_tags;
9270- std::string m_indent;
9271- std::ostream* m_os;
9272- };
9273-
9274-}
9275-// #included from: catch_reenable_warnings.h
9276-
9277-#define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED
9278-
9279-#ifdef __clang__
9280-# ifdef __ICC // icpc defines the __clang__ macro
9281-# pragma warning(pop)
9282-# else
9283-# pragma clang diagnostic pop
9284-# endif
9285-#elif defined __GNUC__
9286-# pragma GCC diagnostic pop
9287-#endif
9288-
9289-
9290-namespace Catch {
9291- class XmlReporter : public StreamingReporterBase {
9292- public:
9293- XmlReporter( ReporterConfig const& _config )
9294- : StreamingReporterBase( _config ),
9295- m_xml(_config.stream()),
9296- m_sectionDepth( 0 )
9297- {
9298- m_reporterPrefs.shouldRedirectStdOut = true;
9299- }
9300-
9301- virtual ~XmlReporter() CATCH_OVERRIDE;
9302-
9303- static std::string getDescription() {
9304- return "Reports test results as an XML document";
9305- }
9306-
9307- public: // StreamingReporterBase
9308-
9309- virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE {
9310- StreamingReporterBase::noMatchingTestCases( s );
9311- }
9312-
9313- virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE {
9314- StreamingReporterBase::testRunStarting( testInfo );
9315- m_xml.startElement( "Catch" );
9316- if( !m_config->name().empty() )
9317- m_xml.writeAttribute( "name", m_config->name() );
9318- }
9319-
9320- virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
9321- StreamingReporterBase::testGroupStarting( groupInfo );
9322- m_xml.startElement( "Group" )
9323- .writeAttribute( "name", groupInfo.name );
9324- }
9325-
9326- virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
9327- StreamingReporterBase::testCaseStarting(testInfo);
9328- m_xml.startElement( "TestCase" ).writeAttribute( "name", testInfo.name );
9329-
9330- if ( m_config->showDurations() == ShowDurations::Always )
9331- m_testCaseTimer.start();
9332- }
9333-
9334- virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
9335- StreamingReporterBase::sectionStarting( sectionInfo );
9336- if( m_sectionDepth++ > 0 ) {
9337- m_xml.startElement( "Section" )
9338- .writeAttribute( "name", trim( sectionInfo.name ) )
9339- .writeAttribute( "description", sectionInfo.description );
9340- }
9341- }
9342-
9343- virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { }
9344-
9345- virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
9346- const AssertionResult& assertionResult = assertionStats.assertionResult;
9347-
9348- // Print any info messages in <Info> tags.
9349- if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
9350- for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
9351- it != itEnd;
9352- ++it ) {
9353- if( it->type == ResultWas::Info ) {
9354- m_xml.scopedElement( "Info" )
9355- .writeText( it->message );
9356- } else if ( it->type == ResultWas::Warning ) {
9357- m_xml.scopedElement( "Warning" )
9358- .writeText( it->message );
9359- }
9360- }
9361- }
9362-
9363- // Drop out if result was successful but we're not printing them.
9364- if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) )
9365- return true;
9366-
9367- // Print the expression if there is one.
9368- if( assertionResult.hasExpression() ) {
9369- m_xml.startElement( "Expression" )
9370- .writeAttribute( "success", assertionResult.succeeded() )
9371- .writeAttribute( "type", assertionResult.getTestMacroName() )
9372- .writeAttribute( "filename", assertionResult.getSourceInfo().file )
9373- .writeAttribute( "line", assertionResult.getSourceInfo().line );
9374-
9375- m_xml.scopedElement( "Original" )
9376- .writeText( assertionResult.getExpression() );
9377- m_xml.scopedElement( "Expanded" )
9378- .writeText( assertionResult.getExpandedExpression() );
9379- }
9380-
9381- // And... Print a result applicable to each result type.
9382- switch( assertionResult.getResultType() ) {
9383- case ResultWas::ThrewException:
9384- m_xml.scopedElement( "Exception" )
9385- .writeAttribute( "filename", assertionResult.getSourceInfo().file )
9386- .writeAttribute( "line", assertionResult.getSourceInfo().line )
9387- .writeText( assertionResult.getMessage() );
9388- break;
9389- case ResultWas::FatalErrorCondition:
9390- m_xml.scopedElement( "FatalErrorCondition" )
9391- .writeAttribute( "filename", assertionResult.getSourceInfo().file )
9392- .writeAttribute( "line", assertionResult.getSourceInfo().line )
9393- .writeText( assertionResult.getMessage() );
9394- break;
9395- case ResultWas::Info:
9396- m_xml.scopedElement( "Info" )
9397- .writeText( assertionResult.getMessage() );
9398- break;
9399- case ResultWas::Warning:
9400- // Warning will already have been written
9401- break;
9402- case ResultWas::ExplicitFailure:
9403- m_xml.scopedElement( "Failure" )
9404- .writeText( assertionResult.getMessage() );
9405- break;
9406- default:
9407- break;
9408- }
9409-
9410- if( assertionResult.hasExpression() )
9411- m_xml.endElement();
9412-
9413- return true;
9414- }
9415-
9416- virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
9417- StreamingReporterBase::sectionEnded( sectionStats );
9418- if( --m_sectionDepth > 0 ) {
9419- XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
9420- e.writeAttribute( "successes", sectionStats.assertions.passed );
9421- e.writeAttribute( "failures", sectionStats.assertions.failed );
9422- e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
9423-
9424- if ( m_config->showDurations() == ShowDurations::Always )
9425- e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
9426-
9427- m_xml.endElement();
9428- }
9429- }
9430-
9431- virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
9432- StreamingReporterBase::testCaseEnded( testCaseStats );
9433- XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
9434- e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
9435-
9436- if ( m_config->showDurations() == ShowDurations::Always )
9437- e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
9438-
9439- m_xml.endElement();
9440- }
9441-
9442- virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
9443- StreamingReporterBase::testGroupEnded( testGroupStats );
9444- // TODO: Check testGroupStats.aborting and act accordingly.
9445- m_xml.scopedElement( "OverallResults" )
9446- .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
9447- .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
9448- .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
9449- m_xml.endElement();
9450- }
9451-
9452- virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
9453- StreamingReporterBase::testRunEnded( testRunStats );
9454- m_xml.scopedElement( "OverallResults" )
9455- .writeAttribute( "successes", testRunStats.totals.assertions.passed )
9456- .writeAttribute( "failures", testRunStats.totals.assertions.failed )
9457- .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
9458- m_xml.endElement();
9459- }
9460-
9461- private:
9462- Timer m_testCaseTimer;
9463- XmlWriter m_xml;
9464- int m_sectionDepth;
9465- };
9466-
9467- INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter )
9468-
9469-} // end namespace Catch
9470-
9471-// #included from: ../reporters/catch_reporter_junit.hpp
9472-#define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED
9473-
9474-#include <assert.h>
9475-
9476-namespace Catch {
9477-
9478- namespace {
9479- std::string getCurrentTimestamp() {
9480- // Beware, this is not reentrant because of backward compatibility issues
9481- // Also, UTC only, again because of backward compatibility (%z is C++11)
9482- time_t rawtime;
9483- std::time(&rawtime);
9484- const size_t timeStampSize = sizeof("2017-01-16T17:06:45Z");
9485-
9486-#ifdef CATCH_PLATFORM_WINDOWS
9487- std::tm timeInfo = {};
9488- gmtime_s(&timeInfo, &rawtime);
9489-#else
9490- std::tm* timeInfo;
9491- timeInfo = std::gmtime(&rawtime);
9492-#endif
9493-
9494- char timeStamp[timeStampSize];
9495- const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
9496-
9497-#ifdef CATCH_PLATFORM_WINDOWS
9498- std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
9499-#else
9500- std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
9501-#endif
9502- return std::string(timeStamp);
9503- }
9504-
9505- }
9506-
9507- class JunitReporter : public CumulativeReporterBase {
9508- public:
9509- JunitReporter( ReporterConfig const& _config )
9510- : CumulativeReporterBase( _config ),
9511- xml( _config.stream() )
9512- {
9513- m_reporterPrefs.shouldRedirectStdOut = true;
9514- }
9515-
9516- virtual ~JunitReporter() CATCH_OVERRIDE;
9517-
9518- static std::string getDescription() {
9519- return "Reports test results in an XML format that looks like Ant's junitreport target";
9520- }
9521-
9522- virtual void noMatchingTestCases( std::string const& /*spec*/ ) CATCH_OVERRIDE {}
9523-
9524- virtual void testRunStarting( TestRunInfo const& runInfo ) CATCH_OVERRIDE {
9525- CumulativeReporterBase::testRunStarting( runInfo );
9526- xml.startElement( "testsuites" );
9527- }
9528-
9529- virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
9530- suiteTimer.start();
9531- stdOutForSuite.str("");
9532- stdErrForSuite.str("");
9533- unexpectedExceptions = 0;
9534- CumulativeReporterBase::testGroupStarting( groupInfo );
9535- }
9536-
9537- virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
9538- if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException )
9539- unexpectedExceptions++;
9540- return CumulativeReporterBase::assertionEnded( assertionStats );
9541- }
9542-
9543- virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
9544- stdOutForSuite << testCaseStats.stdOut;
9545- stdErrForSuite << testCaseStats.stdErr;
9546- CumulativeReporterBase::testCaseEnded( testCaseStats );
9547- }
9548-
9549- virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
9550- double suiteTime = suiteTimer.getElapsedSeconds();
9551- CumulativeReporterBase::testGroupEnded( testGroupStats );
9552- writeGroup( *m_testGroups.back(), suiteTime );
9553- }
9554-
9555- virtual void testRunEndedCumulative() CATCH_OVERRIDE {
9556- xml.endElement();
9557- }
9558-
9559- void writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
9560- XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
9561- TestGroupStats const& stats = groupNode.value;
9562- xml.writeAttribute( "name", stats.groupInfo.name );
9563- xml.writeAttribute( "errors", unexpectedExceptions );
9564- xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
9565- xml.writeAttribute( "tests", stats.totals.assertions.total() );
9566- xml.writeAttribute( "hostname", "tbd" ); // !TBD
9567- if( m_config->showDurations() == ShowDurations::Never )
9568- xml.writeAttribute( "time", "" );
9569- else
9570- xml.writeAttribute( "time", suiteTime );
9571- xml.writeAttribute( "timestamp", getCurrentTimestamp() );
9572-
9573- // Write test cases
9574- for( TestGroupNode::ChildNodes::const_iterator
9575- it = groupNode.children.begin(), itEnd = groupNode.children.end();
9576- it != itEnd;
9577- ++it )
9578- writeTestCase( **it );
9579-
9580- xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false );
9581- xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false );
9582- }
9583-
9584- void writeTestCase( TestCaseNode const& testCaseNode ) {
9585- TestCaseStats const& stats = testCaseNode.value;
9586-
9587- // All test cases have exactly one section - which represents the
9588- // test case itself. That section may have 0-n nested sections
9589- assert( testCaseNode.children.size() == 1 );
9590- SectionNode const& rootSection = *testCaseNode.children.front();
9591-
9592- std::string className = stats.testInfo.className;
9593-
9594- if( className.empty() ) {
9595- if( rootSection.childSections.empty() )
9596- className = "global";
9597- }
9598- writeSection( className, "", rootSection );
9599- }
9600-
9601- void writeSection( std::string const& className,
9602- std::string const& rootName,
9603- SectionNode const& sectionNode ) {
9604- std::string name = trim( sectionNode.stats.sectionInfo.name );
9605- if( !rootName.empty() )
9606- name = rootName + "/" + name;
9607-
9608- if( !sectionNode.assertions.empty() ||
9609- !sectionNode.stdOut.empty() ||
9610- !sectionNode.stdErr.empty() ) {
9611- XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
9612- if( className.empty() ) {
9613- xml.writeAttribute( "classname", name );
9614- xml.writeAttribute( "name", "root" );
9615- }
9616- else {
9617- xml.writeAttribute( "classname", className );
9618- xml.writeAttribute( "name", name );
9619- }
9620- xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) );
9621-
9622- writeAssertions( sectionNode );
9623-
9624- if( !sectionNode.stdOut.empty() )
9625- xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
9626- if( !sectionNode.stdErr.empty() )
9627- xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
9628- }
9629- for( SectionNode::ChildSections::const_iterator
9630- it = sectionNode.childSections.begin(),
9631- itEnd = sectionNode.childSections.end();
9632- it != itEnd;
9633- ++it )
9634- if( className.empty() )
9635- writeSection( name, "", **it );
9636- else
9637- writeSection( className, name, **it );
9638- }
9639-
9640- void writeAssertions( SectionNode const& sectionNode ) {
9641- for( SectionNode::Assertions::const_iterator
9642- it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end();
9643- it != itEnd;
9644- ++it )
9645- writeAssertion( *it );
9646- }
9647- void writeAssertion( AssertionStats const& stats ) {
9648- AssertionResult const& result = stats.assertionResult;
9649- if( !result.isOk() ) {
9650- std::string elementName;
9651- switch( result.getResultType() ) {
9652- case ResultWas::ThrewException:
9653- case ResultWas::FatalErrorCondition:
9654- elementName = "error";
9655- break;
9656- case ResultWas::ExplicitFailure:
9657- elementName = "failure";
9658- break;
9659- case ResultWas::ExpressionFailed:
9660- elementName = "failure";
9661- break;
9662- case ResultWas::DidntThrowException:
9663- elementName = "failure";
9664- break;
9665-
9666- // We should never see these here:
9667- case ResultWas::Info:
9668- case ResultWas::Warning:
9669- case ResultWas::Ok:
9670- case ResultWas::Unknown:
9671- case ResultWas::FailureBit:
9672- case ResultWas::Exception:
9673- elementName = "internalError";
9674- break;
9675- }
9676-
9677- XmlWriter::ScopedElement e = xml.scopedElement( elementName );
9678-
9679- xml.writeAttribute( "message", result.getExpandedExpression() );
9680- xml.writeAttribute( "type", result.getTestMacroName() );
9681-
9682- std::ostringstream oss;
9683- if( !result.getMessage().empty() )
9684- oss << result.getMessage() << "\n";
9685- for( std::vector<MessageInfo>::const_iterator
9686- it = stats.infoMessages.begin(),
9687- itEnd = stats.infoMessages.end();
9688- it != itEnd;
9689- ++it )
9690- if( it->type == ResultWas::Info )
9691- oss << it->message << "\n";
9692-
9693- oss << "at " << result.getSourceInfo();
9694- xml.writeText( oss.str(), false );
9695- }
9696- }
9697-
9698- XmlWriter xml;
9699- Timer suiteTimer;
9700- std::ostringstream stdOutForSuite;
9701- std::ostringstream stdErrForSuite;
9702- unsigned int unexpectedExceptions;
9703- };
9704-
9705- INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter )
9706-
9707-} // end namespace Catch
9708-
9709-// #included from: ../reporters/catch_reporter_console.hpp
9710-#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED
9711-
9712-namespace Catch {
9713-
9714- struct ConsoleReporter : StreamingReporterBase {
9715- ConsoleReporter( ReporterConfig const& _config )
9716- : StreamingReporterBase( _config ),
9717- m_headerPrinted( false )
9718- {}
9719-
9720- virtual ~ConsoleReporter() CATCH_OVERRIDE;
9721- static std::string getDescription() {
9722- return "Reports test results as plain lines of text";
9723- }
9724-
9725- virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
9726- stream << "No test cases matched '" << spec << "'" << std::endl;
9727- }
9728-
9729- virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {
9730- }
9731-
9732- virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE {
9733- AssertionResult const& result = _assertionStats.assertionResult;
9734-
9735- bool printInfoMessages = true;
9736-
9737- // Drop out if result was successful and we're not printing those
9738- if( !m_config->includeSuccessfulResults() && result.isOk() ) {
9739- if( result.getResultType() != ResultWas::Warning )
9740- return false;
9741- printInfoMessages = false;
9742- }
9743-
9744- lazyPrint();
9745-
9746- AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
9747- printer.print();
9748- stream << std::endl;
9749- return true;
9750- }
9751-
9752- virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
9753- m_headerPrinted = false;
9754- StreamingReporterBase::sectionStarting( _sectionInfo );
9755- }
9756- virtual void sectionEnded( SectionStats const& _sectionStats ) CATCH_OVERRIDE {
9757- if( _sectionStats.missingAssertions ) {
9758- lazyPrint();
9759- Colour colour( Colour::ResultError );
9760- if( m_sectionStack.size() > 1 )
9761- stream << "\nNo assertions in section";
9762- else
9763- stream << "\nNo assertions in test case";
9764- stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
9765- }
9766- if( m_headerPrinted ) {
9767- if( m_config->showDurations() == ShowDurations::Always )
9768- stream << "Completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
9769- m_headerPrinted = false;
9770- }
9771- else {
9772- if( m_config->showDurations() == ShowDurations::Always )
9773- stream << _sectionStats.sectionInfo.name << " completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
9774- }
9775- StreamingReporterBase::sectionEnded( _sectionStats );
9776- }
9777-
9778- virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE {
9779- StreamingReporterBase::testCaseEnded( _testCaseStats );
9780- m_headerPrinted = false;
9781- }
9782- virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) CATCH_OVERRIDE {
9783- if( currentGroupInfo.used ) {
9784- printSummaryDivider();
9785- stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
9786- printTotals( _testGroupStats.totals );
9787- stream << "\n" << std::endl;
9788- }
9789- StreamingReporterBase::testGroupEnded( _testGroupStats );
9790- }
9791- virtual void testRunEnded( TestRunStats const& _testRunStats ) CATCH_OVERRIDE {
9792- printTotalsDivider( _testRunStats.totals );
9793- printTotals( _testRunStats.totals );
9794- stream << std::endl;
9795- StreamingReporterBase::testRunEnded( _testRunStats );
9796- }
9797-
9798- private:
9799-
9800- class AssertionPrinter {
9801- void operator= ( AssertionPrinter const& );
9802- public:
9803- AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
9804- : stream( _stream ),
9805- stats( _stats ),
9806- result( _stats.assertionResult ),
9807- colour( Colour::None ),
9808- message( result.getMessage() ),
9809- messages( _stats.infoMessages ),
9810- printInfoMessages( _printInfoMessages )
9811- {
9812- switch( result.getResultType() ) {
9813- case ResultWas::Ok:
9814- colour = Colour::Success;
9815- passOrFail = "PASSED";
9816- //if( result.hasMessage() )
9817- if( _stats.infoMessages.size() == 1 )
9818- messageLabel = "with message";
9819- if( _stats.infoMessages.size() > 1 )
9820- messageLabel = "with messages";
9821- break;
9822- case ResultWas::ExpressionFailed:
9823- if( result.isOk() ) {
9824- colour = Colour::Success;
9825- passOrFail = "FAILED - but was ok";
9826- }
9827- else {
9828- colour = Colour::Error;
9829- passOrFail = "FAILED";
9830- }
9831- if( _stats.infoMessages.size() == 1 )
9832- messageLabel = "with message";
9833- if( _stats.infoMessages.size() > 1 )
9834- messageLabel = "with messages";
9835- break;
9836- case ResultWas::ThrewException:
9837- colour = Colour::Error;
9838- passOrFail = "FAILED";
9839- messageLabel = "due to unexpected exception with message";
9840- break;
9841- case ResultWas::FatalErrorCondition:
9842- colour = Colour::Error;
9843- passOrFail = "FAILED";
9844- messageLabel = "due to a fatal error condition";
9845- break;
9846- case ResultWas::DidntThrowException:
9847- colour = Colour::Error;
9848- passOrFail = "FAILED";
9849- messageLabel = "because no exception was thrown where one was expected";
9850- break;
9851- case ResultWas::Info:
9852- messageLabel = "info";
9853- break;
9854- case ResultWas::Warning:
9855- messageLabel = "warning";
9856- break;
9857- case ResultWas::ExplicitFailure:
9858- passOrFail = "FAILED";
9859- colour = Colour::Error;
9860- if( _stats.infoMessages.size() == 1 )
9861- messageLabel = "explicitly with message";
9862- if( _stats.infoMessages.size() > 1 )
9863- messageLabel = "explicitly with messages";
9864- break;
9865- // These cases are here to prevent compiler warnings
9866- case ResultWas::Unknown:
9867- case ResultWas::FailureBit:
9868- case ResultWas::Exception:
9869- passOrFail = "** internal error **";
9870- colour = Colour::Error;
9871- break;
9872- }
9873- }
9874-
9875- void print() const {
9876- printSourceInfo();
9877- if( stats.totals.assertions.total() > 0 ) {
9878- if( result.isOk() )
9879- stream << "\n";
9880- printResultType();
9881- printOriginalExpression();
9882- printReconstructedExpression();
9883- }
9884- else {
9885- stream << "\n";
9886- }
9887- printMessage();
9888- }
9889-
9890- private:
9891- void printResultType() const {
9892- if( !passOrFail.empty() ) {
9893- Colour colourGuard( colour );
9894- stream << passOrFail << ":\n";
9895- }
9896- }
9897- void printOriginalExpression() const {
9898- if( result.hasExpression() ) {
9899- Colour colourGuard( Colour::OriginalExpression );
9900- stream << " ";
9901- stream << result.getExpressionInMacro();
9902- stream << "\n";
9903- }
9904- }
9905- void printReconstructedExpression() const {
9906- if( result.hasExpandedExpression() ) {
9907- stream << "with expansion:\n";
9908- Colour colourGuard( Colour::ReconstructedExpression );
9909- stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << "\n";
9910- }
9911- }
9912- void printMessage() const {
9913- if( !messageLabel.empty() )
9914- stream << messageLabel << ":" << "\n";
9915- for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();
9916- it != itEnd;
9917- ++it ) {
9918- // If this assertion is a warning ignore any INFO messages
9919- if( printInfoMessages || it->type != ResultWas::Info )
9920- stream << Text( it->message, TextAttributes().setIndent(2) ) << "\n";
9921- }
9922- }
9923- void printSourceInfo() const {
9924- Colour colourGuard( Colour::FileName );
9925- stream << result.getSourceInfo() << ": ";
9926- }
9927-
9928- std::ostream& stream;
9929- AssertionStats const& stats;
9930- AssertionResult const& result;
9931- Colour::Code colour;
9932- std::string passOrFail;
9933- std::string messageLabel;
9934- std::string message;
9935- std::vector<MessageInfo> messages;
9936- bool printInfoMessages;
9937- };
9938-
9939- void lazyPrint() {
9940-
9941- if( !currentTestRunInfo.used )
9942- lazyPrintRunInfo();
9943- if( !currentGroupInfo.used )
9944- lazyPrintGroupInfo();
9945-
9946- if( !m_headerPrinted ) {
9947- printTestCaseAndSectionHeader();
9948- m_headerPrinted = true;
9949- }
9950- }
9951- void lazyPrintRunInfo() {
9952- stream << "\n" << getLineOfChars<'~'>() << "\n";
9953- Colour colour( Colour::SecondaryText );
9954- stream << currentTestRunInfo->name
9955- << " is a Catch v" << libraryVersion << " host application.\n"
9956- << "Run with -? for options\n\n";
9957-
9958- if( m_config->rngSeed() != 0 )
9959- stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
9960-
9961- currentTestRunInfo.used = true;
9962- }
9963- void lazyPrintGroupInfo() {
9964- if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {
9965- printClosedHeader( "Group: " + currentGroupInfo->name );
9966- currentGroupInfo.used = true;
9967- }
9968- }
9969- void printTestCaseAndSectionHeader() {
9970- assert( !m_sectionStack.empty() );
9971- printOpenHeader( currentTestCaseInfo->name );
9972-
9973- if( m_sectionStack.size() > 1 ) {
9974- Colour colourGuard( Colour::Headers );
9975-
9976- std::vector<SectionInfo>::const_iterator
9977- it = m_sectionStack.begin()+1, // Skip first section (test case)
9978- itEnd = m_sectionStack.end();
9979- for( ; it != itEnd; ++it )
9980- printHeaderString( it->name, 2 );
9981- }
9982-
9983- SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
9984-
9985- if( !lineInfo.empty() ){
9986- stream << getLineOfChars<'-'>() << "\n";
9987- Colour colourGuard( Colour::FileName );
9988- stream << lineInfo << "\n";
9989- }
9990- stream << getLineOfChars<'.'>() << "\n" << std::endl;
9991- }
9992-
9993- void printClosedHeader( std::string const& _name ) {
9994- printOpenHeader( _name );
9995- stream << getLineOfChars<'.'>() << "\n";
9996- }
9997- void printOpenHeader( std::string const& _name ) {
9998- stream << getLineOfChars<'-'>() << "\n";
9999- {
10000- Colour colourGuard( Colour::Headers );
10001- printHeaderString( _name );
10002- }
10003- }
10004-
10005- // if string has a : in first line will set indent to follow it on
10006- // subsequent lines
10007- void printHeaderString( std::string const& _string, std::size_t indent = 0 ) {
10008- std::size_t i = _string.find( ": " );
10009- if( i != std::string::npos )
10010- i+=2;
10011- else
10012- i = 0;
10013- stream << Text( _string, TextAttributes()
10014- .setIndent( indent+i)
10015- .setInitialIndent( indent ) ) << "\n";
10016- }
10017-
10018- struct SummaryColumn {
10019-
10020- SummaryColumn( std::string const& _label, Colour::Code _colour )
10021- : label( _label ),
10022- colour( _colour )
10023- {}
10024- SummaryColumn addRow( std::size_t count ) {
10025- std::ostringstream oss;
10026- oss << count;
10027- std::string row = oss.str();
10028- for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) {
10029- while( it->size() < row.size() )
10030- *it = " " + *it;
10031- while( it->size() > row.size() )
10032- row = " " + row;
10033- }
10034- rows.push_back( row );
10035- return *this;
10036- }
10037-
10038- std::string label;
10039- Colour::Code colour;
10040- std::vector<std::string> rows;
10041-
10042- };
10043-
10044- void printTotals( Totals const& totals ) {
10045- if( totals.testCases.total() == 0 ) {
10046- stream << Colour( Colour::Warning ) << "No tests ran\n";
10047- }
10048- else if( totals.assertions.total() > 0 && totals.testCases.allPassed() ) {
10049- stream << Colour( Colour::ResultSuccess ) << "All tests passed";
10050- stream << " ("
10051- << pluralise( totals.assertions.passed, "assertion" ) << " in "
10052- << pluralise( totals.testCases.passed, "test case" ) << ")"
10053- << "\n";
10054- }
10055- else {
10056-
10057- std::vector<SummaryColumn> columns;
10058- columns.push_back( SummaryColumn( "", Colour::None )
10059- .addRow( totals.testCases.total() )
10060- .addRow( totals.assertions.total() ) );
10061- columns.push_back( SummaryColumn( "passed", Colour::Success )
10062- .addRow( totals.testCases.passed )
10063- .addRow( totals.assertions.passed ) );
10064- columns.push_back( SummaryColumn( "failed", Colour::ResultError )
10065- .addRow( totals.testCases.failed )
10066- .addRow( totals.assertions.failed ) );
10067- columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure )
10068- .addRow( totals.testCases.failedButOk )
10069- .addRow( totals.assertions.failedButOk ) );
10070-
10071- printSummaryRow( "test cases", columns, 0 );
10072- printSummaryRow( "assertions", columns, 1 );
10073- }
10074- }
10075- void printSummaryRow( std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row ) {
10076- for( std::vector<SummaryColumn>::const_iterator it = cols.begin(); it != cols.end(); ++it ) {
10077- std::string value = it->rows[row];
10078- if( it->label.empty() ) {
10079- stream << label << ": ";
10080- if( value != "0" )
10081- stream << value;
10082- else
10083- stream << Colour( Colour::Warning ) << "- none -";
10084- }
10085- else if( value != "0" ) {
10086- stream << Colour( Colour::LightGrey ) << " | ";
10087- stream << Colour( it->colour )
10088- << value << " " << it->label;
10089- }
10090- }
10091- stream << "\n";
10092- }
10093-
10094- static std::size_t makeRatio( std::size_t number, std::size_t total ) {
10095- std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0;
10096- return ( ratio == 0 && number > 0 ) ? 1 : ratio;
10097- }
10098- static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {
10099- if( i > j && i > k )
10100- return i;
10101- else if( j > k )
10102- return j;
10103- else
10104- return k;
10105- }
10106-
10107- void printTotalsDivider( Totals const& totals ) {
10108- if( totals.testCases.total() > 0 ) {
10109- std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() );
10110- std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() );
10111- std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() );
10112- while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 )
10113- findMax( failedRatio, failedButOkRatio, passedRatio )++;
10114- while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 )
10115- findMax( failedRatio, failedButOkRatio, passedRatio )--;
10116-
10117- stream << Colour( Colour::Error ) << std::string( failedRatio, '=' );
10118- stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' );
10119- if( totals.testCases.allPassed() )
10120- stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' );
10121- else
10122- stream << Colour( Colour::Success ) << std::string( passedRatio, '=' );
10123- }
10124- else {
10125- stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' );
10126- }
10127- stream << "\n";
10128- }
10129- void printSummaryDivider() {
10130- stream << getLineOfChars<'-'>() << "\n";
10131- }
10132-
10133- private:
10134- bool m_headerPrinted;
10135- };
10136-
10137- INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter )
10138-
10139-} // end namespace Catch
10140-
10141-// #included from: ../reporters/catch_reporter_compact.hpp
10142-#define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED
10143-
10144-namespace Catch {
10145-
10146- struct CompactReporter : StreamingReporterBase {
10147-
10148- CompactReporter( ReporterConfig const& _config )
10149- : StreamingReporterBase( _config )
10150- {}
10151-
10152- virtual ~CompactReporter();
10153-
10154- static std::string getDescription() {
10155- return "Reports test results on a single line, suitable for IDEs";
10156- }
10157-
10158- virtual ReporterPreferences getPreferences() const {
10159- ReporterPreferences prefs;
10160- prefs.shouldRedirectStdOut = false;
10161- return prefs;
10162- }
10163-
10164- virtual void noMatchingTestCases( std::string const& spec ) {
10165- stream << "No test cases matched '" << spec << "'" << std::endl;
10166- }
10167-
10168- virtual void assertionStarting( AssertionInfo const& ) {
10169- }
10170-
10171- virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
10172- AssertionResult const& result = _assertionStats.assertionResult;
10173-
10174- bool printInfoMessages = true;
10175-
10176- // Drop out if result was successful and we're not printing those
10177- if( !m_config->includeSuccessfulResults() && result.isOk() ) {
10178- if( result.getResultType() != ResultWas::Warning )
10179- return false;
10180- printInfoMessages = false;
10181- }
10182-
10183- AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
10184- printer.print();
10185-
10186- stream << std::endl;
10187- return true;
10188- }
10189-
10190- virtual void testRunEnded( TestRunStats const& _testRunStats ) {
10191- printTotals( _testRunStats.totals );
10192- stream << "\n" << std::endl;
10193- StreamingReporterBase::testRunEnded( _testRunStats );
10194- }
10195-
10196- private:
10197- class AssertionPrinter {
10198- void operator= ( AssertionPrinter const& );
10199- public:
10200- AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
10201- : stream( _stream )
10202- , stats( _stats )
10203- , result( _stats.assertionResult )
10204- , messages( _stats.infoMessages )
10205- , itMessage( _stats.infoMessages.begin() )
10206- , printInfoMessages( _printInfoMessages )
10207- {}
10208-
10209- void print() {
10210- printSourceInfo();
10211-
10212- itMessage = messages.begin();
10213-
10214- switch( result.getResultType() ) {
10215- case ResultWas::Ok:
10216- printResultType( Colour::ResultSuccess, passedString() );
10217- printOriginalExpression();
10218- printReconstructedExpression();
10219- if ( ! result.hasExpression() )
10220- printRemainingMessages( Colour::None );
10221- else
10222- printRemainingMessages();
10223- break;
10224- case ResultWas::ExpressionFailed:
10225- if( result.isOk() )
10226- printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) );
10227- else
10228- printResultType( Colour::Error, failedString() );
10229- printOriginalExpression();
10230- printReconstructedExpression();
10231- printRemainingMessages();
10232- break;
10233- case ResultWas::ThrewException:
10234- printResultType( Colour::Error, failedString() );
10235- printIssue( "unexpected exception with message:" );
10236- printMessage();
10237- printExpressionWas();
10238- printRemainingMessages();
10239- break;
10240- case ResultWas::FatalErrorCondition:
10241- printResultType( Colour::Error, failedString() );
10242- printIssue( "fatal error condition with message:" );
10243- printMessage();
10244- printExpressionWas();
10245- printRemainingMessages();
10246- break;
10247- case ResultWas::DidntThrowException:
10248- printResultType( Colour::Error, failedString() );
10249- printIssue( "expected exception, got none" );
10250- printExpressionWas();
10251- printRemainingMessages();
10252- break;
10253- case ResultWas::Info:
10254- printResultType( Colour::None, "info" );
10255- printMessage();
10256- printRemainingMessages();
10257- break;
10258- case ResultWas::Warning:
10259- printResultType( Colour::None, "warning" );
10260- printMessage();
10261- printRemainingMessages();
10262- break;
10263- case ResultWas::ExplicitFailure:
10264- printResultType( Colour::Error, failedString() );
10265- printIssue( "explicitly" );
10266- printRemainingMessages( Colour::None );
10267- break;
10268- // These cases are here to prevent compiler warnings
10269- case ResultWas::Unknown:
10270- case ResultWas::FailureBit:
10271- case ResultWas::Exception:
10272- printResultType( Colour::Error, "** internal error **" );
10273- break;
10274- }
10275- }
10276-
10277- private:
10278- // Colour::LightGrey
10279-
10280- static Colour::Code dimColour() { return Colour::FileName; }
10281-
10282-#ifdef CATCH_PLATFORM_MAC
10283- static const char* failedString() { return "FAILED"; }
10284- static const char* passedString() { return "PASSED"; }
10285-#else
10286- static const char* failedString() { return "failed"; }
10287- static const char* passedString() { return "passed"; }
10288-#endif
10289-
10290- void printSourceInfo() const {
10291- Colour colourGuard( Colour::FileName );
10292- stream << result.getSourceInfo() << ":";
10293- }
10294-
10295- void printResultType( Colour::Code colour, std::string passOrFail ) const {
10296- if( !passOrFail.empty() ) {
10297- {
10298- Colour colourGuard( colour );
10299- stream << " " << passOrFail;
10300- }
10301- stream << ":";
10302- }
10303- }
10304-
10305- void printIssue( std::string issue ) const {
10306- stream << " " << issue;
10307- }
10308-
10309- void printExpressionWas() {
10310- if( result.hasExpression() ) {
10311- stream << ";";
10312- {
10313- Colour colour( dimColour() );
10314- stream << " expression was:";
10315- }
10316- printOriginalExpression();
10317- }
10318- }
10319-
10320- void printOriginalExpression() const {
10321- if( result.hasExpression() ) {
10322- stream << " " << result.getExpression();
10323- }
10324- }
10325-
10326- void printReconstructedExpression() const {
10327- if( result.hasExpandedExpression() ) {
10328- {
10329- Colour colour( dimColour() );
10330- stream << " for: ";
10331- }
10332- stream << result.getExpandedExpression();
10333- }
10334- }
10335-
10336- void printMessage() {
10337- if ( itMessage != messages.end() ) {
10338- stream << " '" << itMessage->message << "'";
10339- ++itMessage;
10340- }
10341- }
10342-
10343- void printRemainingMessages( Colour::Code colour = dimColour() ) {
10344- if ( itMessage == messages.end() )
10345- return;
10346-
10347- // using messages.end() directly yields compilation error:
10348- std::vector<MessageInfo>::const_iterator itEnd = messages.end();
10349- const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );
10350-
10351- {
10352- Colour colourGuard( colour );
10353- stream << " with " << pluralise( N, "message" ) << ":";
10354- }
10355-
10356- for(; itMessage != itEnd; ) {
10357- // If this assertion is a warning ignore any INFO messages
10358- if( printInfoMessages || itMessage->type != ResultWas::Info ) {
10359- stream << " '" << itMessage->message << "'";
10360- if ( ++itMessage != itEnd ) {
10361- Colour colourGuard( dimColour() );
10362- stream << " and";
10363- }
10364- }
10365- }
10366- }
10367-
10368- private:
10369- std::ostream& stream;
10370- AssertionStats const& stats;
10371- AssertionResult const& result;
10372- std::vector<MessageInfo> messages;
10373- std::vector<MessageInfo>::const_iterator itMessage;
10374- bool printInfoMessages;
10375- };
10376-
10377- // Colour, message variants:
10378- // - white: No tests ran.
10379- // - red: Failed [both/all] N test cases, failed [both/all] M assertions.
10380- // - white: Passed [both/all] N test cases (no assertions).
10381- // - red: Failed N tests cases, failed M assertions.
10382- // - green: Passed [both/all] N tests cases with M assertions.
10383-
10384- std::string bothOrAll( std::size_t count ) const {
10385- return count == 1 ? "" : count == 2 ? "both " : "all " ;
10386- }
10387-
10388- void printTotals( const Totals& totals ) const {
10389- if( totals.testCases.total() == 0 ) {
10390- stream << "No tests ran.";
10391- }
10392- else if( totals.testCases.failed == totals.testCases.total() ) {
10393- Colour colour( Colour::ResultError );
10394- const std::string qualify_assertions_failed =
10395- totals.assertions.failed == totals.assertions.total() ?
10396- bothOrAll( totals.assertions.failed ) : "";
10397- stream <<
10398- "Failed " << bothOrAll( totals.testCases.failed )
10399- << pluralise( totals.testCases.failed, "test case" ) << ", "
10400- "failed " << qualify_assertions_failed <<
10401- pluralise( totals.assertions.failed, "assertion" ) << ".";
10402- }
10403- else if( totals.assertions.total() == 0 ) {
10404- stream <<
10405- "Passed " << bothOrAll( totals.testCases.total() )
10406- << pluralise( totals.testCases.total(), "test case" )
10407- << " (no assertions).";
10408- }
10409- else if( totals.assertions.failed ) {
10410- Colour colour( Colour::ResultError );
10411- stream <<
10412- "Failed " << pluralise( totals.testCases.failed, "test case" ) << ", "
10413- "failed " << pluralise( totals.assertions.failed, "assertion" ) << ".";
10414- }
10415- else {
10416- Colour colour( Colour::ResultSuccess );
10417- stream <<
10418- "Passed " << bothOrAll( totals.testCases.passed )
10419- << pluralise( totals.testCases.passed, "test case" ) <<
10420- " with " << pluralise( totals.assertions.passed, "assertion" ) << ".";
10421- }
10422- }
10423- };
10424-
10425- INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter )
10426-
10427-} // end namespace Catch
10428-
10429-namespace Catch {
10430- // These are all here to avoid warnings about not having any out of line
10431- // virtual methods
10432- NonCopyable::~NonCopyable() {}
10433- IShared::~IShared() {}
10434- IStream::~IStream() CATCH_NOEXCEPT {}
10435- FileStream::~FileStream() CATCH_NOEXCEPT {}
10436- CoutStream::~CoutStream() CATCH_NOEXCEPT {}
10437- DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {}
10438- StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}
10439- IContext::~IContext() {}
10440- IResultCapture::~IResultCapture() {}
10441- ITestCase::~ITestCase() {}
10442- ITestCaseRegistry::~ITestCaseRegistry() {}
10443- IRegistryHub::~IRegistryHub() {}
10444- IMutableRegistryHub::~IMutableRegistryHub() {}
10445- IExceptionTranslator::~IExceptionTranslator() {}
10446- IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}
10447- IReporter::~IReporter() {}
10448- IReporterFactory::~IReporterFactory() {}
10449- IReporterRegistry::~IReporterRegistry() {}
10450- IStreamingReporter::~IStreamingReporter() {}
10451- AssertionStats::~AssertionStats() {}
10452- SectionStats::~SectionStats() {}
10453- TestCaseStats::~TestCaseStats() {}
10454- TestGroupStats::~TestGroupStats() {}
10455- TestRunStats::~TestRunStats() {}
10456- CumulativeReporterBase::SectionNode::~SectionNode() {}
10457- CumulativeReporterBase::~CumulativeReporterBase() {}
10458-
10459- StreamingReporterBase::~StreamingReporterBase() {}
10460- ConsoleReporter::~ConsoleReporter() {}
10461- CompactReporter::~CompactReporter() {}
10462- IRunner::~IRunner() {}
10463- IMutableContext::~IMutableContext() {}
10464- IConfig::~IConfig() {}
10465- XmlReporter::~XmlReporter() {}
10466- JunitReporter::~JunitReporter() {}
10467- TestRegistry::~TestRegistry() {}
10468- FreeFunctionTestCase::~FreeFunctionTestCase() {}
10469- IGeneratorInfo::~IGeneratorInfo() {}
10470- IGeneratorsForTest::~IGeneratorsForTest() {}
10471- WildcardPattern::~WildcardPattern() {}
10472- TestSpec::Pattern::~Pattern() {}
10473- TestSpec::NamePattern::~NamePattern() {}
10474- TestSpec::TagPattern::~TagPattern() {}
10475- TestSpec::ExcludedPattern::~ExcludedPattern() {}
10476-
10477- Matchers::Impl::StdString::Equals::~Equals() {}
10478- Matchers::Impl::StdString::Contains::~Contains() {}
10479- Matchers::Impl::StdString::StartsWith::~StartsWith() {}
10480- Matchers::Impl::StdString::EndsWith::~EndsWith() {}
10481-
10482- void Config::dummy() {}
10483-
10484- namespace TestCaseTracking {
10485- ITracker::~ITracker() {}
10486- TrackerBase::~TrackerBase() {}
10487- SectionTracker::~SectionTracker() {}
10488- IndexTracker::~IndexTracker() {}
10489- }
10490-}
10491-
10492-#ifdef __clang__
10493-#pragma clang diagnostic pop
10494-#endif
10495-
10496-#endif
10497-
10498-#ifdef CATCH_CONFIG_MAIN
10499-// #included from: internal/catch_default_main.hpp
10500-#define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
10501-
10502-#ifndef __OBJC__
10503-
10504-// Standard C/C++ main entry point
10505-int main (int argc, char * argv[]) {
10506- return Catch::Session().run( argc, argv );
10507-}
10508-
10509-#else // __OBJC__
10510-
10511-// Objective-C entry point
10512-int main (int argc, char * const argv[]) {
10513-#if !CATCH_ARC_ENABLED
10514- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
10515-#endif
10516-
10517- Catch::registerTestMethods();
10518- int result = Catch::Session().run( argc, (char* const*)argv );
10519-
10520-#if !CATCH_ARC_ENABLED
10521- [pool drain];
10522-#endif
10523-
10524- return result;
10525-}
10526-
10527-#endif // __OBJC__
10528-
10529-#endif
10530-
10531-#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
10532-# undef CLARA_CONFIG_MAIN
10533-#endif
10534-
10535-//////
10536-
10537-// If this config identifier is defined then all CATCH macros are prefixed with CATCH_
10538-#ifdef CATCH_CONFIG_PREFIX_ALL
10539-
10540-#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" )
10541-#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" )
10542-
10543-#define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "CATCH_REQUIRE_THROWS" )
10544-#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" )
10545-#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "CATCH_REQUIRE_THROWS_WITH" )
10546-#define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" )
10547-
10548-#define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" )
10549-#define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CATCH_CHECK_FALSE" )
10550-#define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" )
10551-#define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" )
10552-#define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" )
10553-
10554-#define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "", "CATCH_CHECK_THROWS" )
10555-#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" )
10556-#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CATCH_CHECK_THROWS_WITH" )
10557-#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" )
10558-
10559-#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" )
10560-#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" )
10561-
10562-#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
10563-#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg )
10564-#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
10565-#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
10566-#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
10567-
10568-#ifdef CATCH_CONFIG_VARIADIC_MACROS
10569- #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
10570- #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
10571- #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
10572- #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
10573- #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
10574- #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ )
10575- #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ )
10576-#else
10577- #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
10578- #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
10579- #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
10580- #define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description )
10581- #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
10582- #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg )
10583- #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg )
10584-#endif
10585-#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
10586-
10587-#define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
10588-#define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
10589-
10590-#define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
10591-
10592-// "BDD-style" convenience wrappers
10593-#ifdef CATCH_CONFIG_VARIADIC_MACROS
10594-#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
10595-#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
10596-#else
10597-#define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags )
10598-#define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
10599-#endif
10600-#define CATCH_GIVEN( desc ) CATCH_SECTION( std::string( "Given: ") + desc, "" )
10601-#define CATCH_WHEN( desc ) CATCH_SECTION( std::string( " When: ") + desc, "" )
10602-#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" )
10603-#define CATCH_THEN( desc ) CATCH_SECTION( std::string( " Then: ") + desc, "" )
10604-#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" )
10605-
10606-// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
10607-#else
10608-
10609-#define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" )
10610-#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" )
10611-
10612-#define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "REQUIRE_THROWS" )
10613-#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" )
10614-#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "REQUIRE_THROWS_WITH" )
10615-#define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" )
10616-
10617-#define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" )
10618-#define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CHECK_FALSE" )
10619-#define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" )
10620-#define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" )
10621-#define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" )
10622-
10623-#define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "", "CHECK_THROWS" )
10624-#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" )
10625-#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CHECK_THROWS_WITH" )
10626-#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
10627-
10628-#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" )
10629-#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" )
10630-
10631-#define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
10632-#define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg )
10633-#define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
10634-#define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
10635-#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
10636-
10637-#ifdef CATCH_CONFIG_VARIADIC_MACROS
10638- #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
10639- #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
10640- #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
10641- #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
10642- #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
10643- #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ )
10644- #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ )
10645-#else
10646- #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
10647- #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
10648- #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
10649- #define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description )
10650- #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
10651- #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg )
10652- #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg )
10653-#endif
10654-#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
10655-
10656-#define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
10657-#define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
10658-
10659-#define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
10660-
10661-#endif
10662-
10663-#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
10664-
10665-// "BDD-style" convenience wrappers
10666-#ifdef CATCH_CONFIG_VARIADIC_MACROS
10667-#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
10668-#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
10669-#else
10670-#define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags )
10671-#define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
10672-#endif
10673-#define GIVEN( desc ) SECTION( std::string(" Given: ") + desc, "" )
10674-#define WHEN( desc ) SECTION( std::string(" When: ") + desc, "" )
10675-#define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc, "" )
10676-#define THEN( desc ) SECTION( std::string(" Then: ") + desc, "" )
10677-#define AND_THEN( desc ) SECTION( std::string(" And: ") + desc, "" )
10678-
10679-using Catch::Detail::Approx;
10680-
10681-#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
10682-
10683+/*
10684+ * Catch v1.12.2
10685+ * Generated: 2018-05-14 15:10:01.112442
10686+ * ----------------------------------------------------------
10687+ * This file has been merged from multiple headers. Please don't edit it directly
10688+ * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
10689+ *
10690+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
10691+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10692+ */
10693+#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
10694+#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
10695+
10696+#define TWOBLUECUBES_CATCH_HPP_INCLUDED
10697+
10698+#ifdef __clang__
10699+# pragma clang system_header
10700+#elif defined __GNUC__
10701+# pragma GCC system_header
10702+#endif
10703+
10704+// #included from: internal/catch_suppress_warnings.h
10705+
10706+#ifdef __clang__
10707+# ifdef __ICC // icpc defines the __clang__ macro
10708+# pragma warning(push)
10709+# pragma warning(disable: 161 1682)
10710+# else // __ICC
10711+# pragma clang diagnostic ignored "-Wglobal-constructors"
10712+# pragma clang diagnostic ignored "-Wvariadic-macros"
10713+# pragma clang diagnostic ignored "-Wc99-extensions"
10714+# pragma clang diagnostic ignored "-Wunused-variable"
10715+# pragma clang diagnostic push
10716+# pragma clang diagnostic ignored "-Wpadded"
10717+# pragma clang diagnostic ignored "-Wc++98-compat"
10718+# pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
10719+# pragma clang diagnostic ignored "-Wswitch-enum"
10720+# pragma clang diagnostic ignored "-Wcovered-switch-default"
10721+# endif
10722+#elif defined __GNUC__
10723+# pragma GCC diagnostic ignored "-Wvariadic-macros"
10724+# pragma GCC diagnostic ignored "-Wunused-variable"
10725+# pragma GCC diagnostic ignored "-Wparentheses"
10726+
10727+# pragma GCC diagnostic push
10728+# pragma GCC diagnostic ignored "-Wpadded"
10729+#endif
10730+#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
10731+# define CATCH_IMPL
10732+#endif
10733+
10734+#ifdef CATCH_IMPL
10735+# ifndef CLARA_CONFIG_MAIN
10736+# define CLARA_CONFIG_MAIN_NOT_DEFINED
10737+# define CLARA_CONFIG_MAIN
10738+# endif
10739+#endif
10740+
10741+// #included from: internal/catch_notimplemented_exception.h
10742+#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED
10743+
10744+// #included from: catch_common.h
10745+#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
10746+
10747+// #included from: catch_compiler_capabilities.h
10748+#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
10749+
10750+// Detect a number of compiler features - mostly C++11/14 conformance - by compiler
10751+// The following features are defined:
10752+//
10753+// CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported?
10754+// CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
10755+// CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
10756+// CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported?
10757+// CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported
10758+// CATCH_CONFIG_CPP11_LONG_LONG : is long long supported?
10759+// CATCH_CONFIG_CPP11_OVERRIDE : is override supported?
10760+// CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
10761+// CATCH_CONFIG_CPP11_SHUFFLE : is std::shuffle supported?
10762+// CATCH_CONFIG_CPP11_TYPE_TRAITS : are type_traits and enable_if supported?
10763+
10764+// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
10765+
10766+// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
10767+// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
10768+// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
10769+// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
10770+// ****************
10771+// Note to maintainers: if new toggles are added please document them
10772+// in configuration.md, too
10773+// ****************
10774+
10775+// In general each macro has a _NO_<feature name> form
10776+// (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
10777+// Many features, at point of detection, define an _INTERNAL_ macro, so they
10778+// can be combined, en-mass, with the _NO_ forms later.
10779+
10780+// All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11
10781+
10782+#ifdef __cplusplus
10783+
10784+# if __cplusplus >= 201103L
10785+# define CATCH_CPP11_OR_GREATER
10786+# endif
10787+
10788+# if __cplusplus >= 201402L
10789+# define CATCH_CPP14_OR_GREATER
10790+# endif
10791+
10792+#endif
10793+
10794+#ifdef __clang__
10795+
10796+# if __has_feature(cxx_nullptr)
10797+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
10798+# endif
10799+
10800+# if __has_feature(cxx_noexcept)
10801+# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
10802+# endif
10803+
10804+# if defined(CATCH_CPP11_OR_GREATER)
10805+# define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
10806+ _Pragma( "clang diagnostic push" ) \
10807+ _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" )
10808+# define CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
10809+ _Pragma( "clang diagnostic pop" )
10810+
10811+# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
10812+ _Pragma( "clang diagnostic push" ) \
10813+ _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
10814+# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
10815+ _Pragma( "clang diagnostic pop" )
10816+# endif
10817+
10818+#endif // __clang__
10819+
10820+////////////////////////////////////////////////////////////////////////////////
10821+// We know some environments not to support full POSIX signals
10822+#if defined(__CYGWIN__) || defined(__QNX__)
10823+
10824+# if !defined(CATCH_CONFIG_POSIX_SIGNALS)
10825+# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
10826+# endif
10827+
10828+#endif
10829+
10830+#ifdef __OS400__
10831+# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
10832+# define CATCH_CONFIG_COLOUR_NONE
10833+#endif
10834+
10835+////////////////////////////////////////////////////////////////////////////////
10836+// Cygwin
10837+#ifdef __CYGWIN__
10838+
10839+// Required for some versions of Cygwin to declare gettimeofday
10840+// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
10841+# define _BSD_SOURCE
10842+
10843+#endif // __CYGWIN__
10844+
10845+////////////////////////////////////////////////////////////////////////////////
10846+// Borland
10847+#ifdef __BORLANDC__
10848+
10849+#endif // __BORLANDC__
10850+
10851+////////////////////////////////////////////////////////////////////////////////
10852+// EDG
10853+#ifdef __EDG_VERSION__
10854+
10855+#endif // __EDG_VERSION__
10856+
10857+////////////////////////////////////////////////////////////////////////////////
10858+// Digital Mars
10859+#ifdef __DMC__
10860+
10861+#endif // __DMC__
10862+
10863+////////////////////////////////////////////////////////////////////////////////
10864+// GCC
10865+#ifdef __GNUC__
10866+
10867+# if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
10868+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
10869+# endif
10870+
10871+// - otherwise more recent versions define __cplusplus >= 201103L
10872+// and will get picked up below
10873+
10874+#endif // __GNUC__
10875+
10876+////////////////////////////////////////////////////////////////////////////////
10877+// Visual C++
10878+#ifdef _MSC_VER
10879+
10880+#define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
10881+
10882+#if (_MSC_VER >= 1600)
10883+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
10884+# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
10885+#endif
10886+
10887+#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
10888+#define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
10889+#define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
10890+#define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE
10891+#define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS
10892+#endif
10893+
10894+#endif // _MSC_VER
10895+
10896+////////////////////////////////////////////////////////////////////////////////
10897+
10898+// Use variadic macros if the compiler supports them
10899+#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
10900+ ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
10901+ ( defined __GNUC__ && __GNUC__ >= 3 ) || \
10902+ ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
10903+
10904+#define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
10905+
10906+#endif
10907+
10908+// Use __COUNTER__ if the compiler supports it
10909+#if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \
10910+ ( defined __GNUC__ && ( __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3 )) ) || \
10911+ ( defined __clang__ && __clang_major__ >= 3 )
10912+
10913+// Use of __COUNTER__ is suppressed during code analysis in CLion/AppCode 2017.2.x and former,
10914+// because __COUNTER__ is not properly handled by it.
10915+// This does not affect compilation
10916+#if ( !defined __JETBRAINS_IDE__ || __JETBRAINS_IDE__ >= 20170300L )
10917+ #define CATCH_INTERNAL_CONFIG_COUNTER
10918+#endif
10919+
10920+#endif
10921+
10922+////////////////////////////////////////////////////////////////////////////////
10923+// C++ language feature support
10924+
10925+// catch all support for C++11
10926+#if defined(CATCH_CPP11_OR_GREATER)
10927+
10928+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR)
10929+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
10930+# endif
10931+
10932+# ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
10933+# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
10934+# endif
10935+
10936+# ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
10937+# define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
10938+# endif
10939+
10940+# ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
10941+# define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
10942+# endif
10943+
10944+# ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE
10945+# define CATCH_INTERNAL_CONFIG_CPP11_TUPLE
10946+# endif
10947+
10948+# ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
10949+# define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
10950+# endif
10951+
10952+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG)
10953+# define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG
10954+# endif
10955+
10956+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE)
10957+# define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE
10958+# endif
10959+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
10960+# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
10961+# endif
10962+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE)
10963+# define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE
10964+# endif
10965+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS)
10966+# define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS
10967+# endif
10968+
10969+#endif // __cplusplus >= 201103L
10970+
10971+// Now set the actual defines based on the above + anything the user has configured
10972+#if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11)
10973+# define CATCH_CONFIG_CPP11_NULLPTR
10974+#endif
10975+#if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11)
10976+# define CATCH_CONFIG_CPP11_NOEXCEPT
10977+#endif
10978+#if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11)
10979+# define CATCH_CONFIG_CPP11_GENERATED_METHODS
10980+#endif
10981+#if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11)
10982+# define CATCH_CONFIG_CPP11_IS_ENUM
10983+#endif
10984+#if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11)
10985+# define CATCH_CONFIG_CPP11_TUPLE
10986+#endif
10987+#if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS)
10988+# define CATCH_CONFIG_VARIADIC_MACROS
10989+#endif
10990+#if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11)
10991+# define CATCH_CONFIG_CPP11_LONG_LONG
10992+#endif
10993+#if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11)
10994+# define CATCH_CONFIG_CPP11_OVERRIDE
10995+#endif
10996+#if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11)
10997+# define CATCH_CONFIG_CPP11_UNIQUE_PTR
10998+#endif
10999+#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
11000+# define CATCH_CONFIG_COUNTER
11001+#endif
11002+#if defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_NO_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_NO_CPP11)
11003+# define CATCH_CONFIG_CPP11_SHUFFLE
11004+#endif
11005+# if defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_NO_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_NO_CPP11)
11006+# define CATCH_CONFIG_CPP11_TYPE_TRAITS
11007+# endif
11008+#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH)
11009+# define CATCH_CONFIG_WINDOWS_SEH
11010+#endif
11011+// This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
11012+#if !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
11013+# define CATCH_CONFIG_POSIX_SIGNALS
11014+#endif
11015+
11016+#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
11017+# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
11018+# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
11019+#endif
11020+#if !defined(CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS)
11021+# define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS
11022+# define CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
11023+#endif
11024+
11025+// noexcept support:
11026+#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)
11027+# define CATCH_NOEXCEPT noexcept
11028+# define CATCH_NOEXCEPT_IS(x) noexcept(x)
11029+#else
11030+# define CATCH_NOEXCEPT throw()
11031+# define CATCH_NOEXCEPT_IS(x)
11032+#endif
11033+
11034+// nullptr support
11035+#ifdef CATCH_CONFIG_CPP11_NULLPTR
11036+# define CATCH_NULL nullptr
11037+#else
11038+# define CATCH_NULL NULL
11039+#endif
11040+
11041+// override support
11042+#ifdef CATCH_CONFIG_CPP11_OVERRIDE
11043+# define CATCH_OVERRIDE override
11044+#else
11045+# define CATCH_OVERRIDE
11046+#endif
11047+
11048+// unique_ptr support
11049+#ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR
11050+# define CATCH_AUTO_PTR( T ) std::unique_ptr<T>
11051+#else
11052+# define CATCH_AUTO_PTR( T ) std::auto_ptr<T>
11053+#endif
11054+
11055+#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
11056+#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
11057+#ifdef CATCH_CONFIG_COUNTER
11058+# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
11059+#else
11060+# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
11061+#endif
11062+
11063+#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
11064+#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
11065+
11066+#include <sstream>
11067+#include <algorithm>
11068+
11069+namespace Catch {
11070+
11071+ struct IConfig;
11072+
11073+ struct CaseSensitive { enum Choice {
11074+ Yes,
11075+ No
11076+ }; };
11077+
11078+ class NonCopyable {
11079+#ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
11080+ NonCopyable( NonCopyable const& ) = delete;
11081+ NonCopyable( NonCopyable && ) = delete;
11082+ NonCopyable& operator = ( NonCopyable const& ) = delete;
11083+ NonCopyable& operator = ( NonCopyable && ) = delete;
11084+#else
11085+ NonCopyable( NonCopyable const& info );
11086+ NonCopyable& operator = ( NonCopyable const& );
11087+#endif
11088+
11089+ protected:
11090+ NonCopyable() {}
11091+ virtual ~NonCopyable();
11092+ };
11093+
11094+ class SafeBool {
11095+ public:
11096+ typedef void (SafeBool::*type)() const;
11097+
11098+ static type makeSafe( bool value ) {
11099+ return value ? &SafeBool::trueValue : 0;
11100+ }
11101+ private:
11102+ void trueValue() const {}
11103+ };
11104+
11105+ template<typename ContainerT>
11106+ void deleteAll( ContainerT& container ) {
11107+ typename ContainerT::const_iterator it = container.begin();
11108+ typename ContainerT::const_iterator itEnd = container.end();
11109+ for(; it != itEnd; ++it )
11110+ delete *it;
11111+ }
11112+ template<typename AssociativeContainerT>
11113+ void deleteAllValues( AssociativeContainerT& container ) {
11114+ typename AssociativeContainerT::const_iterator it = container.begin();
11115+ typename AssociativeContainerT::const_iterator itEnd = container.end();
11116+ for(; it != itEnd; ++it )
11117+ delete it->second;
11118+ }
11119+
11120+ bool startsWith( std::string const& s, std::string const& prefix );
11121+ bool startsWith( std::string const& s, char prefix );
11122+ bool endsWith( std::string const& s, std::string const& suffix );
11123+ bool endsWith( std::string const& s, char suffix );
11124+ bool contains( std::string const& s, std::string const& infix );
11125+ void toLowerInPlace( std::string& s );
11126+ std::string toLower( std::string const& s );
11127+ std::string trim( std::string const& str );
11128+ bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
11129+
11130+ struct pluralise {
11131+ pluralise( std::size_t count, std::string const& label );
11132+
11133+ friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
11134+
11135+ std::size_t m_count;
11136+ std::string m_label;
11137+ };
11138+
11139+ struct SourceLineInfo {
11140+
11141+ SourceLineInfo();
11142+ SourceLineInfo( char const* _file, std::size_t _line );
11143+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
11144+ SourceLineInfo(SourceLineInfo const& other) = default;
11145+ SourceLineInfo( SourceLineInfo && ) = default;
11146+ SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
11147+ SourceLineInfo& operator = ( SourceLineInfo && ) = default;
11148+# endif
11149+ bool empty() const;
11150+ bool operator == ( SourceLineInfo const& other ) const;
11151+ bool operator < ( SourceLineInfo const& other ) const;
11152+
11153+ char const* file;
11154+ std::size_t line;
11155+ };
11156+
11157+ std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
11158+
11159+ // This is just here to avoid compiler warnings with macro constants and boolean literals
11160+ inline bool isTrue( bool value ){ return value; }
11161+ inline bool alwaysTrue() { return true; }
11162+ inline bool alwaysFalse() { return false; }
11163+
11164+ void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
11165+
11166+ void seedRng( IConfig const& config );
11167+ unsigned int rngSeed();
11168+
11169+ // Use this in variadic streaming macros to allow
11170+ // >> +StreamEndStop
11171+ // as well as
11172+ // >> stuff +StreamEndStop
11173+ struct StreamEndStop {
11174+ std::string operator+() {
11175+ return std::string();
11176+ }
11177+ };
11178+ template<typename T>
11179+ T const& operator + ( T const& value, StreamEndStop ) {
11180+ return value;
11181+ }
11182+}
11183+
11184+#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
11185+#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
11186+
11187+namespace Catch {
11188+
11189+ class NotImplementedException : public std::exception
11190+ {
11191+ public:
11192+ NotImplementedException( SourceLineInfo const& lineInfo );
11193+
11194+ virtual ~NotImplementedException() CATCH_NOEXCEPT {}
11195+
11196+ virtual const char* what() const CATCH_NOEXCEPT;
11197+
11198+ private:
11199+ std::string m_what;
11200+ SourceLineInfo m_lineInfo;
11201+ };
11202+
11203+} // end namespace Catch
11204+
11205+///////////////////////////////////////////////////////////////////////////////
11206+#define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )
11207+
11208+// #included from: internal/catch_context.h
11209+#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
11210+
11211+// #included from: catch_interfaces_generators.h
11212+#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED
11213+
11214+#include <string>
11215+
11216+namespace Catch {
11217+
11218+ struct IGeneratorInfo {
11219+ virtual ~IGeneratorInfo();
11220+ virtual bool moveNext() = 0;
11221+ virtual std::size_t getCurrentIndex() const = 0;
11222+ };
11223+
11224+ struct IGeneratorsForTest {
11225+ virtual ~IGeneratorsForTest();
11226+
11227+ virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0;
11228+ virtual bool moveNext() = 0;
11229+ };
11230+
11231+ IGeneratorsForTest* createGeneratorsForTest();
11232+
11233+} // end namespace Catch
11234+
11235+// #included from: catch_ptr.hpp
11236+#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
11237+
11238+#ifdef __clang__
11239+#pragma clang diagnostic push
11240+#pragma clang diagnostic ignored "-Wpadded"
11241+#endif
11242+
11243+namespace Catch {
11244+
11245+ // An intrusive reference counting smart pointer.
11246+ // T must implement addRef() and release() methods
11247+ // typically implementing the IShared interface
11248+ template<typename T>
11249+ class Ptr {
11250+ public:
11251+ Ptr() : m_p( CATCH_NULL ){}
11252+ Ptr( T* p ) : m_p( p ){
11253+ if( m_p )
11254+ m_p->addRef();
11255+ }
11256+ Ptr( Ptr const& other ) : m_p( other.m_p ){
11257+ if( m_p )
11258+ m_p->addRef();
11259+ }
11260+ ~Ptr(){
11261+ if( m_p )
11262+ m_p->release();
11263+ }
11264+ void reset() {
11265+ if( m_p )
11266+ m_p->release();
11267+ m_p = CATCH_NULL;
11268+ }
11269+ Ptr& operator = ( T* p ){
11270+ Ptr temp( p );
11271+ swap( temp );
11272+ return *this;
11273+ }
11274+ Ptr& operator = ( Ptr const& other ){
11275+ Ptr temp( other );
11276+ swap( temp );
11277+ return *this;
11278+ }
11279+ void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
11280+ T* get() const{ return m_p; }
11281+ T& operator*() const { return *m_p; }
11282+ T* operator->() const { return m_p; }
11283+ bool operator !() const { return m_p == CATCH_NULL; }
11284+ operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); }
11285+
11286+ private:
11287+ T* m_p;
11288+ };
11289+
11290+ struct IShared : NonCopyable {
11291+ virtual ~IShared();
11292+ virtual void addRef() const = 0;
11293+ virtual void release() const = 0;
11294+ };
11295+
11296+ template<typename T = IShared>
11297+ struct SharedImpl : T {
11298+
11299+ SharedImpl() : m_rc( 0 ){}
11300+
11301+ virtual void addRef() const {
11302+ ++m_rc;
11303+ }
11304+ virtual void release() const {
11305+ if( --m_rc == 0 )
11306+ delete this;
11307+ }
11308+
11309+ mutable unsigned int m_rc;
11310+ };
11311+
11312+} // end namespace Catch
11313+
11314+#ifdef __clang__
11315+#pragma clang diagnostic pop
11316+#endif
11317+
11318+namespace Catch {
11319+
11320+ class TestCase;
11321+ class Stream;
11322+ struct IResultCapture;
11323+ struct IRunner;
11324+ struct IGeneratorsForTest;
11325+ struct IConfig;
11326+
11327+ struct IContext
11328+ {
11329+ virtual ~IContext();
11330+
11331+ virtual IResultCapture* getResultCapture() = 0;
11332+ virtual IRunner* getRunner() = 0;
11333+ virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;
11334+ virtual bool advanceGeneratorsForCurrentTest() = 0;
11335+ virtual Ptr<IConfig const> getConfig() const = 0;
11336+ };
11337+
11338+ struct IMutableContext : IContext
11339+ {
11340+ virtual ~IMutableContext();
11341+ virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
11342+ virtual void setRunner( IRunner* runner ) = 0;
11343+ virtual void setConfig( Ptr<IConfig const> const& config ) = 0;
11344+ };
11345+
11346+ IContext& getCurrentContext();
11347+ IMutableContext& getCurrentMutableContext();
11348+ void cleanUpContext();
11349+ Stream createStream( std::string const& streamName );
11350+
11351+}
11352+
11353+// #included from: internal/catch_test_registry.hpp
11354+#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
11355+
11356+// #included from: catch_interfaces_testcase.h
11357+#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
11358+
11359+#include <vector>
11360+
11361+namespace Catch {
11362+
11363+ class TestSpec;
11364+
11365+ struct ITestCase : IShared {
11366+ virtual void invoke () const = 0;
11367+ protected:
11368+ virtual ~ITestCase();
11369+ };
11370+
11371+ class TestCase;
11372+ struct IConfig;
11373+
11374+ struct ITestCaseRegistry {
11375+ virtual ~ITestCaseRegistry();
11376+ virtual std::vector<TestCase> const& getAllTests() const = 0;
11377+ virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
11378+ };
11379+
11380+ bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
11381+ std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
11382+ std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
11383+
11384+}
11385+
11386+namespace Catch {
11387+
11388+template<typename C>
11389+class MethodTestCase : public SharedImpl<ITestCase> {
11390+
11391+public:
11392+ MethodTestCase( void (C::*method)() ) : m_method( method ) {}
11393+
11394+ virtual void invoke() const {
11395+ C obj;
11396+ (obj.*m_method)();
11397+ }
11398+
11399+private:
11400+ virtual ~MethodTestCase() {}
11401+
11402+ void (C::*m_method)();
11403+};
11404+
11405+typedef void(*TestFunction)();
11406+
11407+struct NameAndDesc {
11408+ NameAndDesc( const char* _name = "", const char* _description= "" )
11409+ : name( _name ), description( _description )
11410+ {}
11411+
11412+ const char* name;
11413+ const char* description;
11414+};
11415+
11416+void registerTestCase
11417+ ( ITestCase* testCase,
11418+ char const* className,
11419+ NameAndDesc const& nameAndDesc,
11420+ SourceLineInfo const& lineInfo );
11421+
11422+struct AutoReg {
11423+
11424+ AutoReg
11425+ ( TestFunction function,
11426+ SourceLineInfo const& lineInfo,
11427+ NameAndDesc const& nameAndDesc );
11428+
11429+ template<typename C>
11430+ AutoReg
11431+ ( void (C::*method)(),
11432+ char const* className,
11433+ NameAndDesc const& nameAndDesc,
11434+ SourceLineInfo const& lineInfo ) {
11435+
11436+ registerTestCase
11437+ ( new MethodTestCase<C>( method ),
11438+ className,
11439+ nameAndDesc,
11440+ lineInfo );
11441+ }
11442+
11443+ ~AutoReg();
11444+
11445+private:
11446+ AutoReg( AutoReg const& );
11447+ void operator= ( AutoReg const& );
11448+};
11449+
11450+void registerTestCaseFunction
11451+ ( TestFunction function,
11452+ SourceLineInfo const& lineInfo,
11453+ NameAndDesc const& nameAndDesc );
11454+
11455+} // end namespace Catch
11456+
11457+#ifdef CATCH_CONFIG_VARIADIC_MACROS
11458+ ///////////////////////////////////////////////////////////////////////////////
11459+ #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
11460+ static void TestName(); \
11461+ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
11462+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); } /* NOLINT */ \
11463+ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
11464+ static void TestName()
11465+ #define INTERNAL_CATCH_TESTCASE( ... ) \
11466+ INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
11467+
11468+ ///////////////////////////////////////////////////////////////////////////////
11469+ #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
11470+ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
11471+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); } /* NOLINT */ \
11472+ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
11473+
11474+ ///////////////////////////////////////////////////////////////////////////////
11475+ #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
11476+ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
11477+ namespace{ \
11478+ struct TestName : ClassName{ \
11479+ void test(); \
11480+ }; \
11481+ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); /* NOLINT */ \
11482+ } \
11483+ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
11484+ void TestName::test()
11485+ #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
11486+ INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
11487+
11488+ ///////////////////////////////////////////////////////////////////////////////
11489+ #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
11490+ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
11491+ Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); /* NOLINT */ \
11492+ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
11493+
11494+#else
11495+ ///////////////////////////////////////////////////////////////////////////////
11496+ #define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \
11497+ static void TestName(); \
11498+ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
11499+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); } /* NOLINT */ \
11500+ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
11501+ static void TestName()
11502+ #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
11503+ INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc )
11504+
11505+ ///////////////////////////////////////////////////////////////////////////////
11506+ #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
11507+ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
11508+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); } /* NOLINT */ \
11509+ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
11510+
11511+ ///////////////////////////////////////////////////////////////////////////////
11512+ #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\
11513+ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
11514+ namespace{ \
11515+ struct TestCaseName : ClassName{ \
11516+ void test(); \
11517+ }; \
11518+ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); /* NOLINT */ \
11519+ } \
11520+ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
11521+ void TestCaseName::test()
11522+ #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
11523+ INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc )
11524+
11525+ ///////////////////////////////////////////////////////////////////////////////
11526+ #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \
11527+ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
11528+ Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); /* NOLINT */ \
11529+ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
11530+
11531+#endif
11532+
11533+// #included from: internal/catch_capture.hpp
11534+#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
11535+
11536+// #included from: catch_result_builder.h
11537+#define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
11538+
11539+// #included from: catch_result_type.h
11540+#define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
11541+
11542+namespace Catch {
11543+
11544+ // ResultWas::OfType enum
11545+ struct ResultWas { enum OfType {
11546+ Unknown = -1,
11547+ Ok = 0,
11548+ Info = 1,
11549+ Warning = 2,
11550+
11551+ FailureBit = 0x10,
11552+
11553+ ExpressionFailed = FailureBit | 1,
11554+ ExplicitFailure = FailureBit | 2,
11555+
11556+ Exception = 0x100 | FailureBit,
11557+
11558+ ThrewException = Exception | 1,
11559+ DidntThrowException = Exception | 2,
11560+
11561+ FatalErrorCondition = 0x200 | FailureBit
11562+
11563+ }; };
11564+
11565+ inline bool isOk( ResultWas::OfType resultType ) {
11566+ return ( resultType & ResultWas::FailureBit ) == 0;
11567+ }
11568+ inline bool isJustInfo( int flags ) {
11569+ return flags == ResultWas::Info;
11570+ }
11571+
11572+ // ResultDisposition::Flags enum
11573+ struct ResultDisposition { enum Flags {
11574+ Normal = 0x01,
11575+
11576+ ContinueOnFailure = 0x02, // Failures fail test, but execution continues
11577+ FalseTest = 0x04, // Prefix expression with !
11578+ SuppressFail = 0x08 // Failures are reported but do not fail the test
11579+ }; };
11580+
11581+ inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
11582+ return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
11583+ }
11584+
11585+ inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
11586+ inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
11587+ inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
11588+
11589+} // end namespace Catch
11590+
11591+// #included from: catch_assertionresult.h
11592+#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
11593+
11594+#include <string>
11595+
11596+namespace Catch {
11597+
11598+ struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
11599+
11600+ struct DecomposedExpression
11601+ {
11602+ virtual ~DecomposedExpression() {}
11603+ virtual bool isBinaryExpression() const {
11604+ return false;
11605+ }
11606+ virtual void reconstructExpression( std::string& dest ) const = 0;
11607+
11608+ // Only simple binary comparisons can be decomposed.
11609+ // If more complex check is required then wrap sub-expressions in parentheses.
11610+ template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( T const& );
11611+ template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( T const& );
11612+ template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( T const& );
11613+ template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( T const& );
11614+ template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator % ( T const& );
11615+ template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( T const& );
11616+ template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( T const& );
11617+
11618+ private:
11619+ DecomposedExpression& operator = (DecomposedExpression const&);
11620+ };
11621+
11622+ struct AssertionInfo
11623+ {
11624+ AssertionInfo();
11625+ AssertionInfo( char const * _macroName,
11626+ SourceLineInfo const& _lineInfo,
11627+ char const * _capturedExpression,
11628+ ResultDisposition::Flags _resultDisposition,
11629+ char const * _secondArg = "");
11630+
11631+ char const * macroName;
11632+ SourceLineInfo lineInfo;
11633+ char const * capturedExpression;
11634+ ResultDisposition::Flags resultDisposition;
11635+ char const * secondArg;
11636+ };
11637+
11638+ struct AssertionResultData
11639+ {
11640+ AssertionResultData() : decomposedExpression( CATCH_NULL )
11641+ , resultType( ResultWas::Unknown )
11642+ , negated( false )
11643+ , parenthesized( false ) {}
11644+
11645+ void negate( bool parenthesize ) {
11646+ negated = !negated;
11647+ parenthesized = parenthesize;
11648+ if( resultType == ResultWas::Ok )
11649+ resultType = ResultWas::ExpressionFailed;
11650+ else if( resultType == ResultWas::ExpressionFailed )
11651+ resultType = ResultWas::Ok;
11652+ }
11653+
11654+ std::string const& reconstructExpression() const {
11655+ if( decomposedExpression != CATCH_NULL ) {
11656+ decomposedExpression->reconstructExpression( reconstructedExpression );
11657+ if( parenthesized ) {
11658+ reconstructedExpression.insert( 0, 1, '(' );
11659+ reconstructedExpression.append( 1, ')' );
11660+ }
11661+ if( negated ) {
11662+ reconstructedExpression.insert( 0, 1, '!' );
11663+ }
11664+ decomposedExpression = CATCH_NULL;
11665+ }
11666+ return reconstructedExpression;
11667+ }
11668+
11669+ mutable DecomposedExpression const* decomposedExpression;
11670+ mutable std::string reconstructedExpression;
11671+ std::string message;
11672+ ResultWas::OfType resultType;
11673+ bool negated;
11674+ bool parenthesized;
11675+ };
11676+
11677+ class AssertionResult {
11678+ public:
11679+ AssertionResult();
11680+ AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
11681+ ~AssertionResult();
11682+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
11683+ AssertionResult( AssertionResult const& ) = default;
11684+ AssertionResult( AssertionResult && ) = default;
11685+ AssertionResult& operator = ( AssertionResult const& ) = default;
11686+ AssertionResult& operator = ( AssertionResult && ) = default;
11687+# endif
11688+
11689+ bool isOk() const;
11690+ bool succeeded() const;
11691+ ResultWas::OfType getResultType() const;
11692+ bool hasExpression() const;
11693+ bool hasMessage() const;
11694+ std::string getExpression() const;
11695+ std::string getExpressionInMacro() const;
11696+ bool hasExpandedExpression() const;
11697+ std::string getExpandedExpression() const;
11698+ std::string getMessage() const;
11699+ SourceLineInfo getSourceInfo() const;
11700+ std::string getTestMacroName() const;
11701+ void discardDecomposedExpression() const;
11702+ void expandDecomposedExpression() const;
11703+
11704+ protected:
11705+ AssertionInfo m_info;
11706+ AssertionResultData m_resultData;
11707+ };
11708+
11709+} // end namespace Catch
11710+
11711+// #included from: catch_matchers.hpp
11712+#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
11713+
11714+namespace Catch {
11715+namespace Matchers {
11716+ namespace Impl {
11717+
11718+ template<typename ArgT> struct MatchAllOf;
11719+ template<typename ArgT> struct MatchAnyOf;
11720+ template<typename ArgT> struct MatchNotOf;
11721+
11722+ class MatcherUntypedBase {
11723+ public:
11724+ std::string toString() const {
11725+ if( m_cachedToString.empty() )
11726+ m_cachedToString = describe();
11727+ return m_cachedToString;
11728+ }
11729+
11730+ protected:
11731+ virtual ~MatcherUntypedBase();
11732+ virtual std::string describe() const = 0;
11733+ mutable std::string m_cachedToString;
11734+ private:
11735+ MatcherUntypedBase& operator = ( MatcherUntypedBase const& );
11736+ };
11737+
11738+ template<typename ObjectT>
11739+ struct MatcherMethod {
11740+ virtual bool match( ObjectT const& arg ) const = 0;
11741+ };
11742+ template<typename PtrT>
11743+ struct MatcherMethod<PtrT*> {
11744+ virtual bool match( PtrT* arg ) const = 0;
11745+ };
11746+
11747+ template<typename ObjectT, typename ComparatorT = ObjectT>
11748+ struct MatcherBase : MatcherUntypedBase, MatcherMethod<ObjectT> {
11749+
11750+ MatchAllOf<ComparatorT> operator && ( MatcherBase const& other ) const;
11751+ MatchAnyOf<ComparatorT> operator || ( MatcherBase const& other ) const;
11752+ MatchNotOf<ComparatorT> operator ! () const;
11753+ };
11754+
11755+ template<typename ArgT>
11756+ struct MatchAllOf : MatcherBase<ArgT> {
11757+ virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE {
11758+ for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
11759+ if (!m_matchers[i]->match(arg))
11760+ return false;
11761+ }
11762+ return true;
11763+ }
11764+ virtual std::string describe() const CATCH_OVERRIDE {
11765+ std::string description;
11766+ description.reserve( 4 + m_matchers.size()*32 );
11767+ description += "( ";
11768+ for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
11769+ if( i != 0 )
11770+ description += " and ";
11771+ description += m_matchers[i]->toString();
11772+ }
11773+ description += " )";
11774+ return description;
11775+ }
11776+
11777+ MatchAllOf<ArgT>& operator && ( MatcherBase<ArgT> const& other ) {
11778+ m_matchers.push_back( &other );
11779+ return *this;
11780+ }
11781+
11782+ std::vector<MatcherBase<ArgT> const*> m_matchers;
11783+ };
11784+ template<typename ArgT>
11785+ struct MatchAnyOf : MatcherBase<ArgT> {
11786+
11787+ virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE {
11788+ for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
11789+ if (m_matchers[i]->match(arg))
11790+ return true;
11791+ }
11792+ return false;
11793+ }
11794+ virtual std::string describe() const CATCH_OVERRIDE {
11795+ std::string description;
11796+ description.reserve( 4 + m_matchers.size()*32 );
11797+ description += "( ";
11798+ for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
11799+ if( i != 0 )
11800+ description += " or ";
11801+ description += m_matchers[i]->toString();
11802+ }
11803+ description += " )";
11804+ return description;
11805+ }
11806+
11807+ MatchAnyOf<ArgT>& operator || ( MatcherBase<ArgT> const& other ) {
11808+ m_matchers.push_back( &other );
11809+ return *this;
11810+ }
11811+
11812+ std::vector<MatcherBase<ArgT> const*> m_matchers;
11813+ };
11814+
11815+ template<typename ArgT>
11816+ struct MatchNotOf : MatcherBase<ArgT> {
11817+
11818+ MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
11819+
11820+ virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE {
11821+ return !m_underlyingMatcher.match( arg );
11822+ }
11823+
11824+ virtual std::string describe() const CATCH_OVERRIDE {
11825+ return "not " + m_underlyingMatcher.toString();
11826+ }
11827+ MatcherBase<ArgT> const& m_underlyingMatcher;
11828+ };
11829+
11830+ template<typename ObjectT, typename ComparatorT>
11831+ MatchAllOf<ComparatorT> MatcherBase<ObjectT, ComparatorT>::operator && ( MatcherBase const& other ) const {
11832+ return MatchAllOf<ComparatorT>() && *this && other;
11833+ }
11834+ template<typename ObjectT, typename ComparatorT>
11835+ MatchAnyOf<ComparatorT> MatcherBase<ObjectT, ComparatorT>::operator || ( MatcherBase const& other ) const {
11836+ return MatchAnyOf<ComparatorT>() || *this || other;
11837+ }
11838+ template<typename ObjectT, typename ComparatorT>
11839+ MatchNotOf<ComparatorT> MatcherBase<ObjectT, ComparatorT>::operator ! () const {
11840+ return MatchNotOf<ComparatorT>( *this );
11841+ }
11842+
11843+ } // namespace Impl
11844+
11845+ // The following functions create the actual matcher objects.
11846+ // This allows the types to be inferred
11847+ // - deprecated: prefer ||, && and !
11848+ template<typename T>
11849+ Impl::MatchNotOf<T> Not( Impl::MatcherBase<T> const& underlyingMatcher ) {
11850+ return Impl::MatchNotOf<T>( underlyingMatcher );
11851+ }
11852+ template<typename T>
11853+ Impl::MatchAllOf<T> AllOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2 ) {
11854+ return Impl::MatchAllOf<T>() && m1 && m2;
11855+ }
11856+ template<typename T>
11857+ Impl::MatchAllOf<T> AllOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2, Impl::MatcherBase<T> const& m3 ) {
11858+ return Impl::MatchAllOf<T>() && m1 && m2 && m3;
11859+ }
11860+ template<typename T>
11861+ Impl::MatchAnyOf<T> AnyOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2 ) {
11862+ return Impl::MatchAnyOf<T>() || m1 || m2;
11863+ }
11864+ template<typename T>
11865+ Impl::MatchAnyOf<T> AnyOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2, Impl::MatcherBase<T> const& m3 ) {
11866+ return Impl::MatchAnyOf<T>() || m1 || m2 || m3;
11867+ }
11868+
11869+} // namespace Matchers
11870+
11871+using namespace Matchers;
11872+using Matchers::Impl::MatcherBase;
11873+
11874+} // namespace Catch
11875+
11876+namespace Catch {
11877+
11878+ struct TestFailureException{};
11879+
11880+ template<typename T> class ExpressionLhs;
11881+
11882+ struct CopyableStream {
11883+ CopyableStream() {}
11884+ CopyableStream( CopyableStream const& other ) {
11885+ oss << other.oss.str();
11886+ }
11887+ CopyableStream& operator=( CopyableStream const& other ) {
11888+ oss.str(std::string());
11889+ oss << other.oss.str();
11890+ return *this;
11891+ }
11892+ std::ostringstream oss;
11893+ };
11894+
11895+ class ResultBuilder : public DecomposedExpression {
11896+ public:
11897+ ResultBuilder( char const* macroName,
11898+ SourceLineInfo const& lineInfo,
11899+ char const* capturedExpression,
11900+ ResultDisposition::Flags resultDisposition,
11901+ char const* secondArg = "" );
11902+ ~ResultBuilder();
11903+
11904+ template<typename T>
11905+ ExpressionLhs<T const&> operator <= ( T const& operand );
11906+ ExpressionLhs<bool> operator <= ( bool value );
11907+
11908+ template<typename T>
11909+ ResultBuilder& operator << ( T const& value ) {
11910+ stream().oss << value;
11911+ return *this;
11912+ }
11913+
11914+ ResultBuilder& setResultType( ResultWas::OfType result );
11915+ ResultBuilder& setResultType( bool result );
11916+
11917+ void endExpression( DecomposedExpression const& expr );
11918+
11919+ virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE;
11920+
11921+ AssertionResult build() const;
11922+ AssertionResult build( DecomposedExpression const& expr ) const;
11923+
11924+ void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
11925+ void captureResult( ResultWas::OfType resultType );
11926+ void captureExpression();
11927+ void captureExpectedException( std::string const& expectedMessage );
11928+ void captureExpectedException( Matchers::Impl::MatcherBase<std::string> const& matcher );
11929+ void handleResult( AssertionResult const& result );
11930+ void react();
11931+ bool shouldDebugBreak() const;
11932+ bool allowThrows() const;
11933+
11934+ template<typename ArgT, typename MatcherT>
11935+ void captureMatch( ArgT const& arg, MatcherT const& matcher, char const* matcherString );
11936+
11937+ void setExceptionGuard();
11938+ void unsetExceptionGuard();
11939+
11940+ private:
11941+ AssertionInfo m_assertionInfo;
11942+ AssertionResultData m_data;
11943+
11944+ CopyableStream &stream()
11945+ {
11946+ if(!m_usedStream)
11947+ {
11948+ m_usedStream = true;
11949+ m_stream().oss.str("");
11950+ }
11951+ return m_stream();
11952+ }
11953+
11954+ static CopyableStream &m_stream()
11955+ {
11956+ static CopyableStream s;
11957+ return s;
11958+ }
11959+
11960+ bool m_shouldDebugBreak;
11961+ bool m_shouldThrow;
11962+ bool m_guardException;
11963+ bool m_usedStream;
11964+ };
11965+
11966+} // namespace Catch
11967+
11968+// Include after due to circular dependency:
11969+// #included from: catch_expression_lhs.hpp
11970+#define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
11971+
11972+// #included from: catch_evaluate.hpp
11973+#define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
11974+
11975+#ifdef _MSC_VER
11976+#pragma warning(push)
11977+#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
11978+#pragma warning(disable:4018) // more "signed/unsigned mismatch"
11979+#pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
11980+#endif
11981+
11982+#include <cstddef>
11983+
11984+namespace Catch {
11985+namespace Internal {
11986+
11987+ enum Operator {
11988+ IsEqualTo,
11989+ IsNotEqualTo,
11990+ IsLessThan,
11991+ IsGreaterThan,
11992+ IsLessThanOrEqualTo,
11993+ IsGreaterThanOrEqualTo
11994+ };
11995+
11996+ template<Operator Op> struct OperatorTraits { static const char* getName(){ return "*error*"; } };
11997+ template<> struct OperatorTraits<IsEqualTo> { static const char* getName(){ return "=="; } };
11998+ template<> struct OperatorTraits<IsNotEqualTo> { static const char* getName(){ return "!="; } };
11999+ template<> struct OperatorTraits<IsLessThan> { static const char* getName(){ return "<"; } };
12000+ template<> struct OperatorTraits<IsGreaterThan> { static const char* getName(){ return ">"; } };
12001+ template<> struct OperatorTraits<IsLessThanOrEqualTo> { static const char* getName(){ return "<="; } };
12002+ template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
12003+
12004+ template<typename T>
12005+ T& opCast(T const& t) { return const_cast<T&>(t); }
12006+
12007+// nullptr_t support based on pull request #154 from Konstantin Baumann
12008+#ifdef CATCH_CONFIG_CPP11_NULLPTR
12009+ inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
12010+#endif // CATCH_CONFIG_CPP11_NULLPTR
12011+
12012+ // So the compare overloads can be operator agnostic we convey the operator as a template
12013+ // enum, which is used to specialise an Evaluator for doing the comparison.
12014+ template<typename T1, typename T2, Operator Op>
12015+ struct Evaluator{};
12016+
12017+ template<typename T1, typename T2>
12018+ struct Evaluator<T1, T2, IsEqualTo> {
12019+ static bool evaluate( T1 const& lhs, T2 const& rhs) {
12020+ return bool( opCast( lhs ) == opCast( rhs ) );
12021+ }
12022+ };
12023+ template<typename T1, typename T2>
12024+ struct Evaluator<T1, T2, IsNotEqualTo> {
12025+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
12026+ return bool( opCast( lhs ) != opCast( rhs ) );
12027+ }
12028+ };
12029+ template<typename T1, typename T2>
12030+ struct Evaluator<T1, T2, IsLessThan> {
12031+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
12032+ return bool( opCast( lhs ) < opCast( rhs ) );
12033+ }
12034+ };
12035+ template<typename T1, typename T2>
12036+ struct Evaluator<T1, T2, IsGreaterThan> {
12037+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
12038+ return bool( opCast( lhs ) > opCast( rhs ) );
12039+ }
12040+ };
12041+ template<typename T1, typename T2>
12042+ struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
12043+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
12044+ return bool( opCast( lhs ) >= opCast( rhs ) );
12045+ }
12046+ };
12047+ template<typename T1, typename T2>
12048+ struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
12049+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
12050+ return bool( opCast( lhs ) <= opCast( rhs ) );
12051+ }
12052+ };
12053+
12054+ template<Operator Op, typename T1, typename T2>
12055+ bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
12056+ return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
12057+ }
12058+
12059+ // This level of indirection allows us to specialise for integer types
12060+ // to avoid signed/ unsigned warnings
12061+
12062+ // "base" overload
12063+ template<Operator Op, typename T1, typename T2>
12064+ bool compare( T1 const& lhs, T2 const& rhs ) {
12065+ return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
12066+ }
12067+
12068+ // unsigned X to int
12069+ template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
12070+ return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
12071+ }
12072+ template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
12073+ return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
12074+ }
12075+ template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
12076+ return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
12077+ }
12078+
12079+ // unsigned X to long
12080+ template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
12081+ return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
12082+ }
12083+ template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
12084+ return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
12085+ }
12086+ template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
12087+ return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
12088+ }
12089+
12090+ // int to unsigned X
12091+ template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
12092+ return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
12093+ }
12094+ template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
12095+ return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
12096+ }
12097+ template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
12098+ return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
12099+ }
12100+
12101+ // long to unsigned X
12102+ template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
12103+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
12104+ }
12105+ template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
12106+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
12107+ }
12108+ template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
12109+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
12110+ }
12111+
12112+ // pointer to long (when comparing against NULL)
12113+ template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
12114+ return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
12115+ }
12116+ template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
12117+ return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
12118+ }
12119+
12120+ // pointer to int (when comparing against NULL)
12121+ template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
12122+ return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
12123+ }
12124+ template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
12125+ return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
12126+ }
12127+
12128+#ifdef CATCH_CONFIG_CPP11_LONG_LONG
12129+ // long long to unsigned X
12130+ template<Operator Op> bool compare( long long lhs, unsigned int rhs ) {
12131+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
12132+ }
12133+ template<Operator Op> bool compare( long long lhs, unsigned long rhs ) {
12134+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
12135+ }
12136+ template<Operator Op> bool compare( long long lhs, unsigned long long rhs ) {
12137+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
12138+ }
12139+ template<Operator Op> bool compare( long long lhs, unsigned char rhs ) {
12140+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
12141+ }
12142+
12143+ // unsigned long long to X
12144+ template<Operator Op> bool compare( unsigned long long lhs, int rhs ) {
12145+ return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
12146+ }
12147+ template<Operator Op> bool compare( unsigned long long lhs, long rhs ) {
12148+ return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
12149+ }
12150+ template<Operator Op> bool compare( unsigned long long lhs, long long rhs ) {
12151+ return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
12152+ }
12153+ template<Operator Op> bool compare( unsigned long long lhs, char rhs ) {
12154+ return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
12155+ }
12156+
12157+ // pointer to long long (when comparing against NULL)
12158+ template<Operator Op, typename T> bool compare( long long lhs, T* rhs ) {
12159+ return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
12160+ }
12161+ template<Operator Op, typename T> bool compare( T* lhs, long long rhs ) {
12162+ return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
12163+ }
12164+#endif // CATCH_CONFIG_CPP11_LONG_LONG
12165+
12166+#ifdef CATCH_CONFIG_CPP11_NULLPTR
12167+ // pointer to nullptr_t (when comparing against nullptr)
12168+ template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
12169+ return Evaluator<T*, T*, Op>::evaluate( nullptr, rhs );
12170+ }
12171+ template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
12172+ return Evaluator<T*, T*, Op>::evaluate( lhs, nullptr );
12173+ }
12174+#endif // CATCH_CONFIG_CPP11_NULLPTR
12175+
12176+} // end of namespace Internal
12177+} // end of namespace Catch
12178+
12179+#ifdef _MSC_VER
12180+#pragma warning(pop)
12181+#endif
12182+
12183+// #included from: catch_tostring.h
12184+#define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED
12185+
12186+#include <sstream>
12187+#include <iomanip>
12188+#include <limits>
12189+#include <vector>
12190+#include <cstddef>
12191+
12192+#ifdef __OBJC__
12193+// #included from: catch_objc_arc.hpp
12194+#define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED
12195+
12196+#import <Foundation/Foundation.h>
12197+
12198+#ifdef __has_feature
12199+#define CATCH_ARC_ENABLED __has_feature(objc_arc)
12200+#else
12201+#define CATCH_ARC_ENABLED 0
12202+#endif
12203+
12204+void arcSafeRelease( NSObject* obj );
12205+id performOptionalSelector( id obj, SEL sel );
12206+
12207+#if !CATCH_ARC_ENABLED
12208+inline void arcSafeRelease( NSObject* obj ) {
12209+ [obj release];
12210+}
12211+inline id performOptionalSelector( id obj, SEL sel ) {
12212+ if( [obj respondsToSelector: sel] )
12213+ return [obj performSelector: sel];
12214+ return nil;
12215+}
12216+#define CATCH_UNSAFE_UNRETAINED
12217+#define CATCH_ARC_STRONG
12218+#else
12219+inline void arcSafeRelease( NSObject* ){}
12220+inline id performOptionalSelector( id obj, SEL sel ) {
12221+#ifdef __clang__
12222+#pragma clang diagnostic push
12223+#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
12224+#endif
12225+ if( [obj respondsToSelector: sel] )
12226+ return [obj performSelector: sel];
12227+#ifdef __clang__
12228+#pragma clang diagnostic pop
12229+#endif
12230+ return nil;
12231+}
12232+#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
12233+#define CATCH_ARC_STRONG __strong
12234+#endif
12235+
12236+#endif
12237+
12238+#ifdef CATCH_CONFIG_CPP11_TUPLE
12239+#include <tuple>
12240+#endif
12241+
12242+#ifdef CATCH_CONFIG_CPP11_IS_ENUM
12243+#include <type_traits>
12244+#endif
12245+
12246+namespace Catch {
12247+
12248+// Why we're here.
12249+template<typename T>
12250+std::string toString( T const& value );
12251+
12252+// Built in overloads
12253+
12254+std::string toString( std::string const& value );
12255+std::string toString( std::wstring const& value );
12256+std::string toString( const char* const value );
12257+std::string toString( char* const value );
12258+std::string toString( const wchar_t* const value );
12259+std::string toString( wchar_t* const value );
12260+std::string toString( int value );
12261+std::string toString( unsigned long value );
12262+std::string toString( unsigned int value );
12263+std::string toString( const double value );
12264+std::string toString( const float value );
12265+std::string toString( bool value );
12266+std::string toString( char value );
12267+std::string toString( signed char value );
12268+std::string toString( unsigned char value );
12269+
12270+#ifdef CATCH_CONFIG_CPP11_LONG_LONG
12271+std::string toString( long long value );
12272+std::string toString( unsigned long long value );
12273+#endif
12274+
12275+#ifdef CATCH_CONFIG_CPP11_NULLPTR
12276+std::string toString( std::nullptr_t );
12277+#endif
12278+
12279+#ifdef __OBJC__
12280+ std::string toString( NSString const * const& nsstring );
12281+ std::string toString( NSString * CATCH_ARC_STRONG & nsstring );
12282+ std::string toString( NSObject* const& nsObject );
12283+#endif
12284+
12285+namespace Detail {
12286+
12287+ extern const std::string unprintableString;
12288+
12289+ #if !defined(CATCH_CONFIG_CPP11_STREAM_INSERTABLE_CHECK)
12290+ struct BorgType {
12291+ template<typename T> BorgType( T const& );
12292+ };
12293+
12294+ struct TrueType { char sizer[1]; };
12295+ struct FalseType { char sizer[2]; };
12296+
12297+ TrueType& testStreamable( std::ostream& );
12298+ FalseType testStreamable( FalseType );
12299+
12300+ FalseType operator<<( std::ostream const&, BorgType const& );
12301+
12302+ template<typename T>
12303+ struct IsStreamInsertable {
12304+ static std::ostream &s;
12305+ static T const&t;
12306+ enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
12307+ };
12308+#else
12309+ template<typename T>
12310+ class IsStreamInsertable {
12311+ template<typename SS, typename TT>
12312+ static auto test(int)
12313+ -> decltype( std::declval<SS&>() << std::declval<TT>(), std::true_type() );
12314+
12315+ template<typename, typename>
12316+ static auto test(...) -> std::false_type;
12317+
12318+ public:
12319+ static const bool value = decltype(test<std::ostream,const T&>(0))::value;
12320+ };
12321+#endif
12322+
12323+#if defined(CATCH_CONFIG_CPP11_IS_ENUM)
12324+ template<typename T,
12325+ bool IsEnum = std::is_enum<T>::value
12326+ >
12327+ struct EnumStringMaker
12328+ {
12329+ static std::string convert( T const& ) { return unprintableString; }
12330+ };
12331+
12332+ template<typename T>
12333+ struct EnumStringMaker<T,true>
12334+ {
12335+ static std::string convert( T const& v )
12336+ {
12337+ return ::Catch::toString(
12338+ static_cast<typename std::underlying_type<T>::type>(v)
12339+ );
12340+ }
12341+ };
12342+#endif
12343+ template<bool C>
12344+ struct StringMakerBase {
12345+#if defined(CATCH_CONFIG_CPP11_IS_ENUM)
12346+ template<typename T>
12347+ static std::string convert( T const& v )
12348+ {
12349+ return EnumStringMaker<T>::convert( v );
12350+ }
12351+#else
12352+ template<typename T>
12353+ static std::string convert( T const& ) { return unprintableString; }
12354+#endif
12355+ };
12356+
12357+ template<>
12358+ struct StringMakerBase<true> {
12359+ template<typename T>
12360+ static std::string convert( T const& _value ) {
12361+ std::ostringstream oss;
12362+ oss << _value;
12363+ return oss.str();
12364+ }
12365+ };
12366+
12367+ std::string rawMemoryToString( const void *object, std::size_t size );
12368+
12369+ template<typename T>
12370+ std::string rawMemoryToString( const T& object ) {
12371+ return rawMemoryToString( &object, sizeof(object) );
12372+ }
12373+
12374+} // end namespace Detail
12375+
12376+template<typename T>
12377+struct StringMaker :
12378+ Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};
12379+
12380+template<typename T>
12381+struct StringMaker<T*> {
12382+ template<typename U>
12383+ static std::string convert( U* p ) {
12384+ if( !p )
12385+ return "NULL";
12386+ else
12387+ return Detail::rawMemoryToString( p );
12388+ }
12389+};
12390+
12391+template<typename R, typename C>
12392+struct StringMaker<R C::*> {
12393+ static std::string convert( R C::* p ) {
12394+ if( !p )
12395+ return "NULL";
12396+ else
12397+ return Detail::rawMemoryToString( p );
12398+ }
12399+};
12400+
12401+namespace Detail {
12402+ template<typename InputIterator>
12403+ std::string rangeToString( InputIterator first, InputIterator last );
12404+}
12405+
12406+//template<typename T, typename Allocator>
12407+//struct StringMaker<std::vector<T, Allocator> > {
12408+// static std::string convert( std::vector<T,Allocator> const& v ) {
12409+// return Detail::rangeToString( v.begin(), v.end() );
12410+// }
12411+//};
12412+
12413+template<typename T, typename Allocator>
12414+std::string toString( std::vector<T,Allocator> const& v ) {
12415+ return Detail::rangeToString( v.begin(), v.end() );
12416+}
12417+
12418+#ifdef CATCH_CONFIG_CPP11_TUPLE
12419+
12420+// toString for tuples
12421+namespace TupleDetail {
12422+ template<
12423+ typename Tuple,
12424+ std::size_t N = 0,
12425+ bool = (N < std::tuple_size<Tuple>::value)
12426+ >
12427+ struct ElementPrinter {
12428+ static void print( const Tuple& tuple, std::ostream& os )
12429+ {
12430+ os << ( N ? ", " : " " )
12431+ << Catch::toString(std::get<N>(tuple));
12432+ ElementPrinter<Tuple,N+1>::print(tuple,os);
12433+ }
12434+ };
12435+
12436+ template<
12437+ typename Tuple,
12438+ std::size_t N
12439+ >
12440+ struct ElementPrinter<Tuple,N,false> {
12441+ static void print( const Tuple&, std::ostream& ) {}
12442+ };
12443+
12444+}
12445+
12446+template<typename ...Types>
12447+struct StringMaker<std::tuple<Types...>> {
12448+
12449+ static std::string convert( const std::tuple<Types...>& tuple )
12450+ {
12451+ std::ostringstream os;
12452+ os << '{';
12453+ TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os );
12454+ os << " }";
12455+ return os.str();
12456+ }
12457+};
12458+#endif // CATCH_CONFIG_CPP11_TUPLE
12459+
12460+namespace Detail {
12461+ template<typename T>
12462+ std::string makeString( T const& value ) {
12463+ return StringMaker<T>::convert( value );
12464+ }
12465+} // end namespace Detail
12466+
12467+/// \brief converts any type to a string
12468+///
12469+/// The default template forwards on to ostringstream - except when an
12470+/// ostringstream overload does not exist - in which case it attempts to detect
12471+/// that and writes {?}.
12472+/// Overload (not specialise) this template for custom typs that you don't want
12473+/// to provide an ostream overload for.
12474+template<typename T>
12475+std::string toString( T const& value ) {
12476+ return StringMaker<T>::convert( value );
12477+}
12478+
12479+ namespace Detail {
12480+ template<typename InputIterator>
12481+ std::string rangeToString( InputIterator first, InputIterator last ) {
12482+ std::ostringstream oss;
12483+ oss << "{ ";
12484+ if( first != last ) {
12485+ oss << Catch::toString( *first );
12486+ for( ++first ; first != last ; ++first )
12487+ oss << ", " << Catch::toString( *first );
12488+ }
12489+ oss << " }";
12490+ return oss.str();
12491+ }
12492+}
12493+
12494+} // end namespace Catch
12495+
12496+namespace Catch {
12497+
12498+template<typename LhsT, Internal::Operator Op, typename RhsT>
12499+class BinaryExpression;
12500+
12501+template<typename ArgT, typename MatcherT>
12502+class MatchExpression;
12503+
12504+// Wraps the LHS of an expression and overloads comparison operators
12505+// for also capturing those and RHS (if any)
12506+template<typename T>
12507+class ExpressionLhs : public DecomposedExpression {
12508+public:
12509+ ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ), m_truthy(false) {}
12510+
12511+ ExpressionLhs& operator = ( const ExpressionLhs& );
12512+
12513+ template<typename RhsT>
12514+ BinaryExpression<T, Internal::IsEqualTo, RhsT const&>
12515+ operator == ( RhsT const& rhs ) {
12516+ return captureExpression<Internal::IsEqualTo>( rhs );
12517+ }
12518+
12519+ template<typename RhsT>
12520+ BinaryExpression<T, Internal::IsNotEqualTo, RhsT const&>
12521+ operator != ( RhsT const& rhs ) {
12522+ return captureExpression<Internal::IsNotEqualTo>( rhs );
12523+ }
12524+
12525+ template<typename RhsT>
12526+ BinaryExpression<T, Internal::IsLessThan, RhsT const&>
12527+ operator < ( RhsT const& rhs ) {
12528+ return captureExpression<Internal::IsLessThan>( rhs );
12529+ }
12530+
12531+ template<typename RhsT>
12532+ BinaryExpression<T, Internal::IsGreaterThan, RhsT const&>
12533+ operator > ( RhsT const& rhs ) {
12534+ return captureExpression<Internal::IsGreaterThan>( rhs );
12535+ }
12536+
12537+ template<typename RhsT>
12538+ BinaryExpression<T, Internal::IsLessThanOrEqualTo, RhsT const&>
12539+ operator <= ( RhsT const& rhs ) {
12540+ return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
12541+ }
12542+
12543+ template<typename RhsT>
12544+ BinaryExpression<T, Internal::IsGreaterThanOrEqualTo, RhsT const&>
12545+ operator >= ( RhsT const& rhs ) {
12546+ return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
12547+ }
12548+
12549+ BinaryExpression<T, Internal::IsEqualTo, bool> operator == ( bool rhs ) {
12550+ return captureExpression<Internal::IsEqualTo>( rhs );
12551+ }
12552+
12553+ BinaryExpression<T, Internal::IsNotEqualTo, bool> operator != ( bool rhs ) {
12554+ return captureExpression<Internal::IsNotEqualTo>( rhs );
12555+ }
12556+
12557+ void endExpression() {
12558+ m_truthy = m_lhs ? true : false;
12559+ m_rb
12560+ .setResultType( m_truthy )
12561+ .endExpression( *this );
12562+ }
12563+
12564+ virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE {
12565+ dest = Catch::toString( m_lhs );
12566+ }
12567+
12568+private:
12569+ template<Internal::Operator Op, typename RhsT>
12570+ BinaryExpression<T, Op, RhsT&> captureExpression( RhsT& rhs ) const {
12571+ return BinaryExpression<T, Op, RhsT&>( m_rb, m_lhs, rhs );
12572+ }
12573+
12574+ template<Internal::Operator Op>
12575+ BinaryExpression<T, Op, bool> captureExpression( bool rhs ) const {
12576+ return BinaryExpression<T, Op, bool>( m_rb, m_lhs, rhs );
12577+ }
12578+
12579+private:
12580+ ResultBuilder& m_rb;
12581+ T m_lhs;
12582+ bool m_truthy;
12583+};
12584+
12585+template<typename LhsT, Internal::Operator Op, typename RhsT>
12586+class BinaryExpression : public DecomposedExpression {
12587+public:
12588+ BinaryExpression( ResultBuilder& rb, LhsT lhs, RhsT rhs )
12589+ : m_rb( rb ), m_lhs( lhs ), m_rhs( rhs ) {}
12590+
12591+ BinaryExpression& operator = ( BinaryExpression& );
12592+
12593+ void endExpression() const {
12594+ m_rb
12595+ .setResultType( Internal::compare<Op>( m_lhs, m_rhs ) )
12596+ .endExpression( *this );
12597+ }
12598+
12599+ virtual bool isBinaryExpression() const CATCH_OVERRIDE {
12600+ return true;
12601+ }
12602+
12603+ virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE {
12604+ std::string lhs = Catch::toString( m_lhs );
12605+ std::string rhs = Catch::toString( m_rhs );
12606+ char delim = lhs.size() + rhs.size() < 40 &&
12607+ lhs.find('\n') == std::string::npos &&
12608+ rhs.find('\n') == std::string::npos ? ' ' : '\n';
12609+ dest.reserve( 7 + lhs.size() + rhs.size() );
12610+ // 2 for spaces around operator
12611+ // 2 for operator
12612+ // 2 for parentheses (conditionally added later)
12613+ // 1 for negation (conditionally added later)
12614+ dest = lhs;
12615+ dest += delim;
12616+ dest += Internal::OperatorTraits<Op>::getName();
12617+ dest += delim;
12618+ dest += rhs;
12619+ }
12620+
12621+private:
12622+ ResultBuilder& m_rb;
12623+ LhsT m_lhs;
12624+ RhsT m_rhs;
12625+};
12626+
12627+template<typename ArgT, typename MatcherT>
12628+class MatchExpression : public DecomposedExpression {
12629+public:
12630+ MatchExpression( ArgT arg, MatcherT matcher, char const* matcherString )
12631+ : m_arg( arg ), m_matcher( matcher ), m_matcherString( matcherString ) {}
12632+
12633+ virtual bool isBinaryExpression() const CATCH_OVERRIDE {
12634+ return true;
12635+ }
12636+
12637+ virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE {
12638+ std::string matcherAsString = m_matcher.toString();
12639+ dest = Catch::toString( m_arg );
12640+ dest += ' ';
12641+ if( matcherAsString == Detail::unprintableString )
12642+ dest += m_matcherString;
12643+ else
12644+ dest += matcherAsString;
12645+ }
12646+
12647+private:
12648+ ArgT m_arg;
12649+ MatcherT m_matcher;
12650+ char const* m_matcherString;
12651+};
12652+
12653+} // end namespace Catch
12654+
12655+
12656+namespace Catch {
12657+
12658+ template<typename T>
12659+ ExpressionLhs<T const&> ResultBuilder::operator <= ( T const& operand ) {
12660+ return ExpressionLhs<T const&>( *this, operand );
12661+ }
12662+
12663+ inline ExpressionLhs<bool> ResultBuilder::operator <= ( bool value ) {
12664+ return ExpressionLhs<bool>( *this, value );
12665+ }
12666+
12667+ template<typename ArgT, typename MatcherT>
12668+ void ResultBuilder::captureMatch( ArgT const& arg, MatcherT const& matcher,
12669+ char const* matcherString ) {
12670+ MatchExpression<ArgT const&, MatcherT const&> expr( arg, matcher, matcherString );
12671+ setResultType( matcher.match( arg ) );
12672+ endExpression( expr );
12673+ }
12674+
12675+} // namespace Catch
12676+
12677+// #included from: catch_message.h
12678+#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
12679+
12680+#include <string>
12681+
12682+namespace Catch {
12683+
12684+ struct MessageInfo {
12685+ MessageInfo( std::string const& _macroName,
12686+ SourceLineInfo const& _lineInfo,
12687+ ResultWas::OfType _type );
12688+
12689+ std::string macroName;
12690+ SourceLineInfo lineInfo;
12691+ ResultWas::OfType type;
12692+ std::string message;
12693+ unsigned int sequence;
12694+
12695+ bool operator == ( MessageInfo const& other ) const {
12696+ return sequence == other.sequence;
12697+ }
12698+ bool operator < ( MessageInfo const& other ) const {
12699+ return sequence < other.sequence;
12700+ }
12701+ private:
12702+ static unsigned int globalCount;
12703+ };
12704+
12705+ struct MessageBuilder {
12706+ MessageBuilder( std::string const& macroName,
12707+ SourceLineInfo const& lineInfo,
12708+ ResultWas::OfType type )
12709+ : m_info( macroName, lineInfo, type )
12710+ {}
12711+
12712+ template<typename T>
12713+ MessageBuilder& operator << ( T const& value ) {
12714+ m_stream << value;
12715+ return *this;
12716+ }
12717+
12718+ MessageInfo m_info;
12719+ std::ostringstream m_stream;
12720+ };
12721+
12722+ class ScopedMessage {
12723+ public:
12724+ ScopedMessage( MessageBuilder const& builder );
12725+ ScopedMessage( ScopedMessage const& other );
12726+ ~ScopedMessage();
12727+
12728+ MessageInfo m_info;
12729+ };
12730+
12731+} // end namespace Catch
12732+
12733+// #included from: catch_interfaces_capture.h
12734+#define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
12735+
12736+#include <string>
12737+
12738+namespace Catch {
12739+
12740+ class TestCase;
12741+ class AssertionResult;
12742+ struct AssertionInfo;
12743+ struct SectionInfo;
12744+ struct SectionEndInfo;
12745+ struct MessageInfo;
12746+ class ScopedMessageBuilder;
12747+ struct Counts;
12748+
12749+ struct IResultCapture {
12750+
12751+ virtual ~IResultCapture();
12752+
12753+ virtual void assertionEnded( AssertionResult const& result ) = 0;
12754+ virtual bool sectionStarted( SectionInfo const& sectionInfo,
12755+ Counts& assertions ) = 0;
12756+ virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
12757+ virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
12758+ virtual void pushScopedMessage( MessageInfo const& message ) = 0;
12759+ virtual void popScopedMessage( MessageInfo const& message ) = 0;
12760+
12761+ virtual std::string getCurrentTestName() const = 0;
12762+ virtual const AssertionResult* getLastResult() const = 0;
12763+
12764+ virtual void exceptionEarlyReported() = 0;
12765+
12766+ virtual void handleFatalErrorCondition( std::string const& message ) = 0;
12767+
12768+ virtual bool lastAssertionPassed() = 0;
12769+ virtual void assertionPassed() = 0;
12770+ virtual void assertionRun() = 0;
12771+ };
12772+
12773+ IResultCapture& getResultCapture();
12774+}
12775+
12776+// #included from: catch_debugger.h
12777+#define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
12778+
12779+// #included from: catch_platform.h
12780+#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
12781+
12782+#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
12783+# define CATCH_PLATFORM_MAC
12784+#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
12785+# define CATCH_PLATFORM_IPHONE
12786+#elif defined(linux) || defined(__linux) || defined(__linux__)
12787+# define CATCH_PLATFORM_LINUX
12788+#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
12789+# define CATCH_PLATFORM_WINDOWS
12790+# if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
12791+# define CATCH_DEFINES_NOMINMAX
12792+# endif
12793+# if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
12794+# define CATCH_DEFINES_WIN32_LEAN_AND_MEAN
12795+# endif
12796+#endif
12797+
12798+#include <string>
12799+
12800+namespace Catch{
12801+
12802+ bool isDebuggerActive();
12803+ void writeToDebugConsole( std::string const& text );
12804+}
12805+
12806+#ifdef CATCH_PLATFORM_MAC
12807+
12808+ // The following code snippet based on:
12809+ // http://cocoawithlove.com/2008/03/break-into-debugger.html
12810+ #if defined(__ppc64__) || defined(__ppc__)
12811+ #define CATCH_TRAP() \
12812+ __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
12813+ : : : "memory","r0","r3","r4" ) /* NOLINT */
12814+ #else
12815+ #define CATCH_TRAP() __asm__("int $3\n" : : /* NOLINT */ )
12816+ #endif
12817+
12818+#elif defined(CATCH_PLATFORM_LINUX)
12819+ // If we can use inline assembler, do it because this allows us to break
12820+ // directly at the location of the failing check instead of breaking inside
12821+ // raise() called from it, i.e. one stack frame below.
12822+ #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
12823+ #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
12824+ #else // Fall back to the generic way.
12825+ #include <signal.h>
12826+
12827+ #define CATCH_TRAP() raise(SIGTRAP)
12828+ #endif
12829+#elif defined(_MSC_VER)
12830+ #define CATCH_TRAP() __debugbreak()
12831+#elif defined(__MINGW32__)
12832+ extern "C" __declspec(dllimport) void __stdcall DebugBreak();
12833+ #define CATCH_TRAP() DebugBreak()
12834+#endif
12835+
12836+#ifdef CATCH_TRAP
12837+ #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); }
12838+#else
12839+ #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
12840+#endif
12841+
12842+// #included from: catch_interfaces_runner.h
12843+#define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
12844+
12845+namespace Catch {
12846+ class TestCase;
12847+
12848+ struct IRunner {
12849+ virtual ~IRunner();
12850+ virtual bool aborting() const = 0;
12851+ };
12852+}
12853+
12854+#if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
12855+# define CATCH_INTERNAL_STRINGIFY(expr) #expr
12856+#else
12857+# define CATCH_INTERNAL_STRINGIFY(expr) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
12858+#endif
12859+
12860+#if defined(CATCH_CONFIG_FAST_COMPILE)
12861+///////////////////////////////////////////////////////////////////////////////
12862+// We can speedup compilation significantly by breaking into debugger lower in
12863+// the callstack, because then we don't have to expand CATCH_BREAK_INTO_DEBUGGER
12864+// macro in each assertion
12865+#define INTERNAL_CATCH_REACT( resultBuilder ) \
12866+ resultBuilder.react();
12867+
12868+///////////////////////////////////////////////////////////////////////////////
12869+// Another way to speed-up compilation is to omit local try-catch for REQUIRE*
12870+// macros.
12871+// This can potentially cause false negative, if the test code catches
12872+// the exception before it propagates back up to the runner.
12873+#define INTERNAL_CATCH_TEST_NO_TRY( macroName, resultDisposition, expr ) \
12874+ do { \
12875+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \
12876+ __catchResult.setExceptionGuard(); \
12877+ CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
12878+ ( __catchResult <= expr ).endExpression(); \
12879+ CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
12880+ __catchResult.unsetExceptionGuard(); \
12881+ INTERNAL_CATCH_REACT( __catchResult ) \
12882+ } while( Catch::isTrue( false && static_cast<bool>( !!(expr) ) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
12883+// The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
12884+
12885+#define INTERNAL_CHECK_THAT_NO_TRY( macroName, matcher, resultDisposition, arg ) \
12886+ do { \
12887+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
12888+ __catchResult.setExceptionGuard(); \
12889+ __catchResult.captureMatch( arg, matcher, CATCH_INTERNAL_STRINGIFY(matcher) ); \
12890+ __catchResult.unsetExceptionGuard(); \
12891+ INTERNAL_CATCH_REACT( __catchResult ) \
12892+ } while( Catch::alwaysFalse() )
12893+
12894+#else
12895+///////////////////////////////////////////////////////////////////////////////
12896+// In the event of a failure works out if the debugger needs to be invoked
12897+// and/or an exception thrown and takes appropriate action.
12898+// This needs to be done as a macro so the debugger will stop in the user
12899+// source code rather than in Catch library code
12900+#define INTERNAL_CATCH_REACT( resultBuilder ) \
12901+ if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
12902+ resultBuilder.react();
12903+#endif
12904+
12905+///////////////////////////////////////////////////////////////////////////////
12906+#define INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ) \
12907+ do { \
12908+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \
12909+ try { \
12910+ CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
12911+ ( __catchResult <= expr ).endExpression(); \
12912+ CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
12913+ } \
12914+ catch( ... ) { \
12915+ __catchResult.useActiveException( resultDisposition ); \
12916+ } \
12917+ INTERNAL_CATCH_REACT( __catchResult ) \
12918+ } while( Catch::isTrue( false && static_cast<bool>( !!(expr) ) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
12919+ // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
12920+
12921+///////////////////////////////////////////////////////////////////////////////
12922+#define INTERNAL_CATCH_IF( macroName, resultDisposition, expr ) \
12923+ INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \
12924+ if( Catch::getResultCapture().lastAssertionPassed() )
12925+
12926+///////////////////////////////////////////////////////////////////////////////
12927+#define INTERNAL_CATCH_ELSE( macroName, resultDisposition, expr ) \
12928+ INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \
12929+ if( !Catch::getResultCapture().lastAssertionPassed() )
12930+
12931+///////////////////////////////////////////////////////////////////////////////
12932+#define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, expr ) \
12933+ do { \
12934+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \
12935+ try { \
12936+ static_cast<void>(expr); \
12937+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
12938+ } \
12939+ catch( ... ) { \
12940+ __catchResult.useActiveException( resultDisposition ); \
12941+ } \
12942+ INTERNAL_CATCH_REACT( __catchResult ) \
12943+ } while( Catch::alwaysFalse() )
12944+
12945+///////////////////////////////////////////////////////////////////////////////
12946+#define INTERNAL_CATCH_THROWS( macroName, resultDisposition, matcher, expr ) \
12947+ do { \
12948+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition, CATCH_INTERNAL_STRINGIFY(matcher) ); \
12949+ if( __catchResult.allowThrows() ) \
12950+ try { \
12951+ static_cast<void>(expr); \
12952+ __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
12953+ } \
12954+ catch( ... ) { \
12955+ __catchResult.captureExpectedException( matcher ); \
12956+ } \
12957+ else \
12958+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
12959+ INTERNAL_CATCH_REACT( __catchResult ) \
12960+ } while( Catch::alwaysFalse() )
12961+
12962+///////////////////////////////////////////////////////////////////////////////
12963+#define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
12964+ do { \
12965+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
12966+ if( __catchResult.allowThrows() ) \
12967+ try { \
12968+ static_cast<void>(expr); \
12969+ __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
12970+ } \
12971+ catch( exceptionType ) { \
12972+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
12973+ } \
12974+ catch( ... ) { \
12975+ __catchResult.useActiveException( resultDisposition ); \
12976+ } \
12977+ else \
12978+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
12979+ INTERNAL_CATCH_REACT( __catchResult ) \
12980+ } while( Catch::alwaysFalse() )
12981+
12982+///////////////////////////////////////////////////////////////////////////////
12983+#ifdef CATCH_CONFIG_VARIADIC_MACROS
12984+ #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
12985+ do { \
12986+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
12987+ __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \
12988+ __catchResult.captureResult( messageType ); \
12989+ INTERNAL_CATCH_REACT( __catchResult ) \
12990+ } while( Catch::alwaysFalse() )
12991+#else
12992+ #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, log ) \
12993+ do { \
12994+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
12995+ __catchResult << log + ::Catch::StreamEndStop(); \
12996+ __catchResult.captureResult( messageType ); \
12997+ INTERNAL_CATCH_REACT( __catchResult ) \
12998+ } while( Catch::alwaysFalse() )
12999+#endif
13000+
13001+///////////////////////////////////////////////////////////////////////////////
13002+#define INTERNAL_CATCH_INFO( macroName, log ) \
13003+ Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
13004+
13005+///////////////////////////////////////////////////////////////////////////////
13006+#define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
13007+ do { \
13008+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
13009+ try { \
13010+ __catchResult.captureMatch( arg, matcher, CATCH_INTERNAL_STRINGIFY(matcher) ); \
13011+ } catch( ... ) { \
13012+ __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
13013+ } \
13014+ INTERNAL_CATCH_REACT( __catchResult ) \
13015+ } while( Catch::alwaysFalse() )
13016+
13017+// #included from: internal/catch_section.h
13018+#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
13019+
13020+// #included from: catch_section_info.h
13021+#define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
13022+
13023+// #included from: catch_totals.hpp
13024+#define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED
13025+
13026+#include <cstddef>
13027+
13028+namespace Catch {
13029+
13030+ struct Counts {
13031+ Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {}
13032+
13033+ Counts operator - ( Counts const& other ) const {
13034+ Counts diff;
13035+ diff.passed = passed - other.passed;
13036+ diff.failed = failed - other.failed;
13037+ diff.failedButOk = failedButOk - other.failedButOk;
13038+ return diff;
13039+ }
13040+ Counts& operator += ( Counts const& other ) {
13041+ passed += other.passed;
13042+ failed += other.failed;
13043+ failedButOk += other.failedButOk;
13044+ return *this;
13045+ }
13046+
13047+ std::size_t total() const {
13048+ return passed + failed + failedButOk;
13049+ }
13050+ bool allPassed() const {
13051+ return failed == 0 && failedButOk == 0;
13052+ }
13053+ bool allOk() const {
13054+ return failed == 0;
13055+ }
13056+
13057+ std::size_t passed;
13058+ std::size_t failed;
13059+ std::size_t failedButOk;
13060+ };
13061+
13062+ struct Totals {
13063+
13064+ Totals operator - ( Totals const& other ) const {
13065+ Totals diff;
13066+ diff.assertions = assertions - other.assertions;
13067+ diff.testCases = testCases - other.testCases;
13068+ return diff;
13069+ }
13070+
13071+ Totals delta( Totals const& prevTotals ) const {
13072+ Totals diff = *this - prevTotals;
13073+ if( diff.assertions.failed > 0 )
13074+ ++diff.testCases.failed;
13075+ else if( diff.assertions.failedButOk > 0 )
13076+ ++diff.testCases.failedButOk;
13077+ else
13078+ ++diff.testCases.passed;
13079+ return diff;
13080+ }
13081+
13082+ Totals& operator += ( Totals const& other ) {
13083+ assertions += other.assertions;
13084+ testCases += other.testCases;
13085+ return *this;
13086+ }
13087+
13088+ Counts assertions;
13089+ Counts testCases;
13090+ };
13091+}
13092+
13093+#include <string>
13094+
13095+namespace Catch {
13096+
13097+ struct SectionInfo {
13098+ SectionInfo
13099+ ( SourceLineInfo const& _lineInfo,
13100+ std::string const& _name,
13101+ std::string const& _description = std::string() );
13102+
13103+ std::string name;
13104+ std::string description;
13105+ SourceLineInfo lineInfo;
13106+ };
13107+
13108+ struct SectionEndInfo {
13109+ SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )
13110+ : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
13111+ {}
13112+
13113+ SectionInfo sectionInfo;
13114+ Counts prevAssertions;
13115+ double durationInSeconds;
13116+ };
13117+
13118+} // end namespace Catch
13119+
13120+// #included from: catch_timer.h
13121+#define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED
13122+
13123+#ifdef _MSC_VER
13124+
13125+namespace Catch {
13126+ typedef unsigned long long UInt64;
13127+}
13128+#else
13129+#include <stdint.h>
13130+namespace Catch {
13131+ typedef uint64_t UInt64;
13132+}
13133+#endif
13134+
13135+namespace Catch {
13136+ class Timer {
13137+ public:
13138+ Timer() : m_ticks( 0 ) {}
13139+ void start();
13140+ unsigned int getElapsedMicroseconds() const;
13141+ unsigned int getElapsedMilliseconds() const;
13142+ double getElapsedSeconds() const;
13143+
13144+ private:
13145+ UInt64 m_ticks;
13146+ };
13147+
13148+} // namespace Catch
13149+
13150+#include <string>
13151+
13152+namespace Catch {
13153+
13154+ class Section : NonCopyable {
13155+ public:
13156+ Section( SectionInfo const& info );
13157+ ~Section();
13158+
13159+ // This indicates whether the section should be executed or not
13160+ operator bool() const;
13161+
13162+ private:
13163+ SectionInfo m_info;
13164+
13165+ std::string m_name;
13166+ Counts m_assertions;
13167+ bool m_sectionIncluded;
13168+ Timer m_timer;
13169+ };
13170+
13171+} // end namespace Catch
13172+
13173+#ifdef CATCH_CONFIG_VARIADIC_MACROS
13174+ #define INTERNAL_CATCH_SECTION( ... ) \
13175+ if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
13176+#else
13177+ #define INTERNAL_CATCH_SECTION( name, desc ) \
13178+ if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) )
13179+#endif
13180+
13181+// #included from: internal/catch_generators.hpp
13182+#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
13183+
13184+#include <vector>
13185+#include <string>
13186+#include <stdlib.h>
13187+
13188+namespace Catch {
13189+
13190+template<typename T>
13191+struct IGenerator {
13192+ virtual ~IGenerator() {}
13193+ virtual T getValue( std::size_t index ) const = 0;
13194+ virtual std::size_t size () const = 0;
13195+};
13196+
13197+template<typename T>
13198+class BetweenGenerator : public IGenerator<T> {
13199+public:
13200+ BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){}
13201+
13202+ virtual T getValue( std::size_t index ) const {
13203+ return m_from+static_cast<int>( index );
13204+ }
13205+
13206+ virtual std::size_t size() const {
13207+ return static_cast<std::size_t>( 1+m_to-m_from );
13208+ }
13209+
13210+private:
13211+
13212+ T m_from;
13213+ T m_to;
13214+};
13215+
13216+template<typename T>
13217+class ValuesGenerator : public IGenerator<T> {
13218+public:
13219+ ValuesGenerator(){}
13220+
13221+ void add( T value ) {
13222+ m_values.push_back( value );
13223+ }
13224+
13225+ virtual T getValue( std::size_t index ) const {
13226+ return m_values[index];
13227+ }
13228+
13229+ virtual std::size_t size() const {
13230+ return m_values.size();
13231+ }
13232+
13233+private:
13234+ std::vector<T> m_values;
13235+};
13236+
13237+template<typename T>
13238+class CompositeGenerator {
13239+public:
13240+ CompositeGenerator() : m_totalSize( 0 ) {}
13241+
13242+ // *** Move semantics, similar to auto_ptr ***
13243+ CompositeGenerator( CompositeGenerator& other )
13244+ : m_fileInfo( other.m_fileInfo ),
13245+ m_totalSize( 0 )
13246+ {
13247+ move( other );
13248+ }
13249+
13250+ CompositeGenerator& setFileInfo( const char* fileInfo ) {
13251+ m_fileInfo = fileInfo;
13252+ return *this;
13253+ }
13254+
13255+ ~CompositeGenerator() {
13256+ deleteAll( m_composed );
13257+ }
13258+
13259+ operator T () const {
13260+ size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );
13261+
13262+ typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
13263+ typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
13264+ for( size_t index = 0; it != itEnd; ++it )
13265+ {
13266+ const IGenerator<T>* generator = *it;
13267+ if( overallIndex >= index && overallIndex < index + generator->size() )
13268+ {
13269+ return generator->getValue( overallIndex-index );
13270+ }
13271+ index += generator->size();
13272+ }
13273+ CATCH_INTERNAL_ERROR( "Indexed past end of generated range" );
13274+ return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so
13275+ }
13276+
13277+ void add( const IGenerator<T>* generator ) {
13278+ m_totalSize += generator->size();
13279+ m_composed.push_back( generator );
13280+ }
13281+
13282+ CompositeGenerator& then( CompositeGenerator& other ) {
13283+ move( other );
13284+ return *this;
13285+ }
13286+
13287+ CompositeGenerator& then( T value ) {
13288+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
13289+ valuesGen->add( value );
13290+ add( valuesGen );
13291+ return *this;
13292+ }
13293+
13294+private:
13295+
13296+ void move( CompositeGenerator& other ) {
13297+ m_composed.insert( m_composed.end(), other.m_composed.begin(), other.m_composed.end() );
13298+ m_totalSize += other.m_totalSize;
13299+ other.m_composed.clear();
13300+ }
13301+
13302+ std::vector<const IGenerator<T>*> m_composed;
13303+ std::string m_fileInfo;
13304+ size_t m_totalSize;
13305+};
13306+
13307+namespace Generators
13308+{
13309+ template<typename T>
13310+ CompositeGenerator<T> between( T from, T to ) {
13311+ CompositeGenerator<T> generators;
13312+ generators.add( new BetweenGenerator<T>( from, to ) );
13313+ return generators;
13314+ }
13315+
13316+ template<typename T>
13317+ CompositeGenerator<T> values( T val1, T val2 ) {
13318+ CompositeGenerator<T> generators;
13319+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
13320+ valuesGen->add( val1 );
13321+ valuesGen->add( val2 );
13322+ generators.add( valuesGen );
13323+ return generators;
13324+ }
13325+
13326+ template<typename T>
13327+ CompositeGenerator<T> values( T val1, T val2, T val3 ){
13328+ CompositeGenerator<T> generators;
13329+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
13330+ valuesGen->add( val1 );
13331+ valuesGen->add( val2 );
13332+ valuesGen->add( val3 );
13333+ generators.add( valuesGen );
13334+ return generators;
13335+ }
13336+
13337+ template<typename T>
13338+ CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) {
13339+ CompositeGenerator<T> generators;
13340+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
13341+ valuesGen->add( val1 );
13342+ valuesGen->add( val2 );
13343+ valuesGen->add( val3 );
13344+ valuesGen->add( val4 );
13345+ generators.add( valuesGen );
13346+ return generators;
13347+ }
13348+
13349+} // end namespace Generators
13350+
13351+using namespace Generators;
13352+
13353+} // end namespace Catch
13354+
13355+#define INTERNAL_CATCH_LINESTR2( line ) #line
13356+#define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )
13357+
13358+#define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" )
13359+
13360+// #included from: internal/catch_interfaces_exception.h
13361+#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
13362+
13363+#include <string>
13364+#include <vector>
13365+
13366+// #included from: catch_interfaces_registry_hub.h
13367+#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
13368+
13369+#include <string>
13370+
13371+namespace Catch {
13372+
13373+ class TestCase;
13374+ struct ITestCaseRegistry;
13375+ struct IExceptionTranslatorRegistry;
13376+ struct IExceptionTranslator;
13377+ struct IReporterRegistry;
13378+ struct IReporterFactory;
13379+ struct ITagAliasRegistry;
13380+
13381+ struct IRegistryHub {
13382+ virtual ~IRegistryHub();
13383+
13384+ virtual IReporterRegistry const& getReporterRegistry() const = 0;
13385+ virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
13386+ virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
13387+
13388+ virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
13389+ };
13390+
13391+ struct IMutableRegistryHub {
13392+ virtual ~IMutableRegistryHub();
13393+ virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) = 0;
13394+ virtual void registerListener( Ptr<IReporterFactory> const& factory ) = 0;
13395+ virtual void registerTest( TestCase const& testInfo ) = 0;
13396+ virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
13397+ virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
13398+ };
13399+
13400+ IRegistryHub& getRegistryHub();
13401+ IMutableRegistryHub& getMutableRegistryHub();
13402+ void cleanUp();
13403+ std::string translateActiveException();
13404+
13405+}
13406+
13407+namespace Catch {
13408+
13409+ typedef std::string(*exceptionTranslateFunction)();
13410+
13411+ struct IExceptionTranslator;
13412+ typedef std::vector<const IExceptionTranslator*> ExceptionTranslators;
13413+
13414+ struct IExceptionTranslator {
13415+ virtual ~IExceptionTranslator();
13416+ virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
13417+ };
13418+
13419+ struct IExceptionTranslatorRegistry {
13420+ virtual ~IExceptionTranslatorRegistry();
13421+
13422+ virtual std::string translateActiveException() const = 0;
13423+ };
13424+
13425+ class ExceptionTranslatorRegistrar {
13426+ template<typename T>
13427+ class ExceptionTranslator : public IExceptionTranslator {
13428+ public:
13429+
13430+ ExceptionTranslator( std::string(*translateFunction)( T& ) )
13431+ : m_translateFunction( translateFunction )
13432+ {}
13433+
13434+ virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE {
13435+ try {
13436+ if( it == itEnd )
13437+ throw;
13438+ else
13439+ return (*it)->translate( it+1, itEnd );
13440+ }
13441+ catch( T& ex ) {
13442+ return m_translateFunction( ex );
13443+ }
13444+ }
13445+
13446+ protected:
13447+ std::string(*m_translateFunction)( T& );
13448+ };
13449+
13450+ public:
13451+ template<typename T>
13452+ ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
13453+ getMutableRegistryHub().registerTranslator
13454+ ( new ExceptionTranslator<T>( translateFunction ) );
13455+ }
13456+ };
13457+}
13458+
13459+///////////////////////////////////////////////////////////////////////////////
13460+#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
13461+ static std::string translatorName( signature ); \
13462+ namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\
13463+ static std::string translatorName( signature )
13464+
13465+#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
13466+
13467+// #included from: internal/catch_approx.hpp
13468+#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
13469+
13470+#include <cmath>
13471+#include <limits>
13472+
13473+#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS)
13474+#include <type_traits>
13475+#endif
13476+
13477+namespace Catch {
13478+namespace Detail {
13479+
13480+ class Approx {
13481+ public:
13482+ explicit Approx ( double value )
13483+ : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
13484+ m_margin( 0.0 ),
13485+ m_scale( 1.0 ),
13486+ m_value( value )
13487+ {}
13488+
13489+ static Approx custom() {
13490+ return Approx( 0 );
13491+ }
13492+
13493+#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS)
13494+
13495+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
13496+ Approx operator()( T value ) {
13497+ Approx approx( static_cast<double>(value) );
13498+ approx.epsilon( m_epsilon );
13499+ approx.margin( m_margin );
13500+ approx.scale( m_scale );
13501+ return approx;
13502+ }
13503+
13504+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
13505+ explicit Approx( T value ): Approx(static_cast<double>(value))
13506+ {}
13507+
13508+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
13509+ friend bool operator == ( const T& lhs, Approx const& rhs ) {
13510+ // Thanks to Richard Harris for his help refining this formula
13511+ auto lhs_v = double(lhs);
13512+ bool relativeOK = std::fabs(lhs_v - rhs.m_value) < rhs.m_epsilon * (rhs.m_scale + (std::max)(std::fabs(lhs_v), std::fabs(rhs.m_value)));
13513+ if (relativeOK) {
13514+ return true;
13515+ }
13516+
13517+ return std::fabs(lhs_v - rhs.m_value) <= rhs.m_margin;
13518+ }
13519+
13520+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
13521+ friend bool operator == ( Approx const& lhs, const T& rhs ) {
13522+ return operator==( rhs, lhs );
13523+ }
13524+
13525+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
13526+ friend bool operator != ( T lhs, Approx const& rhs ) {
13527+ return !operator==( lhs, rhs );
13528+ }
13529+
13530+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
13531+ friend bool operator != ( Approx const& lhs, T rhs ) {
13532+ return !operator==( rhs, lhs );
13533+ }
13534+
13535+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
13536+ friend bool operator <= ( T lhs, Approx const& rhs ) {
13537+ return double(lhs) < rhs.m_value || lhs == rhs;
13538+ }
13539+
13540+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
13541+ friend bool operator <= ( Approx const& lhs, T rhs ) {
13542+ return lhs.m_value < double(rhs) || lhs == rhs;
13543+ }
13544+
13545+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
13546+ friend bool operator >= ( T lhs, Approx const& rhs ) {
13547+ return double(lhs) > rhs.m_value || lhs == rhs;
13548+ }
13549+
13550+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
13551+ friend bool operator >= ( Approx const& lhs, T rhs ) {
13552+ return lhs.m_value > double(rhs) || lhs == rhs;
13553+ }
13554+
13555+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
13556+ Approx& epsilon( T newEpsilon ) {
13557+ m_epsilon = double(newEpsilon);
13558+ return *this;
13559+ }
13560+
13561+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
13562+ Approx& margin( T newMargin ) {
13563+ m_margin = double(newMargin);
13564+ return *this;
13565+ }
13566+
13567+ template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
13568+ Approx& scale( T newScale ) {
13569+ m_scale = double(newScale);
13570+ return *this;
13571+ }
13572+
13573+#else
13574+
13575+ Approx operator()( double value ) {
13576+ Approx approx( value );
13577+ approx.epsilon( m_epsilon );
13578+ approx.margin( m_margin );
13579+ approx.scale( m_scale );
13580+ return approx;
13581+ }
13582+
13583+ friend bool operator == ( double lhs, Approx const& rhs ) {
13584+ // Thanks to Richard Harris for his help refining this formula
13585+ bool relativeOK = std::fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( std::fabs(lhs), std::fabs(rhs.m_value) ) );
13586+ if (relativeOK) {
13587+ return true;
13588+ }
13589+ return std::fabs(lhs - rhs.m_value) <= rhs.m_margin;
13590+ }
13591+
13592+ friend bool operator == ( Approx const& lhs, double rhs ) {
13593+ return operator==( rhs, lhs );
13594+ }
13595+
13596+ friend bool operator != ( double lhs, Approx const& rhs ) {
13597+ return !operator==( lhs, rhs );
13598+ }
13599+
13600+ friend bool operator != ( Approx const& lhs, double rhs ) {
13601+ return !operator==( rhs, lhs );
13602+ }
13603+
13604+ friend bool operator <= ( double lhs, Approx const& rhs ) {
13605+ return lhs < rhs.m_value || lhs == rhs;
13606+ }
13607+
13608+ friend bool operator <= ( Approx const& lhs, double rhs ) {
13609+ return lhs.m_value < rhs || lhs == rhs;
13610+ }
13611+
13612+ friend bool operator >= ( double lhs, Approx const& rhs ) {
13613+ return lhs > rhs.m_value || lhs == rhs;
13614+ }
13615+
13616+ friend bool operator >= ( Approx const& lhs, double rhs ) {
13617+ return lhs.m_value > rhs || lhs == rhs;
13618+ }
13619+
13620+ Approx& epsilon( double newEpsilon ) {
13621+ m_epsilon = newEpsilon;
13622+ return *this;
13623+ }
13624+
13625+ Approx& margin( double newMargin ) {
13626+ m_margin = newMargin;
13627+ return *this;
13628+ }
13629+
13630+ Approx& scale( double newScale ) {
13631+ m_scale = newScale;
13632+ return *this;
13633+ }
13634+#endif
13635+
13636+ std::string toString() const {
13637+ std::ostringstream oss;
13638+ oss << "Approx( " << Catch::toString( m_value ) << " )";
13639+ return oss.str();
13640+ }
13641+
13642+ private:
13643+ double m_epsilon;
13644+ double m_margin;
13645+ double m_scale;
13646+ double m_value;
13647+ };
13648+}
13649+
13650+template<>
13651+inline std::string toString<Detail::Approx>( Detail::Approx const& value ) {
13652+ return value.toString();
13653+}
13654+
13655+} // end namespace Catch
13656+
13657+// #included from: internal/catch_matchers_string.h
13658+#define TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED
13659+
13660+namespace Catch {
13661+namespace Matchers {
13662+
13663+ namespace StdString {
13664+
13665+ struct CasedString
13666+ {
13667+ CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );
13668+ std::string adjustString( std::string const& str ) const;
13669+ std::string caseSensitivitySuffix() const;
13670+
13671+ CaseSensitive::Choice m_caseSensitivity;
13672+ std::string m_str;
13673+ };
13674+
13675+ struct StringMatcherBase : MatcherBase<std::string> {
13676+ StringMatcherBase( std::string const& operation, CasedString const& comparator );
13677+ virtual std::string describe() const CATCH_OVERRIDE;
13678+
13679+ CasedString m_comparator;
13680+ std::string m_operation;
13681+ };
13682+
13683+ struct EqualsMatcher : StringMatcherBase {
13684+ EqualsMatcher( CasedString const& comparator );
13685+ virtual bool match( std::string const& source ) const CATCH_OVERRIDE;
13686+ };
13687+ struct ContainsMatcher : StringMatcherBase {
13688+ ContainsMatcher( CasedString const& comparator );
13689+ virtual bool match( std::string const& source ) const CATCH_OVERRIDE;
13690+ };
13691+ struct StartsWithMatcher : StringMatcherBase {
13692+ StartsWithMatcher( CasedString const& comparator );
13693+ virtual bool match( std::string const& source ) const CATCH_OVERRIDE;
13694+ };
13695+ struct EndsWithMatcher : StringMatcherBase {
13696+ EndsWithMatcher( CasedString const& comparator );
13697+ virtual bool match( std::string const& source ) const CATCH_OVERRIDE;
13698+ };
13699+
13700+ } // namespace StdString
13701+
13702+ // The following functions create the actual matcher objects.
13703+ // This allows the types to be inferred
13704+
13705+ StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
13706+ StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
13707+ StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
13708+ StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
13709+
13710+} // namespace Matchers
13711+} // namespace Catch
13712+
13713+// #included from: internal/catch_matchers_vector.h
13714+#define TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED
13715+
13716+namespace Catch {
13717+namespace Matchers {
13718+
13719+ namespace Vector {
13720+
13721+ template<typename T>
13722+ struct ContainsElementMatcher : MatcherBase<std::vector<T>, T> {
13723+
13724+ ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
13725+
13726+ bool match(std::vector<T> const &v) const CATCH_OVERRIDE {
13727+ return std::find(v.begin(), v.end(), m_comparator) != v.end();
13728+ }
13729+
13730+ virtual std::string describe() const CATCH_OVERRIDE {
13731+ return "Contains: " + Catch::toString( m_comparator );
13732+ }
13733+
13734+ T const& m_comparator;
13735+ };
13736+
13737+ template<typename T>
13738+ struct ContainsMatcher : MatcherBase<std::vector<T>, std::vector<T> > {
13739+
13740+ ContainsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
13741+
13742+ bool match(std::vector<T> const &v) const CATCH_OVERRIDE {
13743+ // !TBD: see note in EqualsMatcher
13744+ if (m_comparator.size() > v.size())
13745+ return false;
13746+ for (size_t i = 0; i < m_comparator.size(); ++i)
13747+ if (std::find(v.begin(), v.end(), m_comparator[i]) == v.end())
13748+ return false;
13749+ return true;
13750+ }
13751+ virtual std::string describe() const CATCH_OVERRIDE {
13752+ return "Contains: " + Catch::toString( m_comparator );
13753+ }
13754+
13755+ std::vector<T> const& m_comparator;
13756+ };
13757+
13758+ template<typename T>
13759+ struct EqualsMatcher : MatcherBase<std::vector<T>, std::vector<T> > {
13760+
13761+ EqualsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
13762+
13763+ bool match(std::vector<T> const &v) const CATCH_OVERRIDE {
13764+ // !TBD: This currently works if all elements can be compared using !=
13765+ // - a more general approach would be via a compare template that defaults
13766+ // to using !=. but could be specialised for, e.g. std::vector<T> etc
13767+ // - then just call that directly
13768+ if (m_comparator.size() != v.size())
13769+ return false;
13770+ for (size_t i = 0; i < v.size(); ++i)
13771+ if (m_comparator[i] != v[i])
13772+ return false;
13773+ return true;
13774+ }
13775+ virtual std::string describe() const CATCH_OVERRIDE {
13776+ return "Equals: " + Catch::toString( m_comparator );
13777+ }
13778+ std::vector<T> const& m_comparator;
13779+ };
13780+
13781+ } // namespace Vector
13782+
13783+ // The following functions create the actual matcher objects.
13784+ // This allows the types to be inferred
13785+
13786+ template<typename T>
13787+ Vector::ContainsMatcher<T> Contains( std::vector<T> const& comparator ) {
13788+ return Vector::ContainsMatcher<T>( comparator );
13789+ }
13790+
13791+ template<typename T>
13792+ Vector::ContainsElementMatcher<T> VectorContains( T const& comparator ) {
13793+ return Vector::ContainsElementMatcher<T>( comparator );
13794+ }
13795+
13796+ template<typename T>
13797+ Vector::EqualsMatcher<T> Equals( std::vector<T> const& comparator ) {
13798+ return Vector::EqualsMatcher<T>( comparator );
13799+ }
13800+
13801+} // namespace Matchers
13802+} // namespace Catch
13803+
13804+// #included from: internal/catch_interfaces_tag_alias_registry.h
13805+#define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED
13806+
13807+// #included from: catch_tag_alias.h
13808+#define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED
13809+
13810+#include <string>
13811+
13812+namespace Catch {
13813+
13814+ struct TagAlias {
13815+ TagAlias( std::string const& _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
13816+
13817+ std::string tag;
13818+ SourceLineInfo lineInfo;
13819+ };
13820+
13821+ struct RegistrarForTagAliases {
13822+ RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
13823+ };
13824+
13825+} // end namespace Catch
13826+
13827+#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }
13828+// #included from: catch_option.hpp
13829+#define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
13830+
13831+namespace Catch {
13832+
13833+ // An optional type
13834+ template<typename T>
13835+ class Option {
13836+ public:
13837+ Option() : nullableValue( CATCH_NULL ) {}
13838+ Option( T const& _value )
13839+ : nullableValue( new( storage ) T( _value ) )
13840+ {}
13841+ Option( Option const& _other )
13842+ : nullableValue( _other ? new( storage ) T( *_other ) : CATCH_NULL )
13843+ {}
13844+
13845+ ~Option() {
13846+ reset();
13847+ }
13848+
13849+ Option& operator= ( Option const& _other ) {
13850+ if( &_other != this ) {
13851+ reset();
13852+ if( _other )
13853+ nullableValue = new( storage ) T( *_other );
13854+ }
13855+ return *this;
13856+ }
13857+ Option& operator = ( T const& _value ) {
13858+ reset();
13859+ nullableValue = new( storage ) T( _value );
13860+ return *this;
13861+ }
13862+
13863+ void reset() {
13864+ if( nullableValue )
13865+ nullableValue->~T();
13866+ nullableValue = CATCH_NULL;
13867+ }
13868+
13869+ T& operator*() { return *nullableValue; }
13870+ T const& operator*() const { return *nullableValue; }
13871+ T* operator->() { return nullableValue; }
13872+ const T* operator->() const { return nullableValue; }
13873+
13874+ T valueOr( T const& defaultValue ) const {
13875+ return nullableValue ? *nullableValue : defaultValue;
13876+ }
13877+
13878+ bool some() const { return nullableValue != CATCH_NULL; }
13879+ bool none() const { return nullableValue == CATCH_NULL; }
13880+
13881+ bool operator !() const { return nullableValue == CATCH_NULL; }
13882+ operator SafeBool::type() const {
13883+ return SafeBool::makeSafe( some() );
13884+ }
13885+
13886+ private:
13887+ T *nullableValue;
13888+ union {
13889+ char storage[sizeof(T)];
13890+
13891+ // These are here to force alignment for the storage
13892+ long double dummy1;
13893+ void (*dummy2)();
13894+ long double dummy3;
13895+#ifdef CATCH_CONFIG_CPP11_LONG_LONG
13896+ long long dummy4;
13897+#endif
13898+ };
13899+ };
13900+
13901+} // end namespace Catch
13902+
13903+namespace Catch {
13904+
13905+ struct ITagAliasRegistry {
13906+ virtual ~ITagAliasRegistry();
13907+ virtual Option<TagAlias> find( std::string const& alias ) const = 0;
13908+ virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
13909+
13910+ static ITagAliasRegistry const& get();
13911+ };
13912+
13913+} // end namespace Catch
13914+
13915+// These files are included here so the single_include script doesn't put them
13916+// in the conditionally compiled sections
13917+// #included from: internal/catch_test_case_info.h
13918+#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED
13919+
13920+#include <string>
13921+#include <set>
13922+
13923+#ifdef __clang__
13924+#pragma clang diagnostic push
13925+#pragma clang diagnostic ignored "-Wpadded"
13926+#endif
13927+
13928+namespace Catch {
13929+
13930+ struct ITestCase;
13931+
13932+ struct TestCaseInfo {
13933+ enum SpecialProperties{
13934+ None = 0,
13935+ IsHidden = 1 << 1,
13936+ ShouldFail = 1 << 2,
13937+ MayFail = 1 << 3,
13938+ Throws = 1 << 4,
13939+ NonPortable = 1 << 5
13940+ };
13941+
13942+ TestCaseInfo( std::string const& _name,
13943+ std::string const& _className,
13944+ std::string const& _description,
13945+ std::set<std::string> const& _tags,
13946+ SourceLineInfo const& _lineInfo );
13947+
13948+ TestCaseInfo( TestCaseInfo const& other );
13949+
13950+ friend void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags );
13951+
13952+ bool isHidden() const;
13953+ bool throws() const;
13954+ bool okToFail() const;
13955+ bool expectedToFail() const;
13956+
13957+ std::string name;
13958+ std::string className;
13959+ std::string description;
13960+ std::set<std::string> tags;
13961+ std::set<std::string> lcaseTags;
13962+ std::string tagsAsString;
13963+ SourceLineInfo lineInfo;
13964+ SpecialProperties properties;
13965+ };
13966+
13967+ class TestCase : public TestCaseInfo {
13968+ public:
13969+
13970+ TestCase( ITestCase* testCase, TestCaseInfo const& info );
13971+ TestCase( TestCase const& other );
13972+
13973+ TestCase withName( std::string const& _newName ) const;
13974+
13975+ void invoke() const;
13976+
13977+ TestCaseInfo const& getTestCaseInfo() const;
13978+
13979+ void swap( TestCase& other );
13980+ bool operator == ( TestCase const& other ) const;
13981+ bool operator < ( TestCase const& other ) const;
13982+ TestCase& operator = ( TestCase const& other );
13983+
13984+ private:
13985+ Ptr<ITestCase> test;
13986+ };
13987+
13988+ TestCase makeTestCase( ITestCase* testCase,
13989+ std::string const& className,
13990+ std::string const& name,
13991+ std::string const& description,
13992+ SourceLineInfo const& lineInfo );
13993+}
13994+
13995+#ifdef __clang__
13996+#pragma clang diagnostic pop
13997+#endif
13998+
13999+
14000+#ifdef __OBJC__
14001+// #included from: internal/catch_objc.hpp
14002+#define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
14003+
14004+#import <objc/runtime.h>
14005+
14006+#include <string>
14007+
14008+// NB. Any general catch headers included here must be included
14009+// in catch.hpp first to make sure they are included by the single
14010+// header for non obj-usage
14011+
14012+///////////////////////////////////////////////////////////////////////////////
14013+// This protocol is really only here for (self) documenting purposes, since
14014+// all its methods are optional.
14015+@protocol OcFixture
14016+
14017+@optional
14018+
14019+-(void) setUp;
14020+-(void) tearDown;
14021+
14022+@end
14023+
14024+namespace Catch {
14025+
14026+ class OcMethod : public SharedImpl<ITestCase> {
14027+
14028+ public:
14029+ OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
14030+
14031+ virtual void invoke() const {
14032+ id obj = [[m_cls alloc] init];
14033+
14034+ performOptionalSelector( obj, @selector(setUp) );
14035+ performOptionalSelector( obj, m_sel );
14036+ performOptionalSelector( obj, @selector(tearDown) );
14037+
14038+ arcSafeRelease( obj );
14039+ }
14040+ private:
14041+ virtual ~OcMethod() {}
14042+
14043+ Class m_cls;
14044+ SEL m_sel;
14045+ };
14046+
14047+ namespace Detail{
14048+
14049+ inline std::string getAnnotation( Class cls,
14050+ std::string const& annotationName,
14051+ std::string const& testCaseName ) {
14052+ NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
14053+ SEL sel = NSSelectorFromString( selStr );
14054+ arcSafeRelease( selStr );
14055+ id value = performOptionalSelector( cls, sel );
14056+ if( value )
14057+ return [(NSString*)value UTF8String];
14058+ return "";
14059+ }
14060+ }
14061+
14062+ inline size_t registerTestMethods() {
14063+ size_t noTestMethods = 0;
14064+ int noClasses = objc_getClassList( CATCH_NULL, 0 );
14065+
14066+ Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
14067+ objc_getClassList( classes, noClasses );
14068+
14069+ for( int c = 0; c < noClasses; c++ ) {
14070+ Class cls = classes[c];
14071+ {
14072+ u_int count;
14073+ Method* methods = class_copyMethodList( cls, &count );
14074+ for( u_int m = 0; m < count ; m++ ) {
14075+ SEL selector = method_getName(methods[m]);
14076+ std::string methodName = sel_getName(selector);
14077+ if( startsWith( methodName, "Catch_TestCase_" ) ) {
14078+ std::string testCaseName = methodName.substr( 15 );
14079+ std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
14080+ std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
14081+ const char* className = class_getName( cls );
14082+
14083+ getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) );
14084+ noTestMethods++;
14085+ }
14086+ }
14087+ free(methods);
14088+ }
14089+ }
14090+ return noTestMethods;
14091+ }
14092+
14093+ namespace Matchers {
14094+ namespace Impl {
14095+ namespace NSStringMatchers {
14096+
14097+ struct StringHolder : MatcherBase<NSString*>{
14098+ StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
14099+ StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
14100+ StringHolder() {
14101+ arcSafeRelease( m_substr );
14102+ }
14103+
14104+ virtual bool match( NSString* arg ) const CATCH_OVERRIDE {
14105+ return false;
14106+ }
14107+
14108+ NSString* m_substr;
14109+ };
14110+
14111+ struct Equals : StringHolder {
14112+ Equals( NSString* substr ) : StringHolder( substr ){}
14113+
14114+ virtual bool match( NSString* str ) const CATCH_OVERRIDE {
14115+ return (str != nil || m_substr == nil ) &&
14116+ [str isEqualToString:m_substr];
14117+ }
14118+
14119+ virtual std::string describe() const CATCH_OVERRIDE {
14120+ return "equals string: " + Catch::toString( m_substr );
14121+ }
14122+ };
14123+
14124+ struct Contains : StringHolder {
14125+ Contains( NSString* substr ) : StringHolder( substr ){}
14126+
14127+ virtual bool match( NSString* str ) const {
14128+ return (str != nil || m_substr == nil ) &&
14129+ [str rangeOfString:m_substr].location != NSNotFound;
14130+ }
14131+
14132+ virtual std::string describe() const CATCH_OVERRIDE {
14133+ return "contains string: " + Catch::toString( m_substr );
14134+ }
14135+ };
14136+
14137+ struct StartsWith : StringHolder {
14138+ StartsWith( NSString* substr ) : StringHolder( substr ){}
14139+
14140+ virtual bool match( NSString* str ) const {
14141+ return (str != nil || m_substr == nil ) &&
14142+ [str rangeOfString:m_substr].location == 0;
14143+ }
14144+
14145+ virtual std::string describe() const CATCH_OVERRIDE {
14146+ return "starts with: " + Catch::toString( m_substr );
14147+ }
14148+ };
14149+ struct EndsWith : StringHolder {
14150+ EndsWith( NSString* substr ) : StringHolder( substr ){}
14151+
14152+ virtual bool match( NSString* str ) const {
14153+ return (str != nil || m_substr == nil ) &&
14154+ [str rangeOfString:m_substr].location == [str length] - [m_substr length];
14155+ }
14156+
14157+ virtual std::string describe() const CATCH_OVERRIDE {
14158+ return "ends with: " + Catch::toString( m_substr );
14159+ }
14160+ };
14161+
14162+ } // namespace NSStringMatchers
14163+ } // namespace Impl
14164+
14165+ inline Impl::NSStringMatchers::Equals
14166+ Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
14167+
14168+ inline Impl::NSStringMatchers::Contains
14169+ Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
14170+
14171+ inline Impl::NSStringMatchers::StartsWith
14172+ StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
14173+
14174+ inline Impl::NSStringMatchers::EndsWith
14175+ EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
14176+
14177+ } // namespace Matchers
14178+
14179+ using namespace Matchers;
14180+
14181+} // namespace Catch
14182+
14183+///////////////////////////////////////////////////////////////////////////////
14184+#define OC_TEST_CASE( name, desc )\
14185++(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
14186+{\
14187+return @ name; \
14188+}\
14189++(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
14190+{ \
14191+return @ desc; \
14192+} \
14193+-(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
14194+
14195+#endif
14196+
14197+#ifdef CATCH_IMPL
14198+
14199+// !TBD: Move the leak detector code into a separate header
14200+#ifdef CATCH_CONFIG_WINDOWS_CRTDBG
14201+#include <crtdbg.h>
14202+class LeakDetector {
14203+public:
14204+ LeakDetector() {
14205+ int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
14206+ flag |= _CRTDBG_LEAK_CHECK_DF;
14207+ flag |= _CRTDBG_ALLOC_MEM_DF;
14208+ _CrtSetDbgFlag(flag);
14209+ _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
14210+ _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
14211+ // Change this to leaking allocation's number to break there
14212+ _CrtSetBreakAlloc(-1);
14213+ }
14214+};
14215+#else
14216+class LeakDetector {};
14217+#endif
14218+
14219+LeakDetector leakDetector;
14220+
14221+// #included from: internal/catch_impl.hpp
14222+#define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED
14223+
14224+// Collect all the implementation files together here
14225+// These are the equivalent of what would usually be cpp files
14226+
14227+#ifdef __clang__
14228+#pragma clang diagnostic push
14229+#pragma clang diagnostic ignored "-Wweak-vtables"
14230+#endif
14231+
14232+// #included from: ../catch_session.hpp
14233+#define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
14234+
14235+// #included from: internal/catch_commandline.hpp
14236+#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
14237+
14238+// #included from: catch_config.hpp
14239+#define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
14240+
14241+// #included from: catch_test_spec_parser.hpp
14242+#define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
14243+
14244+#ifdef __clang__
14245+#pragma clang diagnostic push
14246+#pragma clang diagnostic ignored "-Wpadded"
14247+#endif
14248+
14249+// #included from: catch_test_spec.hpp
14250+#define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
14251+
14252+#ifdef __clang__
14253+#pragma clang diagnostic push
14254+#pragma clang diagnostic ignored "-Wpadded"
14255+#endif
14256+
14257+// #included from: catch_wildcard_pattern.hpp
14258+#define TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED
14259+
14260+#include <stdexcept>
14261+
14262+namespace Catch
14263+{
14264+ class WildcardPattern {
14265+ enum WildcardPosition {
14266+ NoWildcard = 0,
14267+ WildcardAtStart = 1,
14268+ WildcardAtEnd = 2,
14269+ WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
14270+ };
14271+
14272+ public:
14273+
14274+ WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity )
14275+ : m_caseSensitivity( caseSensitivity ),
14276+ m_wildcard( NoWildcard ),
14277+ m_pattern( adjustCase( pattern ) )
14278+ {
14279+ if( startsWith( m_pattern, '*' ) ) {
14280+ m_pattern = m_pattern.substr( 1 );
14281+ m_wildcard = WildcardAtStart;
14282+ }
14283+ if( endsWith( m_pattern, '*' ) ) {
14284+ m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
14285+ m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
14286+ }
14287+ }
14288+ virtual ~WildcardPattern();
14289+ virtual bool matches( std::string const& str ) const {
14290+ switch( m_wildcard ) {
14291+ case NoWildcard:
14292+ return m_pattern == adjustCase( str );
14293+ case WildcardAtStart:
14294+ return endsWith( adjustCase( str ), m_pattern );
14295+ case WildcardAtEnd:
14296+ return startsWith( adjustCase( str ), m_pattern );
14297+ case WildcardAtBothEnds:
14298+ return contains( adjustCase( str ), m_pattern );
14299+ }
14300+
14301+#ifdef __clang__
14302+#pragma clang diagnostic push
14303+#pragma clang diagnostic ignored "-Wunreachable-code"
14304+#endif
14305+ throw std::logic_error( "Unknown enum" );
14306+#ifdef __clang__
14307+#pragma clang diagnostic pop
14308+#endif
14309+ }
14310+ private:
14311+ std::string adjustCase( std::string const& str ) const {
14312+ return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;
14313+ }
14314+ CaseSensitive::Choice m_caseSensitivity;
14315+ WildcardPosition m_wildcard;
14316+ std::string m_pattern;
14317+ };
14318+}
14319+
14320+#include <string>
14321+#include <vector>
14322+
14323+namespace Catch {
14324+
14325+ class TestSpec {
14326+ struct Pattern : SharedImpl<> {
14327+ virtual ~Pattern();
14328+ virtual bool matches( TestCaseInfo const& testCase ) const = 0;
14329+ };
14330+ class NamePattern : public Pattern {
14331+ public:
14332+ NamePattern( std::string const& name )
14333+ : m_wildcardPattern( toLower( name ), CaseSensitive::No )
14334+ {}
14335+ virtual ~NamePattern();
14336+ virtual bool matches( TestCaseInfo const& testCase ) const {
14337+ return m_wildcardPattern.matches( toLower( testCase.name ) );
14338+ }
14339+ private:
14340+ WildcardPattern m_wildcardPattern;
14341+ };
14342+
14343+ class TagPattern : public Pattern {
14344+ public:
14345+ TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
14346+ virtual ~TagPattern();
14347+ virtual bool matches( TestCaseInfo const& testCase ) const {
14348+ return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end();
14349+ }
14350+ private:
14351+ std::string m_tag;
14352+ };
14353+
14354+ class ExcludedPattern : public Pattern {
14355+ public:
14356+ ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
14357+ virtual ~ExcludedPattern();
14358+ virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
14359+ private:
14360+ Ptr<Pattern> m_underlyingPattern;
14361+ };
14362+
14363+ struct Filter {
14364+ std::vector<Ptr<Pattern> > m_patterns;
14365+
14366+ bool matches( TestCaseInfo const& testCase ) const {
14367+ // All patterns in a filter must match for the filter to be a match
14368+ for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it ) {
14369+ if( !(*it)->matches( testCase ) )
14370+ return false;
14371+ }
14372+ return true;
14373+ }
14374+ };
14375+
14376+ public:
14377+ bool hasFilters() const {
14378+ return !m_filters.empty();
14379+ }
14380+ bool matches( TestCaseInfo const& testCase ) const {
14381+ // A TestSpec matches if any filter matches
14382+ for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it )
14383+ if( it->matches( testCase ) )
14384+ return true;
14385+ return false;
14386+ }
14387+
14388+ private:
14389+ std::vector<Filter> m_filters;
14390+
14391+ friend class TestSpecParser;
14392+ };
14393+}
14394+
14395+#ifdef __clang__
14396+#pragma clang diagnostic pop
14397+#endif
14398+
14399+namespace Catch {
14400+
14401+ class TestSpecParser {
14402+ enum Mode{ None, Name, QuotedName, Tag, EscapedName };
14403+ Mode m_mode;
14404+ bool m_exclusion;
14405+ std::size_t m_start, m_pos;
14406+ std::string m_arg;
14407+ std::vector<std::size_t> m_escapeChars;
14408+ TestSpec::Filter m_currentFilter;
14409+ TestSpec m_testSpec;
14410+ ITagAliasRegistry const* m_tagAliases;
14411+
14412+ public:
14413+ TestSpecParser( ITagAliasRegistry const& tagAliases ) :m_mode(None), m_exclusion(false), m_start(0), m_pos(0), m_tagAliases( &tagAliases ) {}
14414+
14415+ TestSpecParser& parse( std::string const& arg ) {
14416+ m_mode = None;
14417+ m_exclusion = false;
14418+ m_start = std::string::npos;
14419+ m_arg = m_tagAliases->expandAliases( arg );
14420+ m_escapeChars.clear();
14421+ for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
14422+ visitChar( m_arg[m_pos] );
14423+ if( m_mode == Name )
14424+ addPattern<TestSpec::NamePattern>();
14425+ return *this;
14426+ }
14427+ TestSpec testSpec() {
14428+ addFilter();
14429+ return m_testSpec;
14430+ }
14431+ private:
14432+ void visitChar( char c ) {
14433+ if( m_mode == None ) {
14434+ switch( c ) {
14435+ case ' ': return;
14436+ case '~': m_exclusion = true; return;
14437+ case '[': return startNewMode( Tag, ++m_pos );
14438+ case '"': return startNewMode( QuotedName, ++m_pos );
14439+ case '\\': return escape();
14440+ default: startNewMode( Name, m_pos ); break;
14441+ }
14442+ }
14443+ if( m_mode == Name ) {
14444+ if( c == ',' ) {
14445+ addPattern<TestSpec::NamePattern>();
14446+ addFilter();
14447+ }
14448+ else if( c == '[' ) {
14449+ if( subString() == "exclude:" )
14450+ m_exclusion = true;
14451+ else
14452+ addPattern<TestSpec::NamePattern>();
14453+ startNewMode( Tag, ++m_pos );
14454+ }
14455+ else if( c == '\\' )
14456+ escape();
14457+ }
14458+ else if( m_mode == EscapedName )
14459+ m_mode = Name;
14460+ else if( m_mode == QuotedName && c == '"' )
14461+ addPattern<TestSpec::NamePattern>();
14462+ else if( m_mode == Tag && c == ']' )
14463+ addPattern<TestSpec::TagPattern>();
14464+ }
14465+ void startNewMode( Mode mode, std::size_t start ) {
14466+ m_mode = mode;
14467+ m_start = start;
14468+ }
14469+ void escape() {
14470+ if( m_mode == None )
14471+ m_start = m_pos;
14472+ m_mode = EscapedName;
14473+ m_escapeChars.push_back( m_pos );
14474+ }
14475+ std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
14476+ template<typename T>
14477+ void addPattern() {
14478+ std::string token = subString();
14479+ for( size_t i = 0; i < m_escapeChars.size(); ++i )
14480+ token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 );
14481+ m_escapeChars.clear();
14482+ if( startsWith( token, "exclude:" ) ) {
14483+ m_exclusion = true;
14484+ token = token.substr( 8 );
14485+ }
14486+ if( !token.empty() ) {
14487+ Ptr<TestSpec::Pattern> pattern = new T( token );
14488+ if( m_exclusion )
14489+ pattern = new TestSpec::ExcludedPattern( pattern );
14490+ m_currentFilter.m_patterns.push_back( pattern );
14491+ }
14492+ m_exclusion = false;
14493+ m_mode = None;
14494+ }
14495+ void addFilter() {
14496+ if( !m_currentFilter.m_patterns.empty() ) {
14497+ m_testSpec.m_filters.push_back( m_currentFilter );
14498+ m_currentFilter = TestSpec::Filter();
14499+ }
14500+ }
14501+ };
14502+ inline TestSpec parseTestSpec( std::string const& arg ) {
14503+ return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
14504+ }
14505+
14506+} // namespace Catch
14507+
14508+#ifdef __clang__
14509+#pragma clang diagnostic pop
14510+#endif
14511+
14512+// #included from: catch_interfaces_config.h
14513+#define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
14514+
14515+#include <iosfwd>
14516+#include <string>
14517+#include <vector>
14518+
14519+namespace Catch {
14520+
14521+ struct Verbosity { enum Level {
14522+ NoOutput = 0,
14523+ Quiet,
14524+ Normal
14525+ }; };
14526+
14527+ struct WarnAbout { enum What {
14528+ Nothing = 0x00,
14529+ NoAssertions = 0x01
14530+ }; };
14531+
14532+ struct ShowDurations { enum OrNot {
14533+ DefaultForReporter,
14534+ Always,
14535+ Never
14536+ }; };
14537+ struct RunTests { enum InWhatOrder {
14538+ InDeclarationOrder,
14539+ InLexicographicalOrder,
14540+ InRandomOrder
14541+ }; };
14542+ struct UseColour { enum YesOrNo {
14543+ Auto,
14544+ Yes,
14545+ No
14546+ }; };
14547+ struct WaitForKeypress { enum When {
14548+ Never,
14549+ BeforeStart = 1,
14550+ BeforeExit = 2,
14551+ BeforeStartAndExit = BeforeStart | BeforeExit
14552+ }; };
14553+
14554+ class TestSpec;
14555+
14556+ struct IConfig : IShared {
14557+
14558+ virtual ~IConfig();
14559+
14560+ virtual bool allowThrows() const = 0;
14561+ virtual std::ostream& stream() const = 0;
14562+ virtual std::string name() const = 0;
14563+ virtual bool includeSuccessfulResults() const = 0;
14564+ virtual bool shouldDebugBreak() const = 0;
14565+ virtual bool warnAboutMissingAssertions() const = 0;
14566+ virtual int abortAfter() const = 0;
14567+ virtual bool showInvisibles() const = 0;
14568+ virtual ShowDurations::OrNot showDurations() const = 0;
14569+ virtual TestSpec const& testSpec() const = 0;
14570+ virtual RunTests::InWhatOrder runOrder() const = 0;
14571+ virtual unsigned int rngSeed() const = 0;
14572+ virtual UseColour::YesOrNo useColour() const = 0;
14573+ virtual std::vector<std::string> const& getSectionsToRun() const = 0;
14574+
14575+ };
14576+}
14577+
14578+// #included from: catch_stream.h
14579+#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
14580+
14581+// #included from: catch_streambuf.h
14582+#define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED
14583+
14584+#include <streambuf>
14585+
14586+namespace Catch {
14587+
14588+ class StreamBufBase : public std::streambuf {
14589+ public:
14590+ virtual ~StreamBufBase() CATCH_NOEXCEPT;
14591+ };
14592+}
14593+
14594+#include <streambuf>
14595+#include <ostream>
14596+#include <fstream>
14597+#include <memory>
14598+
14599+namespace Catch {
14600+
14601+ std::ostream& cout();
14602+ std::ostream& cerr();
14603+ std::ostream& clog();
14604+
14605+ struct IStream {
14606+ virtual ~IStream() CATCH_NOEXCEPT;
14607+ virtual std::ostream& stream() const = 0;
14608+ };
14609+
14610+ class FileStream : public IStream {
14611+ mutable std::ofstream m_ofs;
14612+ public:
14613+ FileStream( std::string const& filename );
14614+ virtual ~FileStream() CATCH_NOEXCEPT;
14615+ public: // IStream
14616+ virtual std::ostream& stream() const CATCH_OVERRIDE;
14617+ };
14618+
14619+ class CoutStream : public IStream {
14620+ mutable std::ostream m_os;
14621+ public:
14622+ CoutStream();
14623+ virtual ~CoutStream() CATCH_NOEXCEPT;
14624+
14625+ public: // IStream
14626+ virtual std::ostream& stream() const CATCH_OVERRIDE;
14627+ };
14628+
14629+ class DebugOutStream : public IStream {
14630+ CATCH_AUTO_PTR( StreamBufBase ) m_streamBuf;
14631+ mutable std::ostream m_os;
14632+ public:
14633+ DebugOutStream();
14634+ virtual ~DebugOutStream() CATCH_NOEXCEPT;
14635+
14636+ public: // IStream
14637+ virtual std::ostream& stream() const CATCH_OVERRIDE;
14638+ };
14639+}
14640+
14641+#include <memory>
14642+#include <vector>
14643+#include <string>
14644+#include <stdexcept>
14645+
14646+#ifndef CATCH_CONFIG_CONSOLE_WIDTH
14647+#define CATCH_CONFIG_CONSOLE_WIDTH 80
14648+#endif
14649+
14650+namespace Catch {
14651+
14652+ struct ConfigData {
14653+
14654+ ConfigData()
14655+ : listTests( false ),
14656+ listTags( false ),
14657+ listReporters( false ),
14658+ listTestNamesOnly( false ),
14659+ listExtraInfo( false ),
14660+ showSuccessfulTests( false ),
14661+ shouldDebugBreak( false ),
14662+ noThrow( false ),
14663+ showHelp( false ),
14664+ showInvisibles( false ),
14665+ filenamesAsTags( false ),
14666+ libIdentify( false ),
14667+ abortAfter( -1 ),
14668+ rngSeed( 0 ),
14669+ verbosity( Verbosity::Normal ),
14670+ warnings( WarnAbout::Nothing ),
14671+ showDurations( ShowDurations::DefaultForReporter ),
14672+ runOrder( RunTests::InDeclarationOrder ),
14673+ useColour( UseColour::Auto ),
14674+ waitForKeypress( WaitForKeypress::Never )
14675+ {}
14676+
14677+ bool listTests;
14678+ bool listTags;
14679+ bool listReporters;
14680+ bool listTestNamesOnly;
14681+ bool listExtraInfo;
14682+
14683+ bool showSuccessfulTests;
14684+ bool shouldDebugBreak;
14685+ bool noThrow;
14686+ bool showHelp;
14687+ bool showInvisibles;
14688+ bool filenamesAsTags;
14689+ bool libIdentify;
14690+
14691+ int abortAfter;
14692+ unsigned int rngSeed;
14693+
14694+ Verbosity::Level verbosity;
14695+ WarnAbout::What warnings;
14696+ ShowDurations::OrNot showDurations;
14697+ RunTests::InWhatOrder runOrder;
14698+ UseColour::YesOrNo useColour;
14699+ WaitForKeypress::When waitForKeypress;
14700+
14701+ std::string outputFilename;
14702+ std::string name;
14703+ std::string processName;
14704+
14705+ std::vector<std::string> reporterNames;
14706+ std::vector<std::string> testsOrTags;
14707+ std::vector<std::string> sectionsToRun;
14708+ };
14709+
14710+ class Config : public SharedImpl<IConfig> {
14711+ private:
14712+ Config( Config const& other );
14713+ Config& operator = ( Config const& other );
14714+ virtual void dummy();
14715+ public:
14716+
14717+ Config()
14718+ {}
14719+
14720+ Config( ConfigData const& data )
14721+ : m_data( data ),
14722+ m_stream( openStream() )
14723+ {
14724+ if( !data.testsOrTags.empty() ) {
14725+ TestSpecParser parser( ITagAliasRegistry::get() );
14726+ for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )
14727+ parser.parse( data.testsOrTags[i] );
14728+ m_testSpec = parser.testSpec();
14729+ }
14730+ }
14731+
14732+ virtual ~Config() {}
14733+
14734+ std::string const& getFilename() const {
14735+ return m_data.outputFilename ;
14736+ }
14737+
14738+ bool listTests() const { return m_data.listTests; }
14739+ bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }
14740+ bool listTags() const { return m_data.listTags; }
14741+ bool listReporters() const { return m_data.listReporters; }
14742+ bool listExtraInfo() const { return m_data.listExtraInfo; }
14743+
14744+ std::string getProcessName() const { return m_data.processName; }
14745+
14746+ std::vector<std::string> const& getReporterNames() const { return m_data.reporterNames; }
14747+ std::vector<std::string> const& getSectionsToRun() const CATCH_OVERRIDE { return m_data.sectionsToRun; }
14748+
14749+ virtual TestSpec const& testSpec() const CATCH_OVERRIDE { return m_testSpec; }
14750+
14751+ bool showHelp() const { return m_data.showHelp; }
14752+
14753+ // IConfig interface
14754+ virtual bool allowThrows() const CATCH_OVERRIDE { return !m_data.noThrow; }
14755+ virtual std::ostream& stream() const CATCH_OVERRIDE { return m_stream->stream(); }
14756+ virtual std::string name() const CATCH_OVERRIDE { return m_data.name.empty() ? m_data.processName : m_data.name; }
14757+ virtual bool includeSuccessfulResults() const CATCH_OVERRIDE { return m_data.showSuccessfulTests; }
14758+ virtual bool warnAboutMissingAssertions() const CATCH_OVERRIDE { return m_data.warnings & WarnAbout::NoAssertions; }
14759+ virtual ShowDurations::OrNot showDurations() const CATCH_OVERRIDE { return m_data.showDurations; }
14760+ virtual RunTests::InWhatOrder runOrder() const CATCH_OVERRIDE { return m_data.runOrder; }
14761+ virtual unsigned int rngSeed() const CATCH_OVERRIDE { return m_data.rngSeed; }
14762+ virtual UseColour::YesOrNo useColour() const CATCH_OVERRIDE { return m_data.useColour; }
14763+ virtual bool shouldDebugBreak() const CATCH_OVERRIDE { return m_data.shouldDebugBreak; }
14764+ virtual int abortAfter() const CATCH_OVERRIDE { return m_data.abortAfter; }
14765+ virtual bool showInvisibles() const CATCH_OVERRIDE { return m_data.showInvisibles; }
14766+
14767+ private:
14768+
14769+ IStream const* openStream() {
14770+ if( m_data.outputFilename.empty() )
14771+ return new CoutStream();
14772+ else if( m_data.outputFilename[0] == '%' ) {
14773+ if( m_data.outputFilename == "%debug" )
14774+ return new DebugOutStream();
14775+ else
14776+ throw std::domain_error( "Unrecognised stream: " + m_data.outputFilename );
14777+ }
14778+ else
14779+ return new FileStream( m_data.outputFilename );
14780+ }
14781+ ConfigData m_data;
14782+
14783+ CATCH_AUTO_PTR( IStream const ) m_stream;
14784+ TestSpec m_testSpec;
14785+ };
14786+
14787+} // end namespace Catch
14788+
14789+// #included from: catch_clara.h
14790+#define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED
14791+
14792+// Use Catch's value for console width (store Clara's off to the side, if present)
14793+#ifdef CLARA_CONFIG_CONSOLE_WIDTH
14794+#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH
14795+#undef CLARA_CONFIG_CONSOLE_WIDTH
14796+#endif
14797+#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
14798+
14799+// Declare Clara inside the Catch namespace
14800+#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {
14801+// #included from: ../external/clara.h
14802+
14803+// Version 0.0.2.4
14804+
14805+// Only use header guard if we are not using an outer namespace
14806+#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
14807+
14808+#ifndef STITCH_CLARA_OPEN_NAMESPACE
14809+#define TWOBLUECUBES_CLARA_H_INCLUDED
14810+#define STITCH_CLARA_OPEN_NAMESPACE
14811+#define STITCH_CLARA_CLOSE_NAMESPACE
14812+#else
14813+#define STITCH_CLARA_CLOSE_NAMESPACE }
14814+#endif
14815+
14816+#define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE
14817+
14818+// ----------- #included from tbc_text_format.h -----------
14819+
14820+// Only use header guard if we are not using an outer namespace
14821+#if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE)
14822+#ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
14823+#define TBC_TEXT_FORMAT_H_INCLUDED
14824+#endif
14825+
14826+#include <string>
14827+#include <vector>
14828+#include <sstream>
14829+#include <algorithm>
14830+#include <cctype>
14831+
14832+// Use optional outer namespace
14833+#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
14834+namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
14835+#endif
14836+
14837+namespace Tbc {
14838+
14839+#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
14840+ const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
14841+#else
14842+ const unsigned int consoleWidth = 80;
14843+#endif
14844+
14845+ struct TextAttributes {
14846+ TextAttributes()
14847+ : initialIndent( std::string::npos ),
14848+ indent( 0 ),
14849+ width( consoleWidth-1 ),
14850+ tabChar( '\t' )
14851+ {}
14852+
14853+ TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
14854+ TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
14855+ TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
14856+ TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; }
14857+
14858+ std::size_t initialIndent; // indent of first line, or npos
14859+ std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos
14860+ std::size_t width; // maximum width of text, including indent. Longer text will wrap
14861+ char tabChar; // If this char is seen the indent is changed to current pos
14862+ };
14863+
14864+ class Text {
14865+ public:
14866+ Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
14867+ : attr( _attr )
14868+ {
14869+ std::string wrappableChars = " [({.,/|\\-";
14870+ std::size_t indent = _attr.initialIndent != std::string::npos
14871+ ? _attr.initialIndent
14872+ : _attr.indent;
14873+ std::string remainder = _str;
14874+
14875+ while( !remainder.empty() ) {
14876+ if( lines.size() >= 1000 ) {
14877+ lines.push_back( "... message truncated due to excessive size" );
14878+ return;
14879+ }
14880+ std::size_t tabPos = std::string::npos;
14881+ std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
14882+ std::size_t pos = remainder.find_first_of( '\n' );
14883+ if( pos <= width ) {
14884+ width = pos;
14885+ }
14886+ pos = remainder.find_last_of( _attr.tabChar, width );
14887+ if( pos != std::string::npos ) {
14888+ tabPos = pos;
14889+ if( remainder[width] == '\n' )
14890+ width--;
14891+ remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
14892+ }
14893+
14894+ if( width == remainder.size() ) {
14895+ spliceLine( indent, remainder, width );
14896+ }
14897+ else if( remainder[width] == '\n' ) {
14898+ spliceLine( indent, remainder, width );
14899+ if( width <= 1 || remainder.size() != 1 )
14900+ remainder = remainder.substr( 1 );
14901+ indent = _attr.indent;
14902+ }
14903+ else {
14904+ pos = remainder.find_last_of( wrappableChars, width );
14905+ if( pos != std::string::npos && pos > 0 ) {
14906+ spliceLine( indent, remainder, pos );
14907+ if( remainder[0] == ' ' )
14908+ remainder = remainder.substr( 1 );
14909+ }
14910+ else {
14911+ spliceLine( indent, remainder, width-1 );
14912+ lines.back() += "-";
14913+ }
14914+ if( lines.size() == 1 )
14915+ indent = _attr.indent;
14916+ if( tabPos != std::string::npos )
14917+ indent += tabPos;
14918+ }
14919+ }
14920+ }
14921+
14922+ void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
14923+ lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
14924+ _remainder = _remainder.substr( _pos );
14925+ }
14926+
14927+ typedef std::vector<std::string>::const_iterator const_iterator;
14928+
14929+ const_iterator begin() const { return lines.begin(); }
14930+ const_iterator end() const { return lines.end(); }
14931+ std::string const& last() const { return lines.back(); }
14932+ std::size_t size() const { return lines.size(); }
14933+ std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
14934+ std::string toString() const {
14935+ std::ostringstream oss;
14936+ oss << *this;
14937+ return oss.str();
14938+ }
14939+
14940+ friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
14941+ for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
14942+ it != itEnd; ++it ) {
14943+ if( it != _text.begin() )
14944+ _stream << "\n";
14945+ _stream << *it;
14946+ }
14947+ return _stream;
14948+ }
14949+
14950+ private:
14951+ std::string str;
14952+ TextAttributes attr;
14953+ std::vector<std::string> lines;
14954+ };
14955+
14956+} // end namespace Tbc
14957+
14958+#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
14959+} // end outer namespace
14960+#endif
14961+
14962+#endif // TBC_TEXT_FORMAT_H_INCLUDED
14963+
14964+// ----------- end of #include from tbc_text_format.h -----------
14965+// ........... back in clara.h
14966+
14967+#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE
14968+
14969+// ----------- #included from clara_compilers.h -----------
14970+
14971+#ifndef TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
14972+#define TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
14973+
14974+// Detect a number of compiler features - mostly C++11/14 conformance - by compiler
14975+// The following features are defined:
14976+//
14977+// CLARA_CONFIG_CPP11_NULLPTR : is nullptr supported?
14978+// CLARA_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
14979+// CLARA_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
14980+// CLARA_CONFIG_CPP11_OVERRIDE : is override supported?
14981+// CLARA_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
14982+
14983+// CLARA_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
14984+
14985+// CLARA_CONFIG_VARIADIC_MACROS : are variadic macros supported?
14986+
14987+// In general each macro has a _NO_<feature name> form
14988+// (e.g. CLARA_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
14989+// Many features, at point of detection, define an _INTERNAL_ macro, so they
14990+// can be combined, en-mass, with the _NO_ forms later.
14991+
14992+// All the C++11 features can be disabled with CLARA_CONFIG_NO_CPP11
14993+
14994+#ifdef __clang__
14995+
14996+#if __has_feature(cxx_nullptr)
14997+#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
14998+#endif
14999+
15000+#if __has_feature(cxx_noexcept)
15001+#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
15002+#endif
15003+
15004+#endif // __clang__
15005+
15006+////////////////////////////////////////////////////////////////////////////////
15007+// GCC
15008+#ifdef __GNUC__
15009+
15010+#if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
15011+#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
15012+#endif
15013+
15014+// - otherwise more recent versions define __cplusplus >= 201103L
15015+// and will get picked up below
15016+
15017+#endif // __GNUC__
15018+
15019+////////////////////////////////////////////////////////////////////////////////
15020+// Visual C++
15021+#ifdef _MSC_VER
15022+
15023+#if (_MSC_VER >= 1600)
15024+#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
15025+#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
15026+#endif
15027+
15028+#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
15029+#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
15030+#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
15031+#endif
15032+
15033+#endif // _MSC_VER
15034+
15035+////////////////////////////////////////////////////////////////////////////////
15036+// C++ language feature support
15037+
15038+// catch all support for C++11
15039+#if defined(__cplusplus) && __cplusplus >= 201103L
15040+
15041+#define CLARA_CPP11_OR_GREATER
15042+
15043+#if !defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR)
15044+#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
15045+#endif
15046+
15047+#ifndef CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
15048+#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
15049+#endif
15050+
15051+#ifndef CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
15052+#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
15053+#endif
15054+
15055+#if !defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE)
15056+#define CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE
15057+#endif
15058+#if !defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
15059+#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
15060+#endif
15061+
15062+#endif // __cplusplus >= 201103L
15063+
15064+// Now set the actual defines based on the above + anything the user has configured
15065+#if defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NO_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_NO_CPP11)
15066+#define CLARA_CONFIG_CPP11_NULLPTR
15067+#endif
15068+#if defined(CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_NO_CPP11)
15069+#define CLARA_CONFIG_CPP11_NOEXCEPT
15070+#endif
15071+#if defined(CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_NO_CPP11)
15072+#define CLARA_CONFIG_CPP11_GENERATED_METHODS
15073+#endif
15074+#if defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_OVERRIDE) && !defined(CLARA_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_CPP11)
15075+#define CLARA_CONFIG_CPP11_OVERRIDE
15076+#endif
15077+#if defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_UNIQUE_PTR) && !defined(CLARA_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_CPP11)
15078+#define CLARA_CONFIG_CPP11_UNIQUE_PTR
15079+#endif
15080+
15081+// noexcept support:
15082+#if defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_NOEXCEPT)
15083+#define CLARA_NOEXCEPT noexcept
15084+# define CLARA_NOEXCEPT_IS(x) noexcept(x)
15085+#else
15086+#define CLARA_NOEXCEPT throw()
15087+# define CLARA_NOEXCEPT_IS(x)
15088+#endif
15089+
15090+// nullptr support
15091+#ifdef CLARA_CONFIG_CPP11_NULLPTR
15092+#define CLARA_NULL nullptr
15093+#else
15094+#define CLARA_NULL NULL
15095+#endif
15096+
15097+// override support
15098+#ifdef CLARA_CONFIG_CPP11_OVERRIDE
15099+#define CLARA_OVERRIDE override
15100+#else
15101+#define CLARA_OVERRIDE
15102+#endif
15103+
15104+// unique_ptr support
15105+#ifdef CLARA_CONFIG_CPP11_UNIQUE_PTR
15106+# define CLARA_AUTO_PTR( T ) std::unique_ptr<T>
15107+#else
15108+# define CLARA_AUTO_PTR( T ) std::auto_ptr<T>
15109+#endif
15110+
15111+#endif // TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
15112+
15113+// ----------- end of #include from clara_compilers.h -----------
15114+// ........... back in clara.h
15115+
15116+#include <map>
15117+#include <stdexcept>
15118+#include <memory>
15119+
15120+#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
15121+#define CLARA_PLATFORM_WINDOWS
15122+#endif
15123+
15124+// Use optional outer namespace
15125+#ifdef STITCH_CLARA_OPEN_NAMESPACE
15126+STITCH_CLARA_OPEN_NAMESPACE
15127+#endif
15128+
15129+namespace Clara {
15130+
15131+ struct UnpositionalTag {};
15132+
15133+ extern UnpositionalTag _;
15134+
15135+#ifdef CLARA_CONFIG_MAIN
15136+ UnpositionalTag _;
15137+#endif
15138+
15139+ namespace Detail {
15140+
15141+#ifdef CLARA_CONSOLE_WIDTH
15142+ const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
15143+#else
15144+ const unsigned int consoleWidth = 80;
15145+#endif
15146+
15147+ using namespace Tbc;
15148+
15149+ inline bool startsWith( std::string const& str, std::string const& prefix ) {
15150+ return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;
15151+ }
15152+
15153+ template<typename T> struct RemoveConstRef{ typedef T type; };
15154+ template<typename T> struct RemoveConstRef<T&>{ typedef T type; };
15155+ template<typename T> struct RemoveConstRef<T const&>{ typedef T type; };
15156+ template<typename T> struct RemoveConstRef<T const>{ typedef T type; };
15157+
15158+ template<typename T> struct IsBool { static const bool value = false; };
15159+ template<> struct IsBool<bool> { static const bool value = true; };
15160+
15161+ template<typename T>
15162+ void convertInto( std::string const& _source, T& _dest ) {
15163+ std::stringstream ss;
15164+ ss << _source;
15165+ ss >> _dest;
15166+ if( ss.fail() )
15167+ throw std::runtime_error( "Unable to convert " + _source + " to destination type" );
15168+ }
15169+ inline void convertInto( std::string const& _source, std::string& _dest ) {
15170+ _dest = _source;
15171+ }
15172+ char toLowerCh(char c) {
15173+ return static_cast<char>( std::tolower( c ) );
15174+ }
15175+ inline void convertInto( std::string const& _source, bool& _dest ) {
15176+ std::string sourceLC = _source;
15177+ std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), toLowerCh );
15178+ if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" )
15179+ _dest = true;
15180+ else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" )
15181+ _dest = false;
15182+ else
15183+ throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" );
15184+ }
15185+
15186+ template<typename ConfigT>
15187+ struct IArgFunction {
15188+ virtual ~IArgFunction() {}
15189+#ifdef CLARA_CONFIG_CPP11_GENERATED_METHODS
15190+ IArgFunction() = default;
15191+ IArgFunction( IArgFunction const& ) = default;
15192+#endif
15193+ virtual void set( ConfigT& config, std::string const& value ) const = 0;
15194+ virtual bool takesArg() const = 0;
15195+ virtual IArgFunction* clone() const = 0;
15196+ };
15197+
15198+ template<typename ConfigT>
15199+ class BoundArgFunction {
15200+ public:
15201+ BoundArgFunction() : functionObj( CLARA_NULL ) {}
15202+ BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
15203+ BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CLARA_NULL ) {}
15204+ BoundArgFunction& operator = ( BoundArgFunction const& other ) {
15205+ IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : CLARA_NULL;
15206+ delete functionObj;
15207+ functionObj = newFunctionObj;
15208+ return *this;
15209+ }
15210+ ~BoundArgFunction() { delete functionObj; }
15211+
15212+ void set( ConfigT& config, std::string const& value ) const {
15213+ functionObj->set( config, value );
15214+ }
15215+ bool takesArg() const { return functionObj->takesArg(); }
15216+
15217+ bool isSet() const {
15218+ return functionObj != CLARA_NULL;
15219+ }
15220+ private:
15221+ IArgFunction<ConfigT>* functionObj;
15222+ };
15223+
15224+ template<typename C>
15225+ struct NullBinder : IArgFunction<C>{
15226+ virtual void set( C&, std::string const& ) const {}
15227+ virtual bool takesArg() const { return true; }
15228+ virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }
15229+ };
15230+
15231+ template<typename C, typename M>
15232+ struct BoundDataMember : IArgFunction<C>{
15233+ BoundDataMember( M C::* _member ) : member( _member ) {}
15234+ virtual void set( C& p, std::string const& stringValue ) const {
15235+ convertInto( stringValue, p.*member );
15236+ }
15237+ virtual bool takesArg() const { return !IsBool<M>::value; }
15238+ virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }
15239+ M C::* member;
15240+ };
15241+ template<typename C, typename M>
15242+ struct BoundUnaryMethod : IArgFunction<C>{
15243+ BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {}
15244+ virtual void set( C& p, std::string const& stringValue ) const {
15245+ typename RemoveConstRef<M>::type value;
15246+ convertInto( stringValue, value );
15247+ (p.*member)( value );
15248+ }
15249+ virtual bool takesArg() const { return !IsBool<M>::value; }
15250+ virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }
15251+ void (C::*member)( M );
15252+ };
15253+ template<typename C>
15254+ struct BoundNullaryMethod : IArgFunction<C>{
15255+ BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {}
15256+ virtual void set( C& p, std::string const& stringValue ) const {
15257+ bool value;
15258+ convertInto( stringValue, value );
15259+ if( value )
15260+ (p.*member)();
15261+ }
15262+ virtual bool takesArg() const { return false; }
15263+ virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }
15264+ void (C::*member)();
15265+ };
15266+
15267+ template<typename C>
15268+ struct BoundUnaryFunction : IArgFunction<C>{
15269+ BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {}
15270+ virtual void set( C& obj, std::string const& stringValue ) const {
15271+ bool value;
15272+ convertInto( stringValue, value );
15273+ if( value )
15274+ function( obj );
15275+ }
15276+ virtual bool takesArg() const { return false; }
15277+ virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }
15278+ void (*function)( C& );
15279+ };
15280+
15281+ template<typename C, typename T>
15282+ struct BoundBinaryFunction : IArgFunction<C>{
15283+ BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {}
15284+ virtual void set( C& obj, std::string const& stringValue ) const {
15285+ typename RemoveConstRef<T>::type value;
15286+ convertInto( stringValue, value );
15287+ function( obj, value );
15288+ }
15289+ virtual bool takesArg() const { return !IsBool<T>::value; }
15290+ virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }
15291+ void (*function)( C&, T );
15292+ };
15293+
15294+ } // namespace Detail
15295+
15296+ inline std::vector<std::string> argsToVector( int argc, char const* const* const argv ) {
15297+ std::vector<std::string> args( static_cast<std::size_t>( argc ) );
15298+ for( std::size_t i = 0; i < static_cast<std::size_t>( argc ); ++i )
15299+ args[i] = argv[i];
15300+
15301+ return args;
15302+ }
15303+
15304+ class Parser {
15305+ enum Mode { None, MaybeShortOpt, SlashOpt, ShortOpt, LongOpt, Positional };
15306+ Mode mode;
15307+ std::size_t from;
15308+ bool inQuotes;
15309+ public:
15310+
15311+ struct Token {
15312+ enum Type { Positional, ShortOpt, LongOpt };
15313+ Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {}
15314+ Type type;
15315+ std::string data;
15316+ };
15317+
15318+ Parser() : mode( None ), from( 0 ), inQuotes( false ){}
15319+
15320+ void parseIntoTokens( std::vector<std::string> const& args, std::vector<Token>& tokens ) {
15321+ const std::string doubleDash = "--";
15322+ for( std::size_t i = 1; i < args.size() && args[i] != doubleDash; ++i )
15323+ parseIntoTokens( args[i], tokens);
15324+ }
15325+
15326+ void parseIntoTokens( std::string const& arg, std::vector<Token>& tokens ) {
15327+ for( std::size_t i = 0; i < arg.size(); ++i ) {
15328+ char c = arg[i];
15329+ if( c == '"' )
15330+ inQuotes = !inQuotes;
15331+ mode = handleMode( i, c, arg, tokens );
15332+ }
15333+ mode = handleMode( arg.size(), '\0', arg, tokens );
15334+ }
15335+ Mode handleMode( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
15336+ switch( mode ) {
15337+ case None: return handleNone( i, c );
15338+ case MaybeShortOpt: return handleMaybeShortOpt( i, c );
15339+ case ShortOpt:
15340+ case LongOpt:
15341+ case SlashOpt: return handleOpt( i, c, arg, tokens );
15342+ case Positional: return handlePositional( i, c, arg, tokens );
15343+ default: throw std::logic_error( "Unknown mode" );
15344+ }
15345+ }
15346+
15347+ Mode handleNone( std::size_t i, char c ) {
15348+ if( inQuotes ) {
15349+ from = i;
15350+ return Positional;
15351+ }
15352+ switch( c ) {
15353+ case '-': return MaybeShortOpt;
15354+#ifdef CLARA_PLATFORM_WINDOWS
15355+ case '/': from = i+1; return SlashOpt;
15356+#endif
15357+ default: from = i; return Positional;
15358+ }
15359+ }
15360+ Mode handleMaybeShortOpt( std::size_t i, char c ) {
15361+ switch( c ) {
15362+ case '-': from = i+1; return LongOpt;
15363+ default: from = i; return ShortOpt;
15364+ }
15365+ }
15366+
15367+ Mode handleOpt( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
15368+ if( std::string( ":=\0", 3 ).find( c ) == std::string::npos )
15369+ return mode;
15370+
15371+ std::string optName = arg.substr( from, i-from );
15372+ if( mode == ShortOpt )
15373+ for( std::size_t j = 0; j < optName.size(); ++j )
15374+ tokens.push_back( Token( Token::ShortOpt, optName.substr( j, 1 ) ) );
15375+ else if( mode == SlashOpt && optName.size() == 1 )
15376+ tokens.push_back( Token( Token::ShortOpt, optName ) );
15377+ else
15378+ tokens.push_back( Token( Token::LongOpt, optName ) );
15379+ return None;
15380+ }
15381+ Mode handlePositional( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
15382+ if( inQuotes || std::string( "\0", 1 ).find( c ) == std::string::npos )
15383+ return mode;
15384+
15385+ std::string data = arg.substr( from, i-from );
15386+ tokens.push_back( Token( Token::Positional, data ) );
15387+ return None;
15388+ }
15389+ };
15390+
15391+ template<typename ConfigT>
15392+ struct CommonArgProperties {
15393+ CommonArgProperties() {}
15394+ CommonArgProperties( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ) {}
15395+
15396+ Detail::BoundArgFunction<ConfigT> boundField;
15397+ std::string description;
15398+ std::string detail;
15399+ std::string placeholder; // Only value if boundField takes an arg
15400+
15401+ bool takesArg() const {
15402+ return !placeholder.empty();
15403+ }
15404+ void validate() const {
15405+ if( !boundField.isSet() )
15406+ throw std::logic_error( "option not bound" );
15407+ }
15408+ };
15409+ struct OptionArgProperties {
15410+ std::vector<std::string> shortNames;
15411+ std::string longName;
15412+
15413+ bool hasShortName( std::string const& shortName ) const {
15414+ return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end();
15415+ }
15416+ bool hasLongName( std::string const& _longName ) const {
15417+ return _longName == longName;
15418+ }
15419+ };
15420+ struct PositionalArgProperties {
15421+ PositionalArgProperties() : position( -1 ) {}
15422+ int position; // -1 means non-positional (floating)
15423+
15424+ bool isFixedPositional() const {
15425+ return position != -1;
15426+ }
15427+ };
15428+
15429+ template<typename ConfigT>
15430+ class CommandLine {
15431+
15432+ struct Arg : CommonArgProperties<ConfigT>, OptionArgProperties, PositionalArgProperties {
15433+ Arg() {}
15434+ Arg( Detail::BoundArgFunction<ConfigT> const& _boundField ) : CommonArgProperties<ConfigT>( _boundField ) {}
15435+
15436+ using CommonArgProperties<ConfigT>::placeholder; // !TBD
15437+
15438+ std::string dbgName() const {
15439+ if( !longName.empty() )
15440+ return "--" + longName;
15441+ if( !shortNames.empty() )
15442+ return "-" + shortNames[0];
15443+ return "positional args";
15444+ }
15445+ std::string commands() const {
15446+ std::ostringstream oss;
15447+ bool first = true;
15448+ std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();
15449+ for(; it != itEnd; ++it ) {
15450+ if( first )
15451+ first = false;
15452+ else
15453+ oss << ", ";
15454+ oss << "-" << *it;
15455+ }
15456+ if( !longName.empty() ) {
15457+ if( !first )
15458+ oss << ", ";
15459+ oss << "--" << longName;
15460+ }
15461+ if( !placeholder.empty() )
15462+ oss << " <" << placeholder << ">";
15463+ return oss.str();
15464+ }
15465+ };
15466+
15467+ typedef CLARA_AUTO_PTR( Arg ) ArgAutoPtr;
15468+
15469+ friend void addOptName( Arg& arg, std::string const& optName )
15470+ {
15471+ if( optName.empty() )
15472+ return;
15473+ if( Detail::startsWith( optName, "--" ) ) {
15474+ if( !arg.longName.empty() )
15475+ throw std::logic_error( "Only one long opt may be specified. '"
15476+ + arg.longName
15477+ + "' already specified, now attempting to add '"
15478+ + optName + "'" );
15479+ arg.longName = optName.substr( 2 );
15480+ }
15481+ else if( Detail::startsWith( optName, "-" ) )
15482+ arg.shortNames.push_back( optName.substr( 1 ) );
15483+ else
15484+ throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" );
15485+ }
15486+ friend void setPositionalArg( Arg& arg, int position )
15487+ {
15488+ arg.position = position;
15489+ }
15490+
15491+ class ArgBuilder {
15492+ public:
15493+ ArgBuilder( Arg* arg ) : m_arg( arg ) {}
15494+
15495+ // Bind a non-boolean data member (requires placeholder string)
15496+ template<typename C, typename M>
15497+ void bind( M C::* field, std::string const& placeholder ) {
15498+ m_arg->boundField = new Detail::BoundDataMember<C,M>( field );
15499+ m_arg->placeholder = placeholder;
15500+ }
15501+ // Bind a boolean data member (no placeholder required)
15502+ template<typename C>
15503+ void bind( bool C::* field ) {
15504+ m_arg->boundField = new Detail::BoundDataMember<C,bool>( field );
15505+ }
15506+
15507+ // Bind a method taking a single, non-boolean argument (requires a placeholder string)
15508+ template<typename C, typename M>
15509+ void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) {
15510+ m_arg->boundField = new Detail::BoundUnaryMethod<C,M>( unaryMethod );
15511+ m_arg->placeholder = placeholder;
15512+ }
15513+
15514+ // Bind a method taking a single, boolean argument (no placeholder string required)
15515+ template<typename C>
15516+ void bind( void (C::* unaryMethod)( bool ) ) {
15517+ m_arg->boundField = new Detail::BoundUnaryMethod<C,bool>( unaryMethod );
15518+ }
15519+
15520+ // Bind a method that takes no arguments (will be called if opt is present)
15521+ template<typename C>
15522+ void bind( void (C::* nullaryMethod)() ) {
15523+ m_arg->boundField = new Detail::BoundNullaryMethod<C>( nullaryMethod );
15524+ }
15525+
15526+ // Bind a free function taking a single argument - the object to operate on (no placeholder string required)
15527+ template<typename C>
15528+ void bind( void (* unaryFunction)( C& ) ) {
15529+ m_arg->boundField = new Detail::BoundUnaryFunction<C>( unaryFunction );
15530+ }
15531+
15532+ // Bind a free function taking a single argument - the object to operate on (requires a placeholder string)
15533+ template<typename C, typename T>
15534+ void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) {
15535+ m_arg->boundField = new Detail::BoundBinaryFunction<C, T>( binaryFunction );
15536+ m_arg->placeholder = placeholder;
15537+ }
15538+
15539+ ArgBuilder& describe( std::string const& description ) {
15540+ m_arg->description = description;
15541+ return *this;
15542+ }
15543+ ArgBuilder& detail( std::string const& detail ) {
15544+ m_arg->detail = detail;
15545+ return *this;
15546+ }
15547+
15548+ protected:
15549+ Arg* m_arg;
15550+ };
15551+
15552+ class OptBuilder : public ArgBuilder {
15553+ public:
15554+ OptBuilder( Arg* arg ) : ArgBuilder( arg ) {}
15555+ OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {}
15556+
15557+ OptBuilder& operator[]( std::string const& optName ) {
15558+ addOptName( *ArgBuilder::m_arg, optName );
15559+ return *this;
15560+ }
15561+ };
15562+
15563+ public:
15564+
15565+ CommandLine()
15566+ : m_boundProcessName( new Detail::NullBinder<ConfigT>() ),
15567+ m_highestSpecifiedArgPosition( 0 ),
15568+ m_throwOnUnrecognisedTokens( false )
15569+ {}
15570+ CommandLine( CommandLine const& other )
15571+ : m_boundProcessName( other.m_boundProcessName ),
15572+ m_options ( other.m_options ),
15573+ m_positionalArgs( other.m_positionalArgs ),
15574+ m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ),
15575+ m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens )
15576+ {
15577+ if( other.m_floatingArg.get() )
15578+ m_floatingArg.reset( new Arg( *other.m_floatingArg ) );
15579+ }
15580+
15581+ CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) {
15582+ m_throwOnUnrecognisedTokens = shouldThrow;
15583+ return *this;
15584+ }
15585+
15586+ OptBuilder operator[]( std::string const& optName ) {
15587+ m_options.push_back( Arg() );
15588+ addOptName( m_options.back(), optName );
15589+ OptBuilder builder( &m_options.back() );
15590+ return builder;
15591+ }
15592+
15593+ ArgBuilder operator[]( int position ) {
15594+ m_positionalArgs.insert( std::make_pair( position, Arg() ) );
15595+ if( position > m_highestSpecifiedArgPosition )
15596+ m_highestSpecifiedArgPosition = position;
15597+ setPositionalArg( m_positionalArgs[position], position );
15598+ ArgBuilder builder( &m_positionalArgs[position] );
15599+ return builder;
15600+ }
15601+
15602+ // Invoke this with the _ instance
15603+ ArgBuilder operator[]( UnpositionalTag ) {
15604+ if( m_floatingArg.get() )
15605+ throw std::logic_error( "Only one unpositional argument can be added" );
15606+ m_floatingArg.reset( new Arg() );
15607+ ArgBuilder builder( m_floatingArg.get() );
15608+ return builder;
15609+ }
15610+
15611+ template<typename C, typename M>
15612+ void bindProcessName( M C::* field ) {
15613+ m_boundProcessName = new Detail::BoundDataMember<C,M>( field );
15614+ }
15615+ template<typename C, typename M>
15616+ void bindProcessName( void (C::*_unaryMethod)( M ) ) {
15617+ m_boundProcessName = new Detail::BoundUnaryMethod<C,M>( _unaryMethod );
15618+ }
15619+
15620+ void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const {
15621+ typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;
15622+ std::size_t maxWidth = 0;
15623+ for( it = itBegin; it != itEnd; ++it )
15624+ maxWidth = (std::max)( maxWidth, it->commands().size() );
15625+
15626+ for( it = itBegin; it != itEnd; ++it ) {
15627+ Detail::Text usage( it->commands(), Detail::TextAttributes()
15628+ .setWidth( maxWidth+indent )
15629+ .setIndent( indent ) );
15630+ Detail::Text desc( it->description, Detail::TextAttributes()
15631+ .setWidth( width - maxWidth - 3 ) );
15632+
15633+ for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) {
15634+ std::string usageCol = i < usage.size() ? usage[i] : "";
15635+ os << usageCol;
15636+
15637+ if( i < desc.size() && !desc[i].empty() )
15638+ os << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' )
15639+ << desc[i];
15640+ os << "\n";
15641+ }
15642+ }
15643+ }
15644+ std::string optUsage() const {
15645+ std::ostringstream oss;
15646+ optUsage( oss );
15647+ return oss.str();
15648+ }
15649+
15650+ void argSynopsis( std::ostream& os ) const {
15651+ for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {
15652+ if( i > 1 )
15653+ os << " ";
15654+ typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
15655+ if( it != m_positionalArgs.end() )
15656+ os << "<" << it->second.placeholder << ">";
15657+ else if( m_floatingArg.get() )
15658+ os << "<" << m_floatingArg->placeholder << ">";
15659+ else
15660+ throw std::logic_error( "non consecutive positional arguments with no floating args" );
15661+ }
15662+ // !TBD No indication of mandatory args
15663+ if( m_floatingArg.get() ) {
15664+ if( m_highestSpecifiedArgPosition > 1 )
15665+ os << " ";
15666+ os << "[<" << m_floatingArg->placeholder << "> ...]";
15667+ }
15668+ }
15669+ std::string argSynopsis() const {
15670+ std::ostringstream oss;
15671+ argSynopsis( oss );
15672+ return oss.str();
15673+ }
15674+
15675+ void usage( std::ostream& os, std::string const& procName ) const {
15676+ validate();
15677+ os << "usage:\n " << procName << " ";
15678+ argSynopsis( os );
15679+ if( !m_options.empty() ) {
15680+ os << " [options]\n\nwhere options are: \n";
15681+ optUsage( os, 2 );
15682+ }
15683+ os << "\n";
15684+ }
15685+ std::string usage( std::string const& procName ) const {
15686+ std::ostringstream oss;
15687+ usage( oss, procName );
15688+ return oss.str();
15689+ }
15690+
15691+ ConfigT parse( std::vector<std::string> const& args ) const {
15692+ ConfigT config;
15693+ parseInto( args, config );
15694+ return config;
15695+ }
15696+
15697+ std::vector<Parser::Token> parseInto( std::vector<std::string> const& args, ConfigT& config ) const {
15698+ std::string processName = args.empty() ? std::string() : args[0];
15699+ std::size_t lastSlash = processName.find_last_of( "/\\" );
15700+ if( lastSlash != std::string::npos )
15701+ processName = processName.substr( lastSlash+1 );
15702+ m_boundProcessName.set( config, processName );
15703+ std::vector<Parser::Token> tokens;
15704+ Parser parser;
15705+ parser.parseIntoTokens( args, tokens );
15706+ return populate( tokens, config );
15707+ }
15708+
15709+ std::vector<Parser::Token> populate( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
15710+ validate();
15711+ std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config );
15712+ unusedTokens = populateFixedArgs( unusedTokens, config );
15713+ unusedTokens = populateFloatingArgs( unusedTokens, config );
15714+ return unusedTokens;
15715+ }
15716+
15717+ std::vector<Parser::Token> populateOptions( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
15718+ std::vector<Parser::Token> unusedTokens;
15719+ std::vector<std::string> errors;
15720+ for( std::size_t i = 0; i < tokens.size(); ++i ) {
15721+ Parser::Token const& token = tokens[i];
15722+ typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();
15723+ for(; it != itEnd; ++it ) {
15724+ Arg const& arg = *it;
15725+
15726+ try {
15727+ if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||
15728+ ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {
15729+ if( arg.takesArg() ) {
15730+ if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional )
15731+ errors.push_back( "Expected argument to option: " + token.data );
15732+ else
15733+ arg.boundField.set( config, tokens[++i].data );
15734+ }
15735+ else {
15736+ arg.boundField.set( config, "true" );
15737+ }
15738+ break;
15739+ }
15740+ }
15741+ catch( std::exception& ex ) {
15742+ errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" );
15743+ }
15744+ }
15745+ if( it == itEnd ) {
15746+ if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens )
15747+ unusedTokens.push_back( token );
15748+ else if( errors.empty() && m_throwOnUnrecognisedTokens )
15749+ errors.push_back( "unrecognised option: " + token.data );
15750+ }
15751+ }
15752+ if( !errors.empty() ) {
15753+ std::ostringstream oss;
15754+ for( std::vector<std::string>::const_iterator it = errors.begin(), itEnd = errors.end();
15755+ it != itEnd;
15756+ ++it ) {
15757+ if( it != errors.begin() )
15758+ oss << "\n";
15759+ oss << *it;
15760+ }
15761+ throw std::runtime_error( oss.str() );
15762+ }
15763+ return unusedTokens;
15764+ }
15765+ std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
15766+ std::vector<Parser::Token> unusedTokens;
15767+ int position = 1;
15768+ for( std::size_t i = 0; i < tokens.size(); ++i ) {
15769+ Parser::Token const& token = tokens[i];
15770+ typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );
15771+ if( it != m_positionalArgs.end() )
15772+ it->second.boundField.set( config, token.data );
15773+ else
15774+ unusedTokens.push_back( token );
15775+ if( token.type == Parser::Token::Positional )
15776+ position++;
15777+ }
15778+ return unusedTokens;
15779+ }
15780+ std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
15781+ if( !m_floatingArg.get() )
15782+ return tokens;
15783+ std::vector<Parser::Token> unusedTokens;
15784+ for( std::size_t i = 0; i < tokens.size(); ++i ) {
15785+ Parser::Token const& token = tokens[i];
15786+ if( token.type == Parser::Token::Positional )
15787+ m_floatingArg->boundField.set( config, token.data );
15788+ else
15789+ unusedTokens.push_back( token );
15790+ }
15791+ return unusedTokens;
15792+ }
15793+
15794+ void validate() const
15795+ {
15796+ if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() )
15797+ throw std::logic_error( "No options or arguments specified" );
15798+
15799+ for( typename std::vector<Arg>::const_iterator it = m_options.begin(),
15800+ itEnd = m_options.end();
15801+ it != itEnd; ++it )
15802+ it->validate();
15803+ }
15804+
15805+ private:
15806+ Detail::BoundArgFunction<ConfigT> m_boundProcessName;
15807+ std::vector<Arg> m_options;
15808+ std::map<int, Arg> m_positionalArgs;
15809+ ArgAutoPtr m_floatingArg;
15810+ int m_highestSpecifiedArgPosition;
15811+ bool m_throwOnUnrecognisedTokens;
15812+ };
15813+
15814+} // end namespace Clara
15815+
15816+STITCH_CLARA_CLOSE_NAMESPACE
15817+#undef STITCH_CLARA_OPEN_NAMESPACE
15818+#undef STITCH_CLARA_CLOSE_NAMESPACE
15819+
15820+#endif // TWOBLUECUBES_CLARA_H_INCLUDED
15821+#undef STITCH_CLARA_OPEN_NAMESPACE
15822+
15823+// Restore Clara's value for console width, if present
15824+#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
15825+#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
15826+#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
15827+#endif
15828+
15829+#include <fstream>
15830+#include <ctime>
15831+
15832+namespace Catch {
15833+
15834+ inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }
15835+ inline void abortAfterX( ConfigData& config, int x ) {
15836+ if( x < 1 )
15837+ throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" );
15838+ config.abortAfter = x;
15839+ }
15840+ inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
15841+ inline void addSectionToRun( ConfigData& config, std::string const& sectionName ) { config.sectionsToRun.push_back( sectionName ); }
15842+ inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); }
15843+
15844+ inline void addWarning( ConfigData& config, std::string const& _warning ) {
15845+ if( _warning == "NoAssertions" )
15846+ config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );
15847+ else
15848+ throw std::runtime_error( "Unrecognised warning: '" + _warning + '\'' );
15849+ }
15850+ inline void setOrder( ConfigData& config, std::string const& order ) {
15851+ if( startsWith( "declared", order ) )
15852+ config.runOrder = RunTests::InDeclarationOrder;
15853+ else if( startsWith( "lexical", order ) )
15854+ config.runOrder = RunTests::InLexicographicalOrder;
15855+ else if( startsWith( "random", order ) )
15856+ config.runOrder = RunTests::InRandomOrder;
15857+ else
15858+ throw std::runtime_error( "Unrecognised ordering: '" + order + '\'' );
15859+ }
15860+ inline void setRngSeed( ConfigData& config, std::string const& seed ) {
15861+ if( seed == "time" ) {
15862+ config.rngSeed = static_cast<unsigned int>( std::time(0) );
15863+ }
15864+ else {
15865+ std::stringstream ss;
15866+ ss << seed;
15867+ ss >> config.rngSeed;
15868+ if( ss.fail() )
15869+ throw std::runtime_error( "Argument to --rng-seed should be the word 'time' or a number" );
15870+ }
15871+ }
15872+ inline void setVerbosity( ConfigData& config, int level ) {
15873+ // !TBD: accept strings?
15874+ config.verbosity = static_cast<Verbosity::Level>( level );
15875+ }
15876+ inline void setShowDurations( ConfigData& config, bool _showDurations ) {
15877+ config.showDurations = _showDurations
15878+ ? ShowDurations::Always
15879+ : ShowDurations::Never;
15880+ }
15881+ inline void setUseColour( ConfigData& config, std::string const& value ) {
15882+ std::string mode = toLower( value );
15883+
15884+ if( mode == "yes" )
15885+ config.useColour = UseColour::Yes;
15886+ else if( mode == "no" )
15887+ config.useColour = UseColour::No;
15888+ else if( mode == "auto" )
15889+ config.useColour = UseColour::Auto;
15890+ else
15891+ throw std::runtime_error( "colour mode must be one of: auto, yes or no" );
15892+ }
15893+ inline void setWaitForKeypress( ConfigData& config, std::string const& keypress ) {
15894+ std::string keypressLc = toLower( keypress );
15895+ if( keypressLc == "start" )
15896+ config.waitForKeypress = WaitForKeypress::BeforeStart;
15897+ else if( keypressLc == "exit" )
15898+ config.waitForKeypress = WaitForKeypress::BeforeExit;
15899+ else if( keypressLc == "both" )
15900+ config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
15901+ else
15902+ throw std::runtime_error( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" );
15903+ };
15904+
15905+ inline void forceColour( ConfigData& config ) {
15906+ config.useColour = UseColour::Yes;
15907+ }
15908+ inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {
15909+ std::ifstream f( _filename.c_str() );
15910+ if( !f.is_open() )
15911+ throw std::domain_error( "Unable to load input file: " + _filename );
15912+
15913+ std::string line;
15914+ while( std::getline( f, line ) ) {
15915+ line = trim(line);
15916+ if( !line.empty() && !startsWith( line, '#' ) ) {
15917+ if( !startsWith( line, '"' ) )
15918+ line = '"' + line + '"';
15919+ addTestOrTags( config, line + ',' );
15920+ }
15921+ }
15922+ }
15923+
15924+ inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
15925+
15926+ using namespace Clara;
15927+ CommandLine<ConfigData> cli;
15928+
15929+ cli.bindProcessName( &ConfigData::processName );
15930+
15931+ cli["-?"]["-h"]["--help"]
15932+ .describe( "display usage information" )
15933+ .bind( &ConfigData::showHelp );
15934+
15935+ cli["-l"]["--list-tests"]
15936+ .describe( "list all/matching test cases" )
15937+ .bind( &ConfigData::listTests );
15938+
15939+ cli["-t"]["--list-tags"]
15940+ .describe( "list all/matching tags" )
15941+ .bind( &ConfigData::listTags );
15942+
15943+ cli["-s"]["--success"]
15944+ .describe( "include successful tests in output" )
15945+ .bind( &ConfigData::showSuccessfulTests );
15946+
15947+ cli["-b"]["--break"]
15948+ .describe( "break into debugger on failure" )
15949+ .bind( &ConfigData::shouldDebugBreak );
15950+
15951+ cli["-e"]["--nothrow"]
15952+ .describe( "skip exception tests" )
15953+ .bind( &ConfigData::noThrow );
15954+
15955+ cli["-i"]["--invisibles"]
15956+ .describe( "show invisibles (tabs, newlines)" )
15957+ .bind( &ConfigData::showInvisibles );
15958+
15959+ cli["-o"]["--out"]
15960+ .describe( "output filename" )
15961+ .bind( &ConfigData::outputFilename, "filename" );
15962+
15963+ cli["-r"]["--reporter"]
15964+// .placeholder( "name[:filename]" )
15965+ .describe( "reporter to use (defaults to console)" )
15966+ .bind( &addReporterName, "name" );
15967+
15968+ cli["-n"]["--name"]
15969+ .describe( "suite name" )
15970+ .bind( &ConfigData::name, "name" );
15971+
15972+ cli["-a"]["--abort"]
15973+ .describe( "abort at first failure" )
15974+ .bind( &abortAfterFirst );
15975+
15976+ cli["-x"]["--abortx"]
15977+ .describe( "abort after x failures" )
15978+ .bind( &abortAfterX, "no. failures" );
15979+
15980+ cli["-w"]["--warn"]
15981+ .describe( "enable warnings" )
15982+ .bind( &addWarning, "warning name" );
15983+
15984+// - needs updating if reinstated
15985+// cli.into( &setVerbosity )
15986+// .describe( "level of verbosity (0=no output)" )
15987+// .shortOpt( "v")
15988+// .longOpt( "verbosity" )
15989+// .placeholder( "level" );
15990+
15991+ cli[_]
15992+ .describe( "which test or tests to use" )
15993+ .bind( &addTestOrTags, "test name, pattern or tags" );
15994+
15995+ cli["-d"]["--durations"]
15996+ .describe( "show test durations" )
15997+ .bind( &setShowDurations, "yes|no" );
15998+
15999+ cli["-f"]["--input-file"]
16000+ .describe( "load test names to run from a file" )
16001+ .bind( &loadTestNamesFromFile, "filename" );
16002+
16003+ cli["-#"]["--filenames-as-tags"]
16004+ .describe( "adds a tag for the filename" )
16005+ .bind( &ConfigData::filenamesAsTags );
16006+
16007+ cli["-c"]["--section"]
16008+ .describe( "specify section to run" )
16009+ .bind( &addSectionToRun, "section name" );
16010+
16011+ // Less common commands which don't have a short form
16012+ cli["--list-test-names-only"]
16013+ .describe( "list all/matching test cases names only" )
16014+ .bind( &ConfigData::listTestNamesOnly );
16015+
16016+ cli["--list-extra-info"]
16017+ .describe( "list all/matching test cases with more info" )
16018+ .bind( &ConfigData::listExtraInfo );
16019+
16020+ cli["--list-reporters"]
16021+ .describe( "list all reporters" )
16022+ .bind( &ConfigData::listReporters );
16023+
16024+ cli["--order"]
16025+ .describe( "test case order (defaults to decl)" )
16026+ .bind( &setOrder, "decl|lex|rand" );
16027+
16028+ cli["--rng-seed"]
16029+ .describe( "set a specific seed for random numbers" )
16030+ .bind( &setRngSeed, "'time'|number" );
16031+
16032+ cli["--force-colour"]
16033+ .describe( "force colourised output (deprecated)" )
16034+ .bind( &forceColour );
16035+
16036+ cli["--use-colour"]
16037+ .describe( "should output be colourised" )
16038+ .bind( &setUseColour, "yes|no" );
16039+
16040+ cli["--libidentify"]
16041+ .describe( "report name and version according to libidentify standard" )
16042+ .bind( &ConfigData::libIdentify );
16043+
16044+ cli["--wait-for-keypress"]
16045+ .describe( "waits for a keypress before exiting" )
16046+ .bind( &setWaitForKeypress, "start|exit|both" );
16047+
16048+ return cli;
16049+ }
16050+
16051+} // end namespace Catch
16052+
16053+// #included from: internal/catch_list.hpp
16054+#define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED
16055+
16056+// #included from: catch_text.h
16057+#define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED
16058+
16059+#define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
16060+
16061+#define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch
16062+// #included from: ../external/tbc_text_format.h
16063+// Only use header guard if we are not using an outer namespace
16064+#ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
16065+# ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
16066+# ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
16067+# define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
16068+# endif
16069+# else
16070+# define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
16071+# endif
16072+#endif
16073+#ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
16074+#include <string>
16075+#include <vector>
16076+#include <sstream>
16077+
16078+// Use optional outer namespace
16079+#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
16080+namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
16081+#endif
16082+
16083+namespace Tbc {
16084+
16085+#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
16086+ const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
16087+#else
16088+ const unsigned int consoleWidth = 80;
16089+#endif
16090+
16091+ struct TextAttributes {
16092+ TextAttributes()
16093+ : initialIndent( std::string::npos ),
16094+ indent( 0 ),
16095+ width( consoleWidth-1 )
16096+ {}
16097+
16098+ TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
16099+ TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
16100+ TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
16101+
16102+ std::size_t initialIndent; // indent of first line, or npos
16103+ std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos
16104+ std::size_t width; // maximum width of text, including indent. Longer text will wrap
16105+ };
16106+
16107+ class Text {
16108+ public:
16109+ Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
16110+ : attr( _attr )
16111+ {
16112+ const std::string wrappableBeforeChars = "[({<\t";
16113+ const std::string wrappableAfterChars = "])}>-,./|\\";
16114+ const std::string wrappableInsteadOfChars = " \n\r";
16115+ std::string indent = _attr.initialIndent != std::string::npos
16116+ ? std::string( _attr.initialIndent, ' ' )
16117+ : std::string( _attr.indent, ' ' );
16118+
16119+ typedef std::string::const_iterator iterator;
16120+ iterator it = _str.begin();
16121+ const iterator strEnd = _str.end();
16122+
16123+ while( it != strEnd ) {
16124+
16125+ if( lines.size() >= 1000 ) {
16126+ lines.push_back( "... message truncated due to excessive size" );
16127+ return;
16128+ }
16129+
16130+ std::string suffix;
16131+ std::size_t width = (std::min)( static_cast<size_t>( strEnd-it ), _attr.width-static_cast<size_t>( indent.size() ) );
16132+ iterator itEnd = it+width;
16133+ iterator itNext = _str.end();
16134+
16135+ iterator itNewLine = std::find( it, itEnd, '\n' );
16136+ if( itNewLine != itEnd )
16137+ itEnd = itNewLine;
16138+
16139+ if( itEnd != strEnd ) {
16140+ bool foundWrapPoint = false;
16141+ iterator findIt = itEnd;
16142+ do {
16143+ if( wrappableAfterChars.find( *findIt ) != std::string::npos && findIt != itEnd ) {
16144+ itEnd = findIt+1;
16145+ itNext = findIt+1;
16146+ foundWrapPoint = true;
16147+ }
16148+ else if( findIt > it && wrappableBeforeChars.find( *findIt ) != std::string::npos ) {
16149+ itEnd = findIt;
16150+ itNext = findIt;
16151+ foundWrapPoint = true;
16152+ }
16153+ else if( wrappableInsteadOfChars.find( *findIt ) != std::string::npos ) {
16154+ itNext = findIt+1;
16155+ itEnd = findIt;
16156+ foundWrapPoint = true;
16157+ }
16158+ if( findIt == it )
16159+ break;
16160+ else
16161+ --findIt;
16162+ }
16163+ while( !foundWrapPoint );
16164+
16165+ if( !foundWrapPoint ) {
16166+ // No good wrap char, so we'll break mid word and add a hyphen
16167+ --itEnd;
16168+ itNext = itEnd;
16169+ suffix = "-";
16170+ }
16171+ else {
16172+ while( itEnd > it && wrappableInsteadOfChars.find( *(itEnd-1) ) != std::string::npos )
16173+ --itEnd;
16174+ }
16175+ }
16176+ lines.push_back( indent + std::string( it, itEnd ) + suffix );
16177+
16178+ if( indent.size() != _attr.indent )
16179+ indent = std::string( _attr.indent, ' ' );
16180+ it = itNext;
16181+ }
16182+ }
16183+
16184+ typedef std::vector<std::string>::const_iterator const_iterator;
16185+
16186+ const_iterator begin() const { return lines.begin(); }
16187+ const_iterator end() const { return lines.end(); }
16188+ std::string const& last() const { return lines.back(); }
16189+ std::size_t size() const { return lines.size(); }
16190+ std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
16191+ std::string toString() const {
16192+ std::ostringstream oss;
16193+ oss << *this;
16194+ return oss.str();
16195+ }
16196+
16197+ inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
16198+ for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
16199+ it != itEnd; ++it ) {
16200+ if( it != _text.begin() )
16201+ _stream << "\n";
16202+ _stream << *it;
16203+ }
16204+ return _stream;
16205+ }
16206+
16207+ private:
16208+ std::string str;
16209+ TextAttributes attr;
16210+ std::vector<std::string> lines;
16211+ };
16212+
16213+} // end namespace Tbc
16214+
16215+#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
16216+} // end outer namespace
16217+#endif
16218+
16219+#endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
16220+#undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
16221+
16222+namespace Catch {
16223+ using Tbc::Text;
16224+ using Tbc::TextAttributes;
16225+}
16226+
16227+// #included from: catch_console_colour.hpp
16228+#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED
16229+
16230+namespace Catch {
16231+
16232+ struct Colour {
16233+ enum Code {
16234+ None = 0,
16235+
16236+ White,
16237+ Red,
16238+ Green,
16239+ Blue,
16240+ Cyan,
16241+ Yellow,
16242+ Grey,
16243+
16244+ Bright = 0x10,
16245+
16246+ BrightRed = Bright | Red,
16247+ BrightGreen = Bright | Green,
16248+ LightGrey = Bright | Grey,
16249+ BrightWhite = Bright | White,
16250+
16251+ // By intention
16252+ FileName = LightGrey,
16253+ Warning = Yellow,
16254+ ResultError = BrightRed,
16255+ ResultSuccess = BrightGreen,
16256+ ResultExpectedFailure = Warning,
16257+
16258+ Error = BrightRed,
16259+ Success = Green,
16260+
16261+ OriginalExpression = Cyan,
16262+ ReconstructedExpression = Yellow,
16263+
16264+ SecondaryText = LightGrey,
16265+ Headers = White
16266+ };
16267+
16268+ // Use constructed object for RAII guard
16269+ Colour( Code _colourCode );
16270+ Colour( Colour const& other );
16271+ ~Colour();
16272+
16273+ // Use static method for one-shot changes
16274+ static void use( Code _colourCode );
16275+
16276+ private:
16277+ bool m_moved;
16278+ };
16279+
16280+ inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; }
16281+
16282+} // end namespace Catch
16283+
16284+// #included from: catch_interfaces_reporter.h
16285+#define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
16286+
16287+#include <string>
16288+#include <ostream>
16289+#include <map>
16290+
16291+namespace Catch
16292+{
16293+ struct ReporterConfig {
16294+ explicit ReporterConfig( Ptr<IConfig const> const& _fullConfig )
16295+ : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
16296+
16297+ ReporterConfig( Ptr<IConfig const> const& _fullConfig, std::ostream& _stream )
16298+ : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
16299+
16300+ std::ostream& stream() const { return *m_stream; }
16301+ Ptr<IConfig const> fullConfig() const { return m_fullConfig; }
16302+
16303+ private:
16304+ std::ostream* m_stream;
16305+ Ptr<IConfig const> m_fullConfig;
16306+ };
16307+
16308+ struct ReporterPreferences {
16309+ ReporterPreferences()
16310+ : shouldRedirectStdOut( false )
16311+ {}
16312+
16313+ bool shouldRedirectStdOut;
16314+ };
16315+
16316+ template<typename T>
16317+ struct LazyStat : Option<T> {
16318+ LazyStat() : used( false ) {}
16319+ LazyStat& operator=( T const& _value ) {
16320+ Option<T>::operator=( _value );
16321+ used = false;
16322+ return *this;
16323+ }
16324+ void reset() {
16325+ Option<T>::reset();
16326+ used = false;
16327+ }
16328+ bool used;
16329+ };
16330+
16331+ struct TestRunInfo {
16332+ TestRunInfo( std::string const& _name ) : name( _name ) {}
16333+ std::string name;
16334+ };
16335+ struct GroupInfo {
16336+ GroupInfo( std::string const& _name,
16337+ std::size_t _groupIndex,
16338+ std::size_t _groupsCount )
16339+ : name( _name ),
16340+ groupIndex( _groupIndex ),
16341+ groupsCounts( _groupsCount )
16342+ {}
16343+
16344+ std::string name;
16345+ std::size_t groupIndex;
16346+ std::size_t groupsCounts;
16347+ };
16348+
16349+ struct AssertionStats {
16350+ AssertionStats( AssertionResult const& _assertionResult,
16351+ std::vector<MessageInfo> const& _infoMessages,
16352+ Totals const& _totals )
16353+ : assertionResult( _assertionResult ),
16354+ infoMessages( _infoMessages ),
16355+ totals( _totals )
16356+ {
16357+ if( assertionResult.hasMessage() ) {
16358+ // Copy message into messages list.
16359+ // !TBD This should have been done earlier, somewhere
16360+ MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
16361+ builder << assertionResult.getMessage();
16362+ builder.m_info.message = builder.m_stream.str();
16363+
16364+ infoMessages.push_back( builder.m_info );
16365+ }
16366+ }
16367+ virtual ~AssertionStats();
16368+
16369+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
16370+ AssertionStats( AssertionStats const& ) = default;
16371+ AssertionStats( AssertionStats && ) = default;
16372+ AssertionStats& operator = ( AssertionStats const& ) = default;
16373+ AssertionStats& operator = ( AssertionStats && ) = default;
16374+# endif
16375+
16376+ AssertionResult assertionResult;
16377+ std::vector<MessageInfo> infoMessages;
16378+ Totals totals;
16379+ };
16380+
16381+ struct SectionStats {
16382+ SectionStats( SectionInfo const& _sectionInfo,
16383+ Counts const& _assertions,
16384+ double _durationInSeconds,
16385+ bool _missingAssertions )
16386+ : sectionInfo( _sectionInfo ),
16387+ assertions( _assertions ),
16388+ durationInSeconds( _durationInSeconds ),
16389+ missingAssertions( _missingAssertions )
16390+ {}
16391+ virtual ~SectionStats();
16392+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
16393+ SectionStats( SectionStats const& ) = default;
16394+ SectionStats( SectionStats && ) = default;
16395+ SectionStats& operator = ( SectionStats const& ) = default;
16396+ SectionStats& operator = ( SectionStats && ) = default;
16397+# endif
16398+
16399+ SectionInfo sectionInfo;
16400+ Counts assertions;
16401+ double durationInSeconds;
16402+ bool missingAssertions;
16403+ };
16404+
16405+ struct TestCaseStats {
16406+ TestCaseStats( TestCaseInfo const& _testInfo,
16407+ Totals const& _totals,
16408+ std::string const& _stdOut,
16409+ std::string const& _stdErr,
16410+ bool _aborting )
16411+ : testInfo( _testInfo ),
16412+ totals( _totals ),
16413+ stdOut( _stdOut ),
16414+ stdErr( _stdErr ),
16415+ aborting( _aborting )
16416+ {}
16417+ virtual ~TestCaseStats();
16418+
16419+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
16420+ TestCaseStats( TestCaseStats const& ) = default;
16421+ TestCaseStats( TestCaseStats && ) = default;
16422+ TestCaseStats& operator = ( TestCaseStats const& ) = default;
16423+ TestCaseStats& operator = ( TestCaseStats && ) = default;
16424+# endif
16425+
16426+ TestCaseInfo testInfo;
16427+ Totals totals;
16428+ std::string stdOut;
16429+ std::string stdErr;
16430+ bool aborting;
16431+ };
16432+
16433+ struct TestGroupStats {
16434+ TestGroupStats( GroupInfo const& _groupInfo,
16435+ Totals const& _totals,
16436+ bool _aborting )
16437+ : groupInfo( _groupInfo ),
16438+ totals( _totals ),
16439+ aborting( _aborting )
16440+ {}
16441+ TestGroupStats( GroupInfo const& _groupInfo )
16442+ : groupInfo( _groupInfo ),
16443+ aborting( false )
16444+ {}
16445+ virtual ~TestGroupStats();
16446+
16447+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
16448+ TestGroupStats( TestGroupStats const& ) = default;
16449+ TestGroupStats( TestGroupStats && ) = default;
16450+ TestGroupStats& operator = ( TestGroupStats const& ) = default;
16451+ TestGroupStats& operator = ( TestGroupStats && ) = default;
16452+# endif
16453+
16454+ GroupInfo groupInfo;
16455+ Totals totals;
16456+ bool aborting;
16457+ };
16458+
16459+ struct TestRunStats {
16460+ TestRunStats( TestRunInfo const& _runInfo,
16461+ Totals const& _totals,
16462+ bool _aborting )
16463+ : runInfo( _runInfo ),
16464+ totals( _totals ),
16465+ aborting( _aborting )
16466+ {}
16467+ virtual ~TestRunStats();
16468+
16469+# ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS
16470+ TestRunStats( TestRunStats const& _other )
16471+ : runInfo( _other.runInfo ),
16472+ totals( _other.totals ),
16473+ aborting( _other.aborting )
16474+ {}
16475+# else
16476+ TestRunStats( TestRunStats const& ) = default;
16477+ TestRunStats( TestRunStats && ) = default;
16478+ TestRunStats& operator = ( TestRunStats const& ) = default;
16479+ TestRunStats& operator = ( TestRunStats && ) = default;
16480+# endif
16481+
16482+ TestRunInfo runInfo;
16483+ Totals totals;
16484+ bool aborting;
16485+ };
16486+
16487+ class MultipleReporters;
16488+
16489+ struct IStreamingReporter : IShared {
16490+ virtual ~IStreamingReporter();
16491+
16492+ // Implementing class must also provide the following static method:
16493+ // static std::string getDescription();
16494+
16495+ virtual ReporterPreferences getPreferences() const = 0;
16496+
16497+ virtual void noMatchingTestCases( std::string const& spec ) = 0;
16498+
16499+ virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
16500+ virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
16501+
16502+ virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
16503+ virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
16504+
16505+ virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
16506+
16507+ // The return value indicates if the messages buffer should be cleared:
16508+ virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
16509+
16510+ virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
16511+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
16512+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
16513+ virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
16514+
16515+ virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
16516+
16517+ virtual MultipleReporters* tryAsMulti() { return CATCH_NULL; }
16518+ };
16519+
16520+ struct IReporterFactory : IShared {
16521+ virtual ~IReporterFactory();
16522+ virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0;
16523+ virtual std::string getDescription() const = 0;
16524+ };
16525+
16526+ struct IReporterRegistry {
16527+ typedef std::map<std::string, Ptr<IReporterFactory> > FactoryMap;
16528+ typedef std::vector<Ptr<IReporterFactory> > Listeners;
16529+
16530+ virtual ~IReporterRegistry();
16531+ virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const = 0;
16532+ virtual FactoryMap const& getFactories() const = 0;
16533+ virtual Listeners const& getListeners() const = 0;
16534+ };
16535+
16536+ Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter );
16537+
16538+}
16539+
16540+#include <limits>
16541+#include <algorithm>
16542+
16543+namespace Catch {
16544+
16545+ inline std::size_t listTests( Config const& config ) {
16546+
16547+ TestSpec testSpec = config.testSpec();
16548+ if( config.testSpec().hasFilters() )
16549+ Catch::cout() << "Matching test cases:\n";
16550+ else {
16551+ Catch::cout() << "All available test cases:\n";
16552+ testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
16553+ }
16554+
16555+ std::size_t matchedTests = 0;
16556+ TextAttributes nameAttr, descAttr, tagsAttr;
16557+ nameAttr.setInitialIndent( 2 ).setIndent( 4 );
16558+ descAttr.setIndent( 4 );
16559+ tagsAttr.setIndent( 6 );
16560+
16561+ std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
16562+ for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
16563+ it != itEnd;
16564+ ++it ) {
16565+ matchedTests++;
16566+ TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
16567+ Colour::Code colour = testCaseInfo.isHidden()
16568+ ? Colour::SecondaryText
16569+ : Colour::None;
16570+ Colour colourGuard( colour );
16571+
16572+ Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl;
16573+ if( config.listExtraInfo() ) {
16574+ Catch::cout() << " " << testCaseInfo.lineInfo << std::endl;
16575+ std::string description = testCaseInfo.description;
16576+ if( description.empty() )
16577+ description = "(NO DESCRIPTION)";
16578+ Catch::cout() << Text( description, descAttr ) << std::endl;
16579+ }
16580+ if( !testCaseInfo.tags.empty() )
16581+ Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl;
16582+ }
16583+
16584+ if( !config.testSpec().hasFilters() )
16585+ Catch::cout() << pluralise( matchedTests, "test case" ) << '\n' << std::endl;
16586+ else
16587+ Catch::cout() << pluralise( matchedTests, "matching test case" ) << '\n' << std::endl;
16588+ return matchedTests;
16589+ }
16590+
16591+ inline std::size_t listTestsNamesOnly( Config const& config ) {
16592+ TestSpec testSpec = config.testSpec();
16593+ if( !config.testSpec().hasFilters() )
16594+ testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
16595+ std::size_t matchedTests = 0;
16596+ std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
16597+ for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
16598+ it != itEnd;
16599+ ++it ) {
16600+ matchedTests++;
16601+ TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
16602+ if( startsWith( testCaseInfo.name, '#' ) )
16603+ Catch::cout() << '"' << testCaseInfo.name << '"';
16604+ else
16605+ Catch::cout() << testCaseInfo.name;
16606+ if ( config.listExtraInfo() )
16607+ Catch::cout() << "\t@" << testCaseInfo.lineInfo;
16608+ Catch::cout() << std::endl;
16609+ }
16610+ return matchedTests;
16611+ }
16612+
16613+ struct TagInfo {
16614+ TagInfo() : count ( 0 ) {}
16615+ void add( std::string const& spelling ) {
16616+ ++count;
16617+ spellings.insert( spelling );
16618+ }
16619+ std::string all() const {
16620+ std::string out;
16621+ for( std::set<std::string>::const_iterator it = spellings.begin(), itEnd = spellings.end();
16622+ it != itEnd;
16623+ ++it )
16624+ out += "[" + *it + "]";
16625+ return out;
16626+ }
16627+ std::set<std::string> spellings;
16628+ std::size_t count;
16629+ };
16630+
16631+ inline std::size_t listTags( Config const& config ) {
16632+ TestSpec testSpec = config.testSpec();
16633+ if( config.testSpec().hasFilters() )
16634+ Catch::cout() << "Tags for matching test cases:\n";
16635+ else {
16636+ Catch::cout() << "All available tags:\n";
16637+ testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
16638+ }
16639+
16640+ std::map<std::string, TagInfo> tagCounts;
16641+
16642+ std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
16643+ for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
16644+ it != itEnd;
16645+ ++it ) {
16646+ for( std::set<std::string>::const_iterator tagIt = it->getTestCaseInfo().tags.begin(),
16647+ tagItEnd = it->getTestCaseInfo().tags.end();
16648+ tagIt != tagItEnd;
16649+ ++tagIt ) {
16650+ std::string tagName = *tagIt;
16651+ std::string lcaseTagName = toLower( tagName );
16652+ std::map<std::string, TagInfo>::iterator countIt = tagCounts.find( lcaseTagName );
16653+ if( countIt == tagCounts.end() )
16654+ countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
16655+ countIt->second.add( tagName );
16656+ }
16657+ }
16658+
16659+ for( std::map<std::string, TagInfo>::const_iterator countIt = tagCounts.begin(),
16660+ countItEnd = tagCounts.end();
16661+ countIt != countItEnd;
16662+ ++countIt ) {
16663+ std::ostringstream oss;
16664+ oss << " " << std::setw(2) << countIt->second.count << " ";
16665+ Text wrapper( countIt->second.all(), TextAttributes()
16666+ .setInitialIndent( 0 )
16667+ .setIndent( oss.str().size() )
16668+ .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) );
16669+ Catch::cout() << oss.str() << wrapper << '\n';
16670+ }
16671+ Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl;
16672+ return tagCounts.size();
16673+ }
16674+
16675+ inline std::size_t listReporters( Config const& /*config*/ ) {
16676+ Catch::cout() << "Available reporters:\n";
16677+ IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
16678+ IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;
16679+ std::size_t maxNameLen = 0;
16680+ for(it = itBegin; it != itEnd; ++it )
16681+ maxNameLen = (std::max)( maxNameLen, it->first.size() );
16682+
16683+ for(it = itBegin; it != itEnd; ++it ) {
16684+ Text wrapper( it->second->getDescription(), TextAttributes()
16685+ .setInitialIndent( 0 )
16686+ .setIndent( 7+maxNameLen )
16687+ .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );
16688+ Catch::cout() << " "
16689+ << it->first
16690+ << ':'
16691+ << std::string( maxNameLen - it->first.size() + 2, ' ' )
16692+ << wrapper << '\n';
16693+ }
16694+ Catch::cout() << std::endl;
16695+ return factories.size();
16696+ }
16697+
16698+ inline Option<std::size_t> list( Config const& config ) {
16699+ Option<std::size_t> listedCount;
16700+ if( config.listTests() || ( config.listExtraInfo() && !config.listTestNamesOnly() ) )
16701+ listedCount = listedCount.valueOr(0) + listTests( config );
16702+ if( config.listTestNamesOnly() )
16703+ listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
16704+ if( config.listTags() )
16705+ listedCount = listedCount.valueOr(0) + listTags( config );
16706+ if( config.listReporters() )
16707+ listedCount = listedCount.valueOr(0) + listReporters( config );
16708+ return listedCount;
16709+ }
16710+
16711+} // end namespace Catch
16712+
16713+// #included from: internal/catch_run_context.hpp
16714+#define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
16715+
16716+// #included from: catch_test_case_tracker.hpp
16717+#define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
16718+
16719+#include <algorithm>
16720+#include <string>
16721+#include <assert.h>
16722+#include <vector>
16723+#include <stdexcept>
16724+
16725+CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS
16726+
16727+namespace Catch {
16728+namespace TestCaseTracking {
16729+
16730+ struct NameAndLocation {
16731+ std::string name;
16732+ SourceLineInfo location;
16733+
16734+ NameAndLocation( std::string const& _name, SourceLineInfo const& _location )
16735+ : name( _name ),
16736+ location( _location )
16737+ {}
16738+ };
16739+
16740+ struct ITracker : SharedImpl<> {
16741+ virtual ~ITracker();
16742+
16743+ // static queries
16744+ virtual NameAndLocation const& nameAndLocation() const = 0;
16745+
16746+ // dynamic queries
16747+ virtual bool isComplete() const = 0; // Successfully completed or failed
16748+ virtual bool isSuccessfullyCompleted() const = 0;
16749+ virtual bool isOpen() const = 0; // Started but not complete
16750+ virtual bool hasChildren() const = 0;
16751+
16752+ virtual ITracker& parent() = 0;
16753+
16754+ // actions
16755+ virtual void close() = 0; // Successfully complete
16756+ virtual void fail() = 0;
16757+ virtual void markAsNeedingAnotherRun() = 0;
16758+
16759+ virtual void addChild( Ptr<ITracker> const& child ) = 0;
16760+ virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) = 0;
16761+ virtual void openChild() = 0;
16762+
16763+ // Debug/ checking
16764+ virtual bool isSectionTracker() const = 0;
16765+ virtual bool isIndexTracker() const = 0;
16766+ };
16767+
16768+ class TrackerContext {
16769+
16770+ enum RunState {
16771+ NotStarted,
16772+ Executing,
16773+ CompletedCycle
16774+ };
16775+
16776+ Ptr<ITracker> m_rootTracker;
16777+ ITracker* m_currentTracker;
16778+ RunState m_runState;
16779+
16780+ public:
16781+
16782+ static TrackerContext& instance() {
16783+ static TrackerContext s_instance;
16784+ return s_instance;
16785+ }
16786+
16787+ TrackerContext()
16788+ : m_currentTracker( CATCH_NULL ),
16789+ m_runState( NotStarted )
16790+ {}
16791+
16792+ ITracker& startRun();
16793+
16794+ void endRun() {
16795+ m_rootTracker.reset();
16796+ m_currentTracker = CATCH_NULL;
16797+ m_runState = NotStarted;
16798+ }
16799+
16800+ void startCycle() {
16801+ m_currentTracker = m_rootTracker.get();
16802+ m_runState = Executing;
16803+ }
16804+ void completeCycle() {
16805+ m_runState = CompletedCycle;
16806+ }
16807+
16808+ bool completedCycle() const {
16809+ return m_runState == CompletedCycle;
16810+ }
16811+ ITracker& currentTracker() {
16812+ return *m_currentTracker;
16813+ }
16814+ void setCurrentTracker( ITracker* tracker ) {
16815+ m_currentTracker = tracker;
16816+ }
16817+ };
16818+
16819+ class TrackerBase : public ITracker {
16820+ protected:
16821+ enum CycleState {
16822+ NotStarted,
16823+ Executing,
16824+ ExecutingChildren,
16825+ NeedsAnotherRun,
16826+ CompletedSuccessfully,
16827+ Failed
16828+ };
16829+ class TrackerHasName {
16830+ NameAndLocation m_nameAndLocation;
16831+ public:
16832+ TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {}
16833+ bool operator ()( Ptr<ITracker> const& tracker ) {
16834+ return
16835+ tracker->nameAndLocation().name == m_nameAndLocation.name &&
16836+ tracker->nameAndLocation().location == m_nameAndLocation.location;
16837+ }
16838+ };
16839+ typedef std::vector<Ptr<ITracker> > Children;
16840+ NameAndLocation m_nameAndLocation;
16841+ TrackerContext& m_ctx;
16842+ ITracker* m_parent;
16843+ Children m_children;
16844+ CycleState m_runState;
16845+ public:
16846+ TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
16847+ : m_nameAndLocation( nameAndLocation ),
16848+ m_ctx( ctx ),
16849+ m_parent( parent ),
16850+ m_runState( NotStarted )
16851+ {}
16852+ virtual ~TrackerBase();
16853+
16854+ virtual NameAndLocation const& nameAndLocation() const CATCH_OVERRIDE {
16855+ return m_nameAndLocation;
16856+ }
16857+ virtual bool isComplete() const CATCH_OVERRIDE {
16858+ return m_runState == CompletedSuccessfully || m_runState == Failed;
16859+ }
16860+ virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE {
16861+ return m_runState == CompletedSuccessfully;
16862+ }
16863+ virtual bool isOpen() const CATCH_OVERRIDE {
16864+ return m_runState != NotStarted && !isComplete();
16865+ }
16866+ virtual bool hasChildren() const CATCH_OVERRIDE {
16867+ return !m_children.empty();
16868+ }
16869+
16870+ virtual void addChild( Ptr<ITracker> const& child ) CATCH_OVERRIDE {
16871+ m_children.push_back( child );
16872+ }
16873+
16874+ virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) CATCH_OVERRIDE {
16875+ Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( nameAndLocation ) );
16876+ return( it != m_children.end() )
16877+ ? it->get()
16878+ : CATCH_NULL;
16879+ }
16880+ virtual ITracker& parent() CATCH_OVERRIDE {
16881+ assert( m_parent ); // Should always be non-null except for root
16882+ return *m_parent;
16883+ }
16884+
16885+ virtual void openChild() CATCH_OVERRIDE {
16886+ if( m_runState != ExecutingChildren ) {
16887+ m_runState = ExecutingChildren;
16888+ if( m_parent )
16889+ m_parent->openChild();
16890+ }
16891+ }
16892+
16893+ virtual bool isSectionTracker() const CATCH_OVERRIDE { return false; }
16894+ virtual bool isIndexTracker() const CATCH_OVERRIDE { return false; }
16895+
16896+ void open() {
16897+ m_runState = Executing;
16898+ moveToThis();
16899+ if( m_parent )
16900+ m_parent->openChild();
16901+ }
16902+
16903+ virtual void close() CATCH_OVERRIDE {
16904+
16905+ // Close any still open children (e.g. generators)
16906+ while( &m_ctx.currentTracker() != this )
16907+ m_ctx.currentTracker().close();
16908+
16909+ switch( m_runState ) {
16910+ case NotStarted:
16911+ case CompletedSuccessfully:
16912+ case Failed:
16913+ throw std::logic_error( "Illogical state" );
16914+
16915+ case NeedsAnotherRun:
16916+ break;;
16917+
16918+ case Executing:
16919+ m_runState = CompletedSuccessfully;
16920+ break;
16921+ case ExecutingChildren:
16922+ if( m_children.empty() || m_children.back()->isComplete() )
16923+ m_runState = CompletedSuccessfully;
16924+ break;
16925+
16926+ default:
16927+ throw std::logic_error( "Unexpected state" );
16928+ }
16929+ moveToParent();
16930+ m_ctx.completeCycle();
16931+ }
16932+ virtual void fail() CATCH_OVERRIDE {
16933+ m_runState = Failed;
16934+ if( m_parent )
16935+ m_parent->markAsNeedingAnotherRun();
16936+ moveToParent();
16937+ m_ctx.completeCycle();
16938+ }
16939+ virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE {
16940+ m_runState = NeedsAnotherRun;
16941+ }
16942+ private:
16943+ void moveToParent() {
16944+ assert( m_parent );
16945+ m_ctx.setCurrentTracker( m_parent );
16946+ }
16947+ void moveToThis() {
16948+ m_ctx.setCurrentTracker( this );
16949+ }
16950+ };
16951+
16952+ class SectionTracker : public TrackerBase {
16953+ std::vector<std::string> m_filters;
16954+ public:
16955+ SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
16956+ : TrackerBase( nameAndLocation, ctx, parent )
16957+ {
16958+ if( parent ) {
16959+ while( !parent->isSectionTracker() )
16960+ parent = &parent->parent();
16961+
16962+ SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );
16963+ addNextFilters( parentSection.m_filters );
16964+ }
16965+ }
16966+ virtual ~SectionTracker();
16967+
16968+ virtual bool isSectionTracker() const CATCH_OVERRIDE { return true; }
16969+
16970+ static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {
16971+ SectionTracker* section = CATCH_NULL;
16972+
16973+ ITracker& currentTracker = ctx.currentTracker();
16974+ if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) {
16975+ assert( childTracker );
16976+ assert( childTracker->isSectionTracker() );
16977+ section = static_cast<SectionTracker*>( childTracker );
16978+ }
16979+ else {
16980+ section = new SectionTracker( nameAndLocation, ctx, &currentTracker );
16981+ currentTracker.addChild( section );
16982+ }
16983+ if( !ctx.completedCycle() )
16984+ section->tryOpen();
16985+ return *section;
16986+ }
16987+
16988+ void tryOpen() {
16989+ if( !isComplete() && (m_filters.empty() || m_filters[0].empty() || m_filters[0] == m_nameAndLocation.name ) )
16990+ open();
16991+ }
16992+
16993+ void addInitialFilters( std::vector<std::string> const& filters ) {
16994+ if( !filters.empty() ) {
16995+ m_filters.push_back(""); // Root - should never be consulted
16996+ m_filters.push_back(""); // Test Case - not a section filter
16997+ m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
16998+ }
16999+ }
17000+ void addNextFilters( std::vector<std::string> const& filters ) {
17001+ if( filters.size() > 1 )
17002+ m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() );
17003+ }
17004+ };
17005+
17006+ class IndexTracker : public TrackerBase {
17007+ int m_size;
17008+ int m_index;
17009+ public:
17010+ IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size )
17011+ : TrackerBase( nameAndLocation, ctx, parent ),
17012+ m_size( size ),
17013+ m_index( -1 )
17014+ {}
17015+ virtual ~IndexTracker();
17016+
17017+ virtual bool isIndexTracker() const CATCH_OVERRIDE { return true; }
17018+
17019+ static IndexTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size ) {
17020+ IndexTracker* tracker = CATCH_NULL;
17021+
17022+ ITracker& currentTracker = ctx.currentTracker();
17023+ if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) {
17024+ assert( childTracker );
17025+ assert( childTracker->isIndexTracker() );
17026+ tracker = static_cast<IndexTracker*>( childTracker );
17027+ }
17028+ else {
17029+ tracker = new IndexTracker( nameAndLocation, ctx, &currentTracker, size );
17030+ currentTracker.addChild( tracker );
17031+ }
17032+
17033+ if( !ctx.completedCycle() && !tracker->isComplete() ) {
17034+ if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
17035+ tracker->moveNext();
17036+ tracker->open();
17037+ }
17038+
17039+ return *tracker;
17040+ }
17041+
17042+ int index() const { return m_index; }
17043+
17044+ void moveNext() {
17045+ m_index++;
17046+ m_children.clear();
17047+ }
17048+
17049+ virtual void close() CATCH_OVERRIDE {
17050+ TrackerBase::close();
17051+ if( m_runState == CompletedSuccessfully && m_index < m_size-1 )
17052+ m_runState = Executing;
17053+ }
17054+ };
17055+
17056+ inline ITracker& TrackerContext::startRun() {
17057+ m_rootTracker = new SectionTracker( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, CATCH_NULL );
17058+ m_currentTracker = CATCH_NULL;
17059+ m_runState = Executing;
17060+ return *m_rootTracker;
17061+ }
17062+
17063+} // namespace TestCaseTracking
17064+
17065+using TestCaseTracking::ITracker;
17066+using TestCaseTracking::TrackerContext;
17067+using TestCaseTracking::SectionTracker;
17068+using TestCaseTracking::IndexTracker;
17069+
17070+} // namespace Catch
17071+
17072+CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
17073+
17074+// #included from: catch_fatal_condition.hpp
17075+#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
17076+
17077+namespace Catch {
17078+
17079+ // Report the error condition
17080+ inline void reportFatal( std::string const& message ) {
17081+ IContext& context = Catch::getCurrentContext();
17082+ IResultCapture* resultCapture = context.getResultCapture();
17083+ resultCapture->handleFatalErrorCondition( message );
17084+ }
17085+
17086+} // namespace Catch
17087+
17088+#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
17089+// #included from: catch_windows_h_proxy.h
17090+
17091+#define TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED
17092+
17093+#ifdef CATCH_DEFINES_NOMINMAX
17094+# define NOMINMAX
17095+#endif
17096+#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN
17097+# define WIN32_LEAN_AND_MEAN
17098+#endif
17099+
17100+#ifdef __AFXDLL
17101+#include <AfxWin.h>
17102+#else
17103+#include <windows.h>
17104+#endif
17105+
17106+#ifdef CATCH_DEFINES_NOMINMAX
17107+# undef NOMINMAX
17108+#endif
17109+#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN
17110+# undef WIN32_LEAN_AND_MEAN
17111+#endif
17112+
17113+
17114+# if !defined ( CATCH_CONFIG_WINDOWS_SEH )
17115+
17116+namespace Catch {
17117+ struct FatalConditionHandler {
17118+ void reset() {}
17119+ };
17120+}
17121+
17122+# else // CATCH_CONFIG_WINDOWS_SEH is defined
17123+
17124+namespace Catch {
17125+
17126+ struct SignalDefs { DWORD id; const char* name; };
17127+ extern SignalDefs signalDefs[];
17128+ // There is no 1-1 mapping between signals and windows exceptions.
17129+ // Windows can easily distinguish between SO and SigSegV,
17130+ // but SigInt, SigTerm, etc are handled differently.
17131+ SignalDefs signalDefs[] = {
17132+ { EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal" },
17133+ { EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" },
17134+ { EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" },
17135+ { EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" },
17136+ };
17137+
17138+ struct FatalConditionHandler {
17139+
17140+ static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
17141+ for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
17142+ if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
17143+ reportFatal(signalDefs[i].name);
17144+ }
17145+ }
17146+ // If its not an exception we care about, pass it along.
17147+ // This stops us from eating debugger breaks etc.
17148+ return EXCEPTION_CONTINUE_SEARCH;
17149+ }
17150+
17151+ FatalConditionHandler() {
17152+ isSet = true;
17153+ // 32k seems enough for Catch to handle stack overflow,
17154+ // but the value was found experimentally, so there is no strong guarantee
17155+ guaranteeSize = 32 * 1024;
17156+ exceptionHandlerHandle = CATCH_NULL;
17157+ // Register as first handler in current chain
17158+ exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
17159+ // Pass in guarantee size to be filled
17160+ SetThreadStackGuarantee(&guaranteeSize);
17161+ }
17162+
17163+ static void reset() {
17164+ if (isSet) {
17165+ // Unregister handler and restore the old guarantee
17166+ RemoveVectoredExceptionHandler(exceptionHandlerHandle);
17167+ SetThreadStackGuarantee(&guaranteeSize);
17168+ exceptionHandlerHandle = CATCH_NULL;
17169+ isSet = false;
17170+ }
17171+ }
17172+
17173+ ~FatalConditionHandler() {
17174+ reset();
17175+ }
17176+ private:
17177+ static bool isSet;
17178+ static ULONG guaranteeSize;
17179+ static PVOID exceptionHandlerHandle;
17180+ };
17181+
17182+ bool FatalConditionHandler::isSet = false;
17183+ ULONG FatalConditionHandler::guaranteeSize = 0;
17184+ PVOID FatalConditionHandler::exceptionHandlerHandle = CATCH_NULL;
17185+
17186+} // namespace Catch
17187+
17188+# endif // CATCH_CONFIG_WINDOWS_SEH
17189+
17190+#else // Not Windows - assumed to be POSIX compatible //////////////////////////
17191+
17192+# if !defined(CATCH_CONFIG_POSIX_SIGNALS)
17193+
17194+namespace Catch {
17195+ struct FatalConditionHandler {
17196+ void reset() {}
17197+ };
17198+}
17199+
17200+# else // CATCH_CONFIG_POSIX_SIGNALS is defined
17201+
17202+#include <signal.h>
17203+
17204+namespace Catch {
17205+
17206+ struct SignalDefs {
17207+ int id;
17208+ const char* name;
17209+ };
17210+ extern SignalDefs signalDefs[];
17211+ SignalDefs signalDefs[] = {
17212+ { SIGINT, "SIGINT - Terminal interrupt signal" },
17213+ { SIGILL, "SIGILL - Illegal instruction signal" },
17214+ { SIGFPE, "SIGFPE - Floating point error signal" },
17215+ { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
17216+ { SIGTERM, "SIGTERM - Termination request signal" },
17217+ { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
17218+ };
17219+
17220+ struct FatalConditionHandler {
17221+
17222+ static bool isSet;
17223+ static struct sigaction oldSigActions [sizeof(signalDefs)/sizeof(SignalDefs)];
17224+ static stack_t oldSigStack;
17225+ static char altStackMem[SIGSTKSZ];
17226+
17227+ static void handleSignal( int sig ) {
17228+ std::string name = "<unknown signal>";
17229+ for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
17230+ SignalDefs &def = signalDefs[i];
17231+ if (sig == def.id) {
17232+ name = def.name;
17233+ break;
17234+ }
17235+ }
17236+ reset();
17237+ reportFatal(name);
17238+ raise( sig );
17239+ }
17240+
17241+ FatalConditionHandler() {
17242+ isSet = true;
17243+ stack_t sigStack;
17244+ sigStack.ss_sp = altStackMem;
17245+ sigStack.ss_size = SIGSTKSZ;
17246+ sigStack.ss_flags = 0;
17247+ sigaltstack(&sigStack, &oldSigStack);
17248+ struct sigaction sa = { 0 };
17249+
17250+ sa.sa_handler = handleSignal;
17251+ sa.sa_flags = SA_ONSTACK;
17252+ for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {
17253+ sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
17254+ }
17255+ }
17256+
17257+ ~FatalConditionHandler() {
17258+ reset();
17259+ }
17260+ static void reset() {
17261+ if( isSet ) {
17262+ // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
17263+ for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
17264+ sigaction(signalDefs[i].id, &oldSigActions[i], CATCH_NULL);
17265+ }
17266+ // Return the old stack
17267+ sigaltstack(&oldSigStack, CATCH_NULL);
17268+ isSet = false;
17269+ }
17270+ }
17271+ };
17272+
17273+ bool FatalConditionHandler::isSet = false;
17274+ struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
17275+ stack_t FatalConditionHandler::oldSigStack = {};
17276+ char FatalConditionHandler::altStackMem[SIGSTKSZ] = {};
17277+
17278+} // namespace Catch
17279+
17280+# endif // CATCH_CONFIG_POSIX_SIGNALS
17281+
17282+#endif // not Windows
17283+
17284+#include <cassert>
17285+#include <set>
17286+#include <string>
17287+
17288+namespace Catch {
17289+
17290+ class StreamRedirect {
17291+
17292+ public:
17293+ StreamRedirect( std::ostream& stream, std::string& targetString )
17294+ : m_stream( stream ),
17295+ m_prevBuf( stream.rdbuf() ),
17296+ m_targetString( targetString )
17297+ {
17298+ stream.rdbuf( m_oss.rdbuf() );
17299+ }
17300+
17301+ ~StreamRedirect() {
17302+ m_targetString += m_oss.str();
17303+ m_stream.rdbuf( m_prevBuf );
17304+ }
17305+
17306+ private:
17307+ std::ostream& m_stream;
17308+ std::streambuf* m_prevBuf;
17309+ std::ostringstream m_oss;
17310+ std::string& m_targetString;
17311+ };
17312+
17313+ // StdErr has two constituent streams in C++, std::cerr and std::clog
17314+ // This means that we need to redirect 2 streams into 1 to keep proper
17315+ // order of writes and cannot use StreamRedirect on its own
17316+ class StdErrRedirect {
17317+ public:
17318+ StdErrRedirect(std::string& targetString)
17319+ :m_cerrBuf( cerr().rdbuf() ), m_clogBuf(clog().rdbuf()),
17320+ m_targetString(targetString){
17321+ cerr().rdbuf(m_oss.rdbuf());
17322+ clog().rdbuf(m_oss.rdbuf());
17323+ }
17324+ ~StdErrRedirect() {
17325+ m_targetString += m_oss.str();
17326+ cerr().rdbuf(m_cerrBuf);
17327+ clog().rdbuf(m_clogBuf);
17328+ }
17329+ private:
17330+ std::streambuf* m_cerrBuf;
17331+ std::streambuf* m_clogBuf;
17332+ std::ostringstream m_oss;
17333+ std::string& m_targetString;
17334+ };
17335+
17336+ ///////////////////////////////////////////////////////////////////////////
17337+
17338+ class RunContext : public IResultCapture, public IRunner {
17339+
17340+ RunContext( RunContext const& );
17341+ void operator =( RunContext const& );
17342+
17343+ public:
17344+
17345+ explicit RunContext( Ptr<IConfig const> const& _config, Ptr<IStreamingReporter> const& reporter )
17346+ : m_runInfo( _config->name() ),
17347+ m_context( getCurrentMutableContext() ),
17348+ m_activeTestCase( CATCH_NULL ),
17349+ m_config( _config ),
17350+ m_reporter( reporter ),
17351+ m_shouldReportUnexpected ( true )
17352+ {
17353+ m_context.setRunner( this );
17354+ m_context.setConfig( m_config );
17355+ m_context.setResultCapture( this );
17356+ m_reporter->testRunStarting( m_runInfo );
17357+ }
17358+
17359+ virtual ~RunContext() {
17360+ m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );
17361+ }
17362+
17363+ void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
17364+ m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) );
17365+ }
17366+ void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) {
17367+ m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );
17368+ }
17369+
17370+ Totals runTest( TestCase const& testCase ) {
17371+ Totals prevTotals = m_totals;
17372+
17373+ std::string redirectedCout;
17374+ std::string redirectedCerr;
17375+
17376+ TestCaseInfo testInfo = testCase.getTestCaseInfo();
17377+
17378+ m_reporter->testCaseStarting( testInfo );
17379+
17380+ m_activeTestCase = &testCase;
17381+
17382+ do {
17383+ ITracker& rootTracker = m_trackerContext.startRun();
17384+ assert( rootTracker.isSectionTracker() );
17385+ static_cast<SectionTracker&>( rootTracker ).addInitialFilters( m_config->getSectionsToRun() );
17386+ do {
17387+ m_trackerContext.startCycle();
17388+ m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( testInfo.name, testInfo.lineInfo ) );
17389+ runCurrentTest( redirectedCout, redirectedCerr );
17390+ }
17391+ while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() );
17392+ }
17393+ // !TBD: deprecated - this will be replaced by indexed trackers
17394+ while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
17395+
17396+ Totals deltaTotals = m_totals.delta( prevTotals );
17397+ if( testInfo.expectedToFail() && deltaTotals.testCases.passed > 0 ) {
17398+ deltaTotals.assertions.failed++;
17399+ deltaTotals.testCases.passed--;
17400+ deltaTotals.testCases.failed++;
17401+ }
17402+ m_totals.testCases += deltaTotals.testCases;
17403+ m_reporter->testCaseEnded( TestCaseStats( testInfo,
17404+ deltaTotals,
17405+ redirectedCout,
17406+ redirectedCerr,
17407+ aborting() ) );
17408+
17409+ m_activeTestCase = CATCH_NULL;
17410+ m_testCaseTracker = CATCH_NULL;
17411+
17412+ return deltaTotals;
17413+ }
17414+
17415+ Ptr<IConfig const> config() const {
17416+ return m_config;
17417+ }
17418+
17419+ private: // IResultCapture
17420+
17421+ virtual void assertionEnded( AssertionResult const& result ) {
17422+ if( result.getResultType() == ResultWas::Ok ) {
17423+ m_totals.assertions.passed++;
17424+ }
17425+ else if( !result.isOk() ) {
17426+ if( m_activeTestCase->getTestCaseInfo().okToFail() )
17427+ m_totals.assertions.failedButOk++;
17428+ else
17429+ m_totals.assertions.failed++;
17430+ }
17431+
17432+ // We have no use for the return value (whether messages should be cleared), because messages were made scoped
17433+ // and should be let to clear themselves out.
17434+ static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
17435+
17436+ // Reset working state
17437+ m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
17438+ m_lastResult = result;
17439+ }
17440+
17441+ virtual bool lastAssertionPassed()
17442+ {
17443+ return m_totals.assertions.passed == (m_prevPassed + 1);
17444+ }
17445+
17446+ virtual void assertionPassed()
17447+ {
17448+ m_totals.assertions.passed++;
17449+ m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}";
17450+ m_lastAssertionInfo.macroName = "";
17451+ }
17452+
17453+ virtual void assertionRun()
17454+ {
17455+ m_prevPassed = m_totals.assertions.passed;
17456+ }
17457+
17458+ virtual bool sectionStarted (
17459+ SectionInfo const& sectionInfo,
17460+ Counts& assertions
17461+ )
17462+ {
17463+ ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( sectionInfo.name, sectionInfo.lineInfo ) );
17464+ if( !sectionTracker.isOpen() )
17465+ return false;
17466+ m_activeSections.push_back( &sectionTracker );
17467+
17468+ m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
17469+
17470+ m_reporter->sectionStarting( sectionInfo );
17471+
17472+ assertions = m_totals.assertions;
17473+
17474+ return true;
17475+ }
17476+ bool testForMissingAssertions( Counts& assertions ) {
17477+ if( assertions.total() != 0 )
17478+ return false;
17479+ if( !m_config->warnAboutMissingAssertions() )
17480+ return false;
17481+ if( m_trackerContext.currentTracker().hasChildren() )
17482+ return false;
17483+ m_totals.assertions.failed++;
17484+ assertions.failed++;
17485+ return true;
17486+ }
17487+
17488+ virtual void sectionEnded( SectionEndInfo const& endInfo ) {
17489+ Counts assertions = m_totals.assertions - endInfo.prevAssertions;
17490+ bool missingAssertions = testForMissingAssertions( assertions );
17491+
17492+ if( !m_activeSections.empty() ) {
17493+ m_activeSections.back()->close();
17494+ m_activeSections.pop_back();
17495+ }
17496+
17497+ m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) );
17498+ m_messages.clear();
17499+ }
17500+
17501+ virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) {
17502+ if( m_unfinishedSections.empty() )
17503+ m_activeSections.back()->fail();
17504+ else
17505+ m_activeSections.back()->close();
17506+ m_activeSections.pop_back();
17507+
17508+ m_unfinishedSections.push_back( endInfo );
17509+ }
17510+
17511+ virtual void pushScopedMessage( MessageInfo const& message ) {
17512+ m_messages.push_back( message );
17513+ }
17514+
17515+ virtual void popScopedMessage( MessageInfo const& message ) {
17516+ m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() );
17517+ }
17518+
17519+ virtual std::string getCurrentTestName() const {
17520+ return m_activeTestCase
17521+ ? m_activeTestCase->getTestCaseInfo().name
17522+ : std::string();
17523+ }
17524+
17525+ virtual const AssertionResult* getLastResult() const {
17526+ return &m_lastResult;
17527+ }
17528+
17529+ virtual void exceptionEarlyReported() {
17530+ m_shouldReportUnexpected = false;
17531+ }
17532+
17533+ virtual void handleFatalErrorCondition( std::string const& message ) {
17534+ // Don't rebuild the result -- the stringification itself can cause more fatal errors
17535+ // Instead, fake a result data.
17536+ AssertionResultData tempResult;
17537+ tempResult.resultType = ResultWas::FatalErrorCondition;
17538+ tempResult.message = message;
17539+ AssertionResult result(m_lastAssertionInfo, tempResult);
17540+
17541+ getResultCapture().assertionEnded(result);
17542+
17543+ handleUnfinishedSections();
17544+
17545+ // Recreate section for test case (as we will lose the one that was in scope)
17546+ TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
17547+ SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
17548+
17549+ Counts assertions;
17550+ assertions.failed = 1;
17551+ SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false );
17552+ m_reporter->sectionEnded( testCaseSectionStats );
17553+
17554+ TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo();
17555+
17556+ Totals deltaTotals;
17557+ deltaTotals.testCases.failed = 1;
17558+ deltaTotals.assertions.failed = 1;
17559+ m_reporter->testCaseEnded( TestCaseStats( testInfo,
17560+ deltaTotals,
17561+ std::string(),
17562+ std::string(),
17563+ false ) );
17564+ m_totals.testCases.failed++;
17565+ testGroupEnded( std::string(), m_totals, 1, 1 );
17566+ m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) );
17567+ }
17568+
17569+ public:
17570+ // !TBD We need to do this another way!
17571+ bool aborting() const {
17572+ return m_totals.assertions.failed == static_cast<std::size_t>( m_config->abortAfter() );
17573+ }
17574+
17575+ private:
17576+
17577+ void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
17578+ TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
17579+ SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
17580+ m_reporter->sectionStarting( testCaseSection );
17581+ Counts prevAssertions = m_totals.assertions;
17582+ double duration = 0;
17583+ m_shouldReportUnexpected = true;
17584+ try {
17585+ m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
17586+
17587+ seedRng( *m_config );
17588+
17589+ Timer timer;
17590+ timer.start();
17591+ if( m_reporter->getPreferences().shouldRedirectStdOut ) {
17592+ StreamRedirect coutRedir( Catch::cout(), redirectedCout );
17593+ StdErrRedirect errRedir( redirectedCerr );
17594+ invokeActiveTestCase();
17595+ }
17596+ else {
17597+ invokeActiveTestCase();
17598+ }
17599+ duration = timer.getElapsedSeconds();
17600+ }
17601+ catch( TestFailureException& ) {
17602+ // This just means the test was aborted due to failure
17603+ }
17604+ catch(...) {
17605+ // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
17606+ // are reported without translation at the point of origin.
17607+ if (m_shouldReportUnexpected) {
17608+ makeUnexpectedResultBuilder().useActiveException();
17609+ }
17610+ }
17611+ m_testCaseTracker->close();
17612+ handleUnfinishedSections();
17613+ m_messages.clear();
17614+
17615+ Counts assertions = m_totals.assertions - prevAssertions;
17616+ bool missingAssertions = testForMissingAssertions( assertions );
17617+
17618+ SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );
17619+ m_reporter->sectionEnded( testCaseSectionStats );
17620+ }
17621+
17622+ void invokeActiveTestCase() {
17623+ FatalConditionHandler fatalConditionHandler; // Handle signals
17624+ m_activeTestCase->invoke();
17625+ fatalConditionHandler.reset();
17626+ }
17627+
17628+ private:
17629+
17630+ ResultBuilder makeUnexpectedResultBuilder() const {
17631+ return ResultBuilder( m_lastAssertionInfo.macroName,
17632+ m_lastAssertionInfo.lineInfo,
17633+ m_lastAssertionInfo.capturedExpression,
17634+ m_lastAssertionInfo.resultDisposition );
17635+ }
17636+
17637+ void handleUnfinishedSections() {
17638+ // If sections ended prematurely due to an exception we stored their
17639+ // infos here so we can tear them down outside the unwind process.
17640+ for( std::vector<SectionEndInfo>::const_reverse_iterator it = m_unfinishedSections.rbegin(),
17641+ itEnd = m_unfinishedSections.rend();
17642+ it != itEnd;
17643+ ++it )
17644+ sectionEnded( *it );
17645+ m_unfinishedSections.clear();
17646+ }
17647+
17648+ TestRunInfo m_runInfo;
17649+ IMutableContext& m_context;
17650+ TestCase const* m_activeTestCase;
17651+ ITracker* m_testCaseTracker;
17652+ ITracker* m_currentSectionTracker;
17653+ AssertionResult m_lastResult;
17654+
17655+ Ptr<IConfig const> m_config;
17656+ Totals m_totals;
17657+ Ptr<IStreamingReporter> m_reporter;
17658+ std::vector<MessageInfo> m_messages;
17659+ AssertionInfo m_lastAssertionInfo;
17660+ std::vector<SectionEndInfo> m_unfinishedSections;
17661+ std::vector<ITracker*> m_activeSections;
17662+ TrackerContext m_trackerContext;
17663+ size_t m_prevPassed;
17664+ bool m_shouldReportUnexpected;
17665+ };
17666+
17667+ IResultCapture& getResultCapture() {
17668+ if( IResultCapture* capture = getCurrentContext().getResultCapture() )
17669+ return *capture;
17670+ else
17671+ throw std::logic_error( "No result capture instance" );
17672+ }
17673+
17674+} // end namespace Catch
17675+
17676+// #included from: internal/catch_version.h
17677+#define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED
17678+
17679+namespace Catch {
17680+
17681+ // Versioning information
17682+ struct Version {
17683+ Version( unsigned int _majorVersion,
17684+ unsigned int _minorVersion,
17685+ unsigned int _patchNumber,
17686+ char const * const _branchName,
17687+ unsigned int _buildNumber );
17688+
17689+ unsigned int const majorVersion;
17690+ unsigned int const minorVersion;
17691+ unsigned int const patchNumber;
17692+
17693+ // buildNumber is only used if branchName is not null
17694+ char const * const branchName;
17695+ unsigned int const buildNumber;
17696+
17697+ friend std::ostream& operator << ( std::ostream& os, Version const& version );
17698+
17699+ private:
17700+ void operator=( Version const& );
17701+ };
17702+
17703+ inline Version libraryVersion();
17704+}
17705+
17706+#include <fstream>
17707+#include <stdlib.h>
17708+#include <limits>
17709+
17710+namespace Catch {
17711+
17712+ Ptr<IStreamingReporter> createReporter( std::string const& reporterName, Ptr<Config> const& config ) {
17713+ Ptr<IStreamingReporter> reporter = getRegistryHub().getReporterRegistry().create( reporterName, config.get() );
17714+ if( !reporter ) {
17715+ std::ostringstream oss;
17716+ oss << "No reporter registered with name: '" << reporterName << "'";
17717+ throw std::domain_error( oss.str() );
17718+ }
17719+ return reporter;
17720+ }
17721+
17722+#if !defined(CATCH_CONFIG_DEFAULT_REPORTER)
17723+#define CATCH_CONFIG_DEFAULT_REPORTER "console"
17724+#endif
17725+
17726+ Ptr<IStreamingReporter> makeReporter( Ptr<Config> const& config ) {
17727+ std::vector<std::string> reporters = config->getReporterNames();
17728+ if( reporters.empty() )
17729+ reporters.push_back( CATCH_CONFIG_DEFAULT_REPORTER );
17730+
17731+ Ptr<IStreamingReporter> reporter;
17732+ for( std::vector<std::string>::const_iterator it = reporters.begin(), itEnd = reporters.end();
17733+ it != itEnd;
17734+ ++it )
17735+ reporter = addReporter( reporter, createReporter( *it, config ) );
17736+ return reporter;
17737+ }
17738+ Ptr<IStreamingReporter> addListeners( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> reporters ) {
17739+ IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners();
17740+ for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end();
17741+ it != itEnd;
17742+ ++it )
17743+ reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) );
17744+ return reporters;
17745+ }
17746+
17747+ Totals runTests( Ptr<Config> const& config ) {
17748+
17749+ Ptr<IConfig const> iconfig = config.get();
17750+
17751+ Ptr<IStreamingReporter> reporter = makeReporter( config );
17752+ reporter = addListeners( iconfig, reporter );
17753+
17754+ RunContext context( iconfig, reporter );
17755+
17756+ Totals totals;
17757+
17758+ context.testGroupStarting( config->name(), 1, 1 );
17759+
17760+ TestSpec testSpec = config->testSpec();
17761+ if( !testSpec.hasFilters() )
17762+ testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests
17763+
17764+ std::vector<TestCase> const& allTestCases = getAllTestCasesSorted( *iconfig );
17765+ for( std::vector<TestCase>::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end();
17766+ it != itEnd;
17767+ ++it ) {
17768+ if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) )
17769+ totals += context.runTest( *it );
17770+ else
17771+ reporter->skipTest( *it );
17772+ }
17773+
17774+ context.testGroupEnded( iconfig->name(), totals, 1, 1 );
17775+ return totals;
17776+ }
17777+
17778+ void applyFilenamesAsTags( IConfig const& config ) {
17779+ std::vector<TestCase> const& tests = getAllTestCasesSorted( config );
17780+ for(std::size_t i = 0; i < tests.size(); ++i ) {
17781+ TestCase& test = const_cast<TestCase&>( tests[i] );
17782+ std::set<std::string> tags = test.tags;
17783+
17784+ std::string filename = test.lineInfo.file;
17785+ std::string::size_type lastSlash = filename.find_last_of( "\\/" );
17786+ if( lastSlash != std::string::npos )
17787+ filename = filename.substr( lastSlash+1 );
17788+
17789+ std::string::size_type lastDot = filename.find_last_of( '.' );
17790+ if( lastDot != std::string::npos )
17791+ filename = filename.substr( 0, lastDot );
17792+
17793+ tags.insert( '#' + filename );
17794+ setTags( test, tags );
17795+ }
17796+ }
17797+
17798+ class Session : NonCopyable {
17799+ static bool alreadyInstantiated;
17800+
17801+ public:
17802+
17803+ struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; };
17804+
17805+ Session()
17806+ : m_cli( makeCommandLineParser() ) {
17807+ if( alreadyInstantiated ) {
17808+ std::string msg = "Only one instance of Catch::Session can ever be used";
17809+ Catch::cerr() << msg << std::endl;
17810+ throw std::logic_error( msg );
17811+ }
17812+ alreadyInstantiated = true;
17813+ }
17814+ ~Session() {
17815+ Catch::cleanUp();
17816+ }
17817+
17818+ void showHelp( std::string const& processName ) {
17819+ Catch::cout() << "\nCatch v" << libraryVersion() << "\n";
17820+
17821+ m_cli.usage( Catch::cout(), processName );
17822+ Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
17823+ }
17824+ void libIdentify() {
17825+ Catch::cout()
17826+ << std::left << std::setw(16) << "description: " << "A Catch test executable\n"
17827+ << std::left << std::setw(16) << "category: " << "testframework\n"
17828+ << std::left << std::setw(16) << "framework: " << "Catch Test\n"
17829+ << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
17830+ }
17831+
17832+ int applyCommandLine( int argc, char const* const* const argv, OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
17833+ try {
17834+ m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
17835+ m_unusedTokens = m_cli.parseInto( Clara::argsToVector( argc, argv ), m_configData );
17836+ if( m_configData.showHelp )
17837+ showHelp( m_configData.processName );
17838+ if( m_configData.libIdentify )
17839+ libIdentify();
17840+ m_config.reset();
17841+ }
17842+ catch( std::exception& ex ) {
17843+ {
17844+ Colour colourGuard( Colour::Red );
17845+ Catch::cerr()
17846+ << "\nError(s) in input:\n"
17847+ << Text( ex.what(), TextAttributes().setIndent(2) )
17848+ << "\n\n";
17849+ }
17850+ m_cli.usage( Catch::cout(), m_configData.processName );
17851+ return (std::numeric_limits<int>::max)();
17852+ }
17853+ return 0;
17854+ }
17855+
17856+ void useConfigData( ConfigData const& _configData ) {
17857+ m_configData = _configData;
17858+ m_config.reset();
17859+ }
17860+
17861+ int run( int argc, char const* const* const argv ) {
17862+
17863+ int returnCode = applyCommandLine( argc, argv );
17864+ if( returnCode == 0 )
17865+ returnCode = run();
17866+ return returnCode;
17867+ }
17868+
17869+ #if defined(WIN32) && defined(UNICODE)
17870+ int run( int argc, wchar_t const* const* const argv ) {
17871+
17872+ char **utf8Argv = new char *[ argc ];
17873+
17874+ for ( int i = 0; i < argc; ++i ) {
17875+ int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL );
17876+
17877+ utf8Argv[ i ] = new char[ bufSize ];
17878+
17879+ WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL );
17880+ }
17881+
17882+ int returnCode = applyCommandLine( argc, utf8Argv );
17883+ if( returnCode == 0 )
17884+ returnCode = run();
17885+
17886+ for ( int i = 0; i < argc; ++i )
17887+ delete [] utf8Argv[ i ];
17888+
17889+ delete [] utf8Argv;
17890+
17891+ return returnCode;
17892+ }
17893+ #endif
17894+
17895+ int run() {
17896+ if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {
17897+ Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
17898+ static_cast<void>(std::getchar());
17899+ }
17900+ int exitCode = runInternal();
17901+ if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {
17902+ Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
17903+ static_cast<void>(std::getchar());
17904+ }
17905+ return exitCode;
17906+ }
17907+
17908+ Clara::CommandLine<ConfigData> const& cli() const {
17909+ return m_cli;
17910+ }
17911+ std::vector<Clara::Parser::Token> const& unusedTokens() const {
17912+ return m_unusedTokens;
17913+ }
17914+ ConfigData& configData() {
17915+ return m_configData;
17916+ }
17917+ Config& config() {
17918+ if( !m_config )
17919+ m_config = new Config( m_configData );
17920+ return *m_config;
17921+ }
17922+ private:
17923+
17924+ int runInternal() {
17925+ if( m_configData.showHelp || m_configData.libIdentify )
17926+ return 0;
17927+
17928+ try
17929+ {
17930+ config(); // Force config to be constructed
17931+
17932+ seedRng( *m_config );
17933+
17934+ if( m_configData.filenamesAsTags )
17935+ applyFilenamesAsTags( *m_config );
17936+
17937+ // Handle list request
17938+ if( Option<std::size_t> listed = list( config() ) )
17939+ return static_cast<int>( *listed );
17940+
17941+ return static_cast<int>( runTests( m_config ).assertions.failed );
17942+ }
17943+ catch( std::exception& ex ) {
17944+ Catch::cerr() << ex.what() << std::endl;
17945+ return (std::numeric_limits<int>::max)();
17946+ }
17947+ }
17948+
17949+ Clara::CommandLine<ConfigData> m_cli;
17950+ std::vector<Clara::Parser::Token> m_unusedTokens;
17951+ ConfigData m_configData;
17952+ Ptr<Config> m_config;
17953+ };
17954+
17955+ bool Session::alreadyInstantiated = false;
17956+
17957+} // end namespace Catch
17958+
17959+// #included from: catch_registry_hub.hpp
17960+#define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED
17961+
17962+// #included from: catch_test_case_registry_impl.hpp
17963+#define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
17964+
17965+#include <vector>
17966+#include <set>
17967+#include <sstream>
17968+#include <algorithm>
17969+
17970+namespace Catch {
17971+
17972+ struct RandomNumberGenerator {
17973+ typedef unsigned int result_type;
17974+
17975+ result_type operator()( result_type n ) const { return std::rand() % n; }
17976+
17977+#ifdef CATCH_CONFIG_CPP11_SHUFFLE
17978+ static constexpr result_type (min)() { return 0; }
17979+ static constexpr result_type (max)() { return 1000000; }
17980+ result_type operator()() const { return std::rand() % (max)(); }
17981+#endif
17982+ template<typename V>
17983+ static void shuffle( V& vector ) {
17984+ RandomNumberGenerator rng;
17985+#ifdef CATCH_CONFIG_CPP11_SHUFFLE
17986+ std::shuffle( vector.begin(), vector.end(), rng );
17987+#else
17988+ std::random_shuffle( vector.begin(), vector.end(), rng );
17989+#endif
17990+ }
17991+ };
17992+
17993+ inline std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
17994+
17995+ std::vector<TestCase> sorted = unsortedTestCases;
17996+
17997+ switch( config.runOrder() ) {
17998+ case RunTests::InLexicographicalOrder:
17999+ std::sort( sorted.begin(), sorted.end() );
18000+ break;
18001+ case RunTests::InRandomOrder:
18002+ {
18003+ seedRng( config );
18004+ RandomNumberGenerator::shuffle( sorted );
18005+ }
18006+ break;
18007+ case RunTests::InDeclarationOrder:
18008+ // already in declaration order
18009+ break;
18010+ }
18011+ return sorted;
18012+ }
18013+ bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
18014+ return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
18015+ }
18016+
18017+ void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
18018+ std::set<TestCase> seenFunctions;
18019+ for( std::vector<TestCase>::const_iterator it = functions.begin(), itEnd = functions.end();
18020+ it != itEnd;
18021+ ++it ) {
18022+ std::pair<std::set<TestCase>::const_iterator, bool> prev = seenFunctions.insert( *it );
18023+ if( !prev.second ) {
18024+ std::ostringstream ss;
18025+
18026+ ss << Colour( Colour::Red )
18027+ << "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n"
18028+ << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << '\n'
18029+ << "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl;
18030+
18031+ throw std::runtime_error(ss.str());
18032+ }
18033+ }
18034+ }
18035+
18036+ std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
18037+ std::vector<TestCase> filtered;
18038+ filtered.reserve( testCases.size() );
18039+ for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end();
18040+ it != itEnd;
18041+ ++it )
18042+ if( matchTest( *it, testSpec, config ) )
18043+ filtered.push_back( *it );
18044+ return filtered;
18045+ }
18046+ std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
18047+ return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
18048+ }
18049+
18050+ class TestRegistry : public ITestCaseRegistry {
18051+ public:
18052+ TestRegistry()
18053+ : m_currentSortOrder( RunTests::InDeclarationOrder ),
18054+ m_unnamedCount( 0 )
18055+ {}
18056+ virtual ~TestRegistry();
18057+
18058+ virtual void registerTest( TestCase const& testCase ) {
18059+ std::string name = testCase.getTestCaseInfo().name;
18060+ if( name.empty() ) {
18061+ std::ostringstream oss;
18062+ oss << "Anonymous test case " << ++m_unnamedCount;
18063+ return registerTest( testCase.withName( oss.str() ) );
18064+ }
18065+ m_functions.push_back( testCase );
18066+ }
18067+
18068+ virtual std::vector<TestCase> const& getAllTests() const {
18069+ return m_functions;
18070+ }
18071+ virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const {
18072+ if( m_sortedFunctions.empty() )
18073+ enforceNoDuplicateTestCases( m_functions );
18074+
18075+ if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
18076+ m_sortedFunctions = sortTests( config, m_functions );
18077+ m_currentSortOrder = config.runOrder();
18078+ }
18079+ return m_sortedFunctions;
18080+ }
18081+
18082+ private:
18083+ std::vector<TestCase> m_functions;
18084+ mutable RunTests::InWhatOrder m_currentSortOrder;
18085+ mutable std::vector<TestCase> m_sortedFunctions;
18086+ size_t m_unnamedCount;
18087+ std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
18088+ };
18089+
18090+ ///////////////////////////////////////////////////////////////////////////
18091+
18092+ class FreeFunctionTestCase : public SharedImpl<ITestCase> {
18093+ public:
18094+
18095+ FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}
18096+
18097+ virtual void invoke() const {
18098+ m_fun();
18099+ }
18100+
18101+ private:
18102+ virtual ~FreeFunctionTestCase();
18103+
18104+ TestFunction m_fun;
18105+ };
18106+
18107+ inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) {
18108+ std::string className = classOrQualifiedMethodName;
18109+ if( startsWith( className, '&' ) )
18110+ {
18111+ std::size_t lastColons = className.rfind( "::" );
18112+ std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
18113+ if( penultimateColons == std::string::npos )
18114+ penultimateColons = 1;
18115+ className = className.substr( penultimateColons, lastColons-penultimateColons );
18116+ }
18117+ return className;
18118+ }
18119+
18120+ void registerTestCase
18121+ ( ITestCase* testCase,
18122+ char const* classOrQualifiedMethodName,
18123+ NameAndDesc const& nameAndDesc,
18124+ SourceLineInfo const& lineInfo ) {
18125+
18126+ getMutableRegistryHub().registerTest
18127+ ( makeTestCase
18128+ ( testCase,
18129+ extractClassName( classOrQualifiedMethodName ),
18130+ nameAndDesc.name,
18131+ nameAndDesc.description,
18132+ lineInfo ) );
18133+ }
18134+ void registerTestCaseFunction
18135+ ( TestFunction function,
18136+ SourceLineInfo const& lineInfo,
18137+ NameAndDesc const& nameAndDesc ) {
18138+ registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
18139+ }
18140+
18141+ ///////////////////////////////////////////////////////////////////////////
18142+
18143+ AutoReg::AutoReg
18144+ ( TestFunction function,
18145+ SourceLineInfo const& lineInfo,
18146+ NameAndDesc const& nameAndDesc ) {
18147+ registerTestCaseFunction( function, lineInfo, nameAndDesc );
18148+ }
18149+
18150+ AutoReg::~AutoReg() {}
18151+
18152+} // end namespace Catch
18153+
18154+// #included from: catch_reporter_registry.hpp
18155+#define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED
18156+
18157+#include <map>
18158+
18159+namespace Catch {
18160+
18161+ class ReporterRegistry : public IReporterRegistry {
18162+
18163+ public:
18164+
18165+ virtual ~ReporterRegistry() CATCH_OVERRIDE {}
18166+
18167+ virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const CATCH_OVERRIDE {
18168+ FactoryMap::const_iterator it = m_factories.find( name );
18169+ if( it == m_factories.end() )
18170+ return CATCH_NULL;
18171+ return it->second->create( ReporterConfig( config ) );
18172+ }
18173+
18174+ void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) {
18175+ m_factories.insert( std::make_pair( name, factory ) );
18176+ }
18177+ void registerListener( Ptr<IReporterFactory> const& factory ) {
18178+ m_listeners.push_back( factory );
18179+ }
18180+
18181+ virtual FactoryMap const& getFactories() const CATCH_OVERRIDE {
18182+ return m_factories;
18183+ }
18184+ virtual Listeners const& getListeners() const CATCH_OVERRIDE {
18185+ return m_listeners;
18186+ }
18187+
18188+ private:
18189+ FactoryMap m_factories;
18190+ Listeners m_listeners;
18191+ };
18192+}
18193+
18194+// #included from: catch_exception_translator_registry.hpp
18195+#define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
18196+
18197+#ifdef __OBJC__
18198+#import "Foundation/Foundation.h"
18199+#endif
18200+
18201+namespace Catch {
18202+
18203+ class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
18204+ public:
18205+ ~ExceptionTranslatorRegistry() {
18206+ deleteAll( m_translators );
18207+ }
18208+
18209+ virtual void registerTranslator( const IExceptionTranslator* translator ) {
18210+ m_translators.push_back( translator );
18211+ }
18212+
18213+ virtual std::string translateActiveException() const {
18214+ try {
18215+#ifdef __OBJC__
18216+ // In Objective-C try objective-c exceptions first
18217+ @try {
18218+ return tryTranslators();
18219+ }
18220+ @catch (NSException *exception) {
18221+ return Catch::toString( [exception description] );
18222+ }
18223+#else
18224+ return tryTranslators();
18225+#endif
18226+ }
18227+ catch( TestFailureException& ) {
18228+ throw;
18229+ }
18230+ catch( std::exception& ex ) {
18231+ return ex.what();
18232+ }
18233+ catch( std::string& msg ) {
18234+ return msg;
18235+ }
18236+ catch( const char* msg ) {
18237+ return msg;
18238+ }
18239+ catch(...) {
18240+ return "Unknown exception";
18241+ }
18242+ }
18243+
18244+ std::string tryTranslators() const {
18245+ if( m_translators.empty() )
18246+ throw;
18247+ else
18248+ return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );
18249+ }
18250+
18251+ private:
18252+ std::vector<const IExceptionTranslator*> m_translators;
18253+ };
18254+}
18255+
18256+// #included from: catch_tag_alias_registry.h
18257+#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED
18258+
18259+#include <map>
18260+
18261+namespace Catch {
18262+
18263+ class TagAliasRegistry : public ITagAliasRegistry {
18264+ public:
18265+ virtual ~TagAliasRegistry();
18266+ virtual Option<TagAlias> find( std::string const& alias ) const;
18267+ virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const;
18268+ void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
18269+
18270+ private:
18271+ std::map<std::string, TagAlias> m_registry;
18272+ };
18273+
18274+} // end namespace Catch
18275+
18276+namespace Catch {
18277+
18278+ namespace {
18279+
18280+ class RegistryHub : public IRegistryHub, public IMutableRegistryHub {
18281+
18282+ RegistryHub( RegistryHub const& );
18283+ void operator=( RegistryHub const& );
18284+
18285+ public: // IRegistryHub
18286+ RegistryHub() {
18287+ }
18288+ virtual IReporterRegistry const& getReporterRegistry() const CATCH_OVERRIDE {
18289+ return m_reporterRegistry;
18290+ }
18291+ virtual ITestCaseRegistry const& getTestCaseRegistry() const CATCH_OVERRIDE {
18292+ return m_testCaseRegistry;
18293+ }
18294+ virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE {
18295+ return m_exceptionTranslatorRegistry;
18296+ }
18297+ virtual ITagAliasRegistry const& getTagAliasRegistry() const CATCH_OVERRIDE {
18298+ return m_tagAliasRegistry;
18299+ }
18300+
18301+ public: // IMutableRegistryHub
18302+ virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
18303+ m_reporterRegistry.registerReporter( name, factory );
18304+ }
18305+ virtual void registerListener( Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
18306+ m_reporterRegistry.registerListener( factory );
18307+ }
18308+ virtual void registerTest( TestCase const& testInfo ) CATCH_OVERRIDE {
18309+ m_testCaseRegistry.registerTest( testInfo );
18310+ }
18311+ virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE {
18312+ m_exceptionTranslatorRegistry.registerTranslator( translator );
18313+ }
18314+ virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) CATCH_OVERRIDE {
18315+ m_tagAliasRegistry.add( alias, tag, lineInfo );
18316+ }
18317+
18318+ private:
18319+ TestRegistry m_testCaseRegistry;
18320+ ReporterRegistry m_reporterRegistry;
18321+ ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
18322+ TagAliasRegistry m_tagAliasRegistry;
18323+ };
18324+
18325+ // Single, global, instance
18326+ inline RegistryHub*& getTheRegistryHub() {
18327+ static RegistryHub* theRegistryHub = CATCH_NULL;
18328+ if( !theRegistryHub )
18329+ theRegistryHub = new RegistryHub();
18330+ return theRegistryHub;
18331+ }
18332+ }
18333+
18334+ IRegistryHub& getRegistryHub() {
18335+ return *getTheRegistryHub();
18336+ }
18337+ IMutableRegistryHub& getMutableRegistryHub() {
18338+ return *getTheRegistryHub();
18339+ }
18340+ void cleanUp() {
18341+ delete getTheRegistryHub();
18342+ getTheRegistryHub() = CATCH_NULL;
18343+ cleanUpContext();
18344+ }
18345+ std::string translateActiveException() {
18346+ return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
18347+ }
18348+
18349+} // end namespace Catch
18350+
18351+// #included from: catch_notimplemented_exception.hpp
18352+#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED
18353+
18354+#include <sstream>
18355+
18356+namespace Catch {
18357+
18358+ NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo )
18359+ : m_lineInfo( lineInfo ) {
18360+ std::ostringstream oss;
18361+ oss << lineInfo << ": function ";
18362+ oss << "not implemented";
18363+ m_what = oss.str();
18364+ }
18365+
18366+ const char* NotImplementedException::what() const CATCH_NOEXCEPT {
18367+ return m_what.c_str();
18368+ }
18369+
18370+} // end namespace Catch
18371+
18372+// #included from: catch_context_impl.hpp
18373+#define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
18374+
18375+// #included from: catch_stream.hpp
18376+#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
18377+
18378+#include <stdexcept>
18379+#include <cstdio>
18380+#include <iostream>
18381+
18382+namespace Catch {
18383+
18384+ template<typename WriterF, size_t bufferSize=256>
18385+ class StreamBufImpl : public StreamBufBase {
18386+ char data[bufferSize];
18387+ WriterF m_writer;
18388+
18389+ public:
18390+ StreamBufImpl() {
18391+ setp( data, data + sizeof(data) );
18392+ }
18393+
18394+ ~StreamBufImpl() CATCH_NOEXCEPT {
18395+ sync();
18396+ }
18397+
18398+ private:
18399+ int overflow( int c ) {
18400+ sync();
18401+
18402+ if( c != EOF ) {
18403+ if( pbase() == epptr() )
18404+ m_writer( std::string( 1, static_cast<char>( c ) ) );
18405+ else
18406+ sputc( static_cast<char>( c ) );
18407+ }
18408+ return 0;
18409+ }
18410+
18411+ int sync() {
18412+ if( pbase() != pptr() ) {
18413+ m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
18414+ setp( pbase(), epptr() );
18415+ }
18416+ return 0;
18417+ }
18418+ };
18419+
18420+ ///////////////////////////////////////////////////////////////////////////
18421+
18422+ FileStream::FileStream( std::string const& filename ) {
18423+ m_ofs.open( filename.c_str() );
18424+ if( m_ofs.fail() ) {
18425+ std::ostringstream oss;
18426+ oss << "Unable to open file: '" << filename << '\'';
18427+ throw std::domain_error( oss.str() );
18428+ }
18429+ }
18430+
18431+ std::ostream& FileStream::stream() const {
18432+ return m_ofs;
18433+ }
18434+
18435+ struct OutputDebugWriter {
18436+
18437+ void operator()( std::string const&str ) {
18438+ writeToDebugConsole( str );
18439+ }
18440+ };
18441+
18442+ DebugOutStream::DebugOutStream()
18443+ : m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
18444+ m_os( m_streamBuf.get() )
18445+ {}
18446+
18447+ std::ostream& DebugOutStream::stream() const {
18448+ return m_os;
18449+ }
18450+
18451+ // Store the streambuf from cout up-front because
18452+ // cout may get redirected when running tests
18453+ CoutStream::CoutStream()
18454+ : m_os( Catch::cout().rdbuf() )
18455+ {}
18456+
18457+ std::ostream& CoutStream::stream() const {
18458+ return m_os;
18459+ }
18460+
18461+#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
18462+ std::ostream& cout() {
18463+ return std::cout;
18464+ }
18465+ std::ostream& cerr() {
18466+ return std::cerr;
18467+ }
18468+ std::ostream& clog() {
18469+ return std::clog;
18470+ }
18471+#endif
18472+}
18473+
18474+namespace Catch {
18475+
18476+ class Context : public IMutableContext {
18477+
18478+ Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {}
18479+ Context( Context const& );
18480+ void operator=( Context const& );
18481+
18482+ public:
18483+ virtual ~Context() {
18484+ deleteAllValues( m_generatorsByTestName );
18485+ }
18486+
18487+ public: // IContext
18488+ virtual IResultCapture* getResultCapture() {
18489+ return m_resultCapture;
18490+ }
18491+ virtual IRunner* getRunner() {
18492+ return m_runner;
18493+ }
18494+ virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) {
18495+ return getGeneratorsForCurrentTest()
18496+ .getGeneratorInfo( fileInfo, totalSize )
18497+ .getCurrentIndex();
18498+ }
18499+ virtual bool advanceGeneratorsForCurrentTest() {
18500+ IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
18501+ return generators && generators->moveNext();
18502+ }
18503+
18504+ virtual Ptr<IConfig const> getConfig() const {
18505+ return m_config;
18506+ }
18507+
18508+ public: // IMutableContext
18509+ virtual void setResultCapture( IResultCapture* resultCapture ) {
18510+ m_resultCapture = resultCapture;
18511+ }
18512+ virtual void setRunner( IRunner* runner ) {
18513+ m_runner = runner;
18514+ }
18515+ virtual void setConfig( Ptr<IConfig const> const& config ) {
18516+ m_config = config;
18517+ }
18518+
18519+ friend IMutableContext& getCurrentMutableContext();
18520+
18521+ private:
18522+ IGeneratorsForTest* findGeneratorsForCurrentTest() {
18523+ std::string testName = getResultCapture()->getCurrentTestName();
18524+
18525+ std::map<std::string, IGeneratorsForTest*>::const_iterator it =
18526+ m_generatorsByTestName.find( testName );
18527+ return it != m_generatorsByTestName.end()
18528+ ? it->second
18529+ : CATCH_NULL;
18530+ }
18531+
18532+ IGeneratorsForTest& getGeneratorsForCurrentTest() {
18533+ IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
18534+ if( !generators ) {
18535+ std::string testName = getResultCapture()->getCurrentTestName();
18536+ generators = createGeneratorsForTest();
18537+ m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
18538+ }
18539+ return *generators;
18540+ }
18541+
18542+ private:
18543+ Ptr<IConfig const> m_config;
18544+ IRunner* m_runner;
18545+ IResultCapture* m_resultCapture;
18546+ std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
18547+ };
18548+
18549+ namespace {
18550+ Context* currentContext = CATCH_NULL;
18551+ }
18552+ IMutableContext& getCurrentMutableContext() {
18553+ if( !currentContext )
18554+ currentContext = new Context();
18555+ return *currentContext;
18556+ }
18557+ IContext& getCurrentContext() {
18558+ return getCurrentMutableContext();
18559+ }
18560+
18561+ void cleanUpContext() {
18562+ delete currentContext;
18563+ currentContext = CATCH_NULL;
18564+ }
18565+}
18566+
18567+// #included from: catch_console_colour_impl.hpp
18568+#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
18569+
18570+// #included from: catch_errno_guard.hpp
18571+#define TWOBLUECUBES_CATCH_ERRNO_GUARD_HPP_INCLUDED
18572+
18573+#include <cerrno>
18574+
18575+namespace Catch {
18576+
18577+ class ErrnoGuard {
18578+ public:
18579+ ErrnoGuard():m_oldErrno(errno){}
18580+ ~ErrnoGuard() { errno = m_oldErrno; }
18581+ private:
18582+ int m_oldErrno;
18583+ };
18584+
18585+}
18586+
18587+namespace Catch {
18588+ namespace {
18589+
18590+ struct IColourImpl {
18591+ virtual ~IColourImpl() {}
18592+ virtual void use( Colour::Code _colourCode ) = 0;
18593+ };
18594+
18595+ struct NoColourImpl : IColourImpl {
18596+ void use( Colour::Code ) {}
18597+
18598+ static IColourImpl* instance() {
18599+ static NoColourImpl s_instance;
18600+ return &s_instance;
18601+ }
18602+ };
18603+
18604+ } // anon namespace
18605+} // namespace Catch
18606+
18607+#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
18608+# ifdef CATCH_PLATFORM_WINDOWS
18609+# define CATCH_CONFIG_COLOUR_WINDOWS
18610+# else
18611+# define CATCH_CONFIG_COLOUR_ANSI
18612+# endif
18613+#endif
18614+
18615+#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
18616+
18617+namespace Catch {
18618+namespace {
18619+
18620+ class Win32ColourImpl : public IColourImpl {
18621+ public:
18622+ Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
18623+ {
18624+ CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
18625+ GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
18626+ originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
18627+ originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
18628+ }
18629+
18630+ virtual void use( Colour::Code _colourCode ) {
18631+ switch( _colourCode ) {
18632+ case Colour::None: return setTextAttribute( originalForegroundAttributes );
18633+ case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
18634+ case Colour::Red: return setTextAttribute( FOREGROUND_RED );
18635+ case Colour::Green: return setTextAttribute( FOREGROUND_GREEN );
18636+ case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE );
18637+ case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
18638+ case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
18639+ case Colour::Grey: return setTextAttribute( 0 );
18640+
18641+ case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY );
18642+ case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
18643+ case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
18644+ case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
18645+
18646+ case Colour::Bright: throw std::logic_error( "not a colour" );
18647+ }
18648+ }
18649+
18650+ private:
18651+ void setTextAttribute( WORD _textAttribute ) {
18652+ SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
18653+ }
18654+ HANDLE stdoutHandle;
18655+ WORD originalForegroundAttributes;
18656+ WORD originalBackgroundAttributes;
18657+ };
18658+
18659+ IColourImpl* platformColourInstance() {
18660+ static Win32ColourImpl s_instance;
18661+
18662+ Ptr<IConfig const> config = getCurrentContext().getConfig();
18663+ UseColour::YesOrNo colourMode = config
18664+ ? config->useColour()
18665+ : UseColour::Auto;
18666+ if( colourMode == UseColour::Auto )
18667+ colourMode = !isDebuggerActive()
18668+ ? UseColour::Yes
18669+ : UseColour::No;
18670+ return colourMode == UseColour::Yes
18671+ ? &s_instance
18672+ : NoColourImpl::instance();
18673+ }
18674+
18675+} // end anon namespace
18676+} // end namespace Catch
18677+
18678+#elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
18679+
18680+#include <unistd.h>
18681+
18682+namespace Catch {
18683+namespace {
18684+
18685+ // use POSIX/ ANSI console terminal codes
18686+ // Thanks to Adam Strzelecki for original contribution
18687+ // (http://github.com/nanoant)
18688+ // https://github.com/philsquared/Catch/pull/131
18689+ class PosixColourImpl : public IColourImpl {
18690+ public:
18691+ virtual void use( Colour::Code _colourCode ) {
18692+ switch( _colourCode ) {
18693+ case Colour::None:
18694+ case Colour::White: return setColour( "[0m" );
18695+ case Colour::Red: return setColour( "[0;31m" );
18696+ case Colour::Green: return setColour( "[0;32m" );
18697+ case Colour::Blue: return setColour( "[0;34m" );
18698+ case Colour::Cyan: return setColour( "[0;36m" );
18699+ case Colour::Yellow: return setColour( "[0;33m" );
18700+ case Colour::Grey: return setColour( "[1;30m" );
18701+
18702+ case Colour::LightGrey: return setColour( "[0;37m" );
18703+ case Colour::BrightRed: return setColour( "[1;31m" );
18704+ case Colour::BrightGreen: return setColour( "[1;32m" );
18705+ case Colour::BrightWhite: return setColour( "[1;37m" );
18706+
18707+ case Colour::Bright: throw std::logic_error( "not a colour" );
18708+ }
18709+ }
18710+ static IColourImpl* instance() {
18711+ static PosixColourImpl s_instance;
18712+ return &s_instance;
18713+ }
18714+
18715+ private:
18716+ void setColour( const char* _escapeCode ) {
18717+ Catch::cout() << '\033' << _escapeCode;
18718+ }
18719+ };
18720+
18721+ IColourImpl* platformColourInstance() {
18722+ ErrnoGuard guard;
18723+ Ptr<IConfig const> config = getCurrentContext().getConfig();
18724+ UseColour::YesOrNo colourMode = config
18725+ ? config->useColour()
18726+ : UseColour::Auto;
18727+ if( colourMode == UseColour::Auto )
18728+ colourMode = (!isDebuggerActive() && isatty(STDOUT_FILENO) )
18729+ ? UseColour::Yes
18730+ : UseColour::No;
18731+ return colourMode == UseColour::Yes
18732+ ? PosixColourImpl::instance()
18733+ : NoColourImpl::instance();
18734+ }
18735+
18736+} // end anon namespace
18737+} // end namespace Catch
18738+
18739+#else // not Windows or ANSI ///////////////////////////////////////////////
18740+
18741+namespace Catch {
18742+
18743+ static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
18744+
18745+} // end namespace Catch
18746+
18747+#endif // Windows/ ANSI/ None
18748+
18749+namespace Catch {
18750+
18751+ Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); }
18752+ Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast<Colour&>( _other ).m_moved = true; }
18753+ Colour::~Colour(){ if( !m_moved ) use( None ); }
18754+
18755+ void Colour::use( Code _colourCode ) {
18756+ static IColourImpl* impl = platformColourInstance();
18757+ impl->use( _colourCode );
18758+ }
18759+
18760+} // end namespace Catch
18761+
18762+// #included from: catch_generators_impl.hpp
18763+#define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED
18764+
18765+#include <vector>
18766+#include <string>
18767+#include <map>
18768+
18769+namespace Catch {
18770+
18771+ struct GeneratorInfo : IGeneratorInfo {
18772+
18773+ GeneratorInfo( std::size_t size )
18774+ : m_size( size ),
18775+ m_currentIndex( 0 )
18776+ {}
18777+
18778+ bool moveNext() {
18779+ if( ++m_currentIndex == m_size ) {
18780+ m_currentIndex = 0;
18781+ return false;
18782+ }
18783+ return true;
18784+ }
18785+
18786+ std::size_t getCurrentIndex() const {
18787+ return m_currentIndex;
18788+ }
18789+
18790+ std::size_t m_size;
18791+ std::size_t m_currentIndex;
18792+ };
18793+
18794+ ///////////////////////////////////////////////////////////////////////////
18795+
18796+ class GeneratorsForTest : public IGeneratorsForTest {
18797+
18798+ public:
18799+ ~GeneratorsForTest() {
18800+ deleteAll( m_generatorsInOrder );
18801+ }
18802+
18803+ IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) {
18804+ std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );
18805+ if( it == m_generatorsByName.end() ) {
18806+ IGeneratorInfo* info = new GeneratorInfo( size );
18807+ m_generatorsByName.insert( std::make_pair( fileInfo, info ) );
18808+ m_generatorsInOrder.push_back( info );
18809+ return *info;
18810+ }
18811+ return *it->second;
18812+ }
18813+
18814+ bool moveNext() {
18815+ std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
18816+ std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();
18817+ for(; it != itEnd; ++it ) {
18818+ if( (*it)->moveNext() )
18819+ return true;
18820+ }
18821+ return false;
18822+ }
18823+
18824+ private:
18825+ std::map<std::string, IGeneratorInfo*> m_generatorsByName;
18826+ std::vector<IGeneratorInfo*> m_generatorsInOrder;
18827+ };
18828+
18829+ IGeneratorsForTest* createGeneratorsForTest()
18830+ {
18831+ return new GeneratorsForTest();
18832+ }
18833+
18834+} // end namespace Catch
18835+
18836+// #included from: catch_assertionresult.hpp
18837+#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED
18838+
18839+namespace Catch {
18840+
18841+ AssertionInfo::AssertionInfo():macroName(""), capturedExpression(""), resultDisposition(ResultDisposition::Normal), secondArg(""){}
18842+
18843+ AssertionInfo::AssertionInfo( char const * _macroName,
18844+ SourceLineInfo const& _lineInfo,
18845+ char const * _capturedExpression,
18846+ ResultDisposition::Flags _resultDisposition,
18847+ char const * _secondArg)
18848+ : macroName( _macroName ),
18849+ lineInfo( _lineInfo ),
18850+ capturedExpression( _capturedExpression ),
18851+ resultDisposition( _resultDisposition ),
18852+ secondArg( _secondArg )
18853+ {}
18854+
18855+ AssertionResult::AssertionResult() {}
18856+
18857+ AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
18858+ : m_info( info ),
18859+ m_resultData( data )
18860+ {}
18861+
18862+ AssertionResult::~AssertionResult() {}
18863+
18864+ // Result was a success
18865+ bool AssertionResult::succeeded() const {
18866+ return Catch::isOk( m_resultData.resultType );
18867+ }
18868+
18869+ // Result was a success, or failure is suppressed
18870+ bool AssertionResult::isOk() const {
18871+ return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
18872+ }
18873+
18874+ ResultWas::OfType AssertionResult::getResultType() const {
18875+ return m_resultData.resultType;
18876+ }
18877+
18878+ bool AssertionResult::hasExpression() const {
18879+ return m_info.capturedExpression[0] != 0;
18880+ }
18881+
18882+ bool AssertionResult::hasMessage() const {
18883+ return !m_resultData.message.empty();
18884+ }
18885+
18886+ std::string capturedExpressionWithSecondArgument( char const * capturedExpression, char const * secondArg ) {
18887+ return (secondArg[0] == 0 || secondArg[0] == '"' && secondArg[1] == '"')
18888+ ? capturedExpression
18889+ : std::string(capturedExpression) + ", " + secondArg;
18890+ }
18891+
18892+ std::string AssertionResult::getExpression() const {
18893+ if( isFalseTest( m_info.resultDisposition ) )
18894+ return "!(" + capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg) + ")";
18895+ else
18896+ return capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg);
18897+ }
18898+ std::string AssertionResult::getExpressionInMacro() const {
18899+ if( m_info.macroName[0] == 0 )
18900+ return capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg);
18901+ else
18902+ return std::string(m_info.macroName) + "( " + capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg) + " )";
18903+ }
18904+
18905+ bool AssertionResult::hasExpandedExpression() const {
18906+ return hasExpression() && getExpandedExpression() != getExpression();
18907+ }
18908+
18909+ std::string AssertionResult::getExpandedExpression() const {
18910+ return m_resultData.reconstructExpression();
18911+ }
18912+
18913+ std::string AssertionResult::getMessage() const {
18914+ return m_resultData.message;
18915+ }
18916+ SourceLineInfo AssertionResult::getSourceInfo() const {
18917+ return m_info.lineInfo;
18918+ }
18919+
18920+ std::string AssertionResult::getTestMacroName() const {
18921+ return m_info.macroName;
18922+ }
18923+
18924+ void AssertionResult::discardDecomposedExpression() const {
18925+ m_resultData.decomposedExpression = CATCH_NULL;
18926+ }
18927+
18928+ void AssertionResult::expandDecomposedExpression() const {
18929+ m_resultData.reconstructExpression();
18930+ }
18931+
18932+} // end namespace Catch
18933+
18934+// #included from: catch_test_case_info.hpp
18935+#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED
18936+
18937+#include <cctype>
18938+
18939+namespace Catch {
18940+
18941+ inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
18942+ if( startsWith( tag, '.' ) ||
18943+ tag == "hide" ||
18944+ tag == "!hide" )
18945+ return TestCaseInfo::IsHidden;
18946+ else if( tag == "!throws" )
18947+ return TestCaseInfo::Throws;
18948+ else if( tag == "!shouldfail" )
18949+ return TestCaseInfo::ShouldFail;
18950+ else if( tag == "!mayfail" )
18951+ return TestCaseInfo::MayFail;
18952+ else if( tag == "!nonportable" )
18953+ return TestCaseInfo::NonPortable;
18954+ else
18955+ return TestCaseInfo::None;
18956+ }
18957+ inline bool isReservedTag( std::string const& tag ) {
18958+ return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( tag[0] );
18959+ }
18960+ inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
18961+ if( isReservedTag( tag ) ) {
18962+ std::ostringstream ss;
18963+ ss << Colour(Colour::Red)
18964+ << "Tag name [" << tag << "] not allowed.\n"
18965+ << "Tag names starting with non alpha-numeric characters are reserved\n"
18966+ << Colour(Colour::FileName)
18967+ << _lineInfo << '\n';
18968+ throw std::runtime_error(ss.str());
18969+ }
18970+ }
18971+
18972+ TestCase makeTestCase( ITestCase* _testCase,
18973+ std::string const& _className,
18974+ std::string const& _name,
18975+ std::string const& _descOrTags,
18976+ SourceLineInfo const& _lineInfo )
18977+ {
18978+ bool isHidden( startsWith( _name, "./" ) ); // Legacy support
18979+
18980+ // Parse out tags
18981+ std::set<std::string> tags;
18982+ std::string desc, tag;
18983+ bool inTag = false;
18984+ for( std::size_t i = 0; i < _descOrTags.size(); ++i ) {
18985+ char c = _descOrTags[i];
18986+ if( !inTag ) {
18987+ if( c == '[' )
18988+ inTag = true;
18989+ else
18990+ desc += c;
18991+ }
18992+ else {
18993+ if( c == ']' ) {
18994+ TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
18995+ if( prop == TestCaseInfo::IsHidden )
18996+ isHidden = true;
18997+ else if( prop == TestCaseInfo::None )
18998+ enforceNotReservedTag( tag, _lineInfo );
18999+
19000+ tags.insert( tag );
19001+ tag.clear();
19002+ inTag = false;
19003+ }
19004+ else
19005+ tag += c;
19006+ }
19007+ }
19008+ if( isHidden ) {
19009+ tags.insert( "hide" );
19010+ tags.insert( "." );
19011+ }
19012+
19013+ TestCaseInfo info( _name, _className, desc, tags, _lineInfo );
19014+ return TestCase( _testCase, info );
19015+ }
19016+
19017+ void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags )
19018+ {
19019+ testCaseInfo.tags = tags;
19020+ testCaseInfo.lcaseTags.clear();
19021+
19022+ std::ostringstream oss;
19023+ for( std::set<std::string>::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) {
19024+ oss << '[' << *it << ']';
19025+ std::string lcaseTag = toLower( *it );
19026+ testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
19027+ testCaseInfo.lcaseTags.insert( lcaseTag );
19028+ }
19029+ testCaseInfo.tagsAsString = oss.str();
19030+ }
19031+
19032+ TestCaseInfo::TestCaseInfo( std::string const& _name,
19033+ std::string const& _className,
19034+ std::string const& _description,
19035+ std::set<std::string> const& _tags,
19036+ SourceLineInfo const& _lineInfo )
19037+ : name( _name ),
19038+ className( _className ),
19039+ description( _description ),
19040+ lineInfo( _lineInfo ),
19041+ properties( None )
19042+ {
19043+ setTags( *this, _tags );
19044+ }
19045+
19046+ TestCaseInfo::TestCaseInfo( TestCaseInfo const& other )
19047+ : name( other.name ),
19048+ className( other.className ),
19049+ description( other.description ),
19050+ tags( other.tags ),
19051+ lcaseTags( other.lcaseTags ),
19052+ tagsAsString( other.tagsAsString ),
19053+ lineInfo( other.lineInfo ),
19054+ properties( other.properties )
19055+ {}
19056+
19057+ bool TestCaseInfo::isHidden() const {
19058+ return ( properties & IsHidden ) != 0;
19059+ }
19060+ bool TestCaseInfo::throws() const {
19061+ return ( properties & Throws ) != 0;
19062+ }
19063+ bool TestCaseInfo::okToFail() const {
19064+ return ( properties & (ShouldFail | MayFail ) ) != 0;
19065+ }
19066+ bool TestCaseInfo::expectedToFail() const {
19067+ return ( properties & (ShouldFail ) ) != 0;
19068+ }
19069+
19070+ TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}
19071+
19072+ TestCase::TestCase( TestCase const& other )
19073+ : TestCaseInfo( other ),
19074+ test( other.test )
19075+ {}
19076+
19077+ TestCase TestCase::withName( std::string const& _newName ) const {
19078+ TestCase other( *this );
19079+ other.name = _newName;
19080+ return other;
19081+ }
19082+
19083+ void TestCase::swap( TestCase& other ) {
19084+ test.swap( other.test );
19085+ name.swap( other.name );
19086+ className.swap( other.className );
19087+ description.swap( other.description );
19088+ tags.swap( other.tags );
19089+ lcaseTags.swap( other.lcaseTags );
19090+ tagsAsString.swap( other.tagsAsString );
19091+ std::swap( TestCaseInfo::properties, static_cast<TestCaseInfo&>( other ).properties );
19092+ std::swap( lineInfo, other.lineInfo );
19093+ }
19094+
19095+ void TestCase::invoke() const {
19096+ test->invoke();
19097+ }
19098+
19099+ bool TestCase::operator == ( TestCase const& other ) const {
19100+ return test.get() == other.test.get() &&
19101+ name == other.name &&
19102+ className == other.className;
19103+ }
19104+
19105+ bool TestCase::operator < ( TestCase const& other ) const {
19106+ return name < other.name;
19107+ }
19108+ TestCase& TestCase::operator = ( TestCase const& other ) {
19109+ TestCase temp( other );
19110+ swap( temp );
19111+ return *this;
19112+ }
19113+
19114+ TestCaseInfo const& TestCase::getTestCaseInfo() const
19115+ {
19116+ return *this;
19117+ }
19118+
19119+} // end namespace Catch
19120+
19121+// #included from: catch_version.hpp
19122+#define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED
19123+
19124+namespace Catch {
19125+
19126+ Version::Version
19127+ ( unsigned int _majorVersion,
19128+ unsigned int _minorVersion,
19129+ unsigned int _patchNumber,
19130+ char const * const _branchName,
19131+ unsigned int _buildNumber )
19132+ : majorVersion( _majorVersion ),
19133+ minorVersion( _minorVersion ),
19134+ patchNumber( _patchNumber ),
19135+ branchName( _branchName ),
19136+ buildNumber( _buildNumber )
19137+ {}
19138+
19139+ std::ostream& operator << ( std::ostream& os, Version const& version ) {
19140+ os << version.majorVersion << '.'
19141+ << version.minorVersion << '.'
19142+ << version.patchNumber;
19143+ // branchName is never null -> 0th char is \0 if it is empty
19144+ if (version.branchName[0]) {
19145+ os << '-' << version.branchName
19146+ << '.' << version.buildNumber;
19147+ }
19148+ return os;
19149+ }
19150+
19151+ inline Version libraryVersion() {
19152+ static Version version( 1, 12, 2, "", 0 );
19153+ return version;
19154+ }
19155+
19156+}
19157+
19158+// #included from: catch_message.hpp
19159+#define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED
19160+
19161+namespace Catch {
19162+
19163+ MessageInfo::MessageInfo( std::string const& _macroName,
19164+ SourceLineInfo const& _lineInfo,
19165+ ResultWas::OfType _type )
19166+ : macroName( _macroName ),
19167+ lineInfo( _lineInfo ),
19168+ type( _type ),
19169+ sequence( ++globalCount )
19170+ {}
19171+
19172+ // This may need protecting if threading support is added
19173+ unsigned int MessageInfo::globalCount = 0;
19174+
19175+ ////////////////////////////////////////////////////////////////////////////
19176+
19177+ ScopedMessage::ScopedMessage( MessageBuilder const& builder )
19178+ : m_info( builder.m_info )
19179+ {
19180+ m_info.message = builder.m_stream.str();
19181+ getResultCapture().pushScopedMessage( m_info );
19182+ }
19183+ ScopedMessage::ScopedMessage( ScopedMessage const& other )
19184+ : m_info( other.m_info )
19185+ {}
19186+
19187+#if defined(_MSC_VER)
19188+#pragma warning(push)
19189+#pragma warning(disable:4996) // std::uncaught_exception is deprecated in C++17
19190+#endif
19191+ ScopedMessage::~ScopedMessage() {
19192+ if ( !std::uncaught_exception() ){
19193+ getResultCapture().popScopedMessage(m_info);
19194+ }
19195+ }
19196+#if defined(_MSC_VER)
19197+#pragma warning(pop)
19198+#endif
19199+
19200+} // end namespace Catch
19201+
19202+// #included from: catch_legacy_reporter_adapter.hpp
19203+#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED
19204+
19205+// #included from: catch_legacy_reporter_adapter.h
19206+#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED
19207+
19208+namespace Catch
19209+{
19210+ // Deprecated
19211+ struct IReporter : IShared {
19212+ virtual ~IReporter();
19213+
19214+ virtual bool shouldRedirectStdout() const = 0;
19215+
19216+ virtual void StartTesting() = 0;
19217+ virtual void EndTesting( Totals const& totals ) = 0;
19218+ virtual void StartGroup( std::string const& groupName ) = 0;
19219+ virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0;
19220+ virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0;
19221+ virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0;
19222+ virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0;
19223+ virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0;
19224+ virtual void NoAssertionsInSection( std::string const& sectionName ) = 0;
19225+ virtual void NoAssertionsInTestCase( std::string const& testName ) = 0;
19226+ virtual void Aborted() = 0;
19227+ virtual void Result( AssertionResult const& result ) = 0;
19228+ };
19229+
19230+ class LegacyReporterAdapter : public SharedImpl<IStreamingReporter>
19231+ {
19232+ public:
19233+ LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter );
19234+ virtual ~LegacyReporterAdapter();
19235+
19236+ virtual ReporterPreferences getPreferences() const;
19237+ virtual void noMatchingTestCases( std::string const& );
19238+ virtual void testRunStarting( TestRunInfo const& );
19239+ virtual void testGroupStarting( GroupInfo const& groupInfo );
19240+ virtual void testCaseStarting( TestCaseInfo const& testInfo );
19241+ virtual void sectionStarting( SectionInfo const& sectionInfo );
19242+ virtual void assertionStarting( AssertionInfo const& );
19243+ virtual bool assertionEnded( AssertionStats const& assertionStats );
19244+ virtual void sectionEnded( SectionStats const& sectionStats );
19245+ virtual void testCaseEnded( TestCaseStats const& testCaseStats );
19246+ virtual void testGroupEnded( TestGroupStats const& testGroupStats );
19247+ virtual void testRunEnded( TestRunStats const& testRunStats );
19248+ virtual void skipTest( TestCaseInfo const& );
19249+
19250+ private:
19251+ Ptr<IReporter> m_legacyReporter;
19252+ };
19253+}
19254+
19255+namespace Catch
19256+{
19257+ LegacyReporterAdapter::LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter )
19258+ : m_legacyReporter( legacyReporter )
19259+ {}
19260+ LegacyReporterAdapter::~LegacyReporterAdapter() {}
19261+
19262+ ReporterPreferences LegacyReporterAdapter::getPreferences() const {
19263+ ReporterPreferences prefs;
19264+ prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout();
19265+ return prefs;
19266+ }
19267+
19268+ void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {}
19269+ void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) {
19270+ m_legacyReporter->StartTesting();
19271+ }
19272+ void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) {
19273+ m_legacyReporter->StartGroup( groupInfo.name );
19274+ }
19275+ void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) {
19276+ m_legacyReporter->StartTestCase( testInfo );
19277+ }
19278+ void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) {
19279+ m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description );
19280+ }
19281+ void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) {
19282+ // Not on legacy interface
19283+ }
19284+
19285+ bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) {
19286+ if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
19287+ for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
19288+ it != itEnd;
19289+ ++it ) {
19290+ if( it->type == ResultWas::Info ) {
19291+ ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal );
19292+ rb << it->message;
19293+ rb.setResultType( ResultWas::Info );
19294+ AssertionResult result = rb.build();
19295+ m_legacyReporter->Result( result );
19296+ }
19297+ }
19298+ }
19299+ m_legacyReporter->Result( assertionStats.assertionResult );
19300+ return true;
19301+ }
19302+ void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) {
19303+ if( sectionStats.missingAssertions )
19304+ m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name );
19305+ m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions );
19306+ }
19307+ void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) {
19308+ m_legacyReporter->EndTestCase
19309+ ( testCaseStats.testInfo,
19310+ testCaseStats.totals,
19311+ testCaseStats.stdOut,
19312+ testCaseStats.stdErr );
19313+ }
19314+ void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) {
19315+ if( testGroupStats.aborting )
19316+ m_legacyReporter->Aborted();
19317+ m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals );
19318+ }
19319+ void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) {
19320+ m_legacyReporter->EndTesting( testRunStats.totals );
19321+ }
19322+ void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) {
19323+ }
19324+}
19325+
19326+// #included from: catch_timer.hpp
19327+
19328+#ifdef __clang__
19329+#pragma clang diagnostic push
19330+#pragma clang diagnostic ignored "-Wc++11-long-long"
19331+#endif
19332+
19333+#ifdef CATCH_PLATFORM_WINDOWS
19334+
19335+#else
19336+
19337+#include <sys/time.h>
19338+
19339+#endif
19340+
19341+namespace Catch {
19342+
19343+ namespace {
19344+#ifdef CATCH_PLATFORM_WINDOWS
19345+ UInt64 getCurrentTicks() {
19346+ static UInt64 hz=0, hzo=0;
19347+ if (!hz) {
19348+ QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>( &hz ) );
19349+ QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &hzo ) );
19350+ }
19351+ UInt64 t;
19352+ QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &t ) );
19353+ return ((t-hzo)*1000000)/hz;
19354+ }
19355+#else
19356+ UInt64 getCurrentTicks() {
19357+ timeval t;
19358+ gettimeofday(&t,CATCH_NULL);
19359+ return static_cast<UInt64>( t.tv_sec ) * 1000000ull + static_cast<UInt64>( t.tv_usec );
19360+ }
19361+#endif
19362+ }
19363+
19364+ void Timer::start() {
19365+ m_ticks = getCurrentTicks();
19366+ }
19367+ unsigned int Timer::getElapsedMicroseconds() const {
19368+ return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
19369+ }
19370+ unsigned int Timer::getElapsedMilliseconds() const {
19371+ return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
19372+ }
19373+ double Timer::getElapsedSeconds() const {
19374+ return getElapsedMicroseconds()/1000000.0;
19375+ }
19376+
19377+} // namespace Catch
19378+
19379+#ifdef __clang__
19380+#pragma clang diagnostic pop
19381+#endif
19382+// #included from: catch_common.hpp
19383+#define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED
19384+
19385+#include <cstring>
19386+#include <cctype>
19387+
19388+namespace Catch {
19389+
19390+ bool startsWith( std::string const& s, std::string const& prefix ) {
19391+ return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
19392+ }
19393+ bool startsWith( std::string const& s, char prefix ) {
19394+ return !s.empty() && s[0] == prefix;
19395+ }
19396+ bool endsWith( std::string const& s, std::string const& suffix ) {
19397+ return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
19398+ }
19399+ bool endsWith( std::string const& s, char suffix ) {
19400+ return !s.empty() && s[s.size()-1] == suffix;
19401+ }
19402+ bool contains( std::string const& s, std::string const& infix ) {
19403+ return s.find( infix ) != std::string::npos;
19404+ }
19405+ char toLowerCh(char c) {
19406+ return static_cast<char>( std::tolower( c ) );
19407+ }
19408+ void toLowerInPlace( std::string& s ) {
19409+ std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
19410+ }
19411+ std::string toLower( std::string const& s ) {
19412+ std::string lc = s;
19413+ toLowerInPlace( lc );
19414+ return lc;
19415+ }
19416+ std::string trim( std::string const& str ) {
19417+ static char const* whitespaceChars = "\n\r\t ";
19418+ std::string::size_type start = str.find_first_not_of( whitespaceChars );
19419+ std::string::size_type end = str.find_last_not_of( whitespaceChars );
19420+
19421+ return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
19422+ }
19423+
19424+ bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
19425+ bool replaced = false;
19426+ std::size_t i = str.find( replaceThis );
19427+ while( i != std::string::npos ) {
19428+ replaced = true;
19429+ str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
19430+ if( i < str.size()-withThis.size() )
19431+ i = str.find( replaceThis, i+withThis.size() );
19432+ else
19433+ i = std::string::npos;
19434+ }
19435+ return replaced;
19436+ }
19437+
19438+ pluralise::pluralise( std::size_t count, std::string const& label )
19439+ : m_count( count ),
19440+ m_label( label )
19441+ {}
19442+
19443+ std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
19444+ os << pluraliser.m_count << ' ' << pluraliser.m_label;
19445+ if( pluraliser.m_count != 1 )
19446+ os << 's';
19447+ return os;
19448+ }
19449+
19450+ SourceLineInfo::SourceLineInfo() : file(""), line( 0 ){}
19451+ SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )
19452+ : file( _file ),
19453+ line( _line )
19454+ {}
19455+ bool SourceLineInfo::empty() const {
19456+ return file[0] == '\0';
19457+ }
19458+ bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {
19459+ return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
19460+ }
19461+ bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const {
19462+ return line < other.line || ( line == other.line && (std::strcmp(file, other.file) < 0));
19463+ }
19464+
19465+ void seedRng( IConfig const& config ) {
19466+ if( config.rngSeed() != 0 )
19467+ std::srand( config.rngSeed() );
19468+ }
19469+ unsigned int rngSeed() {
19470+ return getCurrentContext().getConfig()->rngSeed();
19471+ }
19472+
19473+ std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
19474+#ifndef __GNUG__
19475+ os << info.file << '(' << info.line << ')';
19476+#else
19477+ os << info.file << ':' << info.line;
19478+#endif
19479+ return os;
19480+ }
19481+
19482+ void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
19483+ std::ostringstream oss;
19484+ oss << locationInfo << ": Internal Catch error: '" << message << '\'';
19485+ if( alwaysTrue() )
19486+ throw std::logic_error( oss.str() );
19487+ }
19488+}
19489+
19490+// #included from: catch_section.hpp
19491+#define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
19492+
19493+namespace Catch {
19494+
19495+ SectionInfo::SectionInfo
19496+ ( SourceLineInfo const& _lineInfo,
19497+ std::string const& _name,
19498+ std::string const& _description )
19499+ : name( _name ),
19500+ description( _description ),
19501+ lineInfo( _lineInfo )
19502+ {}
19503+
19504+ Section::Section( SectionInfo const& info )
19505+ : m_info( info ),
19506+ m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
19507+ {
19508+ m_timer.start();
19509+ }
19510+
19511+#if defined(_MSC_VER)
19512+#pragma warning(push)
19513+#pragma warning(disable:4996) // std::uncaught_exception is deprecated in C++17
19514+#endif
19515+ Section::~Section() {
19516+ if( m_sectionIncluded ) {
19517+ SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
19518+ if( std::uncaught_exception() )
19519+ getResultCapture().sectionEndedEarly( endInfo );
19520+ else
19521+ getResultCapture().sectionEnded( endInfo );
19522+ }
19523+ }
19524+#if defined(_MSC_VER)
19525+#pragma warning(pop)
19526+#endif
19527+
19528+ // This indicates whether the section should be executed or not
19529+ Section::operator bool() const {
19530+ return m_sectionIncluded;
19531+ }
19532+
19533+} // end namespace Catch
19534+
19535+// #included from: catch_debugger.hpp
19536+#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
19537+
19538+#ifdef CATCH_PLATFORM_MAC
19539+
19540+ #include <assert.h>
19541+ #include <stdbool.h>
19542+ #include <sys/types.h>
19543+ #include <unistd.h>
19544+ #include <sys/sysctl.h>
19545+
19546+ namespace Catch{
19547+
19548+ // The following function is taken directly from the following technical note:
19549+ // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
19550+
19551+ // Returns true if the current process is being debugged (either
19552+ // running under the debugger or has a debugger attached post facto).
19553+ bool isDebuggerActive(){
19554+
19555+ int mib[4];
19556+ struct kinfo_proc info;
19557+ size_t size;
19558+
19559+ // Initialize the flags so that, if sysctl fails for some bizarre
19560+ // reason, we get a predictable result.
19561+
19562+ info.kp_proc.p_flag = 0;
19563+
19564+ // Initialize mib, which tells sysctl the info we want, in this case
19565+ // we're looking for information about a specific process ID.
19566+
19567+ mib[0] = CTL_KERN;
19568+ mib[1] = KERN_PROC;
19569+ mib[2] = KERN_PROC_PID;
19570+ mib[3] = getpid();
19571+
19572+ // Call sysctl.
19573+
19574+ size = sizeof(info);
19575+ if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) {
19576+ Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
19577+ return false;
19578+ }
19579+
19580+ // We're being debugged if the P_TRACED flag is set.
19581+
19582+ return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
19583+ }
19584+ } // namespace Catch
19585+
19586+#elif defined(CATCH_PLATFORM_LINUX)
19587+ #include <fstream>
19588+ #include <string>
19589+
19590+ namespace Catch{
19591+ // The standard POSIX way of detecting a debugger is to attempt to
19592+ // ptrace() the process, but this needs to be done from a child and not
19593+ // this process itself to still allow attaching to this process later
19594+ // if wanted, so is rather heavy. Under Linux we have the PID of the
19595+ // "debugger" (which doesn't need to be gdb, of course, it could also
19596+ // be strace, for example) in /proc/$PID/status, so just get it from
19597+ // there instead.
19598+ bool isDebuggerActive(){
19599+ // Libstdc++ has a bug, where std::ifstream sets errno to 0
19600+ // This way our users can properly assert over errno values
19601+ ErrnoGuard guard;
19602+ std::ifstream in("/proc/self/status");
19603+ for( std::string line; std::getline(in, line); ) {
19604+ static const int PREFIX_LEN = 11;
19605+ if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
19606+ // We're traced if the PID is not 0 and no other PID starts
19607+ // with 0 digit, so it's enough to check for just a single
19608+ // character.
19609+ return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
19610+ }
19611+ }
19612+
19613+ return false;
19614+ }
19615+ } // namespace Catch
19616+#elif defined(_MSC_VER)
19617+ extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
19618+ namespace Catch {
19619+ bool isDebuggerActive() {
19620+ return IsDebuggerPresent() != 0;
19621+ }
19622+ }
19623+#elif defined(__MINGW32__)
19624+ extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
19625+ namespace Catch {
19626+ bool isDebuggerActive() {
19627+ return IsDebuggerPresent() != 0;
19628+ }
19629+ }
19630+#else
19631+ namespace Catch {
19632+ inline bool isDebuggerActive() { return false; }
19633+ }
19634+#endif // Platform
19635+
19636+#ifdef CATCH_PLATFORM_WINDOWS
19637+
19638+ namespace Catch {
19639+ void writeToDebugConsole( std::string const& text ) {
19640+ ::OutputDebugStringA( text.c_str() );
19641+ }
19642+ }
19643+#else
19644+ namespace Catch {
19645+ void writeToDebugConsole( std::string const& text ) {
19646+ // !TBD: Need a version for Mac/ XCode and other IDEs
19647+ Catch::cout() << text;
19648+ }
19649+ }
19650+#endif // Platform
19651+
19652+// #included from: catch_tostring.hpp
19653+#define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED
19654+
19655+namespace Catch {
19656+
19657+namespace Detail {
19658+
19659+ const std::string unprintableString = "{?}";
19660+
19661+ namespace {
19662+ const int hexThreshold = 255;
19663+
19664+ struct Endianness {
19665+ enum Arch { Big, Little };
19666+
19667+ static Arch which() {
19668+ union _{
19669+ int asInt;
19670+ char asChar[sizeof (int)];
19671+ } u;
19672+
19673+ u.asInt = 1;
19674+ return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
19675+ }
19676+ };
19677+ }
19678+
19679+ std::string rawMemoryToString( const void *object, std::size_t size )
19680+ {
19681+ // Reverse order for little endian architectures
19682+ int i = 0, end = static_cast<int>( size ), inc = 1;
19683+ if( Endianness::which() == Endianness::Little ) {
19684+ i = end-1;
19685+ end = inc = -1;
19686+ }
19687+
19688+ unsigned char const *bytes = static_cast<unsigned char const *>(object);
19689+ std::ostringstream os;
19690+ os << "0x" << std::setfill('0') << std::hex;
19691+ for( ; i != end; i += inc )
19692+ os << std::setw(2) << static_cast<unsigned>(bytes[i]);
19693+ return os.str();
19694+ }
19695+}
19696+
19697+std::string toString( std::string const& value ) {
19698+ std::string s = value;
19699+ if( getCurrentContext().getConfig()->showInvisibles() ) {
19700+ for(size_t i = 0; i < s.size(); ++i ) {
19701+ std::string subs;
19702+ switch( s[i] ) {
19703+ case '\n': subs = "\\n"; break;
19704+ case '\t': subs = "\\t"; break;
19705+ default: break;
19706+ }
19707+ if( !subs.empty() ) {
19708+ s = s.substr( 0, i ) + subs + s.substr( i+1 );
19709+ ++i;
19710+ }
19711+ }
19712+ }
19713+ return '"' + s + '"';
19714+}
19715+std::string toString( std::wstring const& value ) {
19716+
19717+ std::string s;
19718+ s.reserve( value.size() );
19719+ for(size_t i = 0; i < value.size(); ++i )
19720+ s += value[i] <= 0xff ? static_cast<char>( value[i] ) : '?';
19721+ return Catch::toString( s );
19722+}
19723+
19724+std::string toString( const char* const value ) {
19725+ return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" );
19726+}
19727+
19728+std::string toString( char* const value ) {
19729+ return Catch::toString( static_cast<const char*>( value ) );
19730+}
19731+
19732+std::string toString( const wchar_t* const value )
19733+{
19734+ return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" );
19735+}
19736+
19737+std::string toString( wchar_t* const value )
19738+{
19739+ return Catch::toString( static_cast<const wchar_t*>( value ) );
19740+}
19741+
19742+std::string toString( int value ) {
19743+ std::ostringstream oss;
19744+ oss << value;
19745+ if( value > Detail::hexThreshold )
19746+ oss << " (0x" << std::hex << value << ')';
19747+ return oss.str();
19748+}
19749+
19750+std::string toString( unsigned long value ) {
19751+ std::ostringstream oss;
19752+ oss << value;
19753+ if( value > Detail::hexThreshold )
19754+ oss << " (0x" << std::hex << value << ')';
19755+ return oss.str();
19756+}
19757+
19758+std::string toString( unsigned int value ) {
19759+ return Catch::toString( static_cast<unsigned long>( value ) );
19760+}
19761+
19762+template<typename T>
19763+std::string fpToString( T value, int precision ) {
19764+ std::ostringstream oss;
19765+ oss << std::setprecision( precision )
19766+ << std::fixed
19767+ << value;
19768+ std::string d = oss.str();
19769+ std::size_t i = d.find_last_not_of( '0' );
19770+ if( i != std::string::npos && i != d.size()-1 ) {
19771+ if( d[i] == '.' )
19772+ i++;
19773+ d = d.substr( 0, i+1 );
19774+ }
19775+ return d;
19776+}
19777+
19778+std::string toString( const double value ) {
19779+ return fpToString( value, 10 );
19780+}
19781+std::string toString( const float value ) {
19782+ return fpToString( value, 5 ) + 'f';
19783+}
19784+
19785+std::string toString( bool value ) {
19786+ return value ? "true" : "false";
19787+}
19788+
19789+std::string toString( char value ) {
19790+ if ( value == '\r' )
19791+ return "'\\r'";
19792+ if ( value == '\f' )
19793+ return "'\\f'";
19794+ if ( value == '\n' )
19795+ return "'\\n'";
19796+ if ( value == '\t' )
19797+ return "'\\t'";
19798+ if ( '\0' <= value && value < ' ' )
19799+ return toString( static_cast<unsigned int>( value ) );
19800+ char chstr[] = "' '";
19801+ chstr[1] = value;
19802+ return chstr;
19803+}
19804+
19805+std::string toString( signed char value ) {
19806+ return toString( static_cast<char>( value ) );
19807+}
19808+
19809+std::string toString( unsigned char value ) {
19810+ return toString( static_cast<char>( value ) );
19811+}
19812+
19813+#ifdef CATCH_CONFIG_CPP11_LONG_LONG
19814+std::string toString( long long value ) {
19815+ std::ostringstream oss;
19816+ oss << value;
19817+ if( value > Detail::hexThreshold )
19818+ oss << " (0x" << std::hex << value << ')';
19819+ return oss.str();
19820+}
19821+std::string toString( unsigned long long value ) {
19822+ std::ostringstream oss;
19823+ oss << value;
19824+ if( value > Detail::hexThreshold )
19825+ oss << " (0x" << std::hex << value << ')';
19826+ return oss.str();
19827+}
19828+#endif
19829+
19830+#ifdef CATCH_CONFIG_CPP11_NULLPTR
19831+std::string toString( std::nullptr_t ) {
19832+ return "nullptr";
19833+}
19834+#endif
19835+
19836+#ifdef __OBJC__
19837+ std::string toString( NSString const * const& nsstring ) {
19838+ if( !nsstring )
19839+ return "nil";
19840+ return "@" + toString([nsstring UTF8String]);
19841+ }
19842+ std::string toString( NSString * CATCH_ARC_STRONG & nsstring ) {
19843+ if( !nsstring )
19844+ return "nil";
19845+ return "@" + toString([nsstring UTF8String]);
19846+ }
19847+ std::string toString( NSObject* const& nsObject ) {
19848+ return toString( [nsObject description] );
19849+ }
19850+#endif
19851+
19852+} // end namespace Catch
19853+
19854+// #included from: catch_result_builder.hpp
19855+#define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED
19856+
19857+#include <cassert>
19858+
19859+namespace Catch {
19860+
19861+ ResultBuilder::ResultBuilder( char const* macroName,
19862+ SourceLineInfo const& lineInfo,
19863+ char const* capturedExpression,
19864+ ResultDisposition::Flags resultDisposition,
19865+ char const* secondArg )
19866+ : m_assertionInfo( macroName, lineInfo, capturedExpression, resultDisposition, secondArg ),
19867+ m_shouldDebugBreak( false ),
19868+ m_shouldThrow( false ),
19869+ m_guardException( false ),
19870+ m_usedStream( false )
19871+ {}
19872+
19873+ ResultBuilder::~ResultBuilder() {
19874+#if defined(CATCH_CONFIG_FAST_COMPILE)
19875+ if ( m_guardException ) {
19876+ stream().oss << "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
19877+ captureResult( ResultWas::ThrewException );
19878+ getCurrentContext().getResultCapture()->exceptionEarlyReported();
19879+ }
19880+#endif
19881+ }
19882+
19883+ ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) {
19884+ m_data.resultType = result;
19885+ return *this;
19886+ }
19887+ ResultBuilder& ResultBuilder::setResultType( bool result ) {
19888+ m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;
19889+ return *this;
19890+ }
19891+
19892+ void ResultBuilder::endExpression( DecomposedExpression const& expr ) {
19893+ // Flip bool results if FalseTest flag is set
19894+ if( isFalseTest( m_assertionInfo.resultDisposition ) ) {
19895+ m_data.negate( expr.isBinaryExpression() );
19896+ }
19897+
19898+ getResultCapture().assertionRun();
19899+
19900+ if(getCurrentContext().getConfig()->includeSuccessfulResults() || m_data.resultType != ResultWas::Ok)
19901+ {
19902+ AssertionResult result = build( expr );
19903+ handleResult( result );
19904+ }
19905+ else
19906+ getResultCapture().assertionPassed();
19907+ }
19908+
19909+ void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) {
19910+ m_assertionInfo.resultDisposition = resultDisposition;
19911+ stream().oss << Catch::translateActiveException();
19912+ captureResult( ResultWas::ThrewException );
19913+ }
19914+
19915+ void ResultBuilder::captureResult( ResultWas::OfType resultType ) {
19916+ setResultType( resultType );
19917+ captureExpression();
19918+ }
19919+
19920+ void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) {
19921+ if( expectedMessage.empty() )
19922+ captureExpectedException( Matchers::Impl::MatchAllOf<std::string>() );
19923+ else
19924+ captureExpectedException( Matchers::Equals( expectedMessage ) );
19925+ }
19926+
19927+ void ResultBuilder::captureExpectedException( Matchers::Impl::MatcherBase<std::string> const& matcher ) {
19928+
19929+ assert( !isFalseTest( m_assertionInfo.resultDisposition ) );
19930+ AssertionResultData data = m_data;
19931+ data.resultType = ResultWas::Ok;
19932+ data.reconstructedExpression = capturedExpressionWithSecondArgument(m_assertionInfo.capturedExpression, m_assertionInfo.secondArg);
19933+
19934+ std::string actualMessage = Catch::translateActiveException();
19935+ if( !matcher.match( actualMessage ) ) {
19936+ data.resultType = ResultWas::ExpressionFailed;
19937+ data.reconstructedExpression = actualMessage;
19938+ }
19939+ AssertionResult result( m_assertionInfo, data );
19940+ handleResult( result );
19941+ }
19942+
19943+ void ResultBuilder::captureExpression() {
19944+ AssertionResult result = build();
19945+ handleResult( result );
19946+ }
19947+
19948+ void ResultBuilder::handleResult( AssertionResult const& result )
19949+ {
19950+ getResultCapture().assertionEnded( result );
19951+
19952+ if( !result.isOk() ) {
19953+ if( getCurrentContext().getConfig()->shouldDebugBreak() )
19954+ m_shouldDebugBreak = true;
19955+ if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) )
19956+ m_shouldThrow = true;
19957+ }
19958+ }
19959+
19960+ void ResultBuilder::react() {
19961+#if defined(CATCH_CONFIG_FAST_COMPILE)
19962+ if (m_shouldDebugBreak) {
19963+ ///////////////////////////////////////////////////////////////////
19964+ // To inspect the state during test, you need to go one level up the callstack
19965+ // To go back to the test and change execution, jump over the throw statement
19966+ ///////////////////////////////////////////////////////////////////
19967+ CATCH_BREAK_INTO_DEBUGGER();
19968+ }
19969+#endif
19970+ if( m_shouldThrow )
19971+ throw Catch::TestFailureException();
19972+ }
19973+
19974+ bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; }
19975+ bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); }
19976+
19977+ AssertionResult ResultBuilder::build() const
19978+ {
19979+ return build( *this );
19980+ }
19981+
19982+ // CAVEAT: The returned AssertionResult stores a pointer to the argument expr,
19983+ // a temporary DecomposedExpression, which in turn holds references to
19984+ // operands, possibly temporary as well.
19985+ // It should immediately be passed to handleResult; if the expression
19986+ // needs to be reported, its string expansion must be composed before
19987+ // the temporaries are destroyed.
19988+ AssertionResult ResultBuilder::build( DecomposedExpression const& expr ) const
19989+ {
19990+ assert( m_data.resultType != ResultWas::Unknown );
19991+ AssertionResultData data = m_data;
19992+
19993+ if(m_usedStream)
19994+ data.message = m_stream().oss.str();
19995+ data.decomposedExpression = &expr; // for lazy reconstruction
19996+ return AssertionResult( m_assertionInfo, data );
19997+ }
19998+
19999+ void ResultBuilder::reconstructExpression( std::string& dest ) const {
20000+ dest = capturedExpressionWithSecondArgument(m_assertionInfo.capturedExpression, m_assertionInfo.secondArg);
20001+ }
20002+
20003+ void ResultBuilder::setExceptionGuard() {
20004+ m_guardException = true;
20005+ }
20006+ void ResultBuilder::unsetExceptionGuard() {
20007+ m_guardException = false;
20008+ }
20009+
20010+} // end namespace Catch
20011+
20012+// #included from: catch_tag_alias_registry.hpp
20013+#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
20014+
20015+namespace Catch {
20016+
20017+ TagAliasRegistry::~TagAliasRegistry() {}
20018+
20019+ Option<TagAlias> TagAliasRegistry::find( std::string const& alias ) const {
20020+ std::map<std::string, TagAlias>::const_iterator it = m_registry.find( alias );
20021+ if( it != m_registry.end() )
20022+ return it->second;
20023+ else
20024+ return Option<TagAlias>();
20025+ }
20026+
20027+ std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
20028+ std::string expandedTestSpec = unexpandedTestSpec;
20029+ for( std::map<std::string, TagAlias>::const_iterator it = m_registry.begin(), itEnd = m_registry.end();
20030+ it != itEnd;
20031+ ++it ) {
20032+ std::size_t pos = expandedTestSpec.find( it->first );
20033+ if( pos != std::string::npos ) {
20034+ expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
20035+ it->second.tag +
20036+ expandedTestSpec.substr( pos + it->first.size() );
20037+ }
20038+ }
20039+ return expandedTestSpec;
20040+ }
20041+
20042+ void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) {
20043+
20044+ if( !startsWith( alias, "[@" ) || !endsWith( alias, ']' ) ) {
20045+ std::ostringstream oss;
20046+ oss << Colour( Colour::Red )
20047+ << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n"
20048+ << Colour( Colour::FileName )
20049+ << lineInfo << '\n';
20050+ throw std::domain_error( oss.str().c_str() );
20051+ }
20052+ if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) {
20053+ std::ostringstream oss;
20054+ oss << Colour( Colour::Red )
20055+ << "error: tag alias, \"" << alias << "\" already registered.\n"
20056+ << "\tFirst seen at "
20057+ << Colour( Colour::Red ) << find(alias)->lineInfo << '\n'
20058+ << Colour( Colour::Red ) << "\tRedefined at "
20059+ << Colour( Colour::FileName) << lineInfo << '\n';
20060+ throw std::domain_error( oss.str().c_str() );
20061+ }
20062+ }
20063+
20064+ ITagAliasRegistry::~ITagAliasRegistry() {}
20065+
20066+ ITagAliasRegistry const& ITagAliasRegistry::get() {
20067+ return getRegistryHub().getTagAliasRegistry();
20068+ }
20069+
20070+ RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
20071+ getMutableRegistryHub().registerTagAlias( alias, tag, lineInfo );
20072+ }
20073+
20074+} // end namespace Catch
20075+
20076+// #included from: catch_matchers_string.hpp
20077+
20078+namespace Catch {
20079+namespace Matchers {
20080+
20081+ namespace StdString {
20082+
20083+ CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
20084+ : m_caseSensitivity( caseSensitivity ),
20085+ m_str( adjustString( str ) )
20086+ {}
20087+ std::string CasedString::adjustString( std::string const& str ) const {
20088+ return m_caseSensitivity == CaseSensitive::No
20089+ ? toLower( str )
20090+ : str;
20091+ }
20092+ std::string CasedString::caseSensitivitySuffix() const {
20093+ return m_caseSensitivity == CaseSensitive::No
20094+ ? " (case insensitive)"
20095+ : std::string();
20096+ }
20097+
20098+ StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )
20099+ : m_comparator( comparator ),
20100+ m_operation( operation ) {
20101+ }
20102+
20103+ std::string StringMatcherBase::describe() const {
20104+ std::string description;
20105+ description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +
20106+ m_comparator.caseSensitivitySuffix().size());
20107+ description += m_operation;
20108+ description += ": \"";
20109+ description += m_comparator.m_str;
20110+ description += "\"";
20111+ description += m_comparator.caseSensitivitySuffix();
20112+ return description;
20113+ }
20114+
20115+ EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {}
20116+
20117+ bool EqualsMatcher::match( std::string const& source ) const {
20118+ return m_comparator.adjustString( source ) == m_comparator.m_str;
20119+ }
20120+
20121+ ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {}
20122+
20123+ bool ContainsMatcher::match( std::string const& source ) const {
20124+ return contains( m_comparator.adjustString( source ), m_comparator.m_str );
20125+ }
20126+
20127+ StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {}
20128+
20129+ bool StartsWithMatcher::match( std::string const& source ) const {
20130+ return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );
20131+ }
20132+
20133+ EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {}
20134+
20135+ bool EndsWithMatcher::match( std::string const& source ) const {
20136+ return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );
20137+ }
20138+
20139+ } // namespace StdString
20140+
20141+ StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
20142+ return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );
20143+ }
20144+ StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
20145+ return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );
20146+ }
20147+ StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
20148+ return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );
20149+ }
20150+ StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
20151+ return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );
20152+ }
20153+
20154+} // namespace Matchers
20155+} // namespace Catch
20156+// #included from: ../reporters/catch_reporter_multi.hpp
20157+#define TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED
20158+
20159+namespace Catch {
20160+
20161+class MultipleReporters : public SharedImpl<IStreamingReporter> {
20162+ typedef std::vector<Ptr<IStreamingReporter> > Reporters;
20163+ Reporters m_reporters;
20164+
20165+public:
20166+ void add( Ptr<IStreamingReporter> const& reporter ) {
20167+ m_reporters.push_back( reporter );
20168+ }
20169+
20170+public: // IStreamingReporter
20171+
20172+ virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
20173+ return m_reporters[0]->getPreferences();
20174+ }
20175+
20176+ virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
20177+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
20178+ it != itEnd;
20179+ ++it )
20180+ (*it)->noMatchingTestCases( spec );
20181+ }
20182+
20183+ virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE {
20184+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
20185+ it != itEnd;
20186+ ++it )
20187+ (*it)->testRunStarting( testRunInfo );
20188+ }
20189+
20190+ virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
20191+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
20192+ it != itEnd;
20193+ ++it )
20194+ (*it)->testGroupStarting( groupInfo );
20195+ }
20196+
20197+ virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
20198+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
20199+ it != itEnd;
20200+ ++it )
20201+ (*it)->testCaseStarting( testInfo );
20202+ }
20203+
20204+ virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
20205+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
20206+ it != itEnd;
20207+ ++it )
20208+ (*it)->sectionStarting( sectionInfo );
20209+ }
20210+
20211+ virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE {
20212+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
20213+ it != itEnd;
20214+ ++it )
20215+ (*it)->assertionStarting( assertionInfo );
20216+ }
20217+
20218+ // The return value indicates if the messages buffer should be cleared:
20219+ virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
20220+ bool clearBuffer = false;
20221+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
20222+ it != itEnd;
20223+ ++it )
20224+ clearBuffer |= (*it)->assertionEnded( assertionStats );
20225+ return clearBuffer;
20226+ }
20227+
20228+ virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
20229+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
20230+ it != itEnd;
20231+ ++it )
20232+ (*it)->sectionEnded( sectionStats );
20233+ }
20234+
20235+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
20236+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
20237+ it != itEnd;
20238+ ++it )
20239+ (*it)->testCaseEnded( testCaseStats );
20240+ }
20241+
20242+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
20243+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
20244+ it != itEnd;
20245+ ++it )
20246+ (*it)->testGroupEnded( testGroupStats );
20247+ }
20248+
20249+ virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
20250+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
20251+ it != itEnd;
20252+ ++it )
20253+ (*it)->testRunEnded( testRunStats );
20254+ }
20255+
20256+ virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
20257+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
20258+ it != itEnd;
20259+ ++it )
20260+ (*it)->skipTest( testInfo );
20261+ }
20262+
20263+ virtual MultipleReporters* tryAsMulti() CATCH_OVERRIDE {
20264+ return this;
20265+ }
20266+
20267+};
20268+
20269+Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter ) {
20270+ Ptr<IStreamingReporter> resultingReporter;
20271+
20272+ if( existingReporter ) {
20273+ MultipleReporters* multi = existingReporter->tryAsMulti();
20274+ if( !multi ) {
20275+ multi = new MultipleReporters;
20276+ resultingReporter = Ptr<IStreamingReporter>( multi );
20277+ if( existingReporter )
20278+ multi->add( existingReporter );
20279+ }
20280+ else
20281+ resultingReporter = existingReporter;
20282+ multi->add( additionalReporter );
20283+ }
20284+ else
20285+ resultingReporter = additionalReporter;
20286+
20287+ return resultingReporter;
20288+}
20289+
20290+} // end namespace Catch
20291+
20292+// #included from: ../reporters/catch_reporter_xml.hpp
20293+#define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED
20294+
20295+// #included from: catch_reporter_bases.hpp
20296+#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
20297+
20298+#include <cstring>
20299+#include <cfloat>
20300+#include <cstdio>
20301+#include <assert.h>
20302+
20303+namespace Catch {
20304+
20305+ namespace {
20306+ // Because formatting using c++ streams is stateful, drop down to C is required
20307+ // Alternatively we could use stringstream, but its performance is... not good.
20308+ std::string getFormattedDuration( double duration ) {
20309+ // Max exponent + 1 is required to represent the whole part
20310+ // + 1 for decimal point
20311+ // + 3 for the 3 decimal places
20312+ // + 1 for null terminator
20313+ const size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
20314+ char buffer[maxDoubleSize];
20315+
20316+ // Save previous errno, to prevent sprintf from overwriting it
20317+ ErrnoGuard guard;
20318+#ifdef _MSC_VER
20319+ sprintf_s(buffer, "%.3f", duration);
20320+#else
20321+ sprintf(buffer, "%.3f", duration);
20322+#endif
20323+ return std::string(buffer);
20324+ }
20325+ }
20326+
20327+ struct StreamingReporterBase : SharedImpl<IStreamingReporter> {
20328+
20329+ StreamingReporterBase( ReporterConfig const& _config )
20330+ : m_config( _config.fullConfig() ),
20331+ stream( _config.stream() )
20332+ {
20333+ m_reporterPrefs.shouldRedirectStdOut = false;
20334+ }
20335+
20336+ virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
20337+ return m_reporterPrefs;
20338+ }
20339+
20340+ virtual ~StreamingReporterBase() CATCH_OVERRIDE;
20341+
20342+ virtual void noMatchingTestCases( std::string const& ) CATCH_OVERRIDE {}
20343+
20344+ virtual void testRunStarting( TestRunInfo const& _testRunInfo ) CATCH_OVERRIDE {
20345+ currentTestRunInfo = _testRunInfo;
20346+ }
20347+ virtual void testGroupStarting( GroupInfo const& _groupInfo ) CATCH_OVERRIDE {
20348+ currentGroupInfo = _groupInfo;
20349+ }
20350+
20351+ virtual void testCaseStarting( TestCaseInfo const& _testInfo ) CATCH_OVERRIDE {
20352+ currentTestCaseInfo = _testInfo;
20353+ }
20354+ virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
20355+ m_sectionStack.push_back( _sectionInfo );
20356+ }
20357+
20358+ virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) CATCH_OVERRIDE {
20359+ m_sectionStack.pop_back();
20360+ }
20361+ virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) CATCH_OVERRIDE {
20362+ currentTestCaseInfo.reset();
20363+ }
20364+ virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) CATCH_OVERRIDE {
20365+ currentGroupInfo.reset();
20366+ }
20367+ virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) CATCH_OVERRIDE {
20368+ currentTestCaseInfo.reset();
20369+ currentGroupInfo.reset();
20370+ currentTestRunInfo.reset();
20371+ }
20372+
20373+ virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {
20374+ // Don't do anything with this by default.
20375+ // It can optionally be overridden in the derived class.
20376+ }
20377+
20378+ Ptr<IConfig const> m_config;
20379+ std::ostream& stream;
20380+
20381+ LazyStat<TestRunInfo> currentTestRunInfo;
20382+ LazyStat<GroupInfo> currentGroupInfo;
20383+ LazyStat<TestCaseInfo> currentTestCaseInfo;
20384+
20385+ std::vector<SectionInfo> m_sectionStack;
20386+ ReporterPreferences m_reporterPrefs;
20387+ };
20388+
20389+ struct CumulativeReporterBase : SharedImpl<IStreamingReporter> {
20390+ template<typename T, typename ChildNodeT>
20391+ struct Node : SharedImpl<> {
20392+ explicit Node( T const& _value ) : value( _value ) {}
20393+ virtual ~Node() {}
20394+
20395+ typedef std::vector<Ptr<ChildNodeT> > ChildNodes;
20396+ T value;
20397+ ChildNodes children;
20398+ };
20399+ struct SectionNode : SharedImpl<> {
20400+ explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {}
20401+ virtual ~SectionNode();
20402+
20403+ bool operator == ( SectionNode const& other ) const {
20404+ return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
20405+ }
20406+ bool operator == ( Ptr<SectionNode> const& other ) const {
20407+ return operator==( *other );
20408+ }
20409+
20410+ SectionStats stats;
20411+ typedef std::vector<Ptr<SectionNode> > ChildSections;
20412+ typedef std::vector<AssertionStats> Assertions;
20413+ ChildSections childSections;
20414+ Assertions assertions;
20415+ std::string stdOut;
20416+ std::string stdErr;
20417+ };
20418+
20419+ struct BySectionInfo {
20420+ BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
20421+ BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
20422+ bool operator() ( Ptr<SectionNode> const& node ) const {
20423+ return ((node->stats.sectionInfo.name == m_other.name) &&
20424+ (node->stats.sectionInfo.lineInfo == m_other.lineInfo));
20425+ }
20426+ private:
20427+ void operator=( BySectionInfo const& );
20428+ SectionInfo const& m_other;
20429+ };
20430+
20431+ typedef Node<TestCaseStats, SectionNode> TestCaseNode;
20432+ typedef Node<TestGroupStats, TestCaseNode> TestGroupNode;
20433+ typedef Node<TestRunStats, TestGroupNode> TestRunNode;
20434+
20435+ CumulativeReporterBase( ReporterConfig const& _config )
20436+ : m_config( _config.fullConfig() ),
20437+ stream( _config.stream() )
20438+ {
20439+ m_reporterPrefs.shouldRedirectStdOut = false;
20440+ }
20441+ ~CumulativeReporterBase();
20442+
20443+ virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
20444+ return m_reporterPrefs;
20445+ }
20446+
20447+ virtual void testRunStarting( TestRunInfo const& ) CATCH_OVERRIDE {}
20448+ virtual void testGroupStarting( GroupInfo const& ) CATCH_OVERRIDE {}
20449+
20450+ virtual void testCaseStarting( TestCaseInfo const& ) CATCH_OVERRIDE {}
20451+
20452+ virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
20453+ SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
20454+ Ptr<SectionNode> node;
20455+ if( m_sectionStack.empty() ) {
20456+ if( !m_rootSection )
20457+ m_rootSection = new SectionNode( incompleteStats );
20458+ node = m_rootSection;
20459+ }
20460+ else {
20461+ SectionNode& parentNode = *m_sectionStack.back();
20462+ SectionNode::ChildSections::const_iterator it =
20463+ std::find_if( parentNode.childSections.begin(),
20464+ parentNode.childSections.end(),
20465+ BySectionInfo( sectionInfo ) );
20466+ if( it == parentNode.childSections.end() ) {
20467+ node = new SectionNode( incompleteStats );
20468+ parentNode.childSections.push_back( node );
20469+ }
20470+ else
20471+ node = *it;
20472+ }
20473+ m_sectionStack.push_back( node );
20474+ m_deepestSection = node;
20475+ }
20476+
20477+ virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
20478+
20479+ virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
20480+ assert( !m_sectionStack.empty() );
20481+ SectionNode& sectionNode = *m_sectionStack.back();
20482+ sectionNode.assertions.push_back( assertionStats );
20483+ // AssertionResult holds a pointer to a temporary DecomposedExpression,
20484+ // which getExpandedExpression() calls to build the expression string.
20485+ // Our section stack copy of the assertionResult will likely outlive the
20486+ // temporary, so it must be expanded or discarded now to avoid calling
20487+ // a destroyed object later.
20488+ prepareExpandedExpression( sectionNode.assertions.back().assertionResult );
20489+ return true;
20490+ }
20491+ virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
20492+ assert( !m_sectionStack.empty() );
20493+ SectionNode& node = *m_sectionStack.back();
20494+ node.stats = sectionStats;
20495+ m_sectionStack.pop_back();
20496+ }
20497+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
20498+ Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats );
20499+ assert( m_sectionStack.size() == 0 );
20500+ node->children.push_back( m_rootSection );
20501+ m_testCases.push_back( node );
20502+ m_rootSection.reset();
20503+
20504+ assert( m_deepestSection );
20505+ m_deepestSection->stdOut = testCaseStats.stdOut;
20506+ m_deepestSection->stdErr = testCaseStats.stdErr;
20507+ }
20508+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
20509+ Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats );
20510+ node->children.swap( m_testCases );
20511+ m_testGroups.push_back( node );
20512+ }
20513+ virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
20514+ Ptr<TestRunNode> node = new TestRunNode( testRunStats );
20515+ node->children.swap( m_testGroups );
20516+ m_testRuns.push_back( node );
20517+ testRunEndedCumulative();
20518+ }
20519+ virtual void testRunEndedCumulative() = 0;
20520+
20521+ virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {}
20522+
20523+ virtual void prepareExpandedExpression( AssertionResult& result ) const {
20524+ if( result.isOk() )
20525+ result.discardDecomposedExpression();
20526+ else
20527+ result.expandDecomposedExpression();
20528+ }
20529+
20530+ Ptr<IConfig const> m_config;
20531+ std::ostream& stream;
20532+ std::vector<AssertionStats> m_assertions;
20533+ std::vector<std::vector<Ptr<SectionNode> > > m_sections;
20534+ std::vector<Ptr<TestCaseNode> > m_testCases;
20535+ std::vector<Ptr<TestGroupNode> > m_testGroups;
20536+
20537+ std::vector<Ptr<TestRunNode> > m_testRuns;
20538+
20539+ Ptr<SectionNode> m_rootSection;
20540+ Ptr<SectionNode> m_deepestSection;
20541+ std::vector<Ptr<SectionNode> > m_sectionStack;
20542+ ReporterPreferences m_reporterPrefs;
20543+
20544+ };
20545+
20546+ template<char C>
20547+ char const* getLineOfChars() {
20548+ static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
20549+ if( !*line ) {
20550+ std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
20551+ line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
20552+ }
20553+ return line;
20554+ }
20555+
20556+ struct TestEventListenerBase : StreamingReporterBase {
20557+ TestEventListenerBase( ReporterConfig const& _config )
20558+ : StreamingReporterBase( _config )
20559+ {}
20560+
20561+ virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
20562+ virtual bool assertionEnded( AssertionStats const& ) CATCH_OVERRIDE {
20563+ return false;
20564+ }
20565+ };
20566+
20567+} // end namespace Catch
20568+
20569+// #included from: ../internal/catch_reporter_registrars.hpp
20570+#define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
20571+
20572+namespace Catch {
20573+
20574+ template<typename T>
20575+ class LegacyReporterRegistrar {
20576+
20577+ class ReporterFactory : public IReporterFactory {
20578+ virtual IStreamingReporter* create( ReporterConfig const& config ) const {
20579+ return new LegacyReporterAdapter( new T( config ) );
20580+ }
20581+
20582+ virtual std::string getDescription() const {
20583+ return T::getDescription();
20584+ }
20585+ };
20586+
20587+ public:
20588+
20589+ LegacyReporterRegistrar( std::string const& name ) {
20590+ getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
20591+ }
20592+ };
20593+
20594+ template<typename T>
20595+ class ReporterRegistrar {
20596+
20597+ class ReporterFactory : public SharedImpl<IReporterFactory> {
20598+
20599+ // *** Please Note ***:
20600+ // - If you end up here looking at a compiler error because it's trying to register
20601+ // your custom reporter class be aware that the native reporter interface has changed
20602+ // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via
20603+ // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter.
20604+ // However please consider updating to the new interface as the old one is now
20605+ // deprecated and will probably be removed quite soon!
20606+ // Please contact me via github if you have any questions at all about this.
20607+ // In fact, ideally, please contact me anyway to let me know you've hit this - as I have
20608+ // no idea who is actually using custom reporters at all (possibly no-one!).
20609+ // The new interface is designed to minimise exposure to interface changes in the future.
20610+ virtual IStreamingReporter* create( ReporterConfig const& config ) const {
20611+ return new T( config );
20612+ }
20613+
20614+ virtual std::string getDescription() const {
20615+ return T::getDescription();
20616+ }
20617+ };
20618+
20619+ public:
20620+
20621+ ReporterRegistrar( std::string const& name ) {
20622+ getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
20623+ }
20624+ };
20625+
20626+ template<typename T>
20627+ class ListenerRegistrar {
20628+
20629+ class ListenerFactory : public SharedImpl<IReporterFactory> {
20630+
20631+ virtual IStreamingReporter* create( ReporterConfig const& config ) const {
20632+ return new T( config );
20633+ }
20634+ virtual std::string getDescription() const {
20635+ return std::string();
20636+ }
20637+ };
20638+
20639+ public:
20640+
20641+ ListenerRegistrar() {
20642+ getMutableRegistryHub().registerListener( new ListenerFactory() );
20643+ }
20644+ };
20645+}
20646+
20647+#define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \
20648+ namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
20649+
20650+#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
20651+ namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
20652+
20653+// Deprecated - use the form without INTERNAL_
20654+#define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \
20655+ namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }
20656+
20657+#define CATCH_REGISTER_LISTENER( listenerType ) \
20658+ namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }
20659+
20660+// #included from: ../internal/catch_xmlwriter.hpp
20661+#define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED
20662+
20663+#include <sstream>
20664+#include <string>
20665+#include <vector>
20666+#include <iomanip>
20667+
20668+namespace Catch {
20669+
20670+ class XmlEncode {
20671+ public:
20672+ enum ForWhat { ForTextNodes, ForAttributes };
20673+
20674+ XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes )
20675+ : m_str( str ),
20676+ m_forWhat( forWhat )
20677+ {}
20678+
20679+ void encodeTo( std::ostream& os ) const {
20680+
20681+ // Apostrophe escaping not necessary if we always use " to write attributes
20682+ // (see: http://www.w3.org/TR/xml/#syntax)
20683+
20684+ for( std::size_t i = 0; i < m_str.size(); ++ i ) {
20685+ char c = m_str[i];
20686+ switch( c ) {
20687+ case '<': os << "&lt;"; break;
20688+ case '&': os << "&amp;"; break;
20689+
20690+ case '>':
20691+ // See: http://www.w3.org/TR/xml/#syntax
20692+ if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' )
20693+ os << "&gt;";
20694+ else
20695+ os << c;
20696+ break;
20697+
20698+ case '\"':
20699+ if( m_forWhat == ForAttributes )
20700+ os << "&quot;";
20701+ else
20702+ os << c;
20703+ break;
20704+
20705+ default:
20706+ // Escape control chars - based on contribution by @espenalb in PR #465 and
20707+ // by @mrpi PR #588
20708+ if ( ( c >= 0 && c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' ) {
20709+ // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
20710+ os << "\\x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
20711+ << static_cast<int>( c );
20712+ }
20713+ else
20714+ os << c;
20715+ }
20716+ }
20717+ }
20718+
20719+ friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
20720+ xmlEncode.encodeTo( os );
20721+ return os;
20722+ }
20723+
20724+ private:
20725+ std::string m_str;
20726+ ForWhat m_forWhat;
20727+ };
20728+
20729+ class XmlWriter {
20730+ public:
20731+
20732+ class ScopedElement {
20733+ public:
20734+ ScopedElement( XmlWriter* writer )
20735+ : m_writer( writer )
20736+ {}
20737+
20738+ ScopedElement( ScopedElement const& other )
20739+ : m_writer( other.m_writer ){
20740+ other.m_writer = CATCH_NULL;
20741+ }
20742+
20743+ ~ScopedElement() {
20744+ if( m_writer )
20745+ m_writer->endElement();
20746+ }
20747+
20748+ ScopedElement& writeText( std::string const& text, bool indent = true ) {
20749+ m_writer->writeText( text, indent );
20750+ return *this;
20751+ }
20752+
20753+ template<typename T>
20754+ ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
20755+ m_writer->writeAttribute( name, attribute );
20756+ return *this;
20757+ }
20758+
20759+ private:
20760+ mutable XmlWriter* m_writer;
20761+ };
20762+
20763+ XmlWriter()
20764+ : m_tagIsOpen( false ),
20765+ m_needsNewline( false ),
20766+ m_os( Catch::cout() )
20767+ {
20768+ writeDeclaration();
20769+ }
20770+
20771+ XmlWriter( std::ostream& os )
20772+ : m_tagIsOpen( false ),
20773+ m_needsNewline( false ),
20774+ m_os( os )
20775+ {
20776+ writeDeclaration();
20777+ }
20778+
20779+ ~XmlWriter() {
20780+ while( !m_tags.empty() )
20781+ endElement();
20782+ }
20783+
20784+ XmlWriter& startElement( std::string const& name ) {
20785+ ensureTagClosed();
20786+ newlineIfNecessary();
20787+ m_os << m_indent << '<' << name;
20788+ m_tags.push_back( name );
20789+ m_indent += " ";
20790+ m_tagIsOpen = true;
20791+ return *this;
20792+ }
20793+
20794+ ScopedElement scopedElement( std::string const& name ) {
20795+ ScopedElement scoped( this );
20796+ startElement( name );
20797+ return scoped;
20798+ }
20799+
20800+ XmlWriter& endElement() {
20801+ newlineIfNecessary();
20802+ m_indent = m_indent.substr( 0, m_indent.size()-2 );
20803+ if( m_tagIsOpen ) {
20804+ m_os << "/>";
20805+ m_tagIsOpen = false;
20806+ }
20807+ else {
20808+ m_os << m_indent << "</" << m_tags.back() << ">";
20809+ }
20810+ m_os << std::endl;
20811+ m_tags.pop_back();
20812+ return *this;
20813+ }
20814+
20815+ XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {
20816+ if( !name.empty() && !attribute.empty() )
20817+ m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
20818+ return *this;
20819+ }
20820+
20821+ XmlWriter& writeAttribute( std::string const& name, bool attribute ) {
20822+ m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
20823+ return *this;
20824+ }
20825+
20826+ template<typename T>
20827+ XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
20828+ std::ostringstream oss;
20829+ oss << attribute;
20830+ return writeAttribute( name, oss.str() );
20831+ }
20832+
20833+ XmlWriter& writeText( std::string const& text, bool indent = true ) {
20834+ if( !text.empty() ){
20835+ bool tagWasOpen = m_tagIsOpen;
20836+ ensureTagClosed();
20837+ if( tagWasOpen && indent )
20838+ m_os << m_indent;
20839+ m_os << XmlEncode( text );
20840+ m_needsNewline = true;
20841+ }
20842+ return *this;
20843+ }
20844+
20845+ XmlWriter& writeComment( std::string const& text ) {
20846+ ensureTagClosed();
20847+ m_os << m_indent << "<!--" << text << "-->";
20848+ m_needsNewline = true;
20849+ return *this;
20850+ }
20851+
20852+ void writeStylesheetRef( std::string const& url ) {
20853+ m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
20854+ }
20855+
20856+ XmlWriter& writeBlankLine() {
20857+ ensureTagClosed();
20858+ m_os << '\n';
20859+ return *this;
20860+ }
20861+
20862+ void ensureTagClosed() {
20863+ if( m_tagIsOpen ) {
20864+ m_os << ">" << std::endl;
20865+ m_tagIsOpen = false;
20866+ }
20867+ }
20868+
20869+ private:
20870+ XmlWriter( XmlWriter const& );
20871+ void operator=( XmlWriter const& );
20872+
20873+ void writeDeclaration() {
20874+ m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
20875+ }
20876+
20877+ void newlineIfNecessary() {
20878+ if( m_needsNewline ) {
20879+ m_os << std::endl;
20880+ m_needsNewline = false;
20881+ }
20882+ }
20883+
20884+ bool m_tagIsOpen;
20885+ bool m_needsNewline;
20886+ std::vector<std::string> m_tags;
20887+ std::string m_indent;
20888+ std::ostream& m_os;
20889+ };
20890+
20891+}
20892+
20893+namespace Catch {
20894+ class XmlReporter : public StreamingReporterBase {
20895+ public:
20896+ XmlReporter( ReporterConfig const& _config )
20897+ : StreamingReporterBase( _config ),
20898+ m_xml(_config.stream()),
20899+ m_sectionDepth( 0 )
20900+ {
20901+ m_reporterPrefs.shouldRedirectStdOut = true;
20902+ }
20903+
20904+ virtual ~XmlReporter() CATCH_OVERRIDE;
20905+
20906+ static std::string getDescription() {
20907+ return "Reports test results as an XML document";
20908+ }
20909+
20910+ virtual std::string getStylesheetRef() const {
20911+ return std::string();
20912+ }
20913+
20914+ void writeSourceInfo( SourceLineInfo const& sourceInfo ) {
20915+ m_xml
20916+ .writeAttribute( "filename", sourceInfo.file )
20917+ .writeAttribute( "line", sourceInfo.line );
20918+ }
20919+
20920+ public: // StreamingReporterBase
20921+
20922+ virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE {
20923+ StreamingReporterBase::noMatchingTestCases( s );
20924+ }
20925+
20926+ virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE {
20927+ StreamingReporterBase::testRunStarting( testInfo );
20928+ std::string stylesheetRef = getStylesheetRef();
20929+ if( !stylesheetRef.empty() )
20930+ m_xml.writeStylesheetRef( stylesheetRef );
20931+ m_xml.startElement( "Catch" );
20932+ if( !m_config->name().empty() )
20933+ m_xml.writeAttribute( "name", m_config->name() );
20934+ }
20935+
20936+ virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
20937+ StreamingReporterBase::testGroupStarting( groupInfo );
20938+ m_xml.startElement( "Group" )
20939+ .writeAttribute( "name", groupInfo.name );
20940+ }
20941+
20942+ virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
20943+ StreamingReporterBase::testCaseStarting(testInfo);
20944+ m_xml.startElement( "TestCase" )
20945+ .writeAttribute( "name", trim( testInfo.name ) )
20946+ .writeAttribute( "description", testInfo.description )
20947+ .writeAttribute( "tags", testInfo.tagsAsString );
20948+
20949+ writeSourceInfo( testInfo.lineInfo );
20950+
20951+ if ( m_config->showDurations() == ShowDurations::Always )
20952+ m_testCaseTimer.start();
20953+ m_xml.ensureTagClosed();
20954+ }
20955+
20956+ virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
20957+ StreamingReporterBase::sectionStarting( sectionInfo );
20958+ if( m_sectionDepth++ > 0 ) {
20959+ m_xml.startElement( "Section" )
20960+ .writeAttribute( "name", trim( sectionInfo.name ) )
20961+ .writeAttribute( "description", sectionInfo.description );
20962+ writeSourceInfo( sectionInfo.lineInfo );
20963+ m_xml.ensureTagClosed();
20964+ }
20965+ }
20966+
20967+ virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { }
20968+
20969+ virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
20970+
20971+ AssertionResult const& result = assertionStats.assertionResult;
20972+
20973+ bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
20974+
20975+ if( includeResults || result.getResultType() == ResultWas::Warning ) {
20976+ // Print any info messages in <Info> tags.
20977+ for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
20978+ it != itEnd;
20979+ ++it ) {
20980+ if( it->type == ResultWas::Info && includeResults ) {
20981+ m_xml.scopedElement( "Info" )
20982+ .writeText( it->message );
20983+ } else if ( it->type == ResultWas::Warning ) {
20984+ m_xml.scopedElement( "Warning" )
20985+ .writeText( it->message );
20986+ }
20987+ }
20988+ }
20989+
20990+ // Drop out if result was successful but we're not printing them.
20991+ if( !includeResults && result.getResultType() != ResultWas::Warning )
20992+ return true;
20993+
20994+ // Print the expression if there is one.
20995+ if( result.hasExpression() ) {
20996+ m_xml.startElement( "Expression" )
20997+ .writeAttribute( "success", result.succeeded() )
20998+ .writeAttribute( "type", result.getTestMacroName() );
20999+
21000+ writeSourceInfo( result.getSourceInfo() );
21001+
21002+ m_xml.scopedElement( "Original" )
21003+ .writeText( result.getExpression() );
21004+ m_xml.scopedElement( "Expanded" )
21005+ .writeText( result.getExpandedExpression() );
21006+ }
21007+
21008+ // And... Print a result applicable to each result type.
21009+ switch( result.getResultType() ) {
21010+ case ResultWas::ThrewException:
21011+ m_xml.startElement( "Exception" );
21012+ writeSourceInfo( result.getSourceInfo() );
21013+ m_xml.writeText( result.getMessage() );
21014+ m_xml.endElement();
21015+ break;
21016+ case ResultWas::FatalErrorCondition:
21017+ m_xml.startElement( "FatalErrorCondition" );
21018+ writeSourceInfo( result.getSourceInfo() );
21019+ m_xml.writeText( result.getMessage() );
21020+ m_xml.endElement();
21021+ break;
21022+ case ResultWas::Info:
21023+ m_xml.scopedElement( "Info" )
21024+ .writeText( result.getMessage() );
21025+ break;
21026+ case ResultWas::Warning:
21027+ // Warning will already have been written
21028+ break;
21029+ case ResultWas::ExplicitFailure:
21030+ m_xml.startElement( "Failure" );
21031+ writeSourceInfo( result.getSourceInfo() );
21032+ m_xml.writeText( result.getMessage() );
21033+ m_xml.endElement();
21034+ break;
21035+ default:
21036+ break;
21037+ }
21038+
21039+ if( result.hasExpression() )
21040+ m_xml.endElement();
21041+
21042+ return true;
21043+ }
21044+
21045+ virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
21046+ StreamingReporterBase::sectionEnded( sectionStats );
21047+ if( --m_sectionDepth > 0 ) {
21048+ XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
21049+ e.writeAttribute( "successes", sectionStats.assertions.passed );
21050+ e.writeAttribute( "failures", sectionStats.assertions.failed );
21051+ e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
21052+
21053+ if ( m_config->showDurations() == ShowDurations::Always )
21054+ e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
21055+
21056+ m_xml.endElement();
21057+ }
21058+ }
21059+
21060+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
21061+ StreamingReporterBase::testCaseEnded( testCaseStats );
21062+ XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
21063+ e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
21064+
21065+ if ( m_config->showDurations() == ShowDurations::Always )
21066+ e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
21067+
21068+ if( !testCaseStats.stdOut.empty() )
21069+ m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false );
21070+ if( !testCaseStats.stdErr.empty() )
21071+ m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false );
21072+
21073+ m_xml.endElement();
21074+ }
21075+
21076+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
21077+ StreamingReporterBase::testGroupEnded( testGroupStats );
21078+ // TODO: Check testGroupStats.aborting and act accordingly.
21079+ m_xml.scopedElement( "OverallResults" )
21080+ .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
21081+ .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
21082+ .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
21083+ m_xml.endElement();
21084+ }
21085+
21086+ virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
21087+ StreamingReporterBase::testRunEnded( testRunStats );
21088+ m_xml.scopedElement( "OverallResults" )
21089+ .writeAttribute( "successes", testRunStats.totals.assertions.passed )
21090+ .writeAttribute( "failures", testRunStats.totals.assertions.failed )
21091+ .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
21092+ m_xml.endElement();
21093+ }
21094+
21095+ private:
21096+ Timer m_testCaseTimer;
21097+ XmlWriter m_xml;
21098+ int m_sectionDepth;
21099+ };
21100+
21101+ INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter )
21102+
21103+} // end namespace Catch
21104+
21105+// #included from: ../reporters/catch_reporter_junit.hpp
21106+#define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED
21107+
21108+#include <assert.h>
21109+
21110+namespace Catch {
21111+
21112+ namespace {
21113+ std::string getCurrentTimestamp() {
21114+ // Beware, this is not reentrant because of backward compatibility issues
21115+ // Also, UTC only, again because of backward compatibility (%z is C++11)
21116+ time_t rawtime;
21117+ std::time(&rawtime);
21118+ const size_t timeStampSize = sizeof("2017-01-16T17:06:45Z");
21119+
21120+#ifdef _MSC_VER
21121+ std::tm timeInfo = {};
21122+ gmtime_s(&timeInfo, &rawtime);
21123+#else
21124+ std::tm* timeInfo;
21125+ timeInfo = std::gmtime(&rawtime);
21126+#endif
21127+
21128+ char timeStamp[timeStampSize];
21129+ const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
21130+
21131+#ifdef _MSC_VER
21132+ std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
21133+#else
21134+ std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
21135+#endif
21136+ return std::string(timeStamp);
21137+ }
21138+
21139+ }
21140+
21141+ class JunitReporter : public CumulativeReporterBase {
21142+ public:
21143+ JunitReporter( ReporterConfig const& _config )
21144+ : CumulativeReporterBase( _config ),
21145+ xml( _config.stream() ),
21146+ unexpectedExceptions( 0 ),
21147+ m_okToFail( false )
21148+ {
21149+ m_reporterPrefs.shouldRedirectStdOut = true;
21150+ }
21151+
21152+ virtual ~JunitReporter() CATCH_OVERRIDE;
21153+
21154+ static std::string getDescription() {
21155+ return "Reports test results in an XML format that looks like Ant's junitreport target";
21156+ }
21157+
21158+ virtual void noMatchingTestCases( std::string const& /*spec*/ ) CATCH_OVERRIDE {}
21159+
21160+ virtual void testRunStarting( TestRunInfo const& runInfo ) CATCH_OVERRIDE {
21161+ CumulativeReporterBase::testRunStarting( runInfo );
21162+ xml.startElement( "testsuites" );
21163+ }
21164+
21165+ virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
21166+ suiteTimer.start();
21167+ stdOutForSuite.str("");
21168+ stdErrForSuite.str("");
21169+ unexpectedExceptions = 0;
21170+ CumulativeReporterBase::testGroupStarting( groupInfo );
21171+ }
21172+
21173+ virtual void testCaseStarting( TestCaseInfo const& testCaseInfo ) CATCH_OVERRIDE {
21174+ m_okToFail = testCaseInfo.okToFail();
21175+ }
21176+ virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
21177+ if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
21178+ unexpectedExceptions++;
21179+ return CumulativeReporterBase::assertionEnded( assertionStats );
21180+ }
21181+
21182+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
21183+ stdOutForSuite << testCaseStats.stdOut;
21184+ stdErrForSuite << testCaseStats.stdErr;
21185+ CumulativeReporterBase::testCaseEnded( testCaseStats );
21186+ }
21187+
21188+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
21189+ double suiteTime = suiteTimer.getElapsedSeconds();
21190+ CumulativeReporterBase::testGroupEnded( testGroupStats );
21191+ writeGroup( *m_testGroups.back(), suiteTime );
21192+ }
21193+
21194+ virtual void testRunEndedCumulative() CATCH_OVERRIDE {
21195+ xml.endElement();
21196+ }
21197+
21198+ void writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
21199+ XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
21200+ TestGroupStats const& stats = groupNode.value;
21201+ xml.writeAttribute( "name", stats.groupInfo.name );
21202+ xml.writeAttribute( "errors", unexpectedExceptions );
21203+ xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
21204+ xml.writeAttribute( "tests", stats.totals.assertions.total() );
21205+ xml.writeAttribute( "hostname", "tbd" ); // !TBD
21206+ if( m_config->showDurations() == ShowDurations::Never )
21207+ xml.writeAttribute( "time", "" );
21208+ else
21209+ xml.writeAttribute( "time", suiteTime );
21210+ xml.writeAttribute( "timestamp", getCurrentTimestamp() );
21211+
21212+ // Write test cases
21213+ for( TestGroupNode::ChildNodes::const_iterator
21214+ it = groupNode.children.begin(), itEnd = groupNode.children.end();
21215+ it != itEnd;
21216+ ++it )
21217+ writeTestCase( **it );
21218+
21219+ xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false );
21220+ xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false );
21221+ }
21222+
21223+ void writeTestCase( TestCaseNode const& testCaseNode ) {
21224+ TestCaseStats const& stats = testCaseNode.value;
21225+
21226+ // All test cases have exactly one section - which represents the
21227+ // test case itself. That section may have 0-n nested sections
21228+ assert( testCaseNode.children.size() == 1 );
21229+ SectionNode const& rootSection = *testCaseNode.children.front();
21230+
21231+ std::string className = stats.testInfo.className;
21232+
21233+ if( className.empty() ) {
21234+ if( rootSection.childSections.empty() )
21235+ className = "global";
21236+ }
21237+ writeSection( className, "", rootSection );
21238+ }
21239+
21240+ void writeSection( std::string const& className,
21241+ std::string const& rootName,
21242+ SectionNode const& sectionNode ) {
21243+ std::string name = trim( sectionNode.stats.sectionInfo.name );
21244+ if( !rootName.empty() )
21245+ name = rootName + '/' + name;
21246+
21247+ if( !sectionNode.assertions.empty() ||
21248+ !sectionNode.stdOut.empty() ||
21249+ !sectionNode.stdErr.empty() ) {
21250+ XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
21251+ if( className.empty() ) {
21252+ xml.writeAttribute( "classname", name );
21253+ xml.writeAttribute( "name", "root" );
21254+ }
21255+ else {
21256+ xml.writeAttribute( "classname", className );
21257+ xml.writeAttribute( "name", name );
21258+ }
21259+ xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) );
21260+
21261+ writeAssertions( sectionNode );
21262+
21263+ if( !sectionNode.stdOut.empty() )
21264+ xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
21265+ if( !sectionNode.stdErr.empty() )
21266+ xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
21267+ }
21268+ for( SectionNode::ChildSections::const_iterator
21269+ it = sectionNode.childSections.begin(),
21270+ itEnd = sectionNode.childSections.end();
21271+ it != itEnd;
21272+ ++it )
21273+ if( className.empty() )
21274+ writeSection( name, "", **it );
21275+ else
21276+ writeSection( className, name, **it );
21277+ }
21278+
21279+ void writeAssertions( SectionNode const& sectionNode ) {
21280+ for( SectionNode::Assertions::const_iterator
21281+ it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end();
21282+ it != itEnd;
21283+ ++it )
21284+ writeAssertion( *it );
21285+ }
21286+ void writeAssertion( AssertionStats const& stats ) {
21287+ AssertionResult const& result = stats.assertionResult;
21288+ if( !result.isOk() ) {
21289+ std::string elementName;
21290+ switch( result.getResultType() ) {
21291+ case ResultWas::ThrewException:
21292+ case ResultWas::FatalErrorCondition:
21293+ elementName = "error";
21294+ break;
21295+ case ResultWas::ExplicitFailure:
21296+ elementName = "failure";
21297+ break;
21298+ case ResultWas::ExpressionFailed:
21299+ elementName = "failure";
21300+ break;
21301+ case ResultWas::DidntThrowException:
21302+ elementName = "failure";
21303+ break;
21304+
21305+ // We should never see these here:
21306+ case ResultWas::Info:
21307+ case ResultWas::Warning:
21308+ case ResultWas::Ok:
21309+ case ResultWas::Unknown:
21310+ case ResultWas::FailureBit:
21311+ case ResultWas::Exception:
21312+ elementName = "internalError";
21313+ break;
21314+ }
21315+
21316+ XmlWriter::ScopedElement e = xml.scopedElement( elementName );
21317+
21318+ xml.writeAttribute( "message", result.getExpandedExpression() );
21319+ xml.writeAttribute( "type", result.getTestMacroName() );
21320+
21321+ std::ostringstream oss;
21322+ if( !result.getMessage().empty() )
21323+ oss << result.getMessage() << '\n';
21324+ for( std::vector<MessageInfo>::const_iterator
21325+ it = stats.infoMessages.begin(),
21326+ itEnd = stats.infoMessages.end();
21327+ it != itEnd;
21328+ ++it )
21329+ if( it->type == ResultWas::Info )
21330+ oss << it->message << '\n';
21331+
21332+ oss << "at " << result.getSourceInfo();
21333+ xml.writeText( oss.str(), false );
21334+ }
21335+ }
21336+
21337+ XmlWriter xml;
21338+ Timer suiteTimer;
21339+ std::ostringstream stdOutForSuite;
21340+ std::ostringstream stdErrForSuite;
21341+ unsigned int unexpectedExceptions;
21342+ bool m_okToFail;
21343+ };
21344+
21345+ INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter )
21346+
21347+} // end namespace Catch
21348+
21349+// #included from: ../reporters/catch_reporter_console.hpp
21350+#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED
21351+
21352+#include <cassert>
21353+#include <cfloat>
21354+#include <cstdio>
21355+
21356+namespace Catch {
21357+
21358+ struct ConsoleReporter : StreamingReporterBase {
21359+ ConsoleReporter( ReporterConfig const& _config )
21360+ : StreamingReporterBase( _config ),
21361+ m_headerPrinted( false )
21362+ {}
21363+
21364+ virtual ~ConsoleReporter() CATCH_OVERRIDE;
21365+ static std::string getDescription() {
21366+ return "Reports test results as plain lines of text";
21367+ }
21368+
21369+ virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
21370+ stream << "No test cases matched '" << spec << '\'' << std::endl;
21371+ }
21372+
21373+ virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {
21374+ }
21375+
21376+ virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE {
21377+ AssertionResult const& result = _assertionStats.assertionResult;
21378+
21379+ bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
21380+
21381+ // Drop out if result was successful but we're not printing them.
21382+ if( !includeResults && result.getResultType() != ResultWas::Warning )
21383+ return false;
21384+
21385+ lazyPrint();
21386+
21387+ AssertionPrinter printer( stream, _assertionStats, includeResults );
21388+ printer.print();
21389+ stream << std::endl;
21390+ return true;
21391+ }
21392+
21393+ virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
21394+ m_headerPrinted = false;
21395+ StreamingReporterBase::sectionStarting( _sectionInfo );
21396+ }
21397+ virtual void sectionEnded( SectionStats const& _sectionStats ) CATCH_OVERRIDE {
21398+ if( _sectionStats.missingAssertions ) {
21399+ lazyPrint();
21400+ Colour colour( Colour::ResultError );
21401+ if( m_sectionStack.size() > 1 )
21402+ stream << "\nNo assertions in section";
21403+ else
21404+ stream << "\nNo assertions in test case";
21405+ stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
21406+ }
21407+ if( m_config->showDurations() == ShowDurations::Always ) {
21408+ stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
21409+ }
21410+ if( m_headerPrinted ) {
21411+ m_headerPrinted = false;
21412+ }
21413+ StreamingReporterBase::sectionEnded( _sectionStats );
21414+ }
21415+
21416+ virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE {
21417+ StreamingReporterBase::testCaseEnded( _testCaseStats );
21418+ m_headerPrinted = false;
21419+ }
21420+ virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) CATCH_OVERRIDE {
21421+ if( currentGroupInfo.used ) {
21422+ printSummaryDivider();
21423+ stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
21424+ printTotals( _testGroupStats.totals );
21425+ stream << '\n' << std::endl;
21426+ }
21427+ StreamingReporterBase::testGroupEnded( _testGroupStats );
21428+ }
21429+ virtual void testRunEnded( TestRunStats const& _testRunStats ) CATCH_OVERRIDE {
21430+ printTotalsDivider( _testRunStats.totals );
21431+ printTotals( _testRunStats.totals );
21432+ stream << std::endl;
21433+ StreamingReporterBase::testRunEnded( _testRunStats );
21434+ }
21435+
21436+ private:
21437+
21438+ class AssertionPrinter {
21439+ void operator= ( AssertionPrinter const& );
21440+ public:
21441+ AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
21442+ : stream( _stream ),
21443+ stats( _stats ),
21444+ result( _stats.assertionResult ),
21445+ colour( Colour::None ),
21446+ message( result.getMessage() ),
21447+ messages( _stats.infoMessages ),
21448+ printInfoMessages( _printInfoMessages )
21449+ {
21450+ switch( result.getResultType() ) {
21451+ case ResultWas::Ok:
21452+ colour = Colour::Success;
21453+ passOrFail = "PASSED";
21454+ //if( result.hasMessage() )
21455+ if( _stats.infoMessages.size() == 1 )
21456+ messageLabel = "with message";
21457+ if( _stats.infoMessages.size() > 1 )
21458+ messageLabel = "with messages";
21459+ break;
21460+ case ResultWas::ExpressionFailed:
21461+ if( result.isOk() ) {
21462+ colour = Colour::Success;
21463+ passOrFail = "FAILED - but was ok";
21464+ }
21465+ else {
21466+ colour = Colour::Error;
21467+ passOrFail = "FAILED";
21468+ }
21469+ if( _stats.infoMessages.size() == 1 )
21470+ messageLabel = "with message";
21471+ if( _stats.infoMessages.size() > 1 )
21472+ messageLabel = "with messages";
21473+ break;
21474+ case ResultWas::ThrewException:
21475+ colour = Colour::Error;
21476+ passOrFail = "FAILED";
21477+ messageLabel = "due to unexpected exception with ";
21478+ if (_stats.infoMessages.size() == 1)
21479+ messageLabel += "message";
21480+ if (_stats.infoMessages.size() > 1)
21481+ messageLabel += "messages";
21482+ break;
21483+ case ResultWas::FatalErrorCondition:
21484+ colour = Colour::Error;
21485+ passOrFail = "FAILED";
21486+ messageLabel = "due to a fatal error condition";
21487+ break;
21488+ case ResultWas::DidntThrowException:
21489+ colour = Colour::Error;
21490+ passOrFail = "FAILED";
21491+ messageLabel = "because no exception was thrown where one was expected";
21492+ break;
21493+ case ResultWas::Info:
21494+ messageLabel = "info";
21495+ break;
21496+ case ResultWas::Warning:
21497+ messageLabel = "warning";
21498+ break;
21499+ case ResultWas::ExplicitFailure:
21500+ passOrFail = "FAILED";
21501+ colour = Colour::Error;
21502+ if( _stats.infoMessages.size() == 1 )
21503+ messageLabel = "explicitly with message";
21504+ if( _stats.infoMessages.size() > 1 )
21505+ messageLabel = "explicitly with messages";
21506+ break;
21507+ // These cases are here to prevent compiler warnings
21508+ case ResultWas::Unknown:
21509+ case ResultWas::FailureBit:
21510+ case ResultWas::Exception:
21511+ passOrFail = "** internal error **";
21512+ colour = Colour::Error;
21513+ break;
21514+ }
21515+ }
21516+
21517+ void print() const {
21518+ printSourceInfo();
21519+ if( stats.totals.assertions.total() > 0 ) {
21520+ if( result.isOk() )
21521+ stream << '\n';
21522+ printResultType();
21523+ printOriginalExpression();
21524+ printReconstructedExpression();
21525+ }
21526+ else {
21527+ stream << '\n';
21528+ }
21529+ printMessage();
21530+ }
21531+
21532+ private:
21533+ void printResultType() const {
21534+ if( !passOrFail.empty() ) {
21535+ Colour colourGuard( colour );
21536+ stream << passOrFail << ":\n";
21537+ }
21538+ }
21539+ void printOriginalExpression() const {
21540+ if( result.hasExpression() ) {
21541+ Colour colourGuard( Colour::OriginalExpression );
21542+ stream << " ";
21543+ stream << result.getExpressionInMacro();
21544+ stream << '\n';
21545+ }
21546+ }
21547+ void printReconstructedExpression() const {
21548+ if( result.hasExpandedExpression() ) {
21549+ stream << "with expansion:\n";
21550+ Colour colourGuard( Colour::ReconstructedExpression );
21551+ stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << '\n';
21552+ }
21553+ }
21554+ void printMessage() const {
21555+ if( !messageLabel.empty() )
21556+ stream << messageLabel << ':' << '\n';
21557+ for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();
21558+ it != itEnd;
21559+ ++it ) {
21560+ // If this assertion is a warning ignore any INFO messages
21561+ if( printInfoMessages || it->type != ResultWas::Info )
21562+ stream << Text( it->message, TextAttributes().setIndent(2) ) << '\n';
21563+ }
21564+ }
21565+ void printSourceInfo() const {
21566+ Colour colourGuard( Colour::FileName );
21567+ stream << result.getSourceInfo() << ": ";
21568+ }
21569+
21570+ std::ostream& stream;
21571+ AssertionStats const& stats;
21572+ AssertionResult const& result;
21573+ Colour::Code colour;
21574+ std::string passOrFail;
21575+ std::string messageLabel;
21576+ std::string message;
21577+ std::vector<MessageInfo> messages;
21578+ bool printInfoMessages;
21579+ };
21580+
21581+ void lazyPrint() {
21582+
21583+ if( !currentTestRunInfo.used )
21584+ lazyPrintRunInfo();
21585+ if( !currentGroupInfo.used )
21586+ lazyPrintGroupInfo();
21587+
21588+ if( !m_headerPrinted ) {
21589+ printTestCaseAndSectionHeader();
21590+ m_headerPrinted = true;
21591+ }
21592+ }
21593+ void lazyPrintRunInfo() {
21594+ stream << '\n' << getLineOfChars<'~'>() << '\n';
21595+ Colour colour( Colour::SecondaryText );
21596+ stream << currentTestRunInfo->name
21597+ << " is a Catch v" << libraryVersion() << " host application.\n"
21598+ << "Run with -? for options\n\n";
21599+
21600+ if( m_config->rngSeed() != 0 )
21601+ stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
21602+
21603+ currentTestRunInfo.used = true;
21604+ }
21605+ void lazyPrintGroupInfo() {
21606+ if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {
21607+ printClosedHeader( "Group: " + currentGroupInfo->name );
21608+ currentGroupInfo.used = true;
21609+ }
21610+ }
21611+ void printTestCaseAndSectionHeader() {
21612+ assert( !m_sectionStack.empty() );
21613+ printOpenHeader( currentTestCaseInfo->name );
21614+
21615+ if( m_sectionStack.size() > 1 ) {
21616+ Colour colourGuard( Colour::Headers );
21617+
21618+ std::vector<SectionInfo>::const_iterator
21619+ it = m_sectionStack.begin()+1, // Skip first section (test case)
21620+ itEnd = m_sectionStack.end();
21621+ for( ; it != itEnd; ++it )
21622+ printHeaderString( it->name, 2 );
21623+ }
21624+
21625+ SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
21626+
21627+ if( !lineInfo.empty() ){
21628+ stream << getLineOfChars<'-'>() << '\n';
21629+ Colour colourGuard( Colour::FileName );
21630+ stream << lineInfo << '\n';
21631+ }
21632+ stream << getLineOfChars<'.'>() << '\n' << std::endl;
21633+ }
21634+
21635+ void printClosedHeader( std::string const& _name ) {
21636+ printOpenHeader( _name );
21637+ stream << getLineOfChars<'.'>() << '\n';
21638+ }
21639+ void printOpenHeader( std::string const& _name ) {
21640+ stream << getLineOfChars<'-'>() << '\n';
21641+ {
21642+ Colour colourGuard( Colour::Headers );
21643+ printHeaderString( _name );
21644+ }
21645+ }
21646+
21647+ // if string has a : in first line will set indent to follow it on
21648+ // subsequent lines
21649+ void printHeaderString( std::string const& _string, std::size_t indent = 0 ) {
21650+ std::size_t i = _string.find( ": " );
21651+ if( i != std::string::npos )
21652+ i+=2;
21653+ else
21654+ i = 0;
21655+ stream << Text( _string, TextAttributes()
21656+ .setIndent( indent+i)
21657+ .setInitialIndent( indent ) ) << '\n';
21658+ }
21659+
21660+ struct SummaryColumn {
21661+
21662+ SummaryColumn( std::string const& _label, Colour::Code _colour )
21663+ : label( _label ),
21664+ colour( _colour )
21665+ {}
21666+ SummaryColumn addRow( std::size_t count ) {
21667+ std::ostringstream oss;
21668+ oss << count;
21669+ std::string row = oss.str();
21670+ for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) {
21671+ while( it->size() < row.size() )
21672+ *it = ' ' + *it;
21673+ while( it->size() > row.size() )
21674+ row = ' ' + row;
21675+ }
21676+ rows.push_back( row );
21677+ return *this;
21678+ }
21679+
21680+ std::string label;
21681+ Colour::Code colour;
21682+ std::vector<std::string> rows;
21683+
21684+ };
21685+
21686+ void printTotals( Totals const& totals ) {
21687+ if( totals.testCases.total() == 0 ) {
21688+ stream << Colour( Colour::Warning ) << "No tests ran\n";
21689+ }
21690+ else if( totals.assertions.total() > 0 && totals.testCases.allPassed() ) {
21691+ stream << Colour( Colour::ResultSuccess ) << "All tests passed";
21692+ stream << " ("
21693+ << pluralise( totals.assertions.passed, "assertion" ) << " in "
21694+ << pluralise( totals.testCases.passed, "test case" ) << ')'
21695+ << '\n';
21696+ }
21697+ else {
21698+
21699+ std::vector<SummaryColumn> columns;
21700+ columns.push_back( SummaryColumn( "", Colour::None )
21701+ .addRow( totals.testCases.total() )
21702+ .addRow( totals.assertions.total() ) );
21703+ columns.push_back( SummaryColumn( "passed", Colour::Success )
21704+ .addRow( totals.testCases.passed )
21705+ .addRow( totals.assertions.passed ) );
21706+ columns.push_back( SummaryColumn( "failed", Colour::ResultError )
21707+ .addRow( totals.testCases.failed )
21708+ .addRow( totals.assertions.failed ) );
21709+ columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure )
21710+ .addRow( totals.testCases.failedButOk )
21711+ .addRow( totals.assertions.failedButOk ) );
21712+
21713+ printSummaryRow( "test cases", columns, 0 );
21714+ printSummaryRow( "assertions", columns, 1 );
21715+ }
21716+ }
21717+ void printSummaryRow( std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row ) {
21718+ for( std::vector<SummaryColumn>::const_iterator it = cols.begin(); it != cols.end(); ++it ) {
21719+ std::string value = it->rows[row];
21720+ if( it->label.empty() ) {
21721+ stream << label << ": ";
21722+ if( value != "0" )
21723+ stream << value;
21724+ else
21725+ stream << Colour( Colour::Warning ) << "- none -";
21726+ }
21727+ else if( value != "0" ) {
21728+ stream << Colour( Colour::LightGrey ) << " | ";
21729+ stream << Colour( it->colour )
21730+ << value << ' ' << it->label;
21731+ }
21732+ }
21733+ stream << '\n';
21734+ }
21735+
21736+ static std::size_t makeRatio( std::size_t number, std::size_t total ) {
21737+ std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0;
21738+ return ( ratio == 0 && number > 0 ) ? 1 : ratio;
21739+ }
21740+ static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {
21741+ if( i > j && i > k )
21742+ return i;
21743+ else if( j > k )
21744+ return j;
21745+ else
21746+ return k;
21747+ }
21748+
21749+ void printTotalsDivider( Totals const& totals ) {
21750+ if( totals.testCases.total() > 0 ) {
21751+ std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() );
21752+ std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() );
21753+ std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() );
21754+ while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 )
21755+ findMax( failedRatio, failedButOkRatio, passedRatio )++;
21756+ while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 )
21757+ findMax( failedRatio, failedButOkRatio, passedRatio )--;
21758+
21759+ stream << Colour( Colour::Error ) << std::string( failedRatio, '=' );
21760+ stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' );
21761+ if( totals.testCases.allPassed() )
21762+ stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' );
21763+ else
21764+ stream << Colour( Colour::Success ) << std::string( passedRatio, '=' );
21765+ }
21766+ else {
21767+ stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' );
21768+ }
21769+ stream << '\n';
21770+ }
21771+ void printSummaryDivider() {
21772+ stream << getLineOfChars<'-'>() << '\n';
21773+ }
21774+
21775+ private:
21776+ bool m_headerPrinted;
21777+ };
21778+
21779+ INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter )
21780+
21781+} // end namespace Catch
21782+
21783+// #included from: ../reporters/catch_reporter_compact.hpp
21784+#define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED
21785+
21786+namespace Catch {
21787+
21788+ struct CompactReporter : StreamingReporterBase {
21789+
21790+ CompactReporter( ReporterConfig const& _config )
21791+ : StreamingReporterBase( _config )
21792+ {}
21793+
21794+ virtual ~CompactReporter();
21795+
21796+ static std::string getDescription() {
21797+ return "Reports test results on a single line, suitable for IDEs";
21798+ }
21799+
21800+ virtual ReporterPreferences getPreferences() const {
21801+ ReporterPreferences prefs;
21802+ prefs.shouldRedirectStdOut = false;
21803+ return prefs;
21804+ }
21805+
21806+ virtual void noMatchingTestCases( std::string const& spec ) {
21807+ stream << "No test cases matched '" << spec << '\'' << std::endl;
21808+ }
21809+
21810+ virtual void assertionStarting( AssertionInfo const& ) {}
21811+
21812+ virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
21813+ AssertionResult const& result = _assertionStats.assertionResult;
21814+
21815+ bool printInfoMessages = true;
21816+
21817+ // Drop out if result was successful and we're not printing those
21818+ if( !m_config->includeSuccessfulResults() && result.isOk() ) {
21819+ if( result.getResultType() != ResultWas::Warning )
21820+ return false;
21821+ printInfoMessages = false;
21822+ }
21823+
21824+ AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
21825+ printer.print();
21826+
21827+ stream << std::endl;
21828+ return true;
21829+ }
21830+
21831+ virtual void sectionEnded(SectionStats const& _sectionStats) CATCH_OVERRIDE {
21832+ if (m_config->showDurations() == ShowDurations::Always) {
21833+ stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
21834+ }
21835+ }
21836+
21837+ virtual void testRunEnded( TestRunStats const& _testRunStats ) {
21838+ printTotals( _testRunStats.totals );
21839+ stream << '\n' << std::endl;
21840+ StreamingReporterBase::testRunEnded( _testRunStats );
21841+ }
21842+
21843+ private:
21844+ class AssertionPrinter {
21845+ void operator= ( AssertionPrinter const& );
21846+ public:
21847+ AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
21848+ : stream( _stream )
21849+ , stats( _stats )
21850+ , result( _stats.assertionResult )
21851+ , messages( _stats.infoMessages )
21852+ , itMessage( _stats.infoMessages.begin() )
21853+ , printInfoMessages( _printInfoMessages )
21854+ {}
21855+
21856+ void print() {
21857+ printSourceInfo();
21858+
21859+ itMessage = messages.begin();
21860+
21861+ switch( result.getResultType() ) {
21862+ case ResultWas::Ok:
21863+ printResultType( Colour::ResultSuccess, passedString() );
21864+ printOriginalExpression();
21865+ printReconstructedExpression();
21866+ if ( ! result.hasExpression() )
21867+ printRemainingMessages( Colour::None );
21868+ else
21869+ printRemainingMessages();
21870+ break;
21871+ case ResultWas::ExpressionFailed:
21872+ if( result.isOk() )
21873+ printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) );
21874+ else
21875+ printResultType( Colour::Error, failedString() );
21876+ printOriginalExpression();
21877+ printReconstructedExpression();
21878+ printRemainingMessages();
21879+ break;
21880+ case ResultWas::ThrewException:
21881+ printResultType( Colour::Error, failedString() );
21882+ printIssue( "unexpected exception with message:" );
21883+ printMessage();
21884+ printExpressionWas();
21885+ printRemainingMessages();
21886+ break;
21887+ case ResultWas::FatalErrorCondition:
21888+ printResultType( Colour::Error, failedString() );
21889+ printIssue( "fatal error condition with message:" );
21890+ printMessage();
21891+ printExpressionWas();
21892+ printRemainingMessages();
21893+ break;
21894+ case ResultWas::DidntThrowException:
21895+ printResultType( Colour::Error, failedString() );
21896+ printIssue( "expected exception, got none" );
21897+ printExpressionWas();
21898+ printRemainingMessages();
21899+ break;
21900+ case ResultWas::Info:
21901+ printResultType( Colour::None, "info" );
21902+ printMessage();
21903+ printRemainingMessages();
21904+ break;
21905+ case ResultWas::Warning:
21906+ printResultType( Colour::None, "warning" );
21907+ printMessage();
21908+ printRemainingMessages();
21909+ break;
21910+ case ResultWas::ExplicitFailure:
21911+ printResultType( Colour::Error, failedString() );
21912+ printIssue( "explicitly" );
21913+ printRemainingMessages( Colour::None );
21914+ break;
21915+ // These cases are here to prevent compiler warnings
21916+ case ResultWas::Unknown:
21917+ case ResultWas::FailureBit:
21918+ case ResultWas::Exception:
21919+ printResultType( Colour::Error, "** internal error **" );
21920+ break;
21921+ }
21922+ }
21923+
21924+ private:
21925+ // Colour::LightGrey
21926+
21927+ static Colour::Code dimColour() { return Colour::FileName; }
21928+
21929+#ifdef CATCH_PLATFORM_MAC
21930+ static const char* failedString() { return "FAILED"; }
21931+ static const char* passedString() { return "PASSED"; }
21932+#else
21933+ static const char* failedString() { return "failed"; }
21934+ static const char* passedString() { return "passed"; }
21935+#endif
21936+
21937+ void printSourceInfo() const {
21938+ Colour colourGuard( Colour::FileName );
21939+ stream << result.getSourceInfo() << ':';
21940+ }
21941+
21942+ void printResultType( Colour::Code colour, std::string const& passOrFail ) const {
21943+ if( !passOrFail.empty() ) {
21944+ {
21945+ Colour colourGuard( colour );
21946+ stream << ' ' << passOrFail;
21947+ }
21948+ stream << ':';
21949+ }
21950+ }
21951+
21952+ void printIssue( std::string const& issue ) const {
21953+ stream << ' ' << issue;
21954+ }
21955+
21956+ void printExpressionWas() {
21957+ if( result.hasExpression() ) {
21958+ stream << ';';
21959+ {
21960+ Colour colour( dimColour() );
21961+ stream << " expression was:";
21962+ }
21963+ printOriginalExpression();
21964+ }
21965+ }
21966+
21967+ void printOriginalExpression() const {
21968+ if( result.hasExpression() ) {
21969+ stream << ' ' << result.getExpression();
21970+ }
21971+ }
21972+
21973+ void printReconstructedExpression() const {
21974+ if( result.hasExpandedExpression() ) {
21975+ {
21976+ Colour colour( dimColour() );
21977+ stream << " for: ";
21978+ }
21979+ stream << result.getExpandedExpression();
21980+ }
21981+ }
21982+
21983+ void printMessage() {
21984+ if ( itMessage != messages.end() ) {
21985+ stream << " '" << itMessage->message << '\'';
21986+ ++itMessage;
21987+ }
21988+ }
21989+
21990+ void printRemainingMessages( Colour::Code colour = dimColour() ) {
21991+ if ( itMessage == messages.end() )
21992+ return;
21993+
21994+ // using messages.end() directly yields compilation error:
21995+ std::vector<MessageInfo>::const_iterator itEnd = messages.end();
21996+ const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );
21997+
21998+ {
21999+ Colour colourGuard( colour );
22000+ stream << " with " << pluralise( N, "message" ) << ':';
22001+ }
22002+
22003+ for(; itMessage != itEnd; ) {
22004+ // If this assertion is a warning ignore any INFO messages
22005+ if( printInfoMessages || itMessage->type != ResultWas::Info ) {
22006+ stream << " '" << itMessage->message << '\'';
22007+ if ( ++itMessage != itEnd ) {
22008+ Colour colourGuard( dimColour() );
22009+ stream << " and";
22010+ }
22011+ }
22012+ }
22013+ }
22014+
22015+ private:
22016+ std::ostream& stream;
22017+ AssertionStats const& stats;
22018+ AssertionResult const& result;
22019+ std::vector<MessageInfo> messages;
22020+ std::vector<MessageInfo>::const_iterator itMessage;
22021+ bool printInfoMessages;
22022+ };
22023+
22024+ // Colour, message variants:
22025+ // - white: No tests ran.
22026+ // - red: Failed [both/all] N test cases, failed [both/all] M assertions.
22027+ // - white: Passed [both/all] N test cases (no assertions).
22028+ // - red: Failed N tests cases, failed M assertions.
22029+ // - green: Passed [both/all] N tests cases with M assertions.
22030+
22031+ std::string bothOrAll( std::size_t count ) const {
22032+ return count == 1 ? std::string() : count == 2 ? "both " : "all " ;
22033+ }
22034+
22035+ void printTotals( const Totals& totals ) const {
22036+ if( totals.testCases.total() == 0 ) {
22037+ stream << "No tests ran.";
22038+ }
22039+ else if( totals.testCases.failed == totals.testCases.total() ) {
22040+ Colour colour( Colour::ResultError );
22041+ const std::string qualify_assertions_failed =
22042+ totals.assertions.failed == totals.assertions.total() ?
22043+ bothOrAll( totals.assertions.failed ) : std::string();
22044+ stream <<
22045+ "Failed " << bothOrAll( totals.testCases.failed )
22046+ << pluralise( totals.testCases.failed, "test case" ) << ", "
22047+ "failed " << qualify_assertions_failed <<
22048+ pluralise( totals.assertions.failed, "assertion" ) << '.';
22049+ }
22050+ else if( totals.assertions.total() == 0 ) {
22051+ stream <<
22052+ "Passed " << bothOrAll( totals.testCases.total() )
22053+ << pluralise( totals.testCases.total(), "test case" )
22054+ << " (no assertions).";
22055+ }
22056+ else if( totals.assertions.failed ) {
22057+ Colour colour( Colour::ResultError );
22058+ stream <<
22059+ "Failed " << pluralise( totals.testCases.failed, "test case" ) << ", "
22060+ "failed " << pluralise( totals.assertions.failed, "assertion" ) << '.';
22061+ }
22062+ else {
22063+ Colour colour( Colour::ResultSuccess );
22064+ stream <<
22065+ "Passed " << bothOrAll( totals.testCases.passed )
22066+ << pluralise( totals.testCases.passed, "test case" ) <<
22067+ " with " << pluralise( totals.assertions.passed, "assertion" ) << '.';
22068+ }
22069+ }
22070+ };
22071+
22072+ INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter )
22073+
22074+} // end namespace Catch
22075+
22076+namespace Catch {
22077+ // These are all here to avoid warnings about not having any out of line
22078+ // virtual methods
22079+ NonCopyable::~NonCopyable() {}
22080+ IShared::~IShared() {}
22081+ IStream::~IStream() CATCH_NOEXCEPT {}
22082+ FileStream::~FileStream() CATCH_NOEXCEPT {}
22083+ CoutStream::~CoutStream() CATCH_NOEXCEPT {}
22084+ DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {}
22085+ StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}
22086+ IContext::~IContext() {}
22087+ IResultCapture::~IResultCapture() {}
22088+ ITestCase::~ITestCase() {}
22089+ ITestCaseRegistry::~ITestCaseRegistry() {}
22090+ IRegistryHub::~IRegistryHub() {}
22091+ IMutableRegistryHub::~IMutableRegistryHub() {}
22092+ IExceptionTranslator::~IExceptionTranslator() {}
22093+ IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}
22094+ IReporter::~IReporter() {}
22095+ IReporterFactory::~IReporterFactory() {}
22096+ IReporterRegistry::~IReporterRegistry() {}
22097+ IStreamingReporter::~IStreamingReporter() {}
22098+ AssertionStats::~AssertionStats() {}
22099+ SectionStats::~SectionStats() {}
22100+ TestCaseStats::~TestCaseStats() {}
22101+ TestGroupStats::~TestGroupStats() {}
22102+ TestRunStats::~TestRunStats() {}
22103+ CumulativeReporterBase::SectionNode::~SectionNode() {}
22104+ CumulativeReporterBase::~CumulativeReporterBase() {}
22105+
22106+ StreamingReporterBase::~StreamingReporterBase() {}
22107+ ConsoleReporter::~ConsoleReporter() {}
22108+ CompactReporter::~CompactReporter() {}
22109+ IRunner::~IRunner() {}
22110+ IMutableContext::~IMutableContext() {}
22111+ IConfig::~IConfig() {}
22112+ XmlReporter::~XmlReporter() {}
22113+ JunitReporter::~JunitReporter() {}
22114+ TestRegistry::~TestRegistry() {}
22115+ FreeFunctionTestCase::~FreeFunctionTestCase() {}
22116+ IGeneratorInfo::~IGeneratorInfo() {}
22117+ IGeneratorsForTest::~IGeneratorsForTest() {}
22118+ WildcardPattern::~WildcardPattern() {}
22119+ TestSpec::Pattern::~Pattern() {}
22120+ TestSpec::NamePattern::~NamePattern() {}
22121+ TestSpec::TagPattern::~TagPattern() {}
22122+ TestSpec::ExcludedPattern::~ExcludedPattern() {}
22123+ Matchers::Impl::MatcherUntypedBase::~MatcherUntypedBase() {}
22124+
22125+ void Config::dummy() {}
22126+
22127+ namespace TestCaseTracking {
22128+ ITracker::~ITracker() {}
22129+ TrackerBase::~TrackerBase() {}
22130+ SectionTracker::~SectionTracker() {}
22131+ IndexTracker::~IndexTracker() {}
22132+ }
22133+}
22134+
22135+#ifdef __clang__
22136+#pragma clang diagnostic pop
22137+#endif
22138+
22139+#endif
22140+
22141+#ifdef CATCH_CONFIG_MAIN
22142+// #included from: internal/catch_default_main.hpp
22143+#define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
22144+
22145+#ifndef __OBJC__
22146+
22147+#if defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
22148+// Standard C/C++ Win32 Unicode wmain entry point
22149+extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
22150+#else
22151+// Standard C/C++ main entry point
22152+int main (int argc, char * argv[]) {
22153+#endif
22154+
22155+ int result = Catch::Session().run( argc, argv );
22156+ return ( result < 0xff ? result : 0xff );
22157+}
22158+
22159+#else // __OBJC__
22160+
22161+// Objective-C entry point
22162+int main (int argc, char * const argv[]) {
22163+#if !CATCH_ARC_ENABLED
22164+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
22165+#endif
22166+
22167+ Catch::registerTestMethods();
22168+ int result = Catch::Session().run( argc, (char* const*)argv );
22169+
22170+#if !CATCH_ARC_ENABLED
22171+ [pool drain];
22172+#endif
22173+
22174+ return ( result < 0xff ? result : 0xff );
22175+}
22176+
22177+#endif // __OBJC__
22178+
22179+#endif
22180+
22181+#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
22182+# undef CLARA_CONFIG_MAIN
22183+#endif
22184+
22185+//////
22186+
22187+// If this config identifier is defined then all CATCH macros are prefixed with CATCH_
22188+#ifdef CATCH_CONFIG_PREFIX_ALL
22189+
22190+#if defined(CATCH_CONFIG_FAST_COMPILE)
22191+#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, expr )
22192+#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr )
22193+#else
22194+#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, expr )
22195+#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr )
22196+#endif
22197+
22198+#define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", expr )
22199+#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
22200+#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
22201+#define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, expr )
22202+
22203+#define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, expr )
22204+#define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, expr )
22205+#define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, expr )
22206+#define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, expr )
22207+#define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, expr )
22208+
22209+#define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", expr )
22210+#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
22211+#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
22212+#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, expr )
22213+
22214+#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
22215+
22216+#if defined(CATCH_CONFIG_FAST_COMPILE)
22217+#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT_NO_TRY( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
22218+#else
22219+#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
22220+#endif
22221+
22222+#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
22223+#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
22224+#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
22225+#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << Catch::toString(msg) )
22226+#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << Catch::toString(msg) )
22227+
22228+#ifdef CATCH_CONFIG_VARIADIC_MACROS
22229+ #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
22230+ #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
22231+ #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
22232+ #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
22233+ #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
22234+ #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
22235+ #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
22236+ #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
22237+#else
22238+ #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
22239+ #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
22240+ #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
22241+ #define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description )
22242+ #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
22243+ #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, msg )
22244+ #define CATCH_FAIL_CHECK( msg ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, msg )
22245+ #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, msg )
22246+#endif
22247+#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
22248+
22249+#define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
22250+#define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
22251+
22252+#define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
22253+
22254+// "BDD-style" convenience wrappers
22255+#ifdef CATCH_CONFIG_VARIADIC_MACROS
22256+#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
22257+#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
22258+#else
22259+#define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags )
22260+#define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
22261+#endif
22262+#define CATCH_GIVEN( desc ) CATCH_SECTION( std::string( "Given: ") + desc, "" )
22263+#define CATCH_WHEN( desc ) CATCH_SECTION( std::string( " When: ") + desc, "" )
22264+#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" )
22265+#define CATCH_THEN( desc ) CATCH_SECTION( std::string( " Then: ") + desc, "" )
22266+#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" )
22267+
22268+// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
22269+#else
22270+
22271+#if defined(CATCH_CONFIG_FAST_COMPILE)
22272+#define REQUIRE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "REQUIRE", Catch::ResultDisposition::Normal, expr )
22273+#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr )
22274+
22275+#else
22276+#define REQUIRE( expr ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, expr )
22277+#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr )
22278+#endif
22279+
22280+#define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", expr )
22281+#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
22282+#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
22283+#define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, expr )
22284+
22285+#define CHECK( expr ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, expr )
22286+#define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, expr )
22287+#define CHECKED_IF( expr ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, expr )
22288+#define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, expr )
22289+#define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, expr )
22290+
22291+#define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", expr )
22292+#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
22293+#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
22294+#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, expr )
22295+
22296+#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
22297+
22298+#if defined(CATCH_CONFIG_FAST_COMPILE)
22299+#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT_NO_TRY( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
22300+#else
22301+#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
22302+#endif
22303+
22304+#define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
22305+#define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
22306+#define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
22307+#define CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << Catch::toString(msg) )
22308+#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << Catch::toString(msg) )
22309+
22310+#ifdef CATCH_CONFIG_VARIADIC_MACROS
22311+#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
22312+#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
22313+#define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
22314+#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
22315+#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
22316+#define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
22317+#define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
22318+#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
22319+#else
22320+#define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
22321+ #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
22322+ #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
22323+ #define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description )
22324+ #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
22325+ #define FAIL( msg ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, msg )
22326+ #define FAIL_CHECK( msg ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, msg )
22327+ #define SUCCEED( msg ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, msg )
22328+#endif
22329+#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
22330+
22331+#define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
22332+#define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
22333+
22334+#define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
22335+
22336+#endif
22337+
22338+#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
22339+
22340+// "BDD-style" convenience wrappers
22341+#ifdef CATCH_CONFIG_VARIADIC_MACROS
22342+#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
22343+#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
22344+#else
22345+#define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags )
22346+#define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
22347+#endif
22348+#define GIVEN( desc ) SECTION( std::string(" Given: ") + desc, "" )
22349+#define WHEN( desc ) SECTION( std::string(" When: ") + desc, "" )
22350+#define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc, "" )
22351+#define THEN( desc ) SECTION( std::string(" Then: ") + desc, "" )
22352+#define AND_THEN( desc ) SECTION( std::string(" And: ") + desc, "" )
22353+
22354+using Catch::Detail::Approx;
22355+
22356+// #included from: internal/catch_reenable_warnings.h
22357+
22358+#define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED
22359+
22360+#ifdef __clang__
22361+# ifdef __ICC // icpc defines the __clang__ macro
22362+# pragma warning(pop)
22363+# else
22364+# pragma clang diagnostic pop
22365+# endif
22366+#elif defined __GNUC__
22367+# pragma GCC diagnostic pop
22368+#endif
22369+
22370+#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
22371+
diff --git a/meta-oe/recipes-devtools/nlohmann-fifo/nlohmann-fifo/0002-catch.hpp-Define-SIGSTKSZ-as-constant.patch b/meta-oe/recipes-devtools/nlohmann-fifo/nlohmann-fifo/0002-catch.hpp-Define-SIGSTKSZ-as-constant.patch
new file mode 100644
index 0000000000..dcbbf9dd3f
--- /dev/null
+++ b/meta-oe/recipes-devtools/nlohmann-fifo/nlohmann-fifo/0002-catch.hpp-Define-SIGSTKSZ-as-constant.patch
@@ -0,0 +1,41 @@
1From 9a3cf8cf44e916cca30cd6c3cfcf6b2f20ce2c06 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Fri, 1 Aug 2025 11:22:24 -0700
4Subject: [PATCH 2/2] catch.hpp: Define SIGSTKSZ as constant
5
6This compilation error is occurring because of a change
7in how SIGSTKSZ is defined in newer versions of glibc.
8In older versions, SIGSTKSZ was a compile-time constant,
9but in glibc 2.34 and later, it became a runtime value
10(specifically a function call to sysconf(_SC_SIGSTKSZ)),
11which means it can't be used to declare static arrays
12at file scope.
13
14This is already fixed for Catch2 but for catch-1.x
15this is best we can do, define it to be 16K which is
16the value in glibc 2.33 for all architectures except
17IA ( itanium ) where it was 256K but we do not support
18it in OE
19
20Upstream-Status: Inappropriate [Cross-compile specific]
21Signed-off-by: Khem Raj <raj.khem@gmail.com>
22---
23 test/thirdparty/catch/catch.hpp | 5 +++++
24 1 file changed, 5 insertions(+)
25
26diff --git a/test/thirdparty/catch/catch.hpp b/test/thirdparty/catch/catch.hpp
27index fdb046f..1e444a4 100644
28--- a/test/thirdparty/catch/catch.hpp
29+++ b/test/thirdparty/catch/catch.hpp
30@@ -6519,6 +6519,11 @@ namespace Catch {
31
32 #include <signal.h>
33
34+#ifdef SIGSTKSZ
35+#undef SIGSTKSZ
36+#define SIGSTKSZ 16384 // 16K bytes
37+#endif
38+
39 namespace Catch {
40
41 struct SignalDefs {
diff --git a/meta-oe/recipes-devtools/nlohmann-fifo/nlohmann-fifo_git.bb b/meta-oe/recipes-devtools/nlohmann-fifo/nlohmann-fifo_git.bb
index ec87535ec7..9b42ea17f5 100644
--- a/meta-oe/recipes-devtools/nlohmann-fifo/nlohmann-fifo_git.bb
+++ b/meta-oe/recipes-devtools/nlohmann-fifo/nlohmann-fifo_git.bb
@@ -4,8 +4,10 @@ SECTION = "libs"
4LICENSE = "MIT" 4LICENSE = "MIT"
5LIC_FILES_CHKSUM = "file://LICENSE.MIT;md5=b67209a1e36b682a8226de19d265b1e0" 5LIC_FILES_CHKSUM = "file://LICENSE.MIT;md5=b67209a1e36b682a8226de19d265b1e0"
6 6
7SRC_URI = "git://github.com/nlohmann/fifo_map.git;branch=master;protocol=https" 7SRC_URI = "git://github.com/nlohmann/fifo_map.git;branch=master;protocol=https \
8 8 file://0001-catch.hpp-Upgrade-to-latest-from-Catch-v1.12.2.patch \
9 file://0002-catch.hpp-Define-SIGSTKSZ-as-constant.patch \
10 "
9PV = "1.0.0+git" 11PV = "1.0.0+git"
10 12
11SRCREV = "d732aaf9a315415ae8fd7eb11e3a4c1f80e42a48" 13SRCREV = "d732aaf9a315415ae8fd7eb11e3a4c1f80e42a48"