Expression Templates Library (ETL)
binary_expression_builder.hpp
Go to the documentation of this file.
1 //=======================================================================
2 // Copyright (c) 2014-2023 Baptiste Wicht
3 // Distributed under the terms of the MIT License.
4 // (See accompanying file LICENSE or copy at
5 // http://opensource.org/licenses/MIT)
6 //=======================================================================
7 
13 #pragma once
14 
15 #include "etl/concepts.hpp"
16 namespace etl {
17 
24 template <etl_expr LE, etl_expr RE>
25 auto operator-(LE&& lhs, RE&& rhs) {
26  validate_expression(lhs, rhs);
27 
28  return detail::left_binary_helper<LE, RE, minus_binary_op>{std::forward<LE>(lhs), std::forward<RE>(rhs)};
29 }
30 
37 template <etl_expr LE, etl_expr RE>
38 auto operator+(LE&& lhs, RE&& rhs) {
39  validate_expression(lhs, rhs);
40 
41  return detail::left_binary_helper<LE, RE, plus_binary_op>{std::forward<LE>(lhs), std::forward<RE>(rhs)};
42 }
43 
50 template <etl_expr LE, etl_expr RE>
51 auto operator>>(LE&& lhs, RE&& rhs) {
52  validate_expression(lhs, rhs);
53 
54  return detail::left_binary_helper<LE, RE, mul_binary_op>{std::forward<LE>(lhs), std::forward<RE>(rhs)};
55 }
56 
63 template <typename LE, typename RE>
64 auto scale(LE&& lhs, RE&& rhs) {
65  validate_expression(lhs, rhs);
66 
67  return detail::left_binary_helper<LE, RE, mul_binary_op>{std::forward<LE>(lhs), std::forward<RE>(rhs)};
68 }
69 
76 template <etl_expr LE, etl_expr RE>
77 auto operator/(LE&& lhs, RE&& rhs) {
78  validate_expression(lhs, rhs);
79 
80  return detail::left_binary_helper<LE, RE, div_binary_op>{std::forward<LE>(lhs), std::forward<RE>(rhs)};
81 }
82 
89 template <etl_expr LE, etl_expr RE>
90 auto operator%(LE&& lhs, RE&& rhs) {
91  validate_expression(lhs, rhs);
92 
93  return detail::left_binary_helper<LE, RE, mod_binary_op>{std::forward<LE>(lhs), std::forward<RE>(rhs)};
94 }
95 
96 // Mix scalars and ETL expressions (vector,matrix,binary,unary)
97 
104 template <etl_expr LE, std::convertible_to<value_t<LE>> RE>
105 auto operator-(LE&& lhs, RE rhs) {
107 }
108 
115 template <etl_expr RE, std::convertible_to<value_t<RE>> LE>
116 auto operator-(LE lhs, RE&& rhs) {
117  return detail::right_binary_helper<scalar<value_t<RE>>, RE, minus_binary_op>{scalar<value_t<RE>>(lhs), std::forward<RE>(rhs)};
118 }
119 
126 template <etl_expr LE, std::convertible_to<value_t<LE>> RE>
127 auto operator+(LE&& lhs, RE rhs) {
129 }
130 
137 template <etl_expr RE, std::convertible_to<value_t<RE>> LE>
138 auto operator+(LE lhs, RE&& rhs) {
139  return detail::right_binary_helper<scalar<value_t<RE>>, RE, plus_binary_op> {scalar<value_t<RE>>(lhs), std::forward<RE>(rhs)};
140 }
141 
148 template <etl_expr LE, std::convertible_to<value_t<LE>> RE>
149 auto operator*(LE&& lhs, RE rhs) {
151 }
152 
159 template <etl_expr RE, std::convertible_to<value_t<RE>> LE>
160 auto operator*(LE lhs, RE&& rhs) {
161  return detail::right_binary_helper<scalar<value_t<RE>>, RE, mul_binary_op> {scalar<value_t<RE>>(lhs), std::forward<RE>(rhs)};
162 }
163 
170 template <etl_expr LE, std::convertible_to<value_t<LE>> RE>
171 auto operator>>(LE&& lhs, RE rhs) {
173 }
174 
181 template <etl_expr RE, std::convertible_to<value_t<RE>> LE>
182 auto operator>>(LE lhs, RE&& rhs) {
183  return detail::right_binary_helper<scalar<value_t<RE>>, RE, mul_binary_op> {scalar<value_t<RE>>(lhs), std::forward<RE>(rhs)};
184 }
185 
192 template <etl_expr LE, std::convertible_to<value_t<LE>> RE>
193 auto operator/(LE&& lhs, RE rhs) {
194  if constexpr (is_div_strict || !std::floating_point<RE>) {
196  } else {
197  return detail::left_binary_helper<LE, scalar<value_t<LE>>, mul_binary_op> {std::forward<LE>(lhs), scalar<value_t<LE>>(value_t<LE>(1.0) / rhs)};
198  }
199 }
200 
207 template <etl_expr RE, std::convertible_to<value_t<RE>> LE>
208 auto operator/(LE lhs, RE&& rhs) {
209  return detail::right_binary_helper<scalar<value_t<RE>>, RE, div_binary_op> {scalar<value_t<RE>>(lhs), std::forward<RE>(rhs)};
210 }
211 
218 template <etl_expr LE, std::convertible_to<value_t<LE>> RE>
219 auto operator%(LE&& lhs, RE rhs) {
221 }
222 
229 template <etl_expr RE, std::convertible_to<value_t<RE>> LE>
230 auto operator%(LE lhs, RE&& rhs) {
231  return detail::right_binary_helper<scalar<value_t<RE>>, RE, mod_binary_op> {scalar<value_t<RE>>(lhs), std::forward<RE>(rhs)};
232 }
233 
234 // Compound operators
235 
242 template <simple_lhs LE, arithmetic RE>
243 decltype(auto) operator+=(LE&& lhs, RE rhs) {
244  etl::scalar<RE>(rhs).assign_add_to(lhs);
245  return std::forward<LE>(lhs);
246 }
247 
254 template <simple_lhs LE, etl_expr RE>
255 decltype(auto) operator+=(LE&& lhs, const RE & rhs) {
256  validate_expression(lhs, rhs);
257  rhs.assign_add_to(lhs);
258  return std::forward<LE>(lhs);
259 }
260 
267 template <simple_lhs LE, arithmetic RE>
268 decltype(auto) operator-=(LE&& lhs, RE rhs) {
269  etl::scalar<RE>(rhs).assign_sub_to(lhs);
270  return std::forward<LE>(lhs);
271 }
272 
279 template <simple_lhs LE, etl_expr RE>
280 decltype(auto) operator-=(LE&& lhs, const RE & rhs) {
281  validate_expression(lhs, rhs);
282  rhs.assign_sub_to(lhs);
283  return std::forward<LE>(lhs);
284 }
285 
292 template <simple_lhs LE, arithmetic RE>
293 decltype(auto) operator*=(LE&& lhs, RE rhs) {
294  etl::scalar<RE>(rhs).assign_mul_to(lhs);
295  return std::forward<LE>(lhs);
296 }
297 
304 template <simple_lhs LE, etl_expr RE>
305 decltype(auto) operator*=(LE&& lhs, const RE & rhs) {
306  validate_expression(lhs, rhs);
307  rhs.assign_mul_to(lhs);
308  return std::forward<LE>(lhs);
309 }
310 
317 template <simple_lhs LE, arithmetic RE>
318 decltype(auto) operator>>=(LE&& lhs, RE rhs) {
319  etl::scalar<RE>(rhs).assign_mul_to(lhs);
320  return std::forward<LE>(lhs);
321 }
322 
329 template <simple_lhs LE, etl_expr RE>
330 decltype(auto) operator>>=(LE&& lhs, const RE & rhs) {
331  validate_expression(lhs, rhs);
332  rhs.assign_mul_to(lhs);
333  return std::forward<LE>(lhs);
334 }
335 
342 template <simple_lhs LE, arithmetic RE>
343 decltype(auto) operator/=(LE&& lhs, RE rhs) {
344  etl::scalar<RE>(rhs).assign_div_to(lhs);
345  return std::forward<LE>(lhs);
346 }
347 
354 template <simple_lhs LE, etl_expr RE>
355 decltype(auto) operator/=(LE&& lhs, const RE & rhs) {
356  validate_expression(lhs, rhs);
357  rhs.assign_div_to(lhs);
358  return std::forward<LE>(lhs);
359 }
360 
367 template <simple_lhs LE, arithmetic RE>
368 decltype(auto) operator%=(LE&& lhs, RE rhs) {
369  etl::scalar<RE>(rhs).assign_mod_to(lhs);
370  return std::forward<LE>(lhs);
371 }
372 
379 template <simple_lhs LE, etl_expr RE>
380 decltype(auto) operator%=(LE&& lhs, const RE & rhs) {
381  validate_expression(lhs, rhs);
382  rhs.assign_mod_to(lhs);
383  return std::forward<LE>(lhs);
384 }
385 
386 // Comparison
387 
394 template <typename LE, typename RE>
395 auto equal(LE&& lhs, RE rhs) {
396  return detail::bool_left_binary_helper_scalar<LE, RE, equal_binary_op> {detail::wrap_scalar(lhs), detail::wrap_scalar(rhs)};
397 }
398 
405 template <typename LE, typename RE>
406 auto not_equal(LE&& lhs, RE rhs) {
407  return detail::bool_left_binary_helper_scalar<LE, RE, not_equal_binary_op> {detail::wrap_scalar(lhs), detail::wrap_scalar(rhs)};
408 }
409 
416 template <typename LE, typename RE>
417 auto less(LE&& lhs, RE rhs) {
418  return detail::bool_left_binary_helper_scalar<LE, RE, less_binary_op> {detail::wrap_scalar(lhs), detail::wrap_scalar(rhs)};
419 }
420 
427 template <typename LE, typename RE>
428 auto less_equal(LE&& lhs, RE rhs) {
429  return detail::bool_left_binary_helper_scalar<LE, RE, less_equal_binary_op> {detail::wrap_scalar(lhs), detail::wrap_scalar(rhs)};
430 }
431 
438 template <typename LE, typename RE>
439 auto greater(LE&& lhs, RE rhs) {
440  return detail::bool_left_binary_helper_scalar<LE, RE, greater_binary_op> {detail::wrap_scalar(lhs), detail::wrap_scalar(rhs)};
441 }
442 
449 template <typename LE, typename RE>
450 auto greater_equal(LE&& lhs, RE rhs) {
451  return detail::bool_left_binary_helper_scalar<LE, RE, greater_equal_binary_op> {detail::wrap_scalar(lhs), detail::wrap_scalar(rhs)};
452 }
453 
454 // Logical operators
455 
462 template <etl_expr LE, etl_expr RE>
463 auto logical_and(LE&& lhs, RE&& rhs) {
464  return detail::bool_left_binary_helper<LE, LE, logical_and_binary_op> {std::forward<LE>(lhs), std::forward<RE>(rhs)};
465 }
466 
473 template <etl_expr LE, std::convertible_to<value_t<LE>> RE>
474 auto logical_and(LE&& lhs, RE rhs) {
476 }
477 
484 template <etl_expr RE, std::convertible_to<value_t<RE>> LE>
485 auto logical_and(LE lhs, RE&& rhs) {
487 }
488 
495 template <etl_expr LE, etl_expr RE>
496 auto logical_xor(LE&& lhs, RE&& rhs) {
497  return detail::bool_left_binary_helper<LE, LE, logical_xor_binary_op> {std::forward<LE>(lhs), std::forward<RE>(rhs)};
498 }
499 
506 template <etl_expr LE, std::convertible_to<value_t<LE>> RE>
507 auto logical_xor(LE&& lhs, RE rhs) {
509 }
510 
517 template <etl_expr RE, std::convertible_to<value_t<RE>> LE>
518 auto logical_xor(LE lhs, RE&& rhs) {
520 }
521 
528 template <etl_expr LE, etl_expr RE>
529 auto logical_or(LE&& lhs, RE&& rhs) {
530  return detail::bool_left_binary_helper<LE, LE, logical_or_binary_op> {std::forward<LE>(lhs), std::forward<RE>(rhs)};
531 }
532 
539 template <etl_expr LE, std::convertible_to<value_t<LE>> RE>
540 auto logical_or(LE&& lhs, RE rhs) {
542 }
543 
550 template <etl_expr RE, std::convertible_to<value_t<RE>> LE>
551 auto logical_or(LE lhs, RE&& rhs) {
553 }
554 
555 } //end of namespace etl
void assign_add_to(L &&lhs) const
Add to the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:217
Binary operator for elementwise logical OR computation.
Definition: logical_or.hpp:18
Binary operator for elementwise logical and computation.
Definition: logical_and.hpp:18
void assign_div_to(L &&lhs) const
Divide the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:244
void assign_mul_to(L &&lhs) const
Multiply the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:235
Binary operator for elementwise logical XOR computation.
Definition: logical_xor.hpp:18
Binary operator for scalar subtraction.
Definition: minus.hpp:16
auto greater(LE &&lhs, RE rhs)
Builds an expression representing the elementwise greater than comparison of lhs and rhs...
Definition: binary_expression_builder.hpp:439
Binary operator for scalar division.
Definition: div.hpp:349
auto operator*(LE &&lhs, RE rhs)
Builds an expression representing the multiplication of lhs and rhs (scalar)
Definition: binary_expression_builder.hpp:149
A binary expression.
Definition: binary_expr.hpp:18
Binary operator for scalar modulo.
Definition: mod.hpp:16
Root namespace for the ETL library.
Definition: adapter.hpp:15
auto operator+(LE &&lhs, RE &&rhs)
Builds an expression representing the addition of lhs and rhs.
Definition: binary_expression_builder.hpp:38
auto scale(LE &&lhs, RE &&rhs)
Builds an expression representing the scalar multiplication of lhs and rhs.
Definition: binary_expression_builder.hpp:64
auto not_equal(LE &&lhs, RE rhs)
Builds an expression representing the elementwise comparison of lhs and rhs.
Definition: binary_expression_builder.hpp:406
auto logical_or(LE &&lhs, RE &&rhs)
Builds an expression representing the elementwise logical or of lhs and rhs.
Definition: binary_expression_builder.hpp:529
auto operator%(LE &&lhs, RE &&rhs)
Builds an expression representing the modulo of lhs and rhs.
Definition: binary_expression_builder.hpp:90
auto operator>>(LE &&lhs, RE &&rhs)
Builds an expression representing the scalar multipliation of lhs and rhs.
Definition: binary_expression_builder.hpp:51
Represents a scalar value.
Definition: concepts_base.hpp:19
constexpr bool is_div_strict
Boolean flag indicating if division can be done by multiplication (false) or not (true) ...
Definition: config.hpp:125
Binary operator for scalar multiplication.
Definition: div.hpp:13
void assign_mod_to(L &&lhs) const
Modulo the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:253
auto less(LE &&lhs, RE rhs)
Builds an expression representing the elementwise less than comparison of lhs and rhs...
Definition: binary_expression_builder.hpp:417
auto operator/(LE &&lhs, RE &&rhs)
Builds an expression representing the division of lhs and rhs.
Definition: binary_expression_builder.hpp:77
auto less_equal(LE &&lhs, RE rhs)
Builds an expression representing the elementwise less than or equals comparison of lhs and rhs...
Definition: binary_expression_builder.hpp:428
auto greater_equal(LE &&lhs, RE rhs)
Builds an expression representing the elementwise greater than or equals comparison of lhs and rhs...
Definition: binary_expression_builder.hpp:450
typename decay_traits< E >::value_type value_t
Traits to extract the value type out of an ETL type.
Definition: tmp.hpp:81
auto logical_xor(LE &&lhs, RE &&rhs)
Builds an expression representing the elementwise logical xor of lhs and rhs.
Definition: binary_expression_builder.hpp:496
auto logical_and(LE &&lhs, RE &&rhs)
Builds an expression representing the elementwise logical and of lhs and rhs.
Definition: binary_expression_builder.hpp:463
auto equal(LE &&lhs, RE rhs)
Builds an expression representing the elementwise comparison of lhs and rhs.
Definition: binary_expression_builder.hpp:395
auto operator-(LE &&lhs, RE &&rhs)
Builds an expression representing the subtraction of lhs and rhs.
Definition: binary_expression_builder.hpp:25
Binary operator for scalar addition.
Definition: plus.hpp:154
void assign_sub_to(L &&lhs) const
Sub from the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:226