24#ifndef STDUTILS_ARRAY_H
25#define STDUTILS_ARRAY_H
51 template <
typename T,
size_t R>
52 std::ostream &
operator<<(std::ostream &out, std::array<T, R>
const &a) {
64 template <
typename T,
size_t R>
68 for (
int i = 0; i < R; ++i) fs << (i == 0 ?
"" :
" ") << a[i];
82 template <
typename T,
size_t R>
83 constexpr std::array<T, R>
operator+(std::array<T, R>
const &lhs, std::array<T, R>
const &rhs) {
85 for (
int i = 0; i < R; ++i) res[i] = lhs[i] + rhs[i];
98 template <
typename T,
size_t R>
99 constexpr std::array<T, R>
operator-(std::array<T, R>
const &lhs, std::array<T, R>
const &rhs) {
100 std::array<T, R> res;
101 for (
int i = 0; i < R; ++i) res[i] = lhs[i] - rhs[i];
115 template <
typename T,
typename U,
size_t R>
116 constexpr auto operator*(std::array<T, R>
const &lhs, std::array<U, R>
const &rhs) {
117 using TU =
decltype(std::declval<T>() * std::declval<U>());
119 std::array<TU, R> res;
120 for (
int i = 0; i < R; ++i) res[i] = lhs[i] * rhs[i];
132 template <
typename T,
size_t R>
133 constexpr std::array<T, R>
operator-(std::array<T, R>
const &a) {
134 std::array<T, R> res;
135 for (
int i = 0; i < R; ++i) res[i] = -a[i];
148 template <
typename T,
size_t R>
149 constexpr std::array<T, R>
operator*(T s, std::array<T, R>
const &a) {
150 std::array<T, R> res;
151 for (
int i = 0; i < R; ++i) res[i] = s * a[i];
157namespace nda::stdutil {
167 template <
size_t R,
typename T>
169 return [&v]<
size_t... Is>(std::index_sequence<Is...>) {
170 return std::array<T, R>{((void)Is, v)...};
171 }(std::make_index_sequence<R>{});
183 template <
typename T,
typename U,
size_t R>
185 static_assert(std::is_constructible_v<T, U>,
"Error in nda::stdutil::make_std_array: T must be constructible from U");
187 for (
int u = 0; u < R; ++u) result[u] = a[u];
199 template <
typename T,
size_t R>
200 constexpr std::vector<T>
to_vector(std::array<T, R>
const &a) {
202 for (
int i = 0; i < R; ++i) V[i] = a[i];
216 template <
typename T, auto R,
typename U>
217 constexpr std::array<T, R + 1>
append(std::array<T, R>
const &a, U
const &x) {
218 std::array<T, R + 1> res;
219 for (
int i = 0; i < R; ++i) res[i] = a[i];
234 template <
typename T,
typename U,
size_t R>
235 constexpr std::array<T, R + 1>
front_append(std::array<T, R>
const &a, U
const &x) {
236 std::array<T, R + 1> res;
238 for (
int i = 0; i < R; ++i) res[i + 1] = a[i];
251 template <
int N,
typename T,
size_t R>
252 constexpr std::array<T, R - N>
mpop(std::array<T, R>
const &a) {
253 std::array<T, R - N> res;
254 for (
int i = 0; i < R - N; ++i) res[i] = a[i];
266 template <
typename T,
size_t R>
267 constexpr std::array<T, R - 1>
pop(std::array<T, R>
const &a) {
280 template <
int N,
typename T,
size_t R>
281 constexpr std::array<T, R - N>
front_mpop(std::array<T, R>
const &a) {
282 std::array<T, R - N> res;
283 for (
int i = N; i < R; ++i) res[i - N] = a[i];
295 template <
typename T,
size_t R>
296 constexpr std::array<T, R - 1>
front_pop(std::array<T, R>
const &a) {
311 template <
typename T,
size_t R1,
size_t R2>
312 constexpr std::array<T, R1 + R2>
join(std::array<T, R1>
const &a1, std::array<T, R2>
const &a2) {
313 std::array<T, R1 + R2> res;
314 for (
int i = 0; i < R1; ++i) res[i] = a1[i];
315 for (
int i = 0; i < R2; ++i) res[R1 + i] = a2[i];
328 template <
typename T,
size_t R>
329 constexpr auto sum(std::array<T, R>
const &a) {
330 if constexpr (R == 0)
334 for (
int i = 1; i < R; ++i) res += a[i];
347 template <
typename T,
size_t R>
348 constexpr auto product(std::array<T, R>
const &a) {
349 static_assert(R > 0,
"Error in nda::stdutil::product: Only defined for R > 0");
351 for (
int i = 1; i < R; ++i) res *= a[i];
368 template <
typename T,
typename U,
size_t R>
369 constexpr auto dot_product(std::array<T, R>
const &a1, std::array<U, R>
const &a2) {
370 if constexpr (R == 0)
373 auto res = a1[0] * a2[0];
374 for (
int i = 1; i < R; ++i) res += a1[i] * a2[i];
constexpr auto operator*(std::array< T, R > const &lhs, std::array< U, R > const &rhs)
Multiply two std::array objects element-wise.
std::ostream & operator<<(std::ostream &out, std::array< T, R > const &a)
Write a std::array to an output stream.
constexpr std::array< T, R - N > front_mpop(std::array< T, R > const &a)
Make a new std::array by popping the first N elements of an existing std::array.
constexpr std::array< T, R+1 > append(std::array< T, R > const &a, U const &x)
Make a new std::array by appending one element at the end to an existing std::array.
constexpr std::array< T, R+1 > front_append(std::array< T, R > const &a, U const &x)
Make a new std::array by prepending one element at the front to an existing std::array.
constexpr std::array< T, R - 1 > pop(std::array< T, R > const &a)
Make a new std::array by popping the last element of an existing std::array.
constexpr std::array< T, R > operator+(std::array< T, R > const &lhs, std::array< T, R > const &rhs)
Add two std::array objects element-wise.
constexpr std::array< T, R1+R2 > join(std::array< T, R1 > const &a1, std::array< T, R2 > const &a2)
Make a new std::array by joining two existing std::array objects.
constexpr std::vector< T > to_vector(std::array< T, R > const &a)
Convert a std::array to a std::vector.
constexpr std::array< T, R > make_initialized_array(T v)
Create a new std::array object initialized with a specific value.
constexpr auto sum(std::array< T, R > const &a)
Calculate the sum of all elements in a std::array.
std::string to_string(std::array< T, R > const &a)
Get a string representation of a std::array.
constexpr std::array< T, R > operator-(std::array< T, R > const &lhs, std::array< T, R > const &rhs)
Subtract two std::array objects element-wise.
constexpr std::array< T, R > make_std_array(std::array< U, R > const &a)
Convert a std::array with value type U to a std::array with value type T.
constexpr std::array< T, R - 1 > front_pop(std::array< T, R > const &a)
Make a new std::array by popping the first element of an existing std::array.
constexpr auto product(std::array< T, R > const &a)
Calculate the product of all elements in a std::array.
constexpr auto dot_product(std::array< T, R > const &a1, std::array< U, R > const &a2)
Calculate the dot product of two std::array objects.
constexpr std::array< T, R - N > mpop(std::array< T, R > const &a)
Make a new std::array by popping the last N elements of an existing std::array.