LibraryLink Utilities  3.0.1
Modern C++ wrapper over LibraryLink and WSTP
MArrayDimensions.h
Go to the documentation of this file.
1 
6 #ifndef LLU_CONTAINERS_MARRAYDIMENSIONS_H_
7 #define LLU_CONTAINERS_MARRAYDIMENSIONS_H_
8 
9 #include <initializer_list>
10 #include <type_traits>
11 #include <vector>
12 
14 #include "LLU/LibraryData.h"
15 #include "LLU/Utilities.hpp"
16 
17 namespace LLU {
18 
24  public:
28  MArrayDimensions() = default;
29 
36  MArrayDimensions(std::initializer_list<mint> dimensions);
37 
45  template<typename T, typename = typename std::enable_if_t<std::is_integral_v<T>>>
46  MArrayDimensions(const T* dimensions, mint rank);
47 
54  template<typename T, typename = typename std::enable_if_t<std::is_integral_v<T>>>
55  explicit MArrayDimensions(const std::vector<T>& dimensions);
56 
63  template<typename InputIter, typename = enable_if_input_iterator<InputIter>>
64  MArrayDimensions(InputIter dimsBegin, InputIter dimsEnd);
65 
69  mint rank() const noexcept {
70  return static_cast<mint>(dims.size());
71  }
72 
76  const mint* data() const noexcept {
77  if (dims.empty()) {
78  return nullptr;
79  }
80  return dims.data();
81  }
82 
86  const std::vector<mint>& get() const noexcept {
87  return dims;
88  }
89 
95  mint get(mint dim) const {
96  if (dim >= rank() || dim < 0) {
98  }
99  return dims[static_cast<decltype(dims)::size_type>(dim)];
100  }
101 
106  mint getIndex(const std::vector<mint>& indices) const;
107 
113  mint getIndexChecked(const std::vector<mint>& indices) const;
114 
120  mint getIndexChecked(mint index) const;
121 
126  mint flatCount() const noexcept {
127  return flattenedLength;
128  }
129 
130  private:
132  mint flattenedLength = 1;
133 
135  std::vector<mint> dims;
136 
138  std::vector<mint> offsets;
139 
141  void fillOffsets();
142 
143  private:
149  template<typename T>
150  mint checkContainerSize(T s) const;
151 
153  [[nodiscard]] mint totalLengthFromDims() const noexcept;
154 
155  static constexpr std::size_t MAX_DIM = static_cast<std::size_t>((std::numeric_limits<mint>::max)());
156  };
157 
158  template<typename T, typename>
159  MArrayDimensions::MArrayDimensions(const T* dimensions, mint rank) : MArrayDimensions(dimensions, std::next(dimensions, rank)) {}
160 
161  template<typename T, typename>
162  MArrayDimensions::MArrayDimensions(const std::vector<T>& dimensions) : MArrayDimensions(std::cbegin(dimensions), std::cend(dimensions)) {}
163 
164  template<typename InputIter, typename>
165  MArrayDimensions::MArrayDimensions(InputIter dimsBegin, InputIter dimsEnd) {
166  if (mint depth = checkContainerSize(std::distance(dimsBegin, dimsEnd)); depth >= 1) {
167  auto dimsOk = std::all_of(dimsBegin, dimsEnd - 1, [](auto d) { return (d > 0) && (static_cast<std::size_t>(d) <= MAX_DIM); }) &&
168  (dimsBegin[depth - 1] >= 0) && (static_cast<std::size_t>(dimsBegin[depth - 1]) <= MAX_DIM);
169  if (!dimsOk) {
170  ErrorManager::throwExceptionWithDebugInfo(ErrorName::DimensionsError, "Invalid input vector with array dimensions");
171  }
172  dims.reserve(depth);
173  }
174  std::copy(dimsBegin, dimsEnd, std::back_inserter(dims));
175  flattenedLength = totalLengthFromDims();
176  fillOffsets();
177  }
178 
179  template<typename T>
180  mint MArrayDimensions::checkContainerSize(T s) const {
181  if (s < 0 || static_cast<std::size_t>(s) > MAX_DIM) {
183  }
184  return static_cast<mint>(s);
185  }
186 
187 } /* namespace LLU */
188 
189 #endif /* LLU_CONTAINERS_MARRAYDIMENSIONS_H_ */
LLU::ErrorManager::throwExceptionWithDebugInfo
static void throwExceptionWithDebugInfo(const std::string &errorName, const std::string &debugInfo, T &&... args)
Throw exception with given name and additional information that might be helpful in debugging.
Definition: ErrorManager.h:214
LLU::MArrayDimensions::flatCount
mint flatCount() const noexcept
Get total number of elements.
Definition: MArrayDimensions.h:126
LLU
Main namespace of LibraryLink Utilities.
Definition: Queue.h:13
LLU::MArrayDimensions::MArrayDimensions
MArrayDimensions()=default
Default constructor.
LibraryData.h
LLU::ErrorName::DimensionsError
const std::string DimensionsError
same as LIBRARY_DIMENSIONS_ERROR
LLU::MArrayDimensions::get
const std::vector< mint > & get() const noexcept
Get container dimensions in the form of const& to std::vector.
Definition: MArrayDimensions.h:86
LLU::MArrayDimensions
Helper class that carries meta-information about container's size and dimensions.
Definition: MArrayDimensions.h:23
LLU::MArrayDimensions::getIndex
mint getIndex(const std::vector< mint > &indices) const
Convert coordinates of an element in a multidimensional MArray to the corresponding index in a flat l...
Definition: MArrayDimensions.cpp:66
LLU::MArrayDimensions::data
const mint * data() const noexcept
Get raw pointer to container dimensions.
Definition: MArrayDimensions.h:76
ErrorManager.h
Definition of the ErrorManager class responsible for error registration and throwing.
LLU::MArrayDimensions::rank
mint rank() const noexcept
Get container rank.
Definition: MArrayDimensions.h:69
LLU::MArrayDimensions::getIndexChecked
mint getIndexChecked(const std::vector< mint > &indices) const
Check if given coordinates are valid for this container.
Definition: MArrayDimensions.cpp:46
LLU::ErrorManager::throwException
static void throwException(const std::string &errorName, T &&... args)
Throw exception with given name.
Definition: ErrorManager.h:199
LLU::ErrorName::MArrayDimensionIndexError
const std::string MArrayDimensionIndexError
attempting to access MArray dimension at invalid index
Utilities.hpp
Short but generally useful functions.
LLU::MArrayDimensions::get
mint get(mint dim) const
Get single dimension.
Definition: MArrayDimensions.h:95