11#ifndef ZEROERR_DISABLE_COMPLEX_AND_OR
20#define AND &&zeroerr::ExpressionDecomposer() <<
21#define OR || zeroerr::ExpressionDecomposer() <<
28#define ZEROERR_SFINAE_OP(ret, op) \
29 typename std::decay<decltype(std::declval<L>() op std::declval<R>(), std::declval<ret>())>::type
33 static const bool value =
false;
36#define ZEROERR_EXPRESSION_COMPARISON(op, op_name) \
37 template <typename R> \
38 ZEROERR_DIAGNOSTIC_NOINLINE ZEROERR_SFINAE_OP(Expression<R>, op) operator op(R&& rhs) { \
39 zeroerr::String text = \
40 detail::comparisonText(decomp, detail::makeDiagnosticValue(lhs), " " #op " ", \
41 detail::makeDiagnosticValue(rhs), res); \
42 return Expression<R>(static_cast<R&&>(rhs), res && (lhs op rhs), std::move(text)); \
44 template <typename R, \
45 typename std::enable_if<!std::is_rvalue_reference<R>::value, void>::type* = nullptr> \
46 ZEROERR_DIAGNOSTIC_NOINLINE ZEROERR_SFINAE_OP(Expression<const R&>, op) operator op( \
48 zeroerr::String text = \
49 detail::comparisonText(decomp, detail::makeDiagnosticValue(lhs), " " #op " ", \
50 detail::makeDiagnosticValue(rhs), res); \
51 return Expression<const R&>(rhs, res && (lhs op rhs), std::move(text)); \
55#define ZEROERR_EXPRESSION_ANDOR(op, op_name) \
56 ExprResult operator op(ExprResult rhs) { \
57 return ExprResult(res op rhs.res, \
58 detail::joinDiagnostic(decomp, " " #op " ", rhs.decomp)); \
62#define ZEROERR_FORBIT_EXPRESSION(rt, op) \
63 template <typename R> \
64 rt& operator op(const R&) { \
65 static_assert(deferred_false<R>::value, \
66 "Please Rewrite Expression As Binary Comparison!"); \
106template <
typename T,
typename =
void>
111 : std::integral_constant<
112 bool, !(std::is_enum<typename std::decay<T>::type>::value &&
113 !std::is_convertible<typename std::decay<T>::type, int>::value)> {};
116typename std::enable_if<has_bool_conversion<T>::value,
bool>::type
getBool(T&& lhs) {
117 return static_cast<bool>(lhs);
121typename std::enable_if<!has_bool_conversion<T>::value,
bool>::type
getBool(T&&) {
132 explicit Expression(L&& in) : lhs(static_cast<L&&>(in)) { res = details::getBool(lhs); }
134 : lhs(static_cast<L&&>(in)), res(res), decomp(static_cast<
zeroerr::
String&&>(decomp)) {}
137 if (decomp.
empty()) {
138 decomp = detail::valueText(detail::makeDiagnosticValue(lhs));
143 operator L()
const {
return lhs; }
173#undef ZEROERR_EXPRESSION_COMPARISON
174#undef ZEROERR_EXPRESSION_ANDOR
175#undef ZEROERR_FORBIT_EXPRESSION
185 template <
typename L>
191 template <
typename L,
192 typename std::enable_if<!std::is_rvalue_reference<L>::value,
void>::type* =
nullptr>
205 virtual bool match(
const T&)
const = 0;
215 p = std::move(other.p);
219 p = std::move(other.p);
242 : lhs(
std::move(lhs)), rhs(
std::move(rhs)), is_and(is_and) {}
248 virtual bool match(
const T& t)
const override {
250 return lhs->match(t) && rhs->match(t);
252 return lhs->match(t) || rhs->match(t);
263 virtual bool match(
const T& t)
const override {
return !matcher->match(t); }
287 virtual bool match(
const T& t)
const override {
289 for (
auto i = start.begin(), j = t.begin(); i != start.end(); ++i, ++j) {
290 if (j == t.end() || *i != *j) {
300typename std::enable_if<std::is_constructible<zeroerr::String, T>::value,
301 IMatcherRef<zeroerr::String>>::type
Definition decomposition.h:239
IMatcherRef< T > lhs
Definition decomposition.h:244
IMatcherRef< T > rhs
Definition decomposition.h:245
virtual bool match(const T &t) const override
Definition decomposition.h:248
bool is_and
Definition decomposition.h:246
CombinedMatcher(IMatcherRef< T > &&lhs, IMatcherRef< T > &&rhs, bool is_and)
Definition decomposition.h:241
Definition decomposition.h:209
IMatcherRef(IMatcherRef &&other)
Definition decomposition.h:214
IMatcherRef(const IMatcher< T > *ptr)
Definition decomposition.h:211
void operator=(IMatcherRef &&other)
Definition decomposition.h:218
IMatcherRef(const IMatcherRef &)=delete
IMatcherRef & operator=(const IMatcherRef &)=delete
const IMatcher< T > * operator->() const
Definition decomposition.h:231
~IMatcherRef()
Definition decomposition.h:223
Definition decomposition.h:200
virtual bool match(const T &) const =0
virtual ~IMatcher()=default
Definition decomposition.h:258
IMatcherRef< T > matcher
Definition decomposition.h:261
NotMatcher(IMatcherRef< T > &&matcher)
Definition decomposition.h:260
virtual bool match(const T &t) const override
Definition decomposition.h:263
bool empty() const noexcept
Definition string.h:80
#define ZEROERR_SUPPRESS_COMPARE
Definition config.h:318
#define ZEROERR_SUPPRESS_COMMON_WARNINGS_POP
Definition config.h:283
#define ZEROERR_SUPPRESS_COMPARE_POP
Definition config.h:331
#define ZEROERR_SUPPRESS_COMMON_WARNINGS_PUSH
Definition config.h:235
#define ZEROERR_FORBIT_EXPRESSION(rt, op)
Definition decomposition.h:62
#define ZEROERR_EXPRESSION_ANDOR(op, op_name)
Definition decomposition.h:55
#define ZEROERR_EXPRESSION_COMPARISON(op, op_name)
Definition decomposition.h:36
std::enable_if< has_bool_conversion< T >::value, bool >::type getBool(T &&lhs)
Definition decomposition.h:116
Definition assert_text.cpp:5
std::enable_if< std::is_constructible< zeroerr::String, T >::value, IMatcherRef< zeroerr::String > >::type start_with(T &&s)
Definition decomposition.h:302
Definition decomposition.h:70
bool res
Definition decomposition.h:71
zeroerr::String decomp
Definition decomposition.h:72
ExprResult(bool res, zeroerr::String decomposition="")
Definition decomposition.h:74
Definition decomposition.h:177
Definition decomposition.h:127
zeroerr::String decomp
Definition decomposition.h:130
L lhs
Definition decomposition.h:128
Expression(L &&in)
Definition decomposition.h:132
Expression(L &&in, bool res, zeroerr::String &&decomp)
Definition decomposition.h:133
Definition decomposition.h:283
StartWithMatcher(const T &s)
Definition decomposition.h:284
virtual bool match(const T &t) const override
Definition decomposition.h:287
T start
Definition decomposition.h:285
Definition decomposition.h:32
static const bool value
Definition decomposition.h:33
Definition decomposition.h:107