18
19
20
24#include "./idx_map.hpp"
25#include "./policies.hpp"
26#include "../basic_array.hpp"
27#include "../basic_functions.hpp"
28#include "../declarations.hpp"
29#include "../exceptions.hpp"
30#include "../traits.hpp"
42
43
44
48 template <
int Rank, uint64_t StaticExtents, uint64_t StrideOrder,
layout_prop_e LayoutProp>
56 struct rect_str_from_base;
59 template <
int Rank, uint64_t StaticExtents, uint64_t StrideOrder,
layout_prop_e LayoutProp>
60 struct rect_str_from_base<
idx_map<Rank, StaticExtents, StrideOrder, LayoutProp>> {
62 using type =
rect_str<Rank, StaticExtents, StrideOrder, LayoutProp>;
68
69
70
71
72
73
74
75
76
77
78 template <
int Rank, uint64_t StaticExtents, uint64_t StrideOrder,
layout_prop_e LayoutProp>
81 using ind_t = nda::array<nda::array<std::string, 1>, 1>;
84 using base_t =
idx_map<Rank, StaticExtents, StrideOrder, LayoutProp>;
87 mutable std::shared_ptr<ind_t
const> s_indices;
90 using base_t::n_dynamic_extents;
93 static std::array<
long, Rank> make_shape_from_string_indices(ind_t
const &str_indices) {
95 NDA_RUNTIME_ERROR <<
"Error in rect_str::make_shape_from_string_indices: String indices do not have the correct rank";
96 std::array<
long, Rank> sha;
97 for (
int i = 0; i < Rank; ++i) sha[i] = str_indices[i]
.size();
103
104
105
106
107
108
109
113 auto ind = ind_t(Rank);
114 for (
int i = 0; i < Rank; ++i) {
115 auto a = nda::array<std::string, 1>(
this->lengths()[i]);
116 for (
int j = 0; j < a
.size(); ++j) a(j) = std::to_string(j);
117 ind(i)
= std::move(a);
119 s_indices = std::make_shared<ind_t>(std::move(ind));
125 template <
typename T>
129 template <
typename T>
134
135
136
140
141
142
143 rect_str(base_t
const &idxm)
noexcept : base_t{idxm} {}
146
147
148
149
150
151
152
153 rect_str(base_t
const &idxm, ind_t
const &str_indices)
noexcept : base_t{idxm}, s_indices{std::make_shared<ind_t>(std::move(str_indices))} {}
156
157
158
159
160
163 : base_t{rstr}, s_indices{std::make_shared<ind_t>(rstr.get_string_indices())} {}
166
167
168
169
170
171
174 : base_t{rstr}, s_indices{std::make_shared<ind_t>(rstr.get_string_indices())} {}
177
178
179
180
181
182 rect_str(std::array<
long, Rank>
const &shape, std::array<
long, Rank>
const &strides)
noexcept : base_t{shape, strides} {}
185
186
187
188 rect_str(std::array<
long, Rank>
const &shape)
noexcept : base_t{shape} {}
191
192
193
194 rect_str(nda::array<nda::array<std::string, 1>, 1> str_indices)
noexcept(
false)
195 : base_t{make_shape_from_string_indices(str_indices)}, s_indices{std::make_shared<ind_t>(std::move(str_indices))} {}
198
199
200
201
202 rect_str(std::array<
long, base_t::n_dynamic_extents>
const &shape)
noexcept
203 requires((base_t::n_dynamic_extents != Rank)
and (base_t::n_dynamic_extents != 0))
220 template <
typename T>
221 auto peel_string(
int pos, T
const &arg)
const {
222 if constexpr (
not std::is_constructible_v<std::string, T>)
228 auto const &idx = sind[pos];
229 auto it = std::find(idx.begin(), idx.end(), arg);
230 if (it == idx.end())
NDA_RUNTIME_ERROR <<
"Error in nda::rect_str: Key " << arg <<
" at position " << pos <<
" does not match an index";
231 return it - idx.begin();
236 template <
typename... Args, size_t... Is>
237 [[nodiscard]]
FORCEINLINE long call_impl(std::index_sequence<Is...>, Args... args)
const {
239 return base_t::operator()(peel_string(Is, args)...);
244
245
246
247
248
249
250
251
252 template <
typename... Args>
254 return call_impl(std::make_index_sequence<
sizeof...(Args)>{}, args...);
259 template <
typename... Args,
auto... Is>
260 FORCEINLINE decltype(
auto) slice_impl(std::index_sequence<Is...>, Args
const &...args)
const {
262 auto const [offset, idxm2] = base_t::slice(peel_string(Is, args)...);
265 using new_rect_str_t =
typename detail::rect_str_from_base<std::decay_t<
decltype(idxm2)>>::type;
268 if (
not s_indices)
return std::make_pair(offset, new_rect_str_t{idxm2});
272 ind_t ind2((
not argument_is_allowed_for_call<Args> + ...));
273 auto add_string_indices = [p = 0, ¤t_ind, &ind2](
int n,
auto const &y)
mutable ->
void {
274 using U = std::decay_t<
decltype(y)>;
275 if constexpr (
not argument_is_allowed_for_call<U>) { ind2[p++] = current_ind[n](y); }
277 (add_string_indices(Is, args), ...);
279 return std::make_pair(offset, new_rect_str_t{idxm2, ind2});
284
285
286
287
288
289
290
291
292
293
294 template <
typename... Args>
295 auto slice(Args
const &...args)
const {
296 return slice_impl(std::make_index_sequence<
sizeof...(args)>{}, args...);
300
301
302
303
304
306 return base_t::operator==(rhs)
and (!s_indices
or !rhs.s_indices
or (*s_indices == *(rhs.s_indices)));
310
311
312
313
314
318
319
320
321
322
323
324
325
326
327
328
329
330
331 template <uint64_t Permutation>
334 auto idxm2 = base_t::
template transpose<Permutation>();
337 using new_rect_str_t =
typename detail::rect_str_from_base<std::decay_t<
decltype(idxm2)>>::type;
340 if (
not s_indices)
return new_rect_str_t{idxm2};
343 ind_t ind2(s_indices->
size());
344 static constexpr std::array<
int, Rank> permu = decode<Rank>(Permutation);
345 for (
int u = 0; u < Rank; ++u) { ind2[permu[u]] = (*s_indices)[u]; }
346 return new_rect_str_t{idxm2, ind2};
353
354
355
364
365
366
380
381
382
396
397
398
412
413
414
428
429
430
431
432
433
434 template <uint64_t StaticExtents, uint64_t StrideOrder,
layout_prop_e LayoutProp>
439 using mapping =
rect_str<Rank, StaticExtents, StrideOrder, LayoutProp>;
451 template <
int Rank, uint64_t StaticExtents, uint64_t StrideOrder,
layout_prop_e LayoutProp>
452 struct layout_to_policy<
rect_str<Rank, StaticExtents, StrideOrder, LayoutProp>> {
long size() const noexcept
Get the total size of the view/array.
basic_array & operator=(basic_array &&)=default
Default move assignment moves the memory handle and layout from the right hand side array.
Layout that specifies how to map multi-dimensional indices to a linear/flat index.
Layout that specifies how to map multi-dimensional indices including possible string indices to a lin...
__inline__ long operator()(Args const &...args) const
Function call operator to map a given multi-dimensional index to a linear index.
bool operator!=(rect_str const &rhs)
Not-equal-to operator for two nda::rect_str objects.
rect_str(std::array< long, Rank > const &shape) noexcept
Construct an nda::rect_str from a given shape and with contiguous strides.
rect_str(rect_str< Rank, StaticExtents, StrideOrder, LP > const &rstr) noexcept
Construct an nda::rect_str from another nda::rect_str with different layout properties.
rect_str & operator=(rect_str &&)=default
Default move assignment operator.
rect_str(nda::array< nda::array< std::string, 1 >, 1 > str_indices) noexcept(false)
Construct an nda::rect_str from given string indices and with contiguous strides.
rect_str(rect_str< Rank, SE, StrideOrder, LP > const &rstr) noexcept(false)
Construct an nda::rect_str from another nda::rect_str with different layout properties and static ext...
auto slice(Args const &...args) const
Get a new nda::rect_str by taking a slice of the current one.
rect_str & operator=(rect_str const &)=default
Default copy assignment operator.
static constexpr int argument_is_allowed_for_call_or_slice
Alias template to check if type T can be used to either access a specific element or a slice of eleme...
static constexpr int argument_is_allowed_for_call
Alias template to check if type T can be used to access a specific element.
rect_str(base_t const &idxm) noexcept
Construct an nda::rect_str from a given nda::idx_map.
bool operator==(rect_str const &rhs) const
Equal-to operator for two nda::rect_str objects.
rect_str(rect_str const &)=default
Default copy constructor.
rect_str(rect_str &&)=default
Default move constructor.
rect_str(std::array< long, Rank > const &shape, std::array< long, Rank > const &strides) noexcept
Construct an nda::rect_str from a given shape and strides.
rect_str()=default
Default constructor.
auto const & get_string_indices() const
Get the string indices.
auto transpose() const
Create a new nda::rect_str by permuting the indices/dimensions with a given permutation.
rect_str(base_t const &idxm, ind_t const &str_indices) noexcept
Construct an nda::rect_str from a given nda::idx_map and string indices.
#define NDA_RUNTIME_ERROR
layout_prop_e
Compile-time guarantees of the memory layout of an array/view.
Contiguous layout policy with C-order (row-major order) and possible string indices.
Strided (non-contiguous) layout policy with C-order (row-major order) and possible string indices.
Contiguous layout policy with Fortran-order (column-major order) and possible string indices.
Strided (non-contiguous) layout policy with Fortran-order (column-major order) and possible string in...
Generic layout policy with arbitrary order and possible string indices.