mirror of
https://github.com/catchorg/Catch2.git
synced 2025-09-12 00:15:39 +02:00
Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
908c370f24 | ||
![]() |
6c6cfe126a | ||
![]() |
72df457bab | ||
![]() |
bb6d08323f | ||
![]() |
64a533551d | ||
![]() |
c32f275a00 | ||
![]() |
6860c8def0 | ||
![]() |
3255ee6312 | ||
![]() |
74effafca7 | ||
![]() |
7d0cfd27ce | ||
![]() |
3fe4d394a5 | ||
![]() |
b97e9a2f8b | ||
![]() |
34f7cfe046 | ||
![]() |
07b9bda1d2 | ||
![]() |
84e8b696b1 |
@@ -3,9 +3,9 @@
|
|||||||
[](https://github.com/philsquared/catch/releases)
|
[](https://github.com/philsquared/catch/releases)
|
||||||
[](https://travis-ci.org/philsquared/Catch)
|
[](https://travis-ci.org/philsquared/Catch)
|
||||||
[](https://ci.appveyor.com/project/philsquared/catch/branch/master)
|
[](https://ci.appveyor.com/project/philsquared/catch/branch/master)
|
||||||
[](https://wandbox.org/permlink/EyEbEIfp8CnnjguW)
|
[](https://wandbox.org/permlink/jG7wnHX9VAcxpSHy)
|
||||||
|
|
||||||
<a href="https://github.com/philsquared/Catch/releases/download/v1.11.0/catch.hpp">The latest, single header, version can be downloaded directly using this link</a>
|
<a href="https://github.com/philsquared/Catch/releases/download/v1.12.2/catch.hpp">The latest, single header, version can be downloaded directly using this link</a>
|
||||||
|
|
||||||
## What's the Catch?
|
## What's the Catch?
|
||||||
|
|
||||||
|
@@ -4,7 +4,7 @@ from conans import ConanFile
|
|||||||
|
|
||||||
class CatchConan(ConanFile):
|
class CatchConan(ConanFile):
|
||||||
name = "Catch"
|
name = "Catch"
|
||||||
version = "1.11.0"
|
version = "1.12.2"
|
||||||
description = "A modern, C++-native, header-only, framework for unit-tests, TDD and BDD"
|
description = "A modern, C++-native, header-only, framework for unit-tests, TDD and BDD"
|
||||||
author = "philsquared"
|
author = "philsquared"
|
||||||
generators = "cmake"
|
generators = "cmake"
|
||||||
|
@@ -1,3 +1,24 @@
|
|||||||
|
# 1.12.2
|
||||||
|
### Fixes
|
||||||
|
* Fixed missing <cassert> include
|
||||||
|
|
||||||
|
# 1.12.1
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
* Fixed deprecation warning in `ScopedMessage::~ScopedMessage`
|
||||||
|
* All uses of `min` or `max` identifiers are now wrapped in parentheses
|
||||||
|
* This avoids problems when Windows headers define `min` and `max` macros
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 1.12.0
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
* Fixed compilation for strict C++98 mode (ie not gnu++98) and older compilers (#1103)
|
||||||
|
* `INFO` messages are included in the `xml` reporter output even without `-s` specified.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 1.11.0
|
# 1.11.0
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# Getting Catch
|
# Getting Catch
|
||||||
|
|
||||||
The simplest way to get Catch is to download the latest [single header version](https://raw.githubusercontent.com/philsquared/Catch/master/single_include/catch.hpp). The single header is generated by merging a set of individual headers but it is still just normal source code in a header file.
|
The simplest way to get Catch is to download the latest [single header version](https://github.com/philsquared/Catch/releases/download/v1.12.2/catch.hpp). The single header is generated by merging a set of individual headers but it is still just normal source code in a header file.
|
||||||
|
|
||||||
The full source for Catch, including test projects, documentation, and other things, is hosted on GitHub. [http://catch-lib.net](http://catch-lib.net) will redirect you there.
|
The full source for Catch, including test projects, documentation, and other things, is hosted on GitHub. [http://catch-lib.net](http://catch-lib.net) will redirect you there.
|
||||||
|
|
||||||
|
@@ -163,7 +163,7 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Use variadic macros if the compiler supports them
|
// Use variadic macros if the compiler supports them
|
||||||
#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
|
#if ( defined _MSC_VER && _MSC_VER >= 1400 && !defined __EDGE__) || \
|
||||||
( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
|
( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
|
||||||
( defined __GNUC__ && __GNUC__ >= 3 ) || \
|
( defined __GNUC__ && __GNUC__ >= 3 ) || \
|
||||||
( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
|
( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
|
||||||
|
@@ -27,6 +27,9 @@ namespace Catch{
|
|||||||
#define CATCH_TRAP() \
|
#define CATCH_TRAP() \
|
||||||
__asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
|
__asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
|
||||||
: : : "memory","r0","r3","r4" ) /* NOLINT */
|
: : : "memory","r0","r3","r4" ) /* NOLINT */
|
||||||
|
#elif defined(__aarch64__)
|
||||||
|
// Backport of https://github.com/catchorg/Catch2/commit/a25c1a24af8bffd35727a888a307ff0280cf9387
|
||||||
|
#define CATCH_TRAP() __asm__(".inst 0xd4200000")
|
||||||
#else
|
#else
|
||||||
#define CATCH_TRAP() __asm__("int $3\n" : : /* NOLINT */ )
|
#define CATCH_TRAP() __asm__("int $3\n" : : /* NOLINT */ )
|
||||||
#endif
|
#endif
|
||||||
|
@@ -38,10 +38,12 @@ namespace Internal {
|
|||||||
template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
|
template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T& removeConst(T const &t) { return const_cast<T&>(t); }
|
T& opCast(T const& t) { return const_cast<T&>(t); }
|
||||||
|
|
||||||
|
// nullptr_t support based on pull request #154 from Konstantin Baumann
|
||||||
#ifdef CATCH_CONFIG_CPP11_NULLPTR
|
#ifdef CATCH_CONFIG_CPP11_NULLPTR
|
||||||
inline std::nullptr_t removeConst(std::nullptr_t) { return nullptr; }
|
inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
|
||||||
#endif
|
#endif // CATCH_CONFIG_CPP11_NULLPTR
|
||||||
|
|
||||||
|
|
||||||
// So the compare overloads can be operator agnostic we convey the operator as a template
|
// So the compare overloads can be operator agnostic we convey the operator as a template
|
||||||
@@ -52,90 +54,161 @@ namespace Internal {
|
|||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct Evaluator<T1, T2, IsEqualTo> {
|
struct Evaluator<T1, T2, IsEqualTo> {
|
||||||
static bool evaluate( T1 const& lhs, T2 const& rhs) {
|
static bool evaluate( T1 const& lhs, T2 const& rhs) {
|
||||||
return bool(removeConst(lhs) == removeConst(rhs) );
|
return bool( opCast( lhs ) == opCast( rhs ) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct Evaluator<T1, T2, IsNotEqualTo> {
|
struct Evaluator<T1, T2, IsNotEqualTo> {
|
||||||
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
||||||
return bool(removeConst(lhs) != removeConst(rhs) );
|
return bool( opCast( lhs ) != opCast( rhs ) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct Evaluator<T1, T2, IsLessThan> {
|
struct Evaluator<T1, T2, IsLessThan> {
|
||||||
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
||||||
return bool(removeConst(lhs) < removeConst(rhs) );
|
return bool( opCast( lhs ) < opCast( rhs ) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct Evaluator<T1, T2, IsGreaterThan> {
|
struct Evaluator<T1, T2, IsGreaterThan> {
|
||||||
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
||||||
return bool(removeConst(lhs) > removeConst(rhs) );
|
return bool( opCast( lhs ) > opCast( rhs ) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
|
struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
|
||||||
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
||||||
return bool(removeConst(lhs) >= removeConst(rhs) );
|
return bool( opCast( lhs ) >= opCast( rhs ) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
|
struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
|
||||||
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
||||||
return bool(removeConst(lhs) <= removeConst(rhs) );
|
return bool( opCast( lhs ) <= opCast( rhs ) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Special case for comparing a pointer to an int (deduced for p==0)
|
template<Operator Op, typename T1, typename T2>
|
||||||
template<typename T>
|
bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
|
||||||
struct Evaluator<int const&, T* const&, IsEqualTo> {
|
return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
|
||||||
static bool evaluate( int lhs, T* rhs) {
|
}
|
||||||
return reinterpret_cast<void const*>( lhs ) == rhs;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template<typename T>
|
|
||||||
struct Evaluator<T* const&, int const&, IsEqualTo> {
|
|
||||||
static bool evaluate( T* lhs, int rhs) {
|
|
||||||
return lhs == reinterpret_cast<void const*>( rhs );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template<typename T>
|
|
||||||
struct Evaluator<int const&, T* const&, IsNotEqualTo> {
|
|
||||||
static bool evaluate( int lhs, T* rhs) {
|
|
||||||
return reinterpret_cast<void const*>( lhs ) != rhs;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template<typename T>
|
|
||||||
struct Evaluator<T* const&, int const&, IsNotEqualTo> {
|
|
||||||
static bool evaluate( T* lhs, int rhs) {
|
|
||||||
return lhs != reinterpret_cast<void const*>( rhs );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
// This level of indirection allows us to specialise for integer types
|
||||||
struct Evaluator<long const&, T* const&, IsEqualTo> {
|
// to avoid signed/ unsigned warnings
|
||||||
static bool evaluate( long lhs, T* rhs) {
|
|
||||||
return reinterpret_cast<void const*>( lhs ) == rhs;
|
// "base" overload
|
||||||
}
|
template<Operator Op, typename T1, typename T2>
|
||||||
};
|
bool compare( T1 const& lhs, T2 const& rhs ) {
|
||||||
template<typename T>
|
return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
|
||||||
struct Evaluator<T* const&, long const&, IsEqualTo> {
|
}
|
||||||
static bool evaluate( T* lhs, long rhs) {
|
|
||||||
return lhs == reinterpret_cast<void const*>( rhs );
|
// unsigned X to int
|
||||||
}
|
template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
|
||||||
};
|
return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
|
||||||
template<typename T>
|
}
|
||||||
struct Evaluator<long const&, T* const&, IsNotEqualTo> {
|
template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
|
||||||
static bool evaluate( long lhs, T* rhs) {
|
return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
|
||||||
return reinterpret_cast<void const*>( lhs ) != rhs;
|
}
|
||||||
}
|
template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
|
||||||
};
|
return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
|
||||||
template<typename T>
|
}
|
||||||
struct Evaluator<T* const&, long const&, IsNotEqualTo> {
|
|
||||||
static bool evaluate( T* lhs, long rhs) {
|
// unsigned X to long
|
||||||
return lhs != reinterpret_cast<void const*>( rhs );
|
template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
|
||||||
}
|
return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
|
||||||
};
|
}
|
||||||
|
template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
|
||||||
|
return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
|
||||||
|
}
|
||||||
|
template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
|
||||||
|
return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// int to unsigned X
|
||||||
|
template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
|
||||||
|
// long to unsigned X
|
||||||
|
template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
|
||||||
|
// pointer to long (when comparing against NULL)
|
||||||
|
template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
|
||||||
|
return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
|
||||||
|
return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// pointer to int (when comparing against NULL)
|
||||||
|
template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
|
||||||
|
return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
|
||||||
|
return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CATCH_CONFIG_CPP11_LONG_LONG
|
||||||
|
// long long to unsigned X
|
||||||
|
template<Operator Op> bool compare( long long lhs, unsigned int rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op> bool compare( long long lhs, unsigned long rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op> bool compare( long long lhs, unsigned long long rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op> bool compare( long long lhs, unsigned char rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
|
||||||
|
// unsigned long long to X
|
||||||
|
template<Operator Op> bool compare( unsigned long long lhs, int rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op> bool compare( unsigned long long lhs, long rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op> bool compare( unsigned long long lhs, long long rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op> bool compare( unsigned long long lhs, char rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
|
||||||
|
// pointer to long long (when comparing against NULL)
|
||||||
|
template<Operator Op, typename T> bool compare( long long lhs, T* rhs ) {
|
||||||
|
return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op, typename T> bool compare( T* lhs, long long rhs ) {
|
||||||
|
return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
|
||||||
|
}
|
||||||
|
#endif // CATCH_CONFIG_CPP11_LONG_LONG
|
||||||
|
|
||||||
|
#ifdef CATCH_CONFIG_CPP11_NULLPTR
|
||||||
|
// pointer to nullptr_t (when comparing against nullptr)
|
||||||
|
template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
|
||||||
|
return Evaluator<T*, T*, Op>::evaluate( nullptr, rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
|
||||||
|
return Evaluator<T*, T*, Op>::evaluate( lhs, nullptr );
|
||||||
|
}
|
||||||
|
#endif // CATCH_CONFIG_CPP11_NULLPTR
|
||||||
|
|
||||||
} // end of namespace Internal
|
} // end of namespace Internal
|
||||||
} // end of namespace Catch
|
} // end of namespace Catch
|
||||||
|
@@ -111,7 +111,7 @@ public:
|
|||||||
|
|
||||||
void endExpression() const {
|
void endExpression() const {
|
||||||
m_rb
|
m_rb
|
||||||
.setResultType( Internal::Evaluator<LhsT, RhsT, Op>::evaluate( m_lhs, m_rhs ) )
|
.setResultType( Internal::compare<Op>( m_lhs, m_rhs ) )
|
||||||
.endExpression( *this );
|
.endExpression( *this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -9,10 +9,12 @@
|
|||||||
#ifndef TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
|
#ifndef TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
|
||||||
#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
|
#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
// Report the error condition
|
//! Signals fatal error message to the run context
|
||||||
inline void reportFatal( std::string const& message ) {
|
inline void reportFatal( std::string const& message ) {
|
||||||
IContext& context = Catch::getCurrentContext();
|
IContext& context = Catch::getCurrentContext();
|
||||||
IResultCapture* resultCapture = context.getResultCapture();
|
IResultCapture* resultCapture = context.getResultCapture();
|
||||||
@@ -27,8 +29,31 @@ namespace Catch {
|
|||||||
# if !defined ( CATCH_CONFIG_WINDOWS_SEH )
|
# if !defined ( CATCH_CONFIG_WINDOWS_SEH )
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
struct FatalConditionHandler {
|
class FatalConditionHandler {
|
||||||
void reset() {}
|
bool m_started;
|
||||||
|
|
||||||
|
// Install/disengage implementation for specific platform.
|
||||||
|
// Should be if-defed to work on current platform, can assume
|
||||||
|
// engage-disengage 1:1 pairing.
|
||||||
|
void engage_platform() {}
|
||||||
|
void disengage_platform() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Should also have platform-specific implementations as needed
|
||||||
|
FatalConditionHandler() : m_started(false) {}
|
||||||
|
~FatalConditionHandler() {}
|
||||||
|
|
||||||
|
void engage() {
|
||||||
|
assert(!m_started && "Handler cannot be installed twice.");
|
||||||
|
m_started = true;
|
||||||
|
engage_platform();
|
||||||
|
}
|
||||||
|
|
||||||
|
void disengage() {
|
||||||
|
assert(m_started && "Handler cannot be uninstalled without being installed first");
|
||||||
|
m_started = false;
|
||||||
|
disengage_platform();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,53 +73,72 @@ namespace Catch {
|
|||||||
{ EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" },
|
{ EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" },
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FatalConditionHandler {
|
static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
|
||||||
|
for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
|
||||||
static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
|
if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
|
||||||
for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
|
reportFatal(signalDefs[i].name);
|
||||||
if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
|
|
||||||
reportFatal(signalDefs[i].name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// If its not an exception we care about, pass it along.
|
|
||||||
// This stops us from eating debugger breaks etc.
|
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
|
||||||
}
|
}
|
||||||
|
// If its not an exception we care about, pass it along.
|
||||||
|
// This stops us from eating debugger breaks etc.
|
||||||
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
|
}
|
||||||
|
|
||||||
FatalConditionHandler() {
|
// Since we do not support multiple instantiations, we put these
|
||||||
isSet = true;
|
// into global variables and rely on cleaning them up in outlined
|
||||||
// 32k seems enough for Catch to handle stack overflow,
|
// constructors/destructors
|
||||||
// but the value was found experimentally, so there is no strong guarantee
|
static PVOID exceptionHandlerHandle = CATCH_NULL;
|
||||||
guaranteeSize = 32 * 1024;
|
|
||||||
exceptionHandlerHandle = CATCH_NULL;
|
class FatalConditionHandler {
|
||||||
|
bool m_started;
|
||||||
|
|
||||||
|
// Install/disengage implementation for specific platform.
|
||||||
|
// Should be if-defed to work on current platform, can assume
|
||||||
|
// engage-disengage 1:1 pairing.
|
||||||
|
|
||||||
|
void engage_platform() {
|
||||||
// Register as first handler in current chain
|
// Register as first handler in current chain
|
||||||
exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
|
exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
|
||||||
// Pass in guarantee size to be filled
|
if (!exceptionHandlerHandle) {
|
||||||
SetThreadStackGuarantee(&guaranteeSize);
|
throw std::runtime_error("Could not register vectored exception handler");
|
||||||
}
|
|
||||||
|
|
||||||
static void reset() {
|
|
||||||
if (isSet) {
|
|
||||||
// Unregister handler and restore the old guarantee
|
|
||||||
RemoveVectoredExceptionHandler(exceptionHandlerHandle);
|
|
||||||
SetThreadStackGuarantee(&guaranteeSize);
|
|
||||||
exceptionHandlerHandle = CATCH_NULL;
|
|
||||||
isSet = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~FatalConditionHandler() {
|
void disengage_platform() {
|
||||||
reset();
|
if (!RemoveVectoredExceptionHandler(exceptionHandlerHandle)) {
|
||||||
|
throw std::runtime_error("Could not unregister vectored exception handler");
|
||||||
|
}
|
||||||
|
exceptionHandlerHandle = CATCH_NULL;
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
static bool isSet;
|
|
||||||
static ULONG guaranteeSize;
|
|
||||||
static PVOID exceptionHandlerHandle;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool FatalConditionHandler::isSet = false;
|
public:
|
||||||
ULONG FatalConditionHandler::guaranteeSize = 0;
|
FatalConditionHandler() : m_started(false) {
|
||||||
PVOID FatalConditionHandler::exceptionHandlerHandle = CATCH_NULL;
|
ULONG guaranteeSize = static_cast<ULONG>(32 * 1024);
|
||||||
|
if (!SetThreadStackGuarantee(&guaranteeSize)) {
|
||||||
|
// We do not want to fully error out, because needing
|
||||||
|
// the stack reserve should be rare enough anyway.
|
||||||
|
Catch::cerr()
|
||||||
|
<< "Failed to reserve piece of stack."
|
||||||
|
<< " Stack overflows will not be reported successfully.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We do not attempt to unset the stack guarantee, because
|
||||||
|
// Windows does not support lowering the stack size guarantee.
|
||||||
|
~FatalConditionHandler() {}
|
||||||
|
|
||||||
|
void engage() {
|
||||||
|
assert(!m_started && "Handler cannot be installed twice.");
|
||||||
|
m_started = true;
|
||||||
|
engage_platform();
|
||||||
|
}
|
||||||
|
|
||||||
|
void disengage() {
|
||||||
|
assert(m_started && "Handler cannot be uninstalled without being installed first");
|
||||||
|
m_started = false;
|
||||||
|
disengage_platform();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Catch
|
} // namespace Catch
|
||||||
|
|
||||||
@@ -105,8 +149,31 @@ namespace Catch {
|
|||||||
# if !defined(CATCH_CONFIG_POSIX_SIGNALS)
|
# if !defined(CATCH_CONFIG_POSIX_SIGNALS)
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
struct FatalConditionHandler {
|
class FatalConditionHandler {
|
||||||
void reset() {}
|
bool m_started;
|
||||||
|
|
||||||
|
// Install/disengage implementation for specific platform.
|
||||||
|
// Should be if-defed to work on current platform, can assume
|
||||||
|
// engage-disengage 1:1 pairing.
|
||||||
|
void engage_platform() {}
|
||||||
|
void disengage_platform() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Should also have platform-specific implementations as needed
|
||||||
|
FatalConditionHandler() : m_started(false) {}
|
||||||
|
~FatalConditionHandler() {}
|
||||||
|
|
||||||
|
void engage() {
|
||||||
|
assert(!m_started && "Handler cannot be installed twice.");
|
||||||
|
m_started = true;
|
||||||
|
engage_platform();
|
||||||
|
}
|
||||||
|
|
||||||
|
void disengage() {
|
||||||
|
assert(m_started && "Handler cannot be uninstalled without being installed first");
|
||||||
|
m_started = false;
|
||||||
|
disengage_platform();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,29 +198,56 @@ namespace Catch {
|
|||||||
{ SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
|
{ SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FatalConditionHandler {
|
// Older GCCs trigger -Wmissing-field-initializers for T foo = {}
|
||||||
|
// which is zero initialization, but not explicit. We want to avoid
|
||||||
|
// that.
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
# pragma GCC diagnostic push
|
||||||
|
# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool isSet;
|
static char* altStackMem = CATCH_NULL;
|
||||||
static struct sigaction oldSigActions [sizeof(signalDefs)/sizeof(SignalDefs)];
|
static std::size_t altStackSize = 0;
|
||||||
static stack_t oldSigStack;
|
static stack_t oldSigStack;
|
||||||
static char altStackMem[SIGSTKSZ];
|
static struct sigaction oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)];
|
||||||
|
|
||||||
static void handleSignal( int sig ) {
|
static void restorePreviousSignalHandlers() {
|
||||||
std::string name = "<unknown signal>";
|
// We set signal handlers back to the previous ones. Hopefully
|
||||||
for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
|
// nobody overwrote them in the meantime, and doesn't expect
|
||||||
SignalDefs &def = signalDefs[i];
|
// their signal handlers to live past ours given that they
|
||||||
if (sig == def.id) {
|
// installed them after ours..
|
||||||
name = def.name;
|
for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
|
||||||
break;
|
sigaction(signalDefs[i].id, &oldSigActions[i], CATCH_NULL);
|
||||||
}
|
|
||||||
}
|
|
||||||
reset();
|
|
||||||
reportFatal(name);
|
|
||||||
raise( sig );
|
|
||||||
}
|
}
|
||||||
|
// Return the old stack
|
||||||
|
sigaltstack(&oldSigStack, CATCH_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
FatalConditionHandler() {
|
static void handleSignal( int sig ) {
|
||||||
isSet = true;
|
char const * name = "<unknown signal>";
|
||||||
|
for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
|
||||||
|
SignalDefs &def = signalDefs[i];
|
||||||
|
if (sig == def.id) {
|
||||||
|
name = def.name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// We need to restore previous signal handlers and let them do
|
||||||
|
// their thing, so that the users can have the debugger break
|
||||||
|
// when a signal is raised, and so on.
|
||||||
|
restorePreviousSignalHandlers();
|
||||||
|
reportFatal( name );
|
||||||
|
raise( sig );
|
||||||
|
}
|
||||||
|
|
||||||
|
class FatalConditionHandler {
|
||||||
|
bool m_started;
|
||||||
|
|
||||||
|
// Install/disengage implementation for specific platform.
|
||||||
|
// Should be if-defed to work on current platform, can assume
|
||||||
|
// engage-disengage 1:1 pairing.
|
||||||
|
|
||||||
|
void engage_platform() {
|
||||||
stack_t sigStack;
|
stack_t sigStack;
|
||||||
sigStack.ss_sp = altStackMem;
|
sigStack.ss_sp = altStackMem;
|
||||||
sigStack.ss_size = SIGSTKSZ;
|
sigStack.ss_size = SIGSTKSZ;
|
||||||
@@ -168,28 +262,42 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void disengage_platform() {
|
||||||
|
restorePreviousSignalHandlers();
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
FatalConditionHandler() : m_started(false) {
|
||||||
|
assert(!altStackMem && "Cannot initialize POSIX signal handler when one already exists");
|
||||||
|
if (altStackSize == 0) {
|
||||||
|
altStackSize = SIGSTKSZ;
|
||||||
|
}
|
||||||
|
altStackMem = new char[altStackSize]();
|
||||||
|
}
|
||||||
|
|
||||||
~FatalConditionHandler() {
|
~FatalConditionHandler() {
|
||||||
reset();
|
delete[] altStackMem;
|
||||||
|
// We signal that another instance can be constructed by zeroing
|
||||||
|
// out the pointer.
|
||||||
|
altStackMem = CATCH_NULL;
|
||||||
}
|
}
|
||||||
static void reset() {
|
|
||||||
if( isSet ) {
|
void engage() {
|
||||||
// Set signals back to previous values -- hopefully nobody overwrote them in the meantime
|
assert(!m_started && "Handler cannot be installed twice.");
|
||||||
for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
|
m_started = true;
|
||||||
sigaction(signalDefs[i].id, &oldSigActions[i], CATCH_NULL);
|
engage_platform();
|
||||||
}
|
}
|
||||||
// Return the old stack
|
|
||||||
sigaltstack(&oldSigStack, CATCH_NULL);
|
void disengage() {
|
||||||
isSet = false;
|
assert(m_started && "Handler cannot be uninstalled without being installed first");
|
||||||
}
|
m_started = false;
|
||||||
|
disengage_platform();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool FatalConditionHandler::isSet = false;
|
#if defined(__GNUC__)
|
||||||
struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
|
# pragma GCC diagnostic pop
|
||||||
stack_t FatalConditionHandler::oldSigStack = {};
|
#endif
|
||||||
char FatalConditionHandler::altStackMem[SIGSTKSZ] = {};
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Catch
|
} // namespace Catch
|
||||||
|
|
||||||
@@ -197,4 +305,21 @@ namespace Catch {
|
|||||||
|
|
||||||
#endif // not Windows
|
#endif // not Windows
|
||||||
|
|
||||||
|
namespace Catch {
|
||||||
|
|
||||||
|
//! Simple RAII guard for (dis)engaging the FatalConditionHandler
|
||||||
|
class FatalConditionHandlerGuard {
|
||||||
|
FatalConditionHandler* m_handler;
|
||||||
|
public:
|
||||||
|
FatalConditionHandlerGuard(FatalConditionHandler* handler):
|
||||||
|
m_handler(handler) {
|
||||||
|
m_handler->engage();
|
||||||
|
}
|
||||||
|
~FatalConditionHandlerGuard() {
|
||||||
|
m_handler->disengage();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace Catch
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
|
||||||
|
@@ -37,11 +37,18 @@ namespace Catch {
|
|||||||
: m_info( other.m_info )
|
: m_info( other.m_info )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4996) // std::uncaught_exception is deprecated in C++17
|
||||||
|
#endif
|
||||||
ScopedMessage::~ScopedMessage() {
|
ScopedMessage::~ScopedMessage() {
|
||||||
if ( !std::uncaught_exception() ){
|
if ( !std::uncaught_exception() ){
|
||||||
getResultCapture().popScopedMessage(m_info);
|
getResultCapture().popScopedMessage(m_info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
@@ -16,6 +16,8 @@
|
|||||||
#include "catch_interfaces_registry_hub.h"
|
#include "catch_interfaces_registry_hub.h"
|
||||||
#include "catch_wildcard_pattern.hpp"
|
#include "catch_wildcard_pattern.hpp"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
ResultBuilder::ResultBuilder( char const* macroName,
|
ResultBuilder::ResultBuilder( char const* macroName,
|
||||||
|
@@ -22,7 +22,7 @@
|
|||||||
#include "catch_result_builder.h"
|
#include "catch_result_builder.h"
|
||||||
#include "catch_fatal_condition.hpp"
|
#include "catch_fatal_condition.hpp"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -363,9 +363,8 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void invokeActiveTestCase() {
|
void invokeActiveTestCase() {
|
||||||
FatalConditionHandler fatalConditionHandler; // Handle signals
|
FatalConditionHandlerGuard _(&m_fatalConditionhandler);
|
||||||
m_activeTestCase->invoke();
|
m_activeTestCase->invoke();
|
||||||
fatalConditionHandler.reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -403,6 +402,7 @@ namespace Catch {
|
|||||||
std::vector<SectionEndInfo> m_unfinishedSections;
|
std::vector<SectionEndInfo> m_unfinishedSections;
|
||||||
std::vector<ITracker*> m_activeSections;
|
std::vector<ITracker*> m_activeSections;
|
||||||
TrackerContext m_trackerContext;
|
TrackerContext m_trackerContext;
|
||||||
|
FatalConditionHandler m_fatalConditionhandler;
|
||||||
size_t m_prevPassed;
|
size_t m_prevPassed;
|
||||||
bool m_shouldReportUnexpected;
|
bool m_shouldReportUnexpected;
|
||||||
};
|
};
|
||||||
|
@@ -27,9 +27,9 @@ namespace Catch {
|
|||||||
result_type operator()( result_type n ) const { return std::rand() % n; }
|
result_type operator()( result_type n ) const { return std::rand() % n; }
|
||||||
|
|
||||||
#ifdef CATCH_CONFIG_CPP11_SHUFFLE
|
#ifdef CATCH_CONFIG_CPP11_SHUFFLE
|
||||||
static constexpr result_type min() { return 0; }
|
static constexpr result_type (min)() { return 0; }
|
||||||
static constexpr result_type max() { return 1000000; }
|
static constexpr result_type (max)() { return 1000000; }
|
||||||
result_type operator()() const { return std::rand() % max(); }
|
result_type operator()() const { return std::rand() % (max)(); }
|
||||||
#endif
|
#endif
|
||||||
template<typename V>
|
template<typename V>
|
||||||
static void shuffle( V& vector ) {
|
static void shuffle( V& vector ) {
|
||||||
|
@@ -38,7 +38,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline Version libraryVersion() {
|
inline Version libraryVersion() {
|
||||||
static Version version( 1, 11, 0, "", 0 );
|
static Version version( 1, 12, 2, "", 0 );
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
#include "../internal/catch_reporter_registrars.hpp"
|
#include "../internal/catch_reporter_registrars.hpp"
|
||||||
#include "../internal/catch_console_colour.hpp"
|
#include "../internal/catch_console_colour.hpp"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
// file can be distributed as a single header that works with the main
|
// file can be distributed as a single header that works with the main
|
||||||
// Catch single header.
|
// Catch single header.
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
|
@@ -97,12 +97,12 @@ namespace Catch {
|
|||||||
|
|
||||||
bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
|
bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
|
||||||
|
|
||||||
if( includeResults ) {
|
if( includeResults || result.getResultType() == ResultWas::Warning ) {
|
||||||
// Print any info messages in <Info> tags.
|
// Print any info messages in <Info> tags.
|
||||||
for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
|
for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
|
||||||
it != itEnd;
|
it != itEnd;
|
||||||
++it ) {
|
++it ) {
|
||||||
if( it->type == ResultWas::Info ) {
|
if( it->type == ResultWas::Info && includeResults ) {
|
||||||
m_xml.scopedElement( "Info" )
|
m_xml.scopedElement( "Info" )
|
||||||
.writeText( it->message );
|
.writeText( it->message );
|
||||||
} else if ( it->type == ResultWas::Warning ) {
|
} else if ( it->type == ResultWas::Warning ) {
|
||||||
|
@@ -8,7 +8,7 @@ from releaseCommon import Version
|
|||||||
|
|
||||||
print(catchPath)
|
print(catchPath)
|
||||||
|
|
||||||
default_path = '../vcpkg/ports/catch/'
|
default_path = '../vcpkg/ports/catch-classic/'
|
||||||
|
|
||||||
def adjusted_path(path):
|
def adjusted_path(path):
|
||||||
return os.path.join(catchPath, path)
|
return os.path.join(catchPath, path)
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Catch v1.11.0
|
* Catch v1.12.2
|
||||||
* Generated: 2017-10-31 13:42:42.914833
|
* Generated: 2018-05-14 15:10:01.112442
|
||||||
* ----------------------------------------------------------
|
* ----------------------------------------------------------
|
||||||
* This file has been merged from multiple headers. Please don't edit it directly
|
* This file has been merged from multiple headers. Please don't edit it directly
|
||||||
* Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
|
* Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
|
||||||
@@ -1320,10 +1320,12 @@ namespace Internal {
|
|||||||
template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
|
template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T& removeConst(T const &t) { return const_cast<T&>(t); }
|
T& opCast(T const& t) { return const_cast<T&>(t); }
|
||||||
|
|
||||||
|
// nullptr_t support based on pull request #154 from Konstantin Baumann
|
||||||
#ifdef CATCH_CONFIG_CPP11_NULLPTR
|
#ifdef CATCH_CONFIG_CPP11_NULLPTR
|
||||||
inline std::nullptr_t removeConst(std::nullptr_t) { return nullptr; }
|
inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
|
||||||
#endif
|
#endif // CATCH_CONFIG_CPP11_NULLPTR
|
||||||
|
|
||||||
// So the compare overloads can be operator agnostic we convey the operator as a template
|
// So the compare overloads can be operator agnostic we convey the operator as a template
|
||||||
// enum, which is used to specialise an Evaluator for doing the comparison.
|
// enum, which is used to specialise an Evaluator for doing the comparison.
|
||||||
@@ -1333,90 +1335,161 @@ namespace Internal {
|
|||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct Evaluator<T1, T2, IsEqualTo> {
|
struct Evaluator<T1, T2, IsEqualTo> {
|
||||||
static bool evaluate( T1 const& lhs, T2 const& rhs) {
|
static bool evaluate( T1 const& lhs, T2 const& rhs) {
|
||||||
return bool(removeConst(lhs) == removeConst(rhs) );
|
return bool( opCast( lhs ) == opCast( rhs ) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct Evaluator<T1, T2, IsNotEqualTo> {
|
struct Evaluator<T1, T2, IsNotEqualTo> {
|
||||||
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
||||||
return bool(removeConst(lhs) != removeConst(rhs) );
|
return bool( opCast( lhs ) != opCast( rhs ) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct Evaluator<T1, T2, IsLessThan> {
|
struct Evaluator<T1, T2, IsLessThan> {
|
||||||
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
||||||
return bool(removeConst(lhs) < removeConst(rhs) );
|
return bool( opCast( lhs ) < opCast( rhs ) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct Evaluator<T1, T2, IsGreaterThan> {
|
struct Evaluator<T1, T2, IsGreaterThan> {
|
||||||
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
||||||
return bool(removeConst(lhs) > removeConst(rhs) );
|
return bool( opCast( lhs ) > opCast( rhs ) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
|
struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
|
||||||
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
||||||
return bool(removeConst(lhs) >= removeConst(rhs) );
|
return bool( opCast( lhs ) >= opCast( rhs ) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
|
struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
|
||||||
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
|
||||||
return bool(removeConst(lhs) <= removeConst(rhs) );
|
return bool( opCast( lhs ) <= opCast( rhs ) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Special case for comparing a pointer to an int (deduced for p==0)
|
template<Operator Op, typename T1, typename T2>
|
||||||
template<typename T>
|
bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
|
||||||
struct Evaluator<int const&, T* const&, IsEqualTo> {
|
return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
|
||||||
static bool evaluate( int lhs, T* rhs) {
|
}
|
||||||
return reinterpret_cast<void const*>( lhs ) == rhs;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template<typename T>
|
|
||||||
struct Evaluator<T* const&, int const&, IsEqualTo> {
|
|
||||||
static bool evaluate( T* lhs, int rhs) {
|
|
||||||
return lhs == reinterpret_cast<void const*>( rhs );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template<typename T>
|
|
||||||
struct Evaluator<int const&, T* const&, IsNotEqualTo> {
|
|
||||||
static bool evaluate( int lhs, T* rhs) {
|
|
||||||
return reinterpret_cast<void const*>( lhs ) != rhs;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template<typename T>
|
|
||||||
struct Evaluator<T* const&, int const&, IsNotEqualTo> {
|
|
||||||
static bool evaluate( T* lhs, int rhs) {
|
|
||||||
return lhs != reinterpret_cast<void const*>( rhs );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
// This level of indirection allows us to specialise for integer types
|
||||||
struct Evaluator<long const&, T* const&, IsEqualTo> {
|
// to avoid signed/ unsigned warnings
|
||||||
static bool evaluate( long lhs, T* rhs) {
|
|
||||||
return reinterpret_cast<void const*>( lhs ) == rhs;
|
// "base" overload
|
||||||
}
|
template<Operator Op, typename T1, typename T2>
|
||||||
};
|
bool compare( T1 const& lhs, T2 const& rhs ) {
|
||||||
template<typename T>
|
return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
|
||||||
struct Evaluator<T* const&, long const&, IsEqualTo> {
|
}
|
||||||
static bool evaluate( T* lhs, long rhs) {
|
|
||||||
return lhs == reinterpret_cast<void const*>( rhs );
|
// unsigned X to int
|
||||||
}
|
template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
|
||||||
};
|
return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
|
||||||
template<typename T>
|
}
|
||||||
struct Evaluator<long const&, T* const&, IsNotEqualTo> {
|
template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
|
||||||
static bool evaluate( long lhs, T* rhs) {
|
return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
|
||||||
return reinterpret_cast<void const*>( lhs ) != rhs;
|
}
|
||||||
}
|
template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
|
||||||
};
|
return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
|
||||||
template<typename T>
|
}
|
||||||
struct Evaluator<T* const&, long const&, IsNotEqualTo> {
|
|
||||||
static bool evaluate( T* lhs, long rhs) {
|
// unsigned X to long
|
||||||
return lhs != reinterpret_cast<void const*>( rhs );
|
template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
|
||||||
}
|
return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
|
||||||
};
|
}
|
||||||
|
template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
|
||||||
|
return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
|
||||||
|
}
|
||||||
|
template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
|
||||||
|
return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// int to unsigned X
|
||||||
|
template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
|
||||||
|
// long to unsigned X
|
||||||
|
template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
|
||||||
|
// pointer to long (when comparing against NULL)
|
||||||
|
template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
|
||||||
|
return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
|
||||||
|
return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// pointer to int (when comparing against NULL)
|
||||||
|
template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
|
||||||
|
return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
|
||||||
|
return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CATCH_CONFIG_CPP11_LONG_LONG
|
||||||
|
// long long to unsigned X
|
||||||
|
template<Operator Op> bool compare( long long lhs, unsigned int rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op> bool compare( long long lhs, unsigned long rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op> bool compare( long long lhs, unsigned long long rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op> bool compare( long long lhs, unsigned char rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
|
||||||
|
// unsigned long long to X
|
||||||
|
template<Operator Op> bool compare( unsigned long long lhs, int rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op> bool compare( unsigned long long lhs, long rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op> bool compare( unsigned long long lhs, long long rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op> bool compare( unsigned long long lhs, char rhs ) {
|
||||||
|
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
|
||||||
|
// pointer to long long (when comparing against NULL)
|
||||||
|
template<Operator Op, typename T> bool compare( long long lhs, T* rhs ) {
|
||||||
|
return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op, typename T> bool compare( T* lhs, long long rhs ) {
|
||||||
|
return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
|
||||||
|
}
|
||||||
|
#endif // CATCH_CONFIG_CPP11_LONG_LONG
|
||||||
|
|
||||||
|
#ifdef CATCH_CONFIG_CPP11_NULLPTR
|
||||||
|
// pointer to nullptr_t (when comparing against nullptr)
|
||||||
|
template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
|
||||||
|
return Evaluator<T*, T*, Op>::evaluate( nullptr, rhs );
|
||||||
|
}
|
||||||
|
template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
|
||||||
|
return Evaluator<T*, T*, Op>::evaluate( lhs, nullptr );
|
||||||
|
}
|
||||||
|
#endif // CATCH_CONFIG_CPP11_NULLPTR
|
||||||
|
|
||||||
} // end of namespace Internal
|
} // end of namespace Internal
|
||||||
} // end of namespace Catch
|
} // end of namespace Catch
|
||||||
@@ -1837,7 +1910,7 @@ public:
|
|||||||
|
|
||||||
void endExpression() const {
|
void endExpression() const {
|
||||||
m_rb
|
m_rb
|
||||||
.setResultType( Internal::Evaluator<LhsT, RhsT, Op>::evaluate( m_lhs, m_rhs ) )
|
.setResultType( Internal::compare<Op>( m_lhs, m_rhs ) )
|
||||||
.endExpression( *this );
|
.endExpression( *this );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6526,6 +6599,7 @@ namespace Catch {
|
|||||||
|
|
||||||
#endif // not Windows
|
#endif // not Windows
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -7219,9 +7293,9 @@ namespace Catch {
|
|||||||
result_type operator()( result_type n ) const { return std::rand() % n; }
|
result_type operator()( result_type n ) const { return std::rand() % n; }
|
||||||
|
|
||||||
#ifdef CATCH_CONFIG_CPP11_SHUFFLE
|
#ifdef CATCH_CONFIG_CPP11_SHUFFLE
|
||||||
static constexpr result_type min() { return 0; }
|
static constexpr result_type (min)() { return 0; }
|
||||||
static constexpr result_type max() { return 1000000; }
|
static constexpr result_type (max)() { return 1000000; }
|
||||||
result_type operator()() const { return std::rand() % max(); }
|
result_type operator()() const { return std::rand() % (max)(); }
|
||||||
#endif
|
#endif
|
||||||
template<typename V>
|
template<typename V>
|
||||||
static void shuffle( V& vector ) {
|
static void shuffle( V& vector ) {
|
||||||
@@ -8393,7 +8467,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline Version libraryVersion() {
|
inline Version libraryVersion() {
|
||||||
static Version version( 1, 11, 0, "", 0 );
|
static Version version( 1, 12, 2, "", 0 );
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8428,11 +8502,18 @@ namespace Catch {
|
|||||||
: m_info( other.m_info )
|
: m_info( other.m_info )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4996) // std::uncaught_exception is deprecated in C++17
|
||||||
|
#endif
|
||||||
ScopedMessage::~ScopedMessage() {
|
ScopedMessage::~ScopedMessage() {
|
||||||
if ( !std::uncaught_exception() ){
|
if ( !std::uncaught_exception() ){
|
||||||
getResultCapture().popScopedMessage(m_info);
|
getResultCapture().popScopedMessage(m_info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
@@ -9091,6 +9172,8 @@ std::string toString( std::nullptr_t ) {
|
|||||||
// #included from: catch_result_builder.hpp
|
// #included from: catch_result_builder.hpp
|
||||||
#define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED
|
#define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
ResultBuilder::ResultBuilder( char const* macroName,
|
ResultBuilder::ResultBuilder( char const* macroName,
|
||||||
@@ -10207,12 +10290,12 @@ namespace Catch {
|
|||||||
|
|
||||||
bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
|
bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
|
||||||
|
|
||||||
if( includeResults ) {
|
if( includeResults || result.getResultType() == ResultWas::Warning ) {
|
||||||
// Print any info messages in <Info> tags.
|
// Print any info messages in <Info> tags.
|
||||||
for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
|
for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
|
||||||
it != itEnd;
|
it != itEnd;
|
||||||
++it ) {
|
++it ) {
|
||||||
if( it->type == ResultWas::Info ) {
|
if( it->type == ResultWas::Info && includeResults ) {
|
||||||
m_xml.scopedElement( "Info" )
|
m_xml.scopedElement( "Info" )
|
||||||
.writeText( it->message );
|
.writeText( it->message );
|
||||||
} else if ( it->type == ResultWas::Warning ) {
|
} else if ( it->type == ResultWas::Warning ) {
|
||||||
@@ -10584,6 +10667,7 @@ namespace Catch {
|
|||||||
// #included from: ../reporters/catch_reporter_console.hpp
|
// #included from: ../reporters/catch_reporter_console.hpp
|
||||||
#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED
|
#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
|
@@ -10,7 +10,7 @@ class CatchConanTest(ConanFile):
|
|||||||
settings = "os", "compiler", "arch", "build_type"
|
settings = "os", "compiler", "arch", "build_type"
|
||||||
username = getenv("CONAN_USERNAME", "philsquared")
|
username = getenv("CONAN_USERNAME", "philsquared")
|
||||||
channel = getenv("CONAN_CHANNEL", "testing")
|
channel = getenv("CONAN_CHANNEL", "testing")
|
||||||
requires = "Catch/1.11.0@%s/%s" % (username, channel)
|
requires = "Catch/1.12.2@%s/%s" % (username, channel)
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
cmake = CMake(self)
|
cmake = CMake(self)
|
||||||
|
Reference in New Issue
Block a user