Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <array>
- #include <vector>
- #include <type_traits>
- template <size_t D, class T> class Array final {
- public:
- template <class... Is,
- class = std::enable_if_t<(... && std::is_convertible_v<size_t, Is>)>>
- Array(Is &&... indices) :
- _size({ std::forward<Is>(indices)... }),
- _index(_size)
- {
- size_t total_size = 1;
- for (size_t i = 0; i < _size.size(); ++i) {
- total_size *= _size[i];
- }
- _data.resize(total_size);
- }
- Array(Array<D, T> const &) = default;
- Array(Array<D, T> &&) = default;
- ~Array() = default;
- Array<D, T> &operator=(Array<D, T> const &) = default;
- Array<D, T> &operator=(Array<D, T> &&) = default;
- size_t size(size_t ix) const {
- return _size[ix];
- }
- size_t total_size() const {
- return _data.size();
- }
- template <class... Index> T &at(Index &&... indices) {
- return _data.at(_index.compute(std::forward<Index>(indices)...));
- }
- template <class... Index> T const &at(Index &&... indices) const {
- return _data.at(_index.compute(std::forward<Index>(indices)...));
- }
- template <class... Index> T &at_unchecked(Index &&... indices) {
- return _data[_index.compute(std::forward<Index>(indices)...)];
- }
- template <class... Index> T const &at_unchecked(Index &&... indices) const {
- return _data[_index.compute(std::forward<Index>(indices)...)];
- }
- auto begin() -> decltype(auto) {
- return _data.begin();
- }
- auto begin() const -> decltype(auto) {
- return _data.begin();
- }
- auto end() -> decltype(auto) {
- return _data.end();
- }
- auto end() const -> decltype(auto) {
- return _data.end();
- }
- T *data() {
- return _data.data();
- }
- T const *data() const {
- return _data.data();
- }
- private:
- class LinearIndex {
- public:
- LinearIndex(std::array<size_t, D> const& size);
- template <class... Index>
- size_t compute(Index&&... index) const;
- private:
- template <class... Index, size_t... Dimension>
- size_t _compute_helper(std::integer_sequence<size_t, Dimension...>, Index&&... index) const;
- constexpr size_t _get_factor(size_t i) const {
- if ((i+1) < D) {
- return _factor[i];
- } else {
- return 1;
- }
- }
- std::array<size_t, D - 1> _factor;
- };
- std::array<size_t, D> _size;
- std::vector<T> _data;
- LinearIndex _index;
- };
- template <size_t D, class T>
- Array<D,T>::LinearIndex::LinearIndex(std::array<size_t, D> const& size) {
- size_t factor = 1;
- for (size_t i = size.size() - 1; i > 0; --i) {
- factor *= size[i];
- _factor[i - 1] = factor;
- }
- }
- template <size_t D, class T>
- template <class... Index>
- size_t Array<D,T>::LinearIndex::compute(Index&&... index) const {
- static_assert(sizeof...(Index) == D, "wrong number of indices.");
- return _compute_helper(
- std::index_sequence_for<Index...>{},
- std::forward<Index>(index)...);
- }
- template <size_t D, class T>
- template <class... Index, size_t... Dimension>
- size_t Array<D,T>::LinearIndex::_compute_helper(
- std::integer_sequence<size_t, Dimension...>,
- Index&&... index) const
- {
- return (... + (_get_factor(Dimension)*index));
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement