mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-25 23:06:10 +01:00
parent
ae1644e7e9
commit
291c502f66
@ -13,6 +13,7 @@
|
|||||||
#include <catch2/internal/catch_meta.hpp>
|
#include <catch2/internal/catch_meta.hpp>
|
||||||
#include <catch2/internal/catch_compare_traits.hpp>
|
#include <catch2/internal/catch_compare_traits.hpp>
|
||||||
#include <catch2/internal/catch_test_failure_exception.hpp>
|
#include <catch2/internal/catch_test_failure_exception.hpp>
|
||||||
|
#include <catch2/internal/catch_logical_traits.hpp>
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
@ -168,18 +169,19 @@ namespace Catch {
|
|||||||
template < \
|
template < \
|
||||||
typename RhsT, \
|
typename RhsT, \
|
||||||
std::enable_if_t< \
|
std::enable_if_t< \
|
||||||
Detail::is_##id##_comparable<LhsT, RhsT>::value && \
|
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
|
||||||
!std::is_arithmetic<std::remove_reference_t<RhsT>>::value, \
|
Detail::negation<std::is_arithmetic< \
|
||||||
|
std::remove_reference_t<RhsT>>>>::value, \
|
||||||
int> = 0> \
|
int> = 0> \
|
||||||
friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
|
friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
|
||||||
->BinaryExpr<LhsT, RhsT const&> { \
|
->BinaryExpr<LhsT, RhsT const&> { \
|
||||||
return { \
|
return { \
|
||||||
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||||
} \
|
} \
|
||||||
template < \
|
template <typename RhsT, \
|
||||||
typename RhsT, \
|
std::enable_if_t<Detail::conjunction< \
|
||||||
std::enable_if_t<Detail::is_##id##_comparable<LhsT, RhsT>::value && \
|
Detail::is_##id##_comparable<LhsT, RhsT>, \
|
||||||
std::is_arithmetic<RhsT>::value, \
|
std::is_arithmetic<RhsT>>::value, \
|
||||||
int> = 0> \
|
int> = 0> \
|
||||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||||
->BinaryExpr<LhsT, RhsT> { \
|
->BinaryExpr<LhsT, RhsT> { \
|
||||||
@ -188,35 +190,33 @@ namespace Catch {
|
|||||||
} \
|
} \
|
||||||
template < \
|
template < \
|
||||||
typename RhsT, \
|
typename RhsT, \
|
||||||
std::enable_if_t<!Detail::is_##id##_comparable<LhsT, RhsT>::value && \
|
std::enable_if_t< \
|
||||||
Detail::is_eq_0_comparable<LhsT>:: \
|
Detail::conjunction< \
|
||||||
value && /* We allow long because we want \
|
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
|
||||||
`ptr op NULL to be accepted */ \
|
Detail::is_eq_0_comparable<LhsT>, \
|
||||||
( std::is_same<RhsT, int>::value || \
|
Detail::disjunction<std::is_same<RhsT, int>, \
|
||||||
std::is_same<RhsT, long>::value ), \
|
/* On some platforms `NULL` is a long */ \
|
||||||
|
std::is_same<RhsT, long>>>::value, \
|
||||||
int> = 0> \
|
int> = 0> \
|
||||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||||
->BinaryExpr<LhsT, RhsT> { \
|
->BinaryExpr<LhsT, RhsT> { \
|
||||||
if ( rhs != 0 ) { \
|
if ( rhs != 0 ) { throw_test_failure_exception(); } \
|
||||||
throw_test_failure_exception(); \
|
|
||||||
} \
|
|
||||||
return { \
|
return { \
|
||||||
static_cast<bool>( lhs.m_lhs op 0 ), lhs.m_lhs, #op##_sr, rhs }; \
|
static_cast<bool>( lhs.m_lhs op 0 ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||||
} \
|
} \
|
||||||
template < \
|
template < \
|
||||||
typename RhsT, \
|
typename RhsT, \
|
||||||
std::enable_if_t<!Detail::is_##id##_comparable<LhsT, RhsT>::value && \
|
std::enable_if_t< \
|
||||||
Detail::is_eq_0_comparable<RhsT>:: \
|
Detail::conjunction< \
|
||||||
value && /* We allow long because we want \
|
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
|
||||||
`ptr op NULL` to be accepted */ \
|
Detail::is_eq_0_comparable<RhsT>, \
|
||||||
( std::is_same<LhsT, int>::value || \
|
Detail::disjunction<std::is_same<LhsT, int>, \
|
||||||
std::is_same<LhsT, long>::value ), \
|
/* On some platforms `NULL` is a long */ \
|
||||||
|
std::is_same<LhsT, long>>>::value, \
|
||||||
int> = 0> \
|
int> = 0> \
|
||||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||||
->BinaryExpr<LhsT, RhsT> { \
|
->BinaryExpr<LhsT, RhsT> { \
|
||||||
if ( lhs.m_lhs != 0 ) { \
|
if ( lhs.m_lhs != 0 ) { throw_test_failure_exception(); } \
|
||||||
throw_test_failure_exception(); \
|
|
||||||
} \
|
|
||||||
return { static_cast<bool>( 0 op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
return { static_cast<bool>( 0 op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||||
}
|
}
|
||||||
CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( eq, == )
|
CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( eq, == )
|
||||||
@ -228,18 +228,19 @@ namespace Catch {
|
|||||||
template < \
|
template < \
|
||||||
typename RhsT, \
|
typename RhsT, \
|
||||||
std::enable_if_t< \
|
std::enable_if_t< \
|
||||||
Detail::is_##id##_comparable<LhsT, RhsT>::value && \
|
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
|
||||||
!std::is_arithmetic<std::remove_reference_t<RhsT>>::value, \
|
Detail::negation<std::is_arithmetic< \
|
||||||
|
std::remove_reference_t<RhsT>>>>::value, \
|
||||||
int> = 0> \
|
int> = 0> \
|
||||||
friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
|
friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
|
||||||
->BinaryExpr<LhsT, RhsT const&> { \
|
->BinaryExpr<LhsT, RhsT const&> { \
|
||||||
return { \
|
return { \
|
||||||
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||||
} \
|
} \
|
||||||
template < \
|
template <typename RhsT, \
|
||||||
typename RhsT, \
|
std::enable_if_t<Detail::conjunction< \
|
||||||
std::enable_if_t<Detail::is_##id##_comparable<LhsT, RhsT>::value && \
|
Detail::is_##id##_comparable<LhsT, RhsT>, \
|
||||||
std::is_arithmetic<RhsT>::value, \
|
std::is_arithmetic<RhsT>>::value, \
|
||||||
int> = 0> \
|
int> = 0> \
|
||||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||||
->BinaryExpr<LhsT, RhsT> { \
|
->BinaryExpr<LhsT, RhsT> { \
|
||||||
@ -248,29 +249,29 @@ namespace Catch {
|
|||||||
} \
|
} \
|
||||||
template < \
|
template < \
|
||||||
typename RhsT, \
|
typename RhsT, \
|
||||||
std::enable_if_t<!Detail::is_##id##_comparable<LhsT, RhsT>::value && \
|
std::enable_if_t< \
|
||||||
Detail::is_##id##_0_comparable<LhsT>::value && \
|
Detail::conjunction< \
|
||||||
std::is_same<RhsT, int>::value, \
|
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
|
||||||
|
Detail::is_##id##_0_comparable<LhsT>, \
|
||||||
|
std::is_same<RhsT, int>>::value, \
|
||||||
int> = 0> \
|
int> = 0> \
|
||||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||||
->BinaryExpr<LhsT, RhsT> { \
|
->BinaryExpr<LhsT, RhsT> { \
|
||||||
if ( rhs != 0 ) { \
|
if ( rhs != 0 ) { throw_test_failure_exception(); } \
|
||||||
throw_test_failure_exception(); \
|
|
||||||
} \
|
|
||||||
return { \
|
return { \
|
||||||
static_cast<bool>( lhs.m_lhs op 0 ), lhs.m_lhs, #op##_sr, rhs }; \
|
static_cast<bool>( lhs.m_lhs op 0 ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||||
} \
|
} \
|
||||||
template < \
|
template < \
|
||||||
typename RhsT, \
|
typename RhsT, \
|
||||||
std::enable_if_t<!Detail::is_##id##_comparable<LhsT, RhsT>::value && \
|
std::enable_if_t< \
|
||||||
Detail::is_##id##_0_comparable<RhsT>::value && \
|
Detail::conjunction< \
|
||||||
std::is_same<LhsT, int>::value, \
|
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
|
||||||
|
Detail::is_##id##_0_comparable<RhsT>, \
|
||||||
|
std::is_same<LhsT, int>>::value, \
|
||||||
int> = 0> \
|
int> = 0> \
|
||||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||||
->BinaryExpr<LhsT, RhsT> { \
|
->BinaryExpr<LhsT, RhsT> { \
|
||||||
if ( lhs.m_lhs != 0 ) { \
|
if ( lhs.m_lhs != 0 ) { throw_test_failure_exception(); } \
|
||||||
throw_test_failure_exception(); \
|
|
||||||
} \
|
|
||||||
return { static_cast<bool>( 0 op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
return { static_cast<bool>( 0 op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,3 +329,29 @@ TEST_CASE( "#2555 - types that can only be compared with 0 literal (not int/long
|
|||||||
REQUIRE( TypeWithLit0Comparisons{} != 0 );
|
REQUIRE( TypeWithLit0Comparisons{} != 0 );
|
||||||
REQUIRE_FALSE( 0 != TypeWithLit0Comparisons{} );
|
REQUIRE_FALSE( 0 != TypeWithLit0Comparisons{} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
struct MultipleImplicitConstructors {
|
||||||
|
MultipleImplicitConstructors( double ) {}
|
||||||
|
MultipleImplicitConstructors( int64_t ) {}
|
||||||
|
|
||||||
|
bool operator==( MultipleImplicitConstructors ) const { return true; }
|
||||||
|
bool operator!=( MultipleImplicitConstructors ) const { return true; }
|
||||||
|
bool operator<( MultipleImplicitConstructors ) const { return true; }
|
||||||
|
bool operator<=( MultipleImplicitConstructors ) const { return true; }
|
||||||
|
bool operator>( MultipleImplicitConstructors ) const { return true; }
|
||||||
|
bool operator>=( MultipleImplicitConstructors ) const { return true; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("#2571 - tests compile types that have multiple implicit constructors from lit 0",
|
||||||
|
"[compilation][approvals]") {
|
||||||
|
MultipleImplicitConstructors mic1( 0.0 );
|
||||||
|
MultipleImplicitConstructors mic2( 0.0 );
|
||||||
|
REQUIRE( mic1 == mic2 );
|
||||||
|
REQUIRE( mic1 != mic2 );
|
||||||
|
REQUIRE( mic1 < mic2 );
|
||||||
|
REQUIRE( mic1 <= mic2 );
|
||||||
|
REQUIRE( mic1 > mic2 );
|
||||||
|
REQUIRE( mic1 >= mic2 );
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user