1 #ifndef CPP_UTILITIES_MULTI_ARRAY_H
2 #define CPP_UTILITIES_MULTI_ARRAY_H
12 template <
class Tuple, std::
size_t N>
struct DimensionsHelper {
13 static std::size_t requiredSize(
const Tuple &dimensionSizes)
15 return DimensionsHelper<Tuple, N - 1>::requiredSize(dimensionSizes) * std::get<N - 1>(dimensionSizes);
17 static std::size_t offset(
const Tuple &dimensions,
const Tuple &indices, std::size_t factor)
19 return DimensionsHelper<Tuple, N - 1>::offset(dimensions, indices, factor * std::get<N - 1>(dimensions))
20 + (factor * std::get<N - 1>(indices));
23 template <
class Tuple>
struct DimensionsHelper<Tuple, 1> {
24 static std::size_t requiredSize(
const Tuple &dimensionSizes)
26 return std::get<0>(dimensionSizes);
28 static std::size_t offset(
const Tuple &,
const Tuple &indices, std::size_t factor)
30 return factor * std::get<0>(indices);
38 template <
typename T>
using Type = std::vector<T, Allocator>;
39 template <
typename T>
static constexpr
Type<T> init(std::size_t requiredSize)
47 template <
typename T>
using Type = std::vector<T, std::allocator<T>>;
48 template <
typename T>
static constexpr
Type<T> init(std::size_t requiredSize)
56 template <
typename T>
using Type = std::array<T, size>;
57 template <
typename T>
static constexpr
Type<T> init(std::size_t)
65 template <
typename T>
using Type = T *;
66 template <
typename T>
static constexpr
Type<T> init(std::size_t)
73 template <
typename T,
typename UnderlyingContainer,
typename... Dimensions>
class MultiArray {
78 template <std::
size_t index> std::size_t
dimensionSize()
const;
79 T &
at(Dimensions... indices);
80 const T &
at(Dimensions... indices)
const;
82 const T *
data()
const;
83 typename UnderlyingContainer::template Type<T> &
buffer();
86 using HelperType = Detail::DimensionsHelper<std::tuple<Dimensions...>,
dimensionCount()>;
87 const std::tuple<Dimensions...> m_dims;
88 const std::size_t m_size;
89 typename UnderlyingContainer::template Type<T> m_buff;
95 template <
typename T,
typename UnderlyingContainer,
typename... Dimensions>
97 : m_dims(std::make_tuple(dimensionSizes...))
98 , m_size(HelperType::requiredSize(m_dims))
99 , m_buff(UnderlyingContainer::template init<T>(m_size))
104 template <
typename T,
typename UnderlyingContainer,
typename... Dimensions>
111 template <
typename T,
typename UnderlyingContainer,
typename... Dimensions>
114 return std::tuple_size<std::tuple<Dimensions...>>::value;
118 template <
typename T,
typename UnderlyingContainer,
typename... Dimensions>
119 template <std::
size_t index>
122 return std::get<index>(m_dims);
127 template <
typename T,
typename UnderlyingContainer,
typename... Dimensions>
130 return m_buff[HelperType::offset(m_dims, std::make_tuple(indices...), 1)];
135 template <
typename T,
typename UnderlyingContainer,
typename... Dimensions>
138 return m_buff[HelperType::offset(m_dims, std::make_tuple(indices...), 1)];
145 return m_buff.data();
152 return m_buff.data();
157 template <
typename T,
typename UnderlyingContainer,
typename... Dimensions>
166 template <
typename ValueType,
typename... DimensionSizes>
inline auto makeMultiArray(DimensionSizes... dimensionSizes)
174 template <
typename ValueType, std::size_t size,
typename... DimensionSizes>
inline auto makeFixedSizeMultiArray(DimensionSizes... dimensionSizes)
189 #endif // CPP_UTILITIES_MULTI_ARRAY_H