Skip to content

Commit 07b9bda

Browse files
committed
Revert backport of new evaluate layer to fix C++98 compilation
The backport fixed some bugs (ie #981), but caused strict C++98 (and MSVC 9) compilers to fail. This means that we will reintroduce some issues but get back compatibility with obsolete compilers. People using newer ones can keep using Catch2. This reverts commit b6e7c9b. This reverts commit b7bd52c. Should fix #1103
1 parent 84e8b69 commit 07b9bda

File tree

2 files changed

+132
-59
lines changed

2 files changed

+132
-59
lines changed

include/internal/catch_evaluate.hpp

Lines changed: 131 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,12 @@ namespace Internal {
3838
template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
3939

4040
template<typename T>
41-
T& removeConst(T const &t) { return const_cast<T&>(t); }
41+
T& opCast(T const& t) { return const_cast<T&>(t); }
42+
43+
// nullptr_t support based on pull request #154 from Konstantin Baumann
4244
#ifdef CATCH_CONFIG_CPP11_NULLPTR
43-
inline std::nullptr_t removeConst(std::nullptr_t) { return nullptr; }
44-
#endif
45+
inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
46+
#endif // CATCH_CONFIG_CPP11_NULLPTR
4547

4648

4749
// So the compare overloads can be operator agnostic we convey the operator as a template
@@ -52,90 +54,161 @@ namespace Internal {
5254
template<typename T1, typename T2>
5355
struct Evaluator<T1, T2, IsEqualTo> {
5456
static bool evaluate( T1 const& lhs, T2 const& rhs) {
55-
return bool(removeConst(lhs) == removeConst(rhs) );
57+
return bool( opCast( lhs ) == opCast( rhs ) );
5658
}
5759
};
5860
template<typename T1, typename T2>
5961
struct Evaluator<T1, T2, IsNotEqualTo> {
6062
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
61-
return bool(removeConst(lhs) != removeConst(rhs) );
63+
return bool( opCast( lhs ) != opCast( rhs ) );
6264
}
6365
};
6466
template<typename T1, typename T2>
6567
struct Evaluator<T1, T2, IsLessThan> {
6668
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
67-
return bool(removeConst(lhs) < removeConst(rhs) );
69+
return bool( opCast( lhs ) < opCast( rhs ) );
6870
}
6971
};
7072
template<typename T1, typename T2>
7173
struct Evaluator<T1, T2, IsGreaterThan> {
7274
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
73-
return bool(removeConst(lhs) > removeConst(rhs) );
75+
return bool( opCast( lhs ) > opCast( rhs ) );
7476
}
7577
};
7678
template<typename T1, typename T2>
7779
struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
7880
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
79-
return bool(removeConst(lhs) >= removeConst(rhs) );
81+
return bool( opCast( lhs ) >= opCast( rhs ) );
8082
}
8183
};
8284
template<typename T1, typename T2>
8385
struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
8486
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
85-
return bool(removeConst(lhs) <= removeConst(rhs) );
87+
return bool( opCast( lhs ) <= opCast( rhs ) );
8688
}
8789
};
8890

89-
// Special case for comparing a pointer to an int (deduced for p==0)
90-
template<typename T>
91-
struct Evaluator<int const&, T* const&, IsEqualTo> {
92-
static bool evaluate( int lhs, T* rhs) {
93-
return reinterpret_cast<void const*>( lhs ) == rhs;
94-
}
95-
};
96-
template<typename T>
97-
struct Evaluator<T* const&, int const&, IsEqualTo> {
98-
static bool evaluate( T* lhs, int rhs) {
99-
return lhs == reinterpret_cast<void const*>( rhs );
100-
}
101-
};
102-
template<typename T>
103-
struct Evaluator<int const&, T* const&, IsNotEqualTo> {
104-
static bool evaluate( int lhs, T* rhs) {
105-
return reinterpret_cast<void const*>( lhs ) != rhs;
106-
}
107-
};
108-
template<typename T>
109-
struct Evaluator<T* const&, int const&, IsNotEqualTo> {
110-
static bool evaluate( T* lhs, int rhs) {
111-
return lhs != reinterpret_cast<void const*>( rhs );
112-
}
113-
};
91+
template<Operator Op, typename T1, typename T2>
92+
bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
93+
return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
94+
}
11495

115-
template<typename T>
116-
struct Evaluator<long const&, T* const&, IsEqualTo> {
117-
static bool evaluate( long lhs, T* rhs) {
118-
return reinterpret_cast<void const*>( lhs ) == rhs;
119-
}
120-
};
121-
template<typename T>
122-
struct Evaluator<T* const&, long const&, IsEqualTo> {
123-
static bool evaluate( T* lhs, long rhs) {
124-
return lhs == reinterpret_cast<void const*>( rhs );
125-
}
126-
};
127-
template<typename T>
128-
struct Evaluator<long const&, T* const&, IsNotEqualTo> {
129-
static bool evaluate( long lhs, T* rhs) {
130-
return reinterpret_cast<void const*>( lhs ) != rhs;
131-
}
132-
};
133-
template<typename T>
134-
struct Evaluator<T* const&, long const&, IsNotEqualTo> {
135-
static bool evaluate( T* lhs, long rhs) {
136-
return lhs != reinterpret_cast<void const*>( rhs );
137-
}
138-
};
96+
// This level of indirection allows us to specialise for integer types
97+
// to avoid signed/ unsigned warnings
98+
99+
// "base" overload
100+
template<Operator Op, typename T1, typename T2>
101+
bool compare( T1 const& lhs, T2 const& rhs ) {
102+
return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
103+
}
104+
105+
// unsigned X to int
106+
template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
107+
return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
108+
}
109+
template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
110+
return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
111+
}
112+
template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
113+
return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
114+
}
115+
116+
// unsigned X to long
117+
template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
118+
return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
119+
}
120+
template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
121+
return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
122+
}
123+
template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
124+
return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
125+
}
126+
127+
// int to unsigned X
128+
template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
129+
return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
130+
}
131+
template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
132+
return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
133+
}
134+
template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
135+
return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
136+
}
137+
138+
// long to unsigned X
139+
template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
140+
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
141+
}
142+
template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
143+
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
144+
}
145+
template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
146+
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
147+
}
148+
149+
// pointer to long (when comparing against NULL)
150+
template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
151+
return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
152+
}
153+
template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
154+
return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
155+
}
156+
157+
// pointer to int (when comparing against NULL)
158+
template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
159+
return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
160+
}
161+
template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
162+
return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
163+
}
164+
165+
#ifdef CATCH_CONFIG_CPP11_LONG_LONG
166+
// long long to unsigned X
167+
template<Operator Op> bool compare( long long lhs, unsigned int rhs ) {
168+
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
169+
}
170+
template<Operator Op> bool compare( long long lhs, unsigned long rhs ) {
171+
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
172+
}
173+
template<Operator Op> bool compare( long long lhs, unsigned long long rhs ) {
174+
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
175+
}
176+
template<Operator Op> bool compare( long long lhs, unsigned char rhs ) {
177+
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
178+
}
179+
180+
// unsigned long long to X
181+
template<Operator Op> bool compare( unsigned long long lhs, int rhs ) {
182+
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
183+
}
184+
template<Operator Op> bool compare( unsigned long long lhs, long rhs ) {
185+
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
186+
}
187+
template<Operator Op> bool compare( unsigned long long lhs, long long rhs ) {
188+
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
189+
}
190+
template<Operator Op> bool compare( unsigned long long lhs, char rhs ) {
191+
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
192+
}
193+
194+
// pointer to long long (when comparing against NULL)
195+
template<Operator Op, typename T> bool compare( long long lhs, T* rhs ) {
196+
return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
197+
}
198+
template<Operator Op, typename T> bool compare( T* lhs, long long rhs ) {
199+
return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
200+
}
201+
#endif // CATCH_CONFIG_CPP11_LONG_LONG
202+
203+
#ifdef CATCH_CONFIG_CPP11_NULLPTR
204+
// pointer to nullptr_t (when comparing against nullptr)
205+
template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
206+
return Evaluator<T*, T*, Op>::evaluate( nullptr, rhs );
207+
}
208+
template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
209+
return Evaluator<T*, T*, Op>::evaluate( lhs, nullptr );
210+
}
211+
#endif // CATCH_CONFIG_CPP11_NULLPTR
139212

140213
} // end of namespace Internal
141214
} // end of namespace Catch

include/internal/catch_expression_lhs.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ class BinaryExpression : public DecomposedExpression {
111111

112112
void endExpression() const {
113113
m_rb
114-
.setResultType( Internal::Evaluator<LhsT, RhsT, Op>::evaluate( m_lhs, m_rhs ) )
114+
.setResultType( Internal::compare<Op>( m_lhs, m_rhs ) )
115115
.endExpression( *this );
116116
}
117117

0 commit comments

Comments
 (0)