1#ifndef CHITECH_NDARRAY_H
2#define CHITECH_NDARRAY_H
34 template<
typename... U>
53 static_assert(std::is_integral<D>::value,
54 "NDArray dims argument must have vector of integral types.");
55 const size_t N = dims.size();
63 for(
size_t i = 0; i < N; ++i)
68 for(
size_t i = 0; i < N; ++i)
73 for(
size_t j = i+1; j < N; ++j)
78 for (
size_t i=0; i <
size_; ++i)
91 template<
typename D,
size_t N>
97 static_assert(std::is_integral<D>::value,
98 "NDArray dims argument must have array of integral types.");
105 for(
size_t i = 0; i < N; ++i)
110 for(
size_t i = 0; i < N; ++i)
115 for(
size_t j = i+1; j < N; ++j)
120 for (
size_t i=0; i <
size_; ++i)
134 NDArray(
const std::initializer_list<D>& dims) :
138 static_assert(std::is_integral<D>::value,
139 "NDArray dims argument must have vector of integral types.");
140 const size_t N = dims.size();
150 for (
size_t val : dims)
159 for(
size_t i = 0; i < N; ++i)
164 for(
size_t j = i+1; j < N; ++j)
169 for (
size_t i=0; i <
size_; ++i)
185 NDArray(
const std::vector<D>& dims, T value) :
189 static_assert(std::is_integral<D>::value,
190 "NDArray dims argument must have vector of integral types.");
191 const size_t N = dims.size();
199 for(
size_t i = 0; i < N; ++i)
204 for(
size_t i = 0; i < N; ++i)
209 for(
size_t j = i+1; j < N; ++j)
214 for (
size_t i=0; i <
size_; ++i)
228 template<
typename D,
size_t N>
230 NDArray(
const std::array<D, N>& dims, T value) :
234 static_assert(std::is_integral<D>::value,
235 "NDArray dims argument must have vector of integral types.");
242 for(
size_t i = 0; i < N; ++i)
247 for(
size_t i = 0; i < N; ++i)
252 for(
size_t j = i+1; j < N; ++j)
257 for (
size_t i=0; i <
size_; ++i)
273 NDArray(
const std::initializer_list<D>& dims, T value) :
277 static_assert(std::is_integral<D>::value,
278 "NDArray dims argument must have vector of integral types.");
279 const size_t N = dims.size();
289 for (
size_t val : dims)
298 for(
size_t i = 0; i < N; ++i)
303 for(
size_t j = i+1; j < N; ++j)
308 for (
size_t i=0; i <
size_; ++i)
334 const size_t N =
rank_;
339 for(
size_t i = 0; i < N; ++i)
345 for (
size_t i=0; i <
size_; ++i)
360 rank_(std::move(other.rank_)),
362 strides_(std::move(other.strides_)),
363 size_(std::move(other.size_)),
364 base_(std::move(other.base_))
374 for (
size_t i = 0; i <
size_; ++i)
417 std::vector<size_t> dim(
rank_, 0);
418 for (
size_t i=0; i <
rank_; ++i)
436 static_assert(std::is_integral<D>::value,
437 "NDArray dims argument must have vector of integral types.");
458 template<
typename D,
size_t N>
459 void resize(
const std::array<D, N>& dims)
461 static_assert(std::is_integral<D>::value,
462 "NDArray dims argument must have vector of integral types.");
484 void resize(
const std::initializer_list<D>& dims)
486 static_assert(std::is_integral<D>::value,
487 "NDArray dims argument must have vector of integral types.");
503 template<
typename... Args>
507 "NDArray::operator[]: All parameters must be of integral type");
509 size_t indices[] {
static_cast<size_t>(args)... };
511 const size_t N =
rank_;
513 T *address =
base_ + indices[N - 1];
514 for(
size_t i = 0;i < N-1;++i)
515 address +=
strides_[i] * indices[i];
523 template<
typename... Args>
527 "NDArray::operator[]: All parameters must be of integral type");
529 size_t indices[] {
static_cast<size_t>(args)... };
531 const size_t N =
rank_;
533 T *address =
base_ + indices[N - 1];
534 for(
size_t i = 0;i < N-1;++i)
535 address +=
strides_[i] * indices[i];
546 template<
typename... Args>
547 T&
at(Args... args)
noexcept
550 "NDArray::at(): All parameters must be of integral type");
552 if (
sizeof...(args) !=
rank_)
553 throw std::invalid_argument(
"NDArray::at(): Number of arguments " +
554 std::to_string(
sizeof...(args)) +
" not equal to rank " +
555 std::to_string(
rank_));
557 const size_t N =
rank_;
558 size_t indices[] {
static_cast<size_t>(args)... };
559 for (
size_t i=0; i<N; ++i)
561 throw std::out_of_range(
"NDArray::at(): Index " + std::to_string(i) +
562 " out of range " + std::to_string(indices[i]) +
565 T *address =
base_ + indices[N - 1];
566 for(
size_t i = 0;i < N-1;++i)
567 address +=
strides_[i] * indices[i];
578 template<
typename... Args>
582 "NDArray::at(): All parameters must be of integral type");
584 if (
sizeof...(args) !=
rank_)
585 throw std::invalid_argument(
"NDArray::at(): Number of arguments " +
586 std::to_string(
sizeof...(args)) +
" not equal to rank " +
587 std::to_string(
rank_));
589 const size_t N =
rank_;
590 size_t indices[] {
static_cast<size_t>(args)... };
591 for (
size_t i=0; i<N; ++i)
593 throw std::out_of_range(
"NDArray::at(): Index " + std::to_string(i) +
594 " out of range " + std::to_string(indices[i]) +
597 size_t index = indices[N-1];
598 for(
size_t i = 0;i < N-1;++i)
bool empty() const noexcept
NDArray(const std::array< D, N > &dims)
NDArray(NDArray< T > &&other) noexcept
typename conjunction< std::is_integral< U >... >::type AllIntegral
T * data() const noexcept
NDArray(const std::vector< D > &dims, T value)
T & at(Args... args) noexcept
void swap(NDArray< T > &other)
std::vector< size_t > dimension() const
T const & operator()(Args... args) const noexcept
void resize(const std::vector< D > &dims)
const T * cend() const noexcept
T & operator()(Args... args) noexcept
NDArray(NDArray< T > const &other)
NDArray(const std::initializer_list< D > &dims, T value)
NDArray(const std::array< D, N > &dims, T value)
std::is_same< bool_pack< true, U::value... >, bool_pack< U::value..., true > > conjunction
size_t rank() const noexcept
NDArray< T > & operator=(NDArray< T > const &other)
size_t MapNDtoLin(Args... args) const
NDArray(const std::vector< D > &dims)
void resize(const std::initializer_list< D > &dims)
T * begin() const noexcept
NDArray< T > & operator=(NDArray< T > &&)=delete
const T * cbegin() const noexcept
NDArray(const std::initializer_list< D > &dims)
size_t size() const noexcept
void resize(const std::array< D, N > &dims)