11#ifndef STDUTILS_ARRAY_H
12#define STDUTILS_ARRAY_H
38 template <
typename T,
size_t R>
39 std::ostream &
operator<<(std::ostream &out, std::array<T, R>
const &a) {
51 template <
typename T,
size_t R>
55 for (
int i = 0; i < R; ++i) fs << (i == 0 ?
"" :
" ") << a[i];
69 template <
typename T,
size_t R>
70 constexpr std::array<T, R>
operator+(std::array<T, R>
const &lhs, std::array<T, R>
const &rhs) {
72 for (
int i = 0; i < R; ++i) res[i] = lhs[i] + rhs[i];
85 template <
typename T,
size_t R>
86 constexpr std::array<T, R>
operator-(std::array<T, R>
const &lhs, std::array<T, R>
const &rhs) {
88 for (
int i = 0; i < R; ++i) res[i] = lhs[i] - rhs[i];
102 template <
typename T,
typename U,
size_t R>
103 constexpr auto operator*(std::array<T, R>
const &lhs, std::array<U, R>
const &rhs) {
104 using TU =
decltype(std::declval<T>() * std::declval<U>());
106 std::array<TU, R> res;
107 for (
int i = 0; i < R; ++i) res[i] = lhs[i] * rhs[i];
119 template <
typename T,
size_t R>
120 constexpr std::array<T, R>
operator-(std::array<T, R>
const &a) {
121 std::array<T, R> res;
122 for (
int i = 0; i < R; ++i) res[i] = -a[i];
135 template <
typename T,
size_t R>
136 constexpr std::array<T, R>
operator*(T s, std::array<T, R>
const &a) {
137 std::array<T, R> res;
138 for (
int i = 0; i < R; ++i) res[i] = s * a[i];
144namespace nda::stdutil {
154 template <
size_t R,
typename T>
156 return [&v]<
size_t... Is>(std::index_sequence<Is...>) {
157 return std::array<T, R>{((void)Is, v)...};
158 }(std::make_index_sequence<R>{});
170 template <
typename T,
typename U,
size_t R>
172 static_assert(std::is_constructible_v<T, U>,
"Error in nda::stdutil::make_std_array: T must be constructible from U");
174 for (
int u = 0; u < R; ++u) result[u] = a[u];
186 template <
typename T,
size_t R>
187 constexpr std::vector<T>
to_vector(std::array<T, R>
const &a) {
189 for (
int i = 0; i < R; ++i) V[i] = a[i];
203 template <
typename T, auto R,
typename U>
204 constexpr std::array<T, R + 1>
append(std::array<T, R>
const &a, U
const &x) {
205 std::array<T, R + 1> res;
206 for (
int i = 0; i < R; ++i) res[i] = a[i];
221 template <
typename T,
typename U,
size_t R>
222 constexpr std::array<T, R + 1>
front_append(std::array<T, R>
const &a, U
const &x) {
223 std::array<T, R + 1> res;
225 for (
int i = 0; i < R; ++i) res[i + 1] = a[i];
238 template <
int N,
typename T,
size_t R>
239 constexpr std::array<T, R - N>
mpop(std::array<T, R>
const &a) {
240 std::array<T, R - N> res;
241 for (
int i = 0; i < R - N; ++i) res[i] = a[i];
253 template <
typename T,
size_t R>
254 constexpr std::array<T, R - 1>
pop(std::array<T, R>
const &a) {
267 template <
int N,
typename T,
size_t R>
268 constexpr std::array<T, R - N>
front_mpop(std::array<T, R>
const &a) {
269 std::array<T, R - N> res;
270 for (
int i = N; i < R; ++i) res[i - N] = a[i];
282 template <
typename T,
size_t R>
283 constexpr std::array<T, R - 1>
front_pop(std::array<T, R>
const &a) {
298 template <
typename T,
size_t R1,
size_t R2>
299 constexpr std::array<T, R1 + R2>
join(std::array<T, R1>
const &a1, std::array<T, R2>
const &a2) {
300 std::array<T, R1 + R2> res;
301 for (
int i = 0; i < R1; ++i) res[i] = a1[i];
302 for (
int i = 0; i < R2; ++i) res[R1 + i] = a2[i];
315 template <
typename T,
size_t R>
316 constexpr auto sum(std::array<T, R>
const &a) {
317 if constexpr (R == 0)
321 for (
int i = 1; i < R; ++i) res += a[i];
334 template <
typename T,
size_t R>
335 constexpr auto product(std::array<T, R>
const &a) {
336 static_assert(R > 0,
"Error in nda::stdutil::product: Only defined for R > 0");
338 for (
int i = 1; i < R; ++i) res *= a[i];
355 template <
typename T,
typename U,
size_t R>
356 constexpr auto dot_product(std::array<T, R>
const &a1, std::array<U, R>
const &a2) {
357 if constexpr (R == 0)
360 auto res = a1[0] * a2[0];
361 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.