tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
proxy_reference.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2// SPDX-FileCopyrightText: Copyright (C) 2023 Tobias Hienzsch
3
4#ifndef TETL_LINALG_PROXY_REFERENCE_HPP
5#define TETL_LINALG_PROXY_REFERENCE_HPP
6
7#include <etl/_linalg/concepts.hpp>
8#include <etl/_type_traits/is_base_of.hpp>
9
10namespace etl::linalg::detail {
11
12struct proxy_reference_base { };
13
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;
19
20 constexpr explicit proxy_reference(Reference reference) // NOLINT(bugprone-crtp-constructor-accessibility)
21 : _reference(reference)
22 {
23 }
24
25 constexpr operator value_type() const // NOLINT(readability-const-return-type)
26 {
27 return static_cast<value_type>(static_cast<Derived const&>(*this).to_value(_reference));
28 }
29
30 friend constexpr auto operator-(derived_type const& cs)
31 {
32 return -value_type(cs);
33 }
34
35 template <typename Rhs>
36 requires(is_base_of_v<proxy_reference_base, Rhs>)
37 friend constexpr auto operator+(derived_type lhs, Rhs rhs)
38 {
39 using rhs_value_type = typename Rhs::value_type;
40 return value_type(lhs) + rhs_value_type(rhs);
41 }
42
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)
46 {
47 return value_type(lhs) + rhs;
48 }
49
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)
53 {
54 return lhs + value_type(rhs);
55 }
56
57 template <typename Rhs>
58 requires(is_base_of_v<proxy_reference_base, Rhs>)
59 friend constexpr auto operator-(derived_type lhs, Rhs rhs)
60 {
61 using rhs_value_type = typename Rhs::value_type;
62 return value_type(lhs) - rhs_value_type(rhs);
63 }
64
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)
68 {
69 return value_type(lhs) - rhs;
70 }
71
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)
75 {
76 return lhs - value_type(rhs);
77 }
78
79 template <typename Rhs>
80 requires(is_base_of_v<proxy_reference_base, Rhs>)
81 friend constexpr auto operator*(derived_type lhs, Rhs rhs)
82 {
83 using rhs_value_type = typename Rhs::value_type;
84 return value_type(lhs) * rhs_value_type(rhs);
85 }
86
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)
90 {
91 return value_type(lhs) * rhs;
92 }
93
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)
97 {
98 return lhs * value_type(rhs);
99 }
100
101 template <typename Rhs>
102 requires(is_base_of_v<proxy_reference_base, Rhs>)
103 friend constexpr auto operator/(derived_type lhs, Rhs rhs)
104 {
105 using rhs_value_type = typename Rhs::value_type;
106 return value_type(lhs) / rhs_value_type(rhs);
107 }
108
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)
112 {
113 return value_type(lhs) / rhs;
114 }
115
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)
119 {
120 return lhs / value_type(rhs);
121 }
122
123 friend constexpr auto abs(derived_type const& x)
124 {
125 return abs_if_needed(value_type(static_cast<this_type const&>(x)));
126 }
127
128 friend constexpr auto real(derived_type const& x)
129 {
130 return real_if_needed(value_type(static_cast<this_type const&>(x)));
131 }
132
133 friend constexpr auto imag(derived_type const& x)
134 {
135 return imag_if_needed(value_type(static_cast<this_type const&>(x)));
136 }
137
138 friend constexpr auto conj(derived_type const& x)
139 {
140 return conj_if_needed(value_type(static_cast<this_type const&>(x)));
141 }
142
143private:
144 using this_type = proxy_reference<Reference, Value, Derived>;
145 Reference _reference; // NOLINT(cppcoreguidelines-avoid-const-or-ref-data-members)
146};
147
148} // namespace etl::linalg::detail
149
150#endif // TETL_LINALG_PROXY_REFERENCE_HPP
Definition accessor_conjugate.hpp:13
Definition adjacent_find.hpp:9