4#ifndef TETL_LINALG_PROXY_REFERENCE_HPP
5#define TETL_LINALG_PROXY_REFERENCE_HPP
7#include <etl/_linalg/concepts.hpp>
8#include <etl/_type_traits/is_base_of.hpp>
12struct proxy_reference_base { };
14template <
typename Reference,
typename Value,
typename Derived>
15struct proxy_reference : proxy_reference_base {
16 using reference_type = Reference;
17 using value_type = Value;
18 using derived_type = Derived;
20 constexpr explicit proxy_reference(Reference reference)
21 : _reference(reference)
25 constexpr operator value_type()
const
27 return static_cast<value_type>(
static_cast<Derived
const&>(*
this).to_value(_reference));
30 friend constexpr auto operator-(derived_type
const& cs)
32 return -value_type(cs);
35 template <
typename Rhs>
36 requires(is_base_of_v<proxy_reference_base, Rhs>)
37 friend constexpr auto operator+(derived_type lhs, Rhs rhs)
39 using rhs_value_type =
typename Rhs::value_type;
40 return value_type(lhs) + rhs_value_type(rhs);
43 template <
typename Rhs>
44 requires(
not is_base_of_v<proxy_reference_base, Rhs>)
45 friend constexpr auto operator+(derived_type lhs, Rhs rhs)
47 return value_type(lhs) + rhs;
50 template <
typename Lhs>
51 requires(
not is_base_of_v<proxy_reference_base, Lhs>)
52 friend constexpr auto operator+(Lhs lhs, derived_type rhs)
54 return lhs + value_type(rhs);
57 template <
typename Rhs>
58 requires(is_base_of_v<proxy_reference_base, Rhs>)
59 friend constexpr auto operator-(derived_type lhs, Rhs rhs)
61 using rhs_value_type =
typename Rhs::value_type;
62 return value_type(lhs) - rhs_value_type(rhs);
65 template <
typename Rhs>
66 requires(
not is_base_of_v<proxy_reference_base, Rhs>)
67 friend constexpr auto operator-(derived_type lhs, Rhs rhs)
69 return value_type(lhs) - rhs;
72 template <
typename Lhs>
73 requires(
not is_base_of_v<proxy_reference_base, Lhs>)
74 friend constexpr auto operator-(Lhs lhs, derived_type rhs)
76 return lhs - value_type(rhs);
79 template <
typename Rhs>
80 requires(is_base_of_v<proxy_reference_base, Rhs>)
81 friend constexpr auto operator*(derived_type lhs, Rhs rhs)
83 using rhs_value_type =
typename Rhs::value_type;
84 return value_type(lhs) * rhs_value_type(rhs);
87 template <
typename Rhs>
88 requires(
not is_base_of_v<proxy_reference_base, Rhs>)
89 friend constexpr auto operator*(derived_type lhs, Rhs rhs)
91 return value_type(lhs) * rhs;
94 template <
typename Lhs>
95 requires(
not is_base_of_v<proxy_reference_base, Lhs>)
96 friend constexpr auto operator*(Lhs lhs, derived_type rhs)
98 return lhs * value_type(rhs);
101 template <
typename Rhs>
102 requires(is_base_of_v<proxy_reference_base, Rhs>)
103 friend constexpr auto operator/(derived_type lhs, Rhs rhs)
105 using rhs_value_type =
typename Rhs::value_type;
106 return value_type(lhs) / rhs_value_type(rhs);
109 template <
typename Rhs>
110 requires(
not is_base_of_v<proxy_reference_base, Rhs>)
111 friend constexpr auto operator/(derived_type lhs, Rhs rhs)
113 return value_type(lhs) / rhs;
116 template <
typename Lhs>
117 requires(
not is_base_of_v<proxy_reference_base, Lhs>)
118 friend constexpr auto operator/(Lhs lhs, derived_type rhs)
120 return lhs / value_type(rhs);
123 friend constexpr auto abs(derived_type
const& x)
125 return abs_if_needed(value_type(
static_cast<this_type
const&>(x)));
128 friend constexpr auto real(derived_type
const& x)
130 return real_if_needed(value_type(
static_cast<this_type
const&>(x)));
133 friend constexpr auto imag(derived_type
const& x)
135 return imag_if_needed(value_type(
static_cast<this_type
const&>(x)));
138 friend constexpr auto conj(derived_type
const& x)
140 return conj_if_needed(value_type(
static_cast<this_type
const&>(x)));
144 using this_type = proxy_reference<Reference, Value, Derived>;
145 Reference _reference;
Definition accessor_conjugate.hpp:13
Definition adjacent_find.hpp:9