1#ifndef CPP_UTILITIES_MULTI_ARRAY_H
2#define CPP_UTILITIES_MULTI_ARRAY_H
12template <
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) *
static_cast<std::size_t
>(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 *
static_cast<std::size_t
>(std::get<N - 1>(dimensions)))
20 + (factor *
static_cast<std::size_t
>(std::get<N - 1>(indices)));
23template <
class Tuple>
struct DimensionsHelper<Tuple, 1> {
24 static std::size_t requiredSize(
const Tuple &dimensionSizes)
26 return static_cast<std::size_t
>(std::get<0>(dimensionSizes));
28 static std::size_t offset(
const Tuple &,
const Tuple &indices, std::size_t factor)
30 return factor *
static_cast<std::size_t
>(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)
76template <
typename T,
typename UnderlyingContainer,
typename... Dimensions>
class MultiArray {
81 template <std::
size_t index> std::size_t
dimensionSize()
const;
82 T &
at(Dimensions... indices);
83 const T &
at(Dimensions... indices)
const;
85 const T *
data()
const;
86 typename UnderlyingContainer::template Type<T> &
buffer();
89 using HelperType = Detail::DimensionsHelper<std::tuple<Dimensions...>,
dimensionCount()>;
90 const std::tuple<Dimensions...> m_dims;
91 const std::size_t m_size;
92 typename UnderlyingContainer::template Type<T> m_buff;
98template <
typename T,
typename UnderlyingContainer,
typename... Dimensions>
100 : m_dims(
std::make_tuple(dimensionSizes...))
101 , m_size(HelperType::requiredSize(m_dims))
102 , m_buff(UnderlyingContainer::template init<T>(m_size))
107template <
typename T,
typename UnderlyingContainer,
typename... Dimensions>
114template <
typename T,
typename UnderlyingContainer,
typename... Dimensions>
117 return std::tuple_size<std::tuple<Dimensions...>>::value;
121template <
typename T,
typename UnderlyingContainer,
typename... Dimensions>
122template <std::
size_t index>
125 return static_cast<std::size_t
>(std::get<index>(m_dims));
130template <
typename T,
typename UnderlyingContainer,
typename... Dimensions>
133 return m_buff[HelperType::offset(m_dims, std::make_tuple(indices...), 1)];
138template <
typename T,
typename UnderlyingContainer,
typename... Dimensions>
141 return m_buff[HelperType::offset(m_dims, std::make_tuple(indices...), 1)];
148 return m_buff.data();
155 return m_buff.data();
160template <
typename T,
typename UnderlyingContainer,
typename... Dimensions>
169template <
typename ValueType,
typename... DimensionSizes>
inline auto makeMultiArray(DimensionSizes... dimensionSizes)
177template <
typename ValueType, std::size_t size,
typename... DimensionSizes>
inline auto makeFixedSizeMultiArray(DimensionSizes... dimensionSizes)
The MultiArray class provides an N-dimensional array.
MultiArray(Dimensions... dimensionSizes)
Constructs a new N-dimensional array. The sizes for the dimensions are passed as arguments and must b...
std::size_t dimensionSize() const
Returns the number of elements in the specified dimension.
std::size_t totalSize() const
Returns the total number of elements.
T & at(Dimensions... indices)
Returns the element at the position specified via indices.
static constexpr std::size_t dimensionCount()
Returns the number of dimensions for that type of array.
T * data()
Returns a pointer to the raw data.
UnderlyingContainer::template Type< T > & buffer()
Allows accessing the underlying buffer directly.
Contains all utilities provides by the c++utilities library.
auto makeNoneOwningMultiArray(DimensionSizes... dimensionSizes)
Constructs a new N-dimensional array using a caller-managed buffer as underlying container....
auto makeFixedSizeMultiArray(DimensionSizes... dimensionSizes)
Constructs a new N-dimensional array using a fixed size array as underlying container....
auto makeMultiArray(DimensionSizes... dimensionSizes)
Constructs a new N-dimensional array using an std::vector with std::allocator as underlying container...
The ArrayBasedMultiArray struct allows using a fixed size array as underlying container for the Multi...
std::array< T, size > Type
static constexpr Type< T > init(std::size_t)
The NoneOwningMultiArray struct allows using a caller-managed buffer array as underlying container fo...
static constexpr Type< T > init(std::size_t)
std::vector< T, std::allocator< T > > Type
static constexpr Type< T > init(std::size_t requiredSize)
The VectorBasedMultiArray struct allows using an std::vector with custom allocator as underlying cont...
std::vector< T, Allocator > Type
static constexpr Type< T > init(std::size_t requiredSize)