Skip to content

Instantly share code, notes, and snippets.

@lierdakil
Last active October 14, 2018 20:56
Show Gist options
  • Select an option

  • Save lierdakil/f76d2c3900a366e542907d0936886a24 to your computer and use it in GitHub Desktop.

Select an option

Save lierdakil/f76d2c3900a366e542907d0936886a24 to your computer and use it in GitHub Desktop.
Minimal robust multidimensional array wrapper over std::vector in C++14
#include <vector>
#include <numeric>
#include <array>
template<class T, size_t Ndim> class arrNd {
const std::array<const size_t, Ndim> _size;
std::array<size_t, Ndim-1> _strides;
std::vector<T> _data;
T& get(std::array<size_t, Ndim> ix) const {
return const_cast<T&>(_data.at(
std::inner_product(_strides.begin(), _strides.end(), ix.begin(), ix.back())
));
}
size_t fill_strides(std::array<size_t, Ndim> dims) {
_strides[Ndim-2] = dims[Ndim-1];
for(int i = Ndim-3; i >= 0; --i) {
_strides[i] = _strides[i+1]*dims[i+1];
}
return dims[0]*_strides[0];
}
public:
template<typename ... dims_t> arrNd(dims_t ... dims)
: _size{dims...}, _data(fill_strides({dims...})) {
static_assert(sizeof...(dims)==Ndim, "Number of dimensions in constructor arguments does not match declared number of dimensions in template parameter");
};
template<size_t dim> constexpr const size_t& dim_size() {
static_assert(dim<Ndim, "Dimension index template parameter in dim_size exceeds the bounds defined by the array size");
return std::get<dim>(_size);
};
template<typename ... idx> T& operator()(idx ... i) {
static_assert(sizeof...(i)==Ndim, "Number of dimensions in element access by index does not match declared number of dimensions in template parameter");
return get({i...});
};
template<typename ... idx> const T& operator()(idx ... i) const {
static_assert(sizeof...(i)==Ndim, "Number of dimensions in element access by index does not match declared number of dimensions in template parameter");
return get({i...});
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment