Distributed Ranges
Loading...
Searching...
No Matches
matrix_entry.hpp
1// SPDX-FileCopyrightText: Intel Corporation
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#pragma once
6
7#include <cassert>
8#include <concepts>
9#include <limits>
10#include <type_traits>
11
12#include <dr/detail/index.hpp>
13
14namespace dr {
15template <typename T>
16concept getable = requires(T x) {
17 std::get<0>(x);
18 std::get<1>(x);
19};
20template <typename T, typename I = std::size_t> class matrix_entry {
21public:
22 using index_type = I;
23 using map_type = T;
24
25 matrix_entry(dr::index<I> index, const map_type &value)
26 : index_(index), value_(value) {}
27 matrix_entry(dr::index<I> index, map_type &&value)
28 : index_(index), value_(std::move(value)) {}
29
30 template <typename U>
31 requires(std::is_constructible_v<T, U>)
33 : index_(index), value_(std::forward<U>(value)) {}
34
35 template <typename Entry>
36 requires(getable<Entry>)
37 matrix_entry(Entry &&entry)
38 : index_(std::get<0>(entry)), value_(std::get<1>(entry)) {}
39
40 template <std::size_t Index> auto get() const noexcept {
41 if constexpr (Index == 0) {
42 return index();
43 }
44 if constexpr (Index == 1) {
45 return value();
46 }
47 }
48
49 operator std::pair<std::pair<I, I>, T>() const noexcept {
50 return {{index_[0], index_[1]}, value_};
51 }
52
53 dr::index<I> index() const noexcept { return index_; }
54
55 map_type value() const noexcept { return value_; }
56
57 template <std::integral U>
58 requires(!std::is_same_v<I, U> &&
59 std::numeric_limits<U>::max() >= std::numeric_limits<I>::max())
60 operator matrix_entry<T, U>() const noexcept {
61 return matrix_entry<T, U>(index_, value_);
62 }
63
64 template <std::integral U>
65 requires(!std::is_const_v<T> && !std::is_same_v<I, U> &&
66 std::numeric_limits<U>::max() >= std::numeric_limits<I>::max())
67 operator matrix_entry<std::add_const_t<T>, U>() const noexcept {
68 return matrix_entry<std::add_const_t<T>, U>(index_, value_);
69 }
70
71 inline bool operator<(const matrix_entry &other) const noexcept {
72 if (index_.first != other.index_.first) {
73 return index_.first < other.index_.first;
74 }
75 return index_.second < other.index_.second;
76 }
77
78 matrix_entry() = default;
79 ~matrix_entry() = default;
80
81 matrix_entry(const matrix_entry &) = default;
82 matrix_entry(matrix_entry &&) = default;
83 matrix_entry &operator=(const matrix_entry &) = default;
84 matrix_entry &operator=(matrix_entry &&) = default;
85
86private:
87 dr::index<I> index_;
88 map_type value_;
89};
90
91} // namespace dr
92
93namespace std {
94
95template <typename T, typename I>
96 requires(!std::is_const_v<T>)
98 dr::matrix_entry<T, I> other = a;
99 a = b;
100 b = other;
101}
102
103template <std::size_t Index, typename T, typename I>
104struct tuple_element<Index, dr::matrix_entry<T, I>>
105 : tuple_element<Index, std::tuple<dr::index<I>, T>> {};
106
107template <typename T, typename I>
108struct tuple_size<dr::matrix_entry<T, I>> : integral_constant<size_t, 2> {};
109
110} // namespace std
111
112namespace dr {
113
114template <typename T, typename I = std::size_t, typename TRef = T &>
116public:
117 using scalar_type = T;
118 using index_type = I;
119
120 using key_type = dr::index<I>;
121 using map_type = T;
122
123 using scalar_reference = TRef;
124
126
127 matrix_ref(dr::index<I> index, scalar_reference value)
128 : index_(index), value_(value) {}
129
130 operator value_type() const noexcept { return value_type(index_, value_); }
131
132 operator std::pair<std::pair<I, I>, T>() const noexcept {
133 return {{index_[0], index_[1]}, value_};
134 }
135
136 template <std::size_t Index>
137 decltype(auto) get() const noexcept
138 requires(Index <= 1)
139 {
140 if constexpr (Index == 0) {
141 return index();
142 }
143 if constexpr (Index == 1) {
144 return value();
145 }
146 }
147
148 dr::index<I> index() const noexcept { return index_; }
149
150 scalar_reference value() const noexcept { return value_; }
151
152 template <std::integral U>
153 requires(!std::is_same_v<I, U> &&
154 std::numeric_limits<U>::max() >= std::numeric_limits<I>::max())
155 operator matrix_ref<T, U, TRef>() const noexcept {
156 return matrix_ref<T, U, TRef>(index_, value_);
157 }
158
159 template <std::integral U>
160 requires(!std::is_const_v<T> && !std::is_same_v<I, U> &&
161 std::numeric_limits<U>::max() >= std::numeric_limits<I>::max())
162 operator matrix_ref<std::add_const_t<T>, U, TRef>() const noexcept {
163 return matrix_ref<std::add_const_t<T>, U, TRef>(index_, value_);
164 }
165
166 bool operator<(matrix_entry<T, I> other) const noexcept {
167 if (index()[0] < other.index()[0]) {
168 return true;
169 } else if (index()[0] == other.index()[0] &&
170 index()[1] < other.index()[1]) {
171 return true;
172 }
173 return false;
174 }
175
176 matrix_ref() = delete;
177 ~matrix_ref() = default;
178
179 matrix_ref(const matrix_ref &) = default;
180 matrix_ref &operator=(const matrix_ref &) = delete;
181 matrix_ref(matrix_ref &&) = default;
182 matrix_ref &operator=(matrix_ref &&) = default;
183
184private:
185 dr::index<I> index_;
186 scalar_reference value_;
187};
188
189} // namespace dr
190
191namespace std {
192
193template <typename T, typename I, typename TRef>
194 requires(!std::is_const_v<T>)
196 dr::matrix_entry<T, I> other = a;
197 a = b;
198 b = other;
199}
200
201template <std::size_t Index, typename T, typename I, typename TRef>
202struct tuple_element<Index, dr::matrix_ref<T, I, TRef>>
203 : tuple_element<Index, std::tuple<dr::index<I>, TRef>> {};
204
205template <typename T, typename I, typename TRef>
206struct tuple_size<dr::matrix_ref<T, I, TRef>>
207 : integral_constant<std::size_t, 2> {};
208
209template <std::size_t Index, typename T, typename I, typename TRef>
210inline decltype(auto) get(dr::matrix_ref<T, I, TRef> ref)
211 requires(Index <= 1)
212{
213 if constexpr (Index == 0) {
214 return ref.index();
215 }
216 if constexpr (Index == 1) {
217 return ref.value();
218 }
219}
220
221template <std::size_t Index, typename T, typename I, typename TRef>
222inline decltype(auto) get(dr::matrix_entry<T, I> entry)
223 requires(Index <= 1)
224{
225 if constexpr (Index == 0) {
226 return entry.index();
227 }
228 if constexpr (Index == 1) {
229 return entry.value();
230 }
231}
232
233} // namespace std
Definition: index.hpp:34
Definition: matrix_entry.hpp:20
Definition: matrix_entry.hpp:115
Definition: matrix_entry.hpp:16