@@ -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
0 commit comments