custom_index_array.h Source File

CPP API: custom_index_array.h Source File
custom_index_array.h
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2020-2026 MEmilio
3 *
4 * Authors: Daniel Abele, Khoa Nguyen
5 *
6 * Contact: Martin J. Kuehn <Martin.Kuehn@DLR.de>
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20 #ifndef MIO_UTILS_CUSTOM_INDEX_ARRAY_H
21 #define MIO_UTILS_CUSTOM_INDEX_ARRAY_H
22 
24 #include "memilio/utils/index.h"
26 
27 #include <concepts>
28 
29 namespace
30 {
31 
32 //calculate the product of tuple elements
33 // TODO std::apply or fold expression in C++17; current version required by CustomIndexArray::Slice
34 template <int I, template <class...> class Index, class... Ts>
35 size_t product(Index<Ts...> const& t)
36 {
37  if constexpr (I < sizeof...(Ts)) {
38  return static_cast<size_t>(mio::get<I>(t)) * product<I + 1, Index, Ts...>(t);
39  }
40  else {
41  return 1;
42  }
43 }
44 
45 template <template <class...> class Index, class... Ts>
46 size_t product(Index<Ts...> const& t)
47 {
48  return product<0, Index, Ts...>(t);
49 }
50 
51 } // namespace
52 
53 namespace mio
54 {
55 
56 namespace details
57 {
58 
59 // Internal implementation for flatten_index
60 template <size_t I, typename Index>
61 std::pair<size_t, size_t> flatten_index(Index const& indices, Index const& dimensions)
62 {
63  assert(get<I>(indices) < get<I>(dimensions));
64  if constexpr (I < (Index::size - 1)) {
65  auto [val, prod] = flatten_index<I + 1>(indices, dimensions);
66  return {val + (size_t)mio::get<I>(indices) * prod, prod * (size_t)mio::get<I>(dimensions)};
67  }
68  else {
69  return {(size_t)mio::get<I>(indices), (size_t)mio::get<I>(dimensions)};
70  }
71 }
72 
73 template <typename T>
75  : std::is_base_of<typename std::iterator_traits<T>::iterator_category, std::random_access_iterator_tag> {
76 };
77 
78 } // namespace details
79 
91 template <typename MultiIndex>
92 size_t flatten_index(MultiIndex const& indices, MultiIndex const& dimensions)
93 {
94  return details::flatten_index<0>(indices, dimensions).first;
95 }
96 
134 template <class Typ, class... Tags>
136 {
137 public:
138  using Type = Typ;
139  using Index = ::mio::Index<Tags...>;
140  using InternalArrayType = Eigen::Array<Type, Eigen::Dynamic, 1>;
141 
143  explicit CustomIndexArray()
144  : m_dimensions(Index::Zero())
145  , m_numel(0)
146  , m_y()
147  {
148  }
149 
160  template <class... Ts>
161  requires(std::is_constructible_v<Type, Ts...>)
162  CustomIndexArray(Index const& dims, Ts&&... args)
163  : m_dimensions{dims}
164  , m_numel(product(dims))
165  , m_y(InternalArrayType::Constant(m_numel, 1, Type{std::forward<Ts>(args)...}))
166  {
167  }
168 
177  template <std::input_or_output_iterator Iter>
178  CustomIndexArray(Index const& dims, Iter b, Iter e)
179  : m_dimensions(dims)
180  , m_numel(product(dims))
181  , m_y(m_numel, 1)
182  {
183  std::copy(b, e, begin());
184  }
185 
193  size_t constexpr numel() const
194  {
195  return m_numel;
196  }
197 
203  template <typename Tag>
205  {
206  return get<Tag>(m_dimensions);
207  }
208 
213  Index size() const
214  {
215  return m_dimensions;
216  }
217 
224  void resize(Index new_dims)
225  {
226  m_dimensions = new_dims;
227  m_numel = product(m_dimensions);
228  m_y.resize(m_numel);
229  }
230 
238  template <class Tag>
239  void resize(mio::Index<Tag> new_dim)
240  {
241  std::get<mio::Index<Tag>>(m_dimensions.indices) = new_dim;
242  m_numel = product(m_dimensions);
243  m_y.resize(m_numel);
244  }
245 
250  auto const& array() const
251  {
252  return m_y;
253  }
254  auto& array()
255  {
256  return m_y;
257  }
258 
264  Type& operator[](Index const& index)
265  {
266  return m_y[get_flat_index(index)];
267  }
268 
274  Type const& operator[](Index const& index) const
275  {
276  return m_y[get_flat_index(index)];
277  }
278 
284  {
285  m_y = scalar;
286  return *this;
287  }
288 
293  bool operator==(const CustomIndexArray& other) const
294  {
295  return this->m_dimensions == other.m_dimensions && (this->m_y.array() == other.m_y.array()).all();
296  }
297  bool operator!=(const CustomIndexArray& other) const
298  {
299  return !(*this == other);
300  }
309  size_t get_flat_index(Index const& index) const
310  {
311  return (Eigen::Index)flatten_index(index, m_dimensions);
312  }
313 
319  void set_multiple(const std::vector<typename CustomIndexArray<Typ, Tags...>::Index>& indices, const Typ& value)
320  {
321  for (const auto& index : indices) {
322  m_y[get_flat_index(index)] = value;
323  }
324  }
325 
331  template <class OtherType>
332  requires std::convertible_to<Type, OtherType>
333  CustomIndexArray<OtherType, Tags...> convert() const
334  {
335  CustomIndexArray<OtherType, Tags...> other;
336  other.resize(m_dimensions);
337  other.array() = m_y.template cast<OtherType>();
338  return other;
339  }
340 
341 private:
365  template <typename Tag, typename iter_type>
367  class Slice
368  {
369  using difference_type = typename iter_type::difference_type;
370 
371  template <typename T>
372  class Iterator
373  {
374  public:
375  using iterator_category = std::random_access_iterator_tag;
376  using difference_type = std::ptrdiff_t;
377  using value_type = T;
378  using pointer = value_type*;
380 
381  Iterator(iter_type begin_, size_t di_, size_t dr_, Seq<size_t> const& seq_, difference_type offset = 0)
382  : data_begin(begin_)
383  , di(di_)
384  , dr(dr_)
385  , seq(seq_)
386  , inner_offset(offset)
387  {
388  }
389 
390  Iterator& operator=(size_t rhs)
391  {
392  inner_offset = rhs;
393  return *this;
394  }
396  {
398  return *this;
399  }
400  Iterator& operator+=(const int& rhs)
401  {
402  inner_offset += rhs;
403  return *this;
404  }
405  Iterator& operator-=(const int& rhs)
406  {
407  inner_offset -= rhs;
408  return *this;
409  }
410 
412  {
413  return data_begin[outer_offset(inner_offset + rhs)];
414  }
415  value_type const& operator[](const difference_type& rhs) const
416  {
417  return data_begin[outer_offset(inner_offset + rhs)];
418  }
420  {
422  }
423  value_type const& operator*() const
424  {
426  }
428  {
430  }
431 
433  {
434  inner_offset++;
435  return *this;
436  }
438  {
439  Iterator tmp = *this;
440  ++(*this);
441  return tmp;
442  }
444  {
445  --inner_offset;
446  return *this;
447  }
449  {
450  Iterator tmp = *this;
451  --(*this);
452  return tmp;
453  }
454 
455  Iterator operator+(const int& rhs) const
456  {
457  return Iterator(data_begin, di, dr, seq, inner_offset + rhs);
458  }
459  Iterator operator-(const int& rhs) const
460  {
461  return Iterator(data_begin, di, dr, seq, inner_offset - rhs);
462  }
463 
464  friend bool operator==(const Iterator& a, const Iterator& b)
465  {
466  return a.inner_offset == b.inner_offset && a.data_begin == b.data_begin && a.di == b.di &&
467  a.dr == b.dr && a.seq.start == b.seq.start && a.seq.n == b.seq.n && a.seq.stride == b.seq.stride;
468  }
469  friend bool operator!=(const Iterator& a, const Iterator& b)
470  {
471  return !(a == b);
472  }
473  friend bool operator<(const Iterator& a, const Iterator& b)
474  {
475  return a.inner_offset < b.inner_offset;
476  }
477  friend bool operator<=(const Iterator& a, const Iterator& b)
478  {
479  return a.inner_offset <= b.inner_offset;
480  }
481  friend bool operator>(const Iterator& a, const Iterator& b)
482  {
483  return a.inner_offset > b.inner_offset;
484  }
485  friend bool operator>=(const Iterator& a, const Iterator& b)
486  {
487  return a.inner_offset >= b.inner_offset;
488  }
489 
490  private:
492  {
493 
494  // calculate the outer offset from the inner offset
495 
496  // first unravel the inner index into an index (i,j,k) for a 3-dim array with dims (dl, idx_sequence.n, dr)
497  auto dv = std::div(inner, seq.n * dr);
498  difference_type i = dv.quot;
499  dv = std::div(dv.rem, dr);
500  difference_type j = dv.quot * seq.stride + seq.start;
501  difference_type k = dv.rem;
502 
503  // then flatten the index for a 3-dim array with dims (dl, di, dr)
504  return i * di * dr + j * dr + k;
505  }
506 
507  iter_type data_begin;
508  size_t di, dr;
511  };
512 
513  public:
514  using value_type = Type;
515  using reference = Type&;
518 
525  Slice(Index const& dimensions, iter_type const& start_iter, Seq<size_t> idx_sequence_)
526  : data_begin(start_iter)
527  , idx_sequence(idx_sequence_)
528  , m_dimensions(dimensions)
529  , di(mio::get<Tag>(dimensions))
530  , dr(product<index_of_type_v<Tag, Index>>(dimensions) / di)
531  , dl(product(dimensions) / (di * dr))
532  {
533  assert((size_t)idx_sequence.start + idx_sequence.n <= di);
534 
535  mio::get<Tag>(m_dimensions) = mio::Index<Tag>(idx_sequence.n);
536  }
537 
538  // returns the number of elements in a slice
539  size_t numel() const
540  {
541  return dl * dr * (idx_sequence.n);
542  }
543 
544  // returns an stl-compatible random access iterator into the slice
546  {
547  return iterator(data_begin, di, dr, idx_sequence, 0);
548  }
549 
550  // returns an stl-compatible random access iterator into the slice
552  {
554  }
555 
556  // returns an stl-compatible end random access iterator into the slice
558  {
559  return iterator(data_begin, di, dr, idx_sequence, numel());
560  }
561 
562  // returns an stl-compatible end random access iterator into the slice
564  {
566  }
567 
568  // copies the slice elements into a CustomIndexArray of appropriate dimension
570  {
572  Eigen::Index idx = 0;
573  for (auto& v : *this) {
574  array.array()[idx++] = v;
575  };
576  return array;
577  }
578 
579  // comparison operators
580  friend bool operator==(const Slice& a, const Slice& b)
581  {
582  return a.data_begin == b.data_begin && a.idx_sequence.start == b.idx_sequence.start &&
584  a.m_dimensions == b.m_dimensions;
585  }
586 
587  friend bool operator!=(const Slice& a, const Slice& b)
588  {
589  return !(a == b);
590  }
591 
599  template <typename OtherTag>
601  {
602  return Slice<OtherTag, iterator>(m_dimensions, begin(), idx_sequence_);
603  }
604 
612  template <typename OtherTag>
614  {
615  return Slice<OtherTag, const_iterator>(m_dimensions, begin(), idx_sequence_);
616  }
617 
622  Slice& operator=(const Type& scalar)
623  {
624  for (auto&& e : *this) {
625  e = scalar;
626  }
627  return *this;
628  }
629 
630  private:
631  iter_type data_begin;
634  size_t di, dr, dl;
635  };
636 
637  // An array storying the size of each category
639 
640  // number of elements stored
641  size_t m_numel;
642 
643  // An array containing the elements
645 
646 public:
647  using value_type = Type;
648  using reference = Type&;
649  using iterator = typename InternalArrayType::iterator;
650  using const_iterator = typename InternalArrayType::const_iterator;
651 
657  {
658  return array().begin();
659  }
660 
666  {
667  return array().cbegin();
668  }
669 
675  {
676  return array().end();
677  }
678 
684  {
685  return array().cend();
686  }
687 
697  template <typename Tag>
699  {
700  return Slice<Tag, iterator>(m_dimensions, begin(), idx_seq);
701  }
702  template <typename Tag>
704  {
705  return Slice<Tag, const_iterator>(m_dimensions, begin(), idx_seq);
706  }
716  template <typename Tag>
718  {
719  return slice<Tag>({(size_t)idx, 1});
720  }
721  template <typename Tag>
723  {
724  return slice<Tag>({(size_t)idx, 1});
725  }
726  template <typename Tag>
727  requires std::is_enum_v<Tag>
729  {
730  return slice<Tag>(mio::Index<Tag>(idx));
731  }
732  template <typename Tag>
733  requires std::is_enum_v<Tag>
735  {
736  return slice<Tag>(mio::Index<Tag>(idx));
737  }
744  template <class IOContext>
745  void serialize(IOContext& io) const
746  {
747  auto obj = io.create_object("Array");
748  obj.add_element("Dimensions", m_dimensions);
749  obj.add_list("Elements", begin(), end());
750  }
751 
752 protected:
757  template <class IOContext, class Derived>
759  {
760  auto obj = io.expect_object("Array");
761  auto dims = obj.expect_element("Dimensions", Tag<Index>{});
762  auto els = obj.expect_list("Elements", Tag<Type>{});
763  return apply(
764  io,
765  [](auto&& d, auto&& e) -> IOResult<Derived> {
766  auto a = Derived(d);
767  if (a.numel() != e.size())
768  return failure(StatusCode::OutOfRange, "Dimensions of Array don't match the number of elements.");
769  std::copy(e.begin(), e.end(), mio::begin(a.m_y));
770  return success(a);
771  },
772  dims, els);
773  }
774 
775 public:
780  template <class IOContext>
782  {
783  return deserialize(io, Tag<CustomIndexArray>{});
784  }
785 };
786 
787 } // namespace mio
788 
789 #endif // MIO_UTILS_CUSTOM_INDEX_ARRAY_H
Definition: custom_index_array.h:373
Iterator & operator-=(const int &rhs)
Definition: custom_index_array.h:405
Iterator & operator=(const Iterator &rhs)
Definition: custom_index_array.h:395
Iterator operator++(int)
Definition: custom_index_array.h:437
friend bool operator!=(const Iterator &a, const Iterator &b)
Definition: custom_index_array.h:469
Iterator operator--(int)
Definition: custom_index_array.h:448
size_t dr
Definition: custom_index_array.h:508
T value_type
Definition: custom_index_array.h:377
Iterator & operator=(size_t rhs)
Definition: custom_index_array.h:390
Iterator(iter_type begin_, size_t di_, size_t dr_, Seq< size_t > const &seq_, difference_type offset=0)
Definition: custom_index_array.h:381
value_type const & operator*() const
Definition: custom_index_array.h:423
reference operator*()
Definition: custom_index_array.h:419
Iterator operator-(const int &rhs) const
Definition: custom_index_array.h:459
Slice::difference_type outer_offset(difference_type const &inner) const
Definition: custom_index_array.h:491
friend bool operator<=(const Iterator &a, const Iterator &b)
Definition: custom_index_array.h:477
Iterator operator+(const int &rhs) const
Definition: custom_index_array.h:455
value_type const & operator[](const difference_type &rhs) const
Definition: custom_index_array.h:415
value_type & reference
Definition: custom_index_array.h:379
Iterator & operator--()
Definition: custom_index_array.h:443
Iterator & operator++()
Definition: custom_index_array.h:432
std::ptrdiff_t difference_type
Definition: custom_index_array.h:376
difference_type inner_offset
Definition: custom_index_array.h:510
friend bool operator>(const Iterator &a, const Iterator &b)
Definition: custom_index_array.h:481
friend bool operator<(const Iterator &a, const Iterator &b)
Definition: custom_index_array.h:473
Seq< size_t > seq
Definition: custom_index_array.h:509
std::random_access_iterator_tag iterator_category
Definition: custom_index_array.h:375
value_type * pointer
Definition: custom_index_array.h:378
friend bool operator==(const Iterator &a, const Iterator &b)
Definition: custom_index_array.h:464
Iterator & operator+=(const int &rhs)
Definition: custom_index_array.h:400
reference operator[](const difference_type &rhs)
Definition: custom_index_array.h:411
size_t di
Definition: custom_index_array.h:508
friend bool operator>=(const Iterator &a, const Iterator &b)
Definition: custom_index_array.h:485
pointer operator->()
Definition: custom_index_array.h:427
iter_type data_begin
Definition: custom_index_array.h:507
A Slice represents a slice of data along one dimension, given a start and end index into that dimensi...
Definition: custom_index_array.h:368
Seq< size_t > idx_sequence
Definition: custom_index_array.h:632
iterator begin()
Definition: custom_index_array.h:545
CustomIndexArray< Type, Tags... > as_array()
Definition: custom_index_array.h:569
friend bool operator!=(const Slice &a, const Slice &b)
Definition: custom_index_array.h:587
typename iter_type::difference_type difference_type
Definition: custom_index_array.h:369
Type & reference
Definition: custom_index_array.h:515
iterator end()
Definition: custom_index_array.h:557
size_t numel() const
Definition: custom_index_array.h:539
size_t dl
Definition: custom_index_array.h:634
Slice(Index const &dimensions, iter_type const &start_iter, Seq< size_t > idx_sequence_)
Constructs a slice into the CustomIndexarray.
Definition: custom_index_array.h:525
Iterator< Type > iterator
Definition: custom_index_array.h:516
Iterator< Type const > const_iterator
Definition: custom_index_array.h:517
size_t dr
Definition: custom_index_array.h:634
Index m_dimensions
Definition: custom_index_array.h:633
Slice< OtherTag, iterator > slice(Seq< size_t > idx_sequence_)
Creates a subslice from the current slice.
Definition: custom_index_array.h:600
const_iterator begin() const
Definition: custom_index_array.h:551
Slice< OtherTag, const_iterator > slice(Seq< size_t > idx_sequence_) const
Creates a subslice from the current slice.
Definition: custom_index_array.h:613
const_iterator end() const
Definition: custom_index_array.h:563
size_t di
Definition: custom_index_array.h:634
Type value_type
Definition: custom_index_array.h:514
friend bool operator==(const Slice &a, const Slice &b)
Definition: custom_index_array.h:580
Slice & operator=(const Type &scalar)
Assign same value to each element of the slice.
Definition: custom_index_array.h:622
iter_type data_begin
Definition: custom_index_array.h:631
A class template for an array with custom indices.
Definition: custom_index_array.h:136
Index m_dimensions
Definition: custom_index_array.h:638
iterator end()
Get an end iterator for the elements.
Definition: custom_index_array.h:674
InternalArrayType m_y
Definition: custom_index_array.h:644
Type const & operator[](Index const &index) const
returns the entry of the array given a flat index index
Definition: custom_index_array.h:274
Type & operator[](Index const &index)
returns the entry of the array given a MultiIndex
Definition: custom_index_array.h:264
Eigen::Array< Type, Eigen::Dynamic, 1 > InternalArrayType
Definition: custom_index_array.h:140
Slice< Tag, iterator > slice(Seq< size_t > idx_seq)
Creates a slice into the multidimensional array.
Definition: custom_index_array.h:698
Slice< Tag, const_iterator > slice(Seq< size_t > idx_seq) const
Creates a slice into the multidimensional array.
Definition: custom_index_array.h:703
requires(std::is_constructible_v< Type, Ts... >) CustomIndexArray(Index const &dims
CustomIndexArray constructor, that initializes the array to constant instances of CustsomIndexArray::...
Slice< Tag, const_iterator > slice(mio::Index< Tag > idx) const
Creates a slice into the multidimensional array.
Definition: custom_index_array.h:722
mio::Index< Tag > size() const
returns the size along the dimension provided as template parameter
Definition: custom_index_array.h:204
auto & array()
Definition: custom_index_array.h:254
CustomIndexArray & operator=(const Type &scalar)
Assign the same value to each element of the array.
Definition: custom_index_array.h:283
Typ Type
Definition: custom_index_array.h:138
typename InternalArrayType::const_iterator const_iterator
Definition: custom_index_array.h:650
iterator begin()
Get a start iterator for the elements.
Definition: custom_index_array.h:656
CustomIndexArray(Index const &dims, Iter b, Iter e)
Initializes array with values from a range.
Definition: custom_index_array.h:178
Ts m_y(InternalArrayType::Constant(m_numel, 1, Type{std::forward< Ts >(args)...}))
Definition: custom_index_array.h:165
CustomIndexArray()
Create an empty CustomIndexArray with size 0. Use the resize member function to add entries.
Definition: custom_index_array.h:143
Ts m_numel(product(dims))
typename InternalArrayType::iterator iterator
Definition: custom_index_array.h:649
void set_multiple(const std::vector< typename CustomIndexArray< Typ, Tags... >::Index > &indices, const Typ &value)
Set multiple entries to the same value.
Definition: custom_index_array.h:319
bool operator!=(const CustomIndexArray &other) const
Equality comparison.
Definition: custom_index_array.h:297
requires std::convertible_to< Type, OtherType > CustomIndexArray< OtherType, Tags... > convert() const
Convert internally stored data to OtherType and save into new CustomIndexArray.
Definition: custom_index_array.h:333
size_t get_flat_index(Index const &index) const
get_flat_index returns the flat index into the stored array, given the indices of each category
Definition: custom_index_array.h:309
Type value_type
Definition: custom_index_array.h:647
size_t m_numel
Definition: custom_index_array.h:641
constexpr size_t numel() const
numel returns the number of elements
Definition: custom_index_array.h:193
Type & reference
Definition: custom_index_array.h:648
void resize(mio::Index< Tag > new_dim)
Resize a single dimension, invalidating entries.
Definition: custom_index_array.h:239
static IOResult< Derived > deserialize(IOContext &io, Tag< Derived >)
deserialize an object of a class derived from this class.
Definition: custom_index_array.h:758
requires std::is_enum_v< Tag > Slice< Tag, iterator > slice(Tag idx)
Creates a slice into the multidimensional array.
Definition: custom_index_array.h:728
static IOResult< CustomIndexArray > deserialize(IOContext &io)
deserialize an object of this class.
Definition: custom_index_array.h:781
Slice< Tag, iterator > slice(mio::Index< Tag > idx)
Creates a slice into the multidimensional array.
Definition: custom_index_array.h:717
const_iterator end() const
Get an end iterator for the elements.
Definition: custom_index_array.h:683
void serialize(IOContext &io) const
serialize this.
Definition: custom_index_array.h:745
void resize(Index new_dims)
Resize all dimensions, invalidating entries.
Definition: custom_index_array.h:224
requires std::is_enum_v< Tag > Slice< Tag, const_iterator > slice(Tag idx) const
Creates a slice into the multidimensional array.
Definition: custom_index_array.h:734
Ts && args
Definition: custom_index_array.h:164
bool operator==(const CustomIndexArray &other) const
Equality comparison.
Definition: custom_index_array.h:293
const_iterator begin() const
Get a start iterator for the elements.
Definition: custom_index_array.h:665
auto const & array() const
array returns a reference to the internally stored flat array.
Definition: custom_index_array.h:250
Index size() const
returns the size of the array along all dimensions.
Definition: custom_index_array.h:213
An Index with more than one template parameter combines several Index objects.
Definition: index.h:181
std::tuple< Index< CategoryTag >... > indices
Definition: index.h:272
static constexpr size_t size
Definition: index.h:183
trait_value< T >::RETURN_TYPE & value(T &x)
Definition: ad.hpp:3308
std::pair< size_t, size_t > flatten_index(Index const &indices, Index const &dimensions)
Definition: custom_index_array.h:61
A collection of classes to simplify handling of matrix shapes in meta programming.
Definition: models/abm/analyze_result.h:30
constexpr std::size_t index_of_type_v
The index of Type in the list Types.
Definition: metaprogramming.h:191
auto failure(const IOStatus &s)
Create an object that is implicitly convertible to an error IOResult<T>.
Definition: io.h:380
boost::outcome_v2::in_place_type_t< T > Tag
Type that is used for overload resolution.
Definition: io.h:407
auto i
Definition: io.h:809
details::ApplyResultT< F, T... > apply(IOContext &io, F f, const IOResult< T > &... rs)
Evaluate a function with zero or more unpacked IOResults as arguments.
Definition: io.h:481
auto success()
Create an object that is implicitly convertible to a succesful IOResult<void>.
Definition: io.h:359
requires details::IsElementReference< M > RowMajorIterator< M, false > begin(M &m)
create a non-const iterator to first element of the matrix m.
Definition: eigen_util.h:421
size_t flatten_index(MultiIndex const &indices, MultiIndex const &dimensions)
flatten_index takes a set of indices into a mutlidemsional array and calculates the flat index
Definition: custom_index_array.h:92
constexpr std::tuple_element< I, std::tuple< Index< CategoryTags >... > >::type & get(Index< CategoryTags... > &i) noexcept
Retrieves the Index (by reference) at the Ith position of a MultiIndex.
Definition: index.h:294
boost::outcome_v2::unchecked< T, IOStatus > IOResult
Value-or-error type for operations that return a value but can fail.
Definition: io.h:353
T start
Definition: eigen_util.h:45
T stride
Definition: eigen_util.h:45
T n
Definition: eigen_util.h:45
Definition: custom_index_array.h:75