NGen
Loading...
Searching...
No Matches
mdarray.hpp
1#ifndef NGEN_MDARRAY_DEFINITION_HPP
2#define NGEN_MDARRAY_DEFINITION_HPP
3
4#include <type_traits>
5#include <vector>
6
7#include <boost/core/span.hpp>
8
9namespace ngen {
10
11template<typename T>
13{
14 public:
15 using value_type = T;
16 using container_type = std::vector<value_type>;
17 using size_type = typename container_type::size_type;
18 using difference_type = typename container_type::difference_type;
19 using reference = typename container_type::reference;
20 using const_reference = typename container_type::const_reference;
21 using pointer = typename container_type::pointer;
22 using const_pointer = typename container_type::const_pointer;
23
24 struct iterator;
25 friend iterator;
26
27 private:
28 template<typename Tp>
30 {
31 size_type max = 1;
32 for (size_type dimension : shape) {
33 max *= dimension;
34 }
35 return max;
36 }
37
38 public:
39
40 mdarray() = default;
41
42 mdarray(const boost::span<const size_type> dsizes)
43 : m_shape(dsizes.begin(), dsizes.end())
44 , m_data(this->max_size(dsizes)) {};
45
46 constexpr mdarray(std::initializer_list<size_type> dsizes)
47 : m_shape(dsizes.begin(), dsizes.end())
48 , m_data(this->max_size(dsizes)) {};
49
61 reference at(const boost::span<const size_type> n)
62 {
63 this->bounds_check(n);
64
65 return this->m_data.at(this->index(n));
66 }
67
79 reference operator[](const boost::span<const size_type> n) noexcept
80 {
81 return this->m_data[this->index(n)];
82 }
83
94 const_reference at(const boost::span<const size_type> n) const
95 {
96 this->bounds_check(n);
97
98 return this->m_data.at(this->index(n));
99 }
100
111 const_reference operator[](const boost::span<const size_type> n) const noexcept
112 {
113 return this->m_data[this->index(n)];
114 }
115
122 void insert(const boost::span<const size_type> n, value_type value)
123 {
124 this->bounds_check(n);
125
126 this->m_data[this->index(n)] = value;
127 }
128
129 void insert(std::initializer_list<std::pair<const boost::span<const size_type>, value_type>> args)
130 {
131 for (const auto& arg : args) {
132 this->insert(arg.first, arg.second);
133 }
134 }
135
141 size_type size() const noexcept
142 {
143 return this->m_data.size();
144 }
145
146 iterator begin() const noexcept {
147 return iterator(*this, 0);
148 }
149
150 iterator end() const noexcept {
151 return iterator(*this, this->m_data.size());
152 }
153
159 size_type rank() const noexcept
160 {
161 return this->m_shape.size();
162 }
163
169 boost::span<const size_t> shape() const noexcept
170 {
171 return this->m_shape;
172 }
173
180 size_type index(const boost::span<const size_type> n) const
181 {
182 size_type index = 0, stride = 1;
183 for (size_type k = 0; k < this->rank(); k++) {
184 assert(n[k] < m_shape[k]);
185 index += n[k] * stride;
186 stride *= this->m_shape[k];
187 }
188
189 assert(index < this->size());
190
191 return index;
192 }
193
200 void deindex(size_type idx, boost::span<size_type> n) const
201 {
202 assert(n.size() == this->rank());
203 assert(idx < this->size());
204
205 size_type stride = 1;
206 for (size_type k = 0; k < this->rank(); k++) {
207 n[k] = idx / stride % this->m_shape[k];
208 stride *= this->m_shape[k];
209 }
210 }
211
212 private:
213
214 inline void bounds_check(const boost::span<const size_type> n) const
215 {
216 // This bounds check is required since `index` performs
217 // modulo arithmetic on the dimension indices with carryover,
218 // such that if an mdarray has shape {2, 2}, the index {2, 0}
219 // is equivalent to {0, 1}.
220 for (size_type i = 0; i < this->m_shape.size(); i++) {
221 if (n[i] >= this->m_shape[i])
222 throw std::out_of_range(
223 "index " + std::to_string(n[i]) +
224 " must be less than dimension size " +
225 std::to_string(this->m_shape[i])
226 );
227 }
228 }
229
230 std::vector<size_type> m_shape;
232};
233
234} // namespace ngen
235
236#endif // NGEN_MDARRAY_DEFINITION_HPP
Definition mdarray.hpp:13
iterator end() const noexcept
Definition mdarray.hpp:150
typename container_type::const_pointer const_pointer
Definition mdarray.hpp:22
reference at(const boost::span< const size_type > n)
Definition mdarray.hpp:61
typename container_type::size_type size_type
Definition mdarray.hpp:17
void insert(std::initializer_list< std::pair< const boost::span< const size_type >, value_type > > args)
Definition mdarray.hpp:129
typename container_type::reference reference
Definition mdarray.hpp:19
typename container_type::const_reference const_reference
Definition mdarray.hpp:20
size_type rank() const noexcept
Get the rank of this mdarray.
Definition mdarray.hpp:159
constexpr mdarray(std::initializer_list< size_type > dsizes)
Definition mdarray.hpp:46
void insert(const boost::span< const size_type > n, value_type value)
Insert a multi-dimensonal value at the given index.
Definition mdarray.hpp:122
std::vector< size_type > m_shape
Definition mdarray.hpp:230
const_reference at(const boost::span< const size_type > n) const
Definition mdarray.hpp:94
container_type m_data
Definition mdarray.hpp:231
friend iterator
Definition mdarray.hpp:25
reference operator[](const boost::span< const size_type > n) noexcept
Definition mdarray.hpp:79
size_type max_size(Tp shape)
Definition mdarray.hpp:29
typename container_type::pointer pointer
Definition mdarray.hpp:21
void bounds_check(const boost::span< const size_type > n) const
Definition mdarray.hpp:214
size_type index(const boost::span< const size_type > n) const
Index a multi-dimensional set of indices to a single address index.
Definition mdarray.hpp:180
iterator begin() const noexcept
Definition mdarray.hpp:146
typename container_type::difference_type difference_type
Definition mdarray.hpp:18
boost::span< const size_t > shape() const noexcept
Get the shape of this mdarray.
Definition mdarray.hpp:169
void deindex(size_type idx, boost::span< size_type > n) const
Retrieve the multi-dimensional index from a given address index.
Definition mdarray.hpp:200
size_type size() const noexcept
Get the size of allocated values in this mdarray (aka the allocated elements in the backing vector)
Definition mdarray.hpp:141
std::vector< value_type > container_type
Definition mdarray.hpp:16
const_reference operator[](const boost::span< const size_type > n) const noexcept
Definition mdarray.hpp:111
mdarray()=default
mdarray(const boost::span< const size_type > dsizes)
Definition mdarray.hpp:42
T value_type
Definition mdarray.hpp:15
Definition DomainLayer.hpp:9
Definition iterator.hpp:10