| 281 | |
| 282 | template <class T, class Operator> |
| 283 | struct lhs_expression |
| 284 | { |
| 285 | T lhs; |
| 286 | explicit lhs_expression(T e) : lhs(std::move(e)) {} |
| 287 | |
| 288 | friend std::ostream& operator<<(std::ostream& s, const lhs_expression& self) |
| 289 | { |
| 290 | std::string op = Operator::as_string(); |
| 291 | if(not op.empty()) |
| 292 | s << Operator::as_string() << " "; |
| 293 | print_stream(s, self.lhs); |
| 294 | return s; |
| 295 | } |
| 296 | |
| 297 | friend decltype(auto) get_value(const lhs_expression& e) { return e.value(); } |
| 298 | |
| 299 | decltype(auto) value() const { return Operator::call(get_value(lhs)); } |
| 300 | |
| 301 | TEST_FOREACH_BINARY_OPERATORS(TEST_EXPR_BINARY_OPERATOR) |
| 302 | TEST_FOREACH_UNARY_OPERATORS(TEST_EXPR_UNARY_OPERATOR) |
| 303 | |
| 304 | // NOLINTNEXTLINE |
| 305 | #define TEST_LHS_REOPERATOR(op) \ |
| 306 | template <class U> \ |
| 307 | auto operator op(const U& rhs) const \ |
| 308 | { \ |
| 309 | return make_lhs_expression(lhs op rhs); \ |
| 310 | } |
| 311 | TEST_LHS_REOPERATOR(+) |
| 312 | TEST_LHS_REOPERATOR(-) |
| 313 | TEST_LHS_REOPERATOR(*) |
| 314 | TEST_LHS_REOPERATOR(/) |
| 315 | TEST_LHS_REOPERATOR(%) |
| 316 | TEST_LHS_REOPERATOR(&) |
| 317 | TEST_LHS_REOPERATOR(|) |
| 318 | TEST_LHS_REOPERATOR(^) |
| 319 | }; |
| 320 | |
| 321 | template <class F> |
| 322 | struct predicate |
nothing calls this directly
no test coverage detected