Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
catch_decomposer.h
Go to the documentation of this file.
1/*
2 * Created by Phil Nash on 8/8/2017.
3 * Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
4 *
5 * Distributed under the Boost Software License, Version 1.0. (See accompanying
6 * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 */
8#ifndef TWOBLUECUBES_CATCH_DECOMPOSER_H_INCLUDED
9#define TWOBLUECUBES_CATCH_DECOMPOSER_H_INCLUDED
10
11#include "catch_tostring.h"
12#include "catch_stringref.h"
13#include "catch_meta.hpp"
14
15#include <iosfwd>
16
17#ifdef _MSC_VER
18#pragma warning(push)
19#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
20#pragma warning(disable:4018) // more "signed/unsigned mismatch"
21#pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
22#pragma warning(disable:4180) // qualifier applied to function type has no meaning
23#pragma warning(disable:4800) // Forcing result to true or false
24#endif
25
26namespace Catch {
27
28 struct ITransientExpression {
29 auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
30 auto getResult() const -> bool { return m_result; }
31 virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
32
37
38 // We don't actually need a virtual destructor, but many static analysers
39 // complain if it's not here :-(
41
44
45 };
46
47 void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
48
49 template<typename LhsT, typename RhsT>
50 class BinaryExpr : public ITransientExpression {
51 LhsT m_lhs;
52 StringRef m_op;
53 RhsT m_rhs;
54
55 void streamReconstructedExpression( std::ostream &os ) const override {
57 ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
58 }
59
60 public:
61 BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
62 : ITransientExpression{ true, comparisonResult },
63 m_lhs( lhs ),
64 m_op( op ),
65 m_rhs( rhs )
66 {}
67
68 template<typename T>
70 static_assert(always_false<T>::value,
71 "chained comparisons are not supported inside assertions, "
72 "wrap the expression inside parentheses, or decompose it");
73 }
74
75 template<typename T>
77 static_assert(always_false<T>::value,
78 "chained comparisons are not supported inside assertions, "
79 "wrap the expression inside parentheses, or decompose it");
80 }
81
82 template<typename T>
84 static_assert(always_false<T>::value,
85 "chained comparisons are not supported inside assertions, "
86 "wrap the expression inside parentheses, or decompose it");
87 }
88
89 template<typename T>
91 static_assert(always_false<T>::value,
92 "chained comparisons are not supported inside assertions, "
93 "wrap the expression inside parentheses, or decompose it");
94 }
95
96 template<typename T>
98 static_assert(always_false<T>::value,
99 "chained comparisons are not supported inside assertions, "
100 "wrap the expression inside parentheses, or decompose it");
101 }
102
103 template<typename T>
105 static_assert(always_false<T>::value,
106 "chained comparisons are not supported inside assertions, "
107 "wrap the expression inside parentheses, or decompose it");
108 }
109
110 template<typename T>
112 static_assert(always_false<T>::value,
113 "chained comparisons are not supported inside assertions, "
114 "wrap the expression inside parentheses, or decompose it");
115 }
116
117 template<typename T>
119 static_assert(always_false<T>::value,
120 "chained comparisons are not supported inside assertions, "
121 "wrap the expression inside parentheses, or decompose it");
122 }
123 };
124
125 template<typename LhsT>
126 class UnaryExpr : public ITransientExpression {
127 LhsT m_lhs;
128
129 void streamReconstructedExpression( std::ostream &os ) const override {
130 os << Catch::Detail::stringify( m_lhs );
131 }
132
133 public:
134 explicit UnaryExpr( LhsT lhs )
135 : ITransientExpression{ false, static_cast<bool>(lhs) },
136 m_lhs( lhs )
137 {}
138 };
139
140
141 // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
142 template<typename LhsT, typename RhsT>
143 auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }
144 template<typename T>
145 auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
146 template<typename T>
147 auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
148 template<typename T>
149 auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
150 template<typename T>
151 auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
152
153 template<typename LhsT, typename RhsT>
154 auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }
155 template<typename T>
156 auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
157 template<typename T>
158 auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
159 template<typename T>
160 auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
161 template<typename T>
162 auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
163
164
165 template<typename LhsT>
166 class ExprLhs {
167 LhsT m_lhs;
168 public:
169 explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
170
171 template<typename RhsT>
172 auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
173 return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs };
174 }
175 auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
176 return { m_lhs == rhs, m_lhs, "==", rhs };
177 }
178
179 template<typename RhsT>
180 auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
181 return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs };
182 }
183 auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {
184 return { m_lhs != rhs, m_lhs, "!=", rhs };
185 }
186
187 template<typename RhsT>
188 auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
189 return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs };
190 }
191 template<typename RhsT>
192 auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
193 return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs };
194 }
195 template<typename RhsT>
196 auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
197 return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs };
198 }
199 template<typename RhsT>
200 auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
201 return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs };
202 }
203
204 template<typename RhsT>
205 auto operator && ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
206 static_assert(always_false<RhsT>::value,
207 "operator&& is not supported inside assertions, "
208 "wrap the expression inside parentheses, or decompose it");
209 }
210
211 template<typename RhsT>
212 auto operator || ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
213 static_assert(always_false<RhsT>::value,
214 "operator|| is not supported inside assertions, "
215 "wrap the expression inside parentheses, or decompose it");
216 }
217
218 auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
219 return UnaryExpr<LhsT>{ m_lhs };
220 }
221 };
222
224
225 template<typename T>
226 void handleExpression( ExprLhs<T> const& expr ) {
227 handleExpression( expr.makeUnaryExpr() );
228 }
229
230 struct Decomposer {
231 template<typename T>
232 auto operator <= ( T const& lhs ) -> ExprLhs<T const&> {
233 return ExprLhs<T const&>{ lhs };
234 }
235
237 return ExprLhs<bool>{ value };
238 }
239 };
240
241} // end namespace Catch
242
243#ifdef _MSC_VER
244#pragma warning(pop)
245#endif
246
247#endif // TWOBLUECUBES_CATCH_DECOMPOSER_H_INCLUDED
auto operator==(T) const -> BinaryExpr< LhsT, RhsT const & > const
auto operator||(T) const -> BinaryExpr< LhsT, RhsT const & > const
auto operator<=(T) const -> BinaryExpr< LhsT, RhsT const & > const
BinaryExpr(bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs)
auto operator>=(T) const -> BinaryExpr< LhsT, RhsT const & > const
auto operator<(T) const -> BinaryExpr< LhsT, RhsT const & > const
auto operator>(T) const -> BinaryExpr< LhsT, RhsT const & > const
auto operator!=(T) const -> BinaryExpr< LhsT, RhsT const & > const
auto operator&&(T) const -> BinaryExpr< LhsT, RhsT const & > const
auto operator!=(RhsT const &rhs) -> BinaryExpr< LhsT, RhsT const & > const
auto operator>=(RhsT const &rhs) -> BinaryExpr< LhsT, RhsT const & > const
auto operator>(RhsT const &rhs) -> BinaryExpr< LhsT, RhsT const & > const
auto operator<=(RhsT const &rhs) -> BinaryExpr< LhsT, RhsT const & > const
auto makeUnaryExpr() const -> UnaryExpr< LhsT >
auto operator&&(RhsT const &) -> BinaryExpr< LhsT, RhsT const & > const
auto operator||(RhsT const &) -> BinaryExpr< LhsT, RhsT const & > const
auto operator==(RhsT const &rhs) -> BinaryExpr< LhsT, RhsT const & > const
auto operator<(RhsT const &rhs) -> BinaryExpr< LhsT, RhsT const & > const
os_t os
std::string stringify(const T &e)
void formatReconstructedExpression(std::ostream &os, std::string const &lhs, StringRef op, std::string const &rhs)
void handleExpression(ITransientExpression const &expr)
auto compareNotEqual(LhsT const &lhs, RhsT &&rhs) -> bool
auto compareEqual(LhsT const &lhs, RhsT const &rhs) -> bool
#define value
Definition pkcs11.h:157
#define T(meth, val, expected)
auto operator<=(T const &lhs) -> ExprLhs< T const & >
auto getResult() const -> bool
auto isBinaryExpression() const -> bool
virtual void streamReconstructedExpression(std::ostream &os) const =0
ITransientExpression(bool isBinaryExpression, bool result)