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];
114 template <
typename T,
size_t R>
115 constexpr std::array<T, R>
operator*(std::array<T, R>
const &lhs, std::array<T, R>
const &rhs) {
116 std::array<T, R> res;
117 for (
int i = 0; i < R; ++i) res[i] = lhs[i] * rhs[i];
129 template <
typename T,
size_t R>
130 constexpr std::array<T, R>
operator-(std::array<T, R>
const &a) {
131 std::array<T, R> res;
132 for (
int i = 0; i < R; ++i) res[i] = -a[i];
145 template <
typename T,
size_t R>
146 constexpr std::array<T, R>
operator*(T s, std::array<T, R>
const &a) {
147 std::array<T, R> res;
148 for (
int i = 0; i < R; ++i) res[i] = s * a[i];
154namespace nda::stdutil {
164 template <
size_t R,
typename T>
166 return [&v]<
size_t... Is>(std::index_sequence<Is...>) {
167 return std::array<T, R>{(Is, v)...};
168 }(std::make_index_sequence<R>{});
180 template <
typename T,
typename U,
size_t R>
182 static_assert(std::is_constructible_v<T, U>,
"Error in nda::stdutil::make_std_array: T must be constructible from U");
184 for (
int u = 0; u < R; ++u) result[u] = a[u];
196 template <
typename T,
size_t R>
197 constexpr std::vector<T>
to_vector(std::array<T, R>
const &a) {
199 for (
int i = 0; i < R; ++i) V[i] = a[i];
213 template <
typename T, auto R,
typename U>
214 constexpr std::array<T, R + 1>
append(std::array<T, R>
const &a, U
const &x) {
215 std::array<T, R + 1> res;
216 for (
int i = 0; i < R; ++i) res[i] = a[i];
231 template <
typename T,
typename U,
size_t R>
232 constexpr std::array<T, R + 1>
front_append(std::array<T, R>
const &a, U
const &x) {
233 std::array<T, R + 1> res;
235 for (
int i = 0; i < R; ++i) res[i + 1] = a[i];
248 template <
int N,
typename T,
size_t R>
249 constexpr std::array<T, R - N>
mpop(std::array<T, R>
const &a) {
250 std::array<T, R - N> res;
251 for (
int i = 0; i < R - N; ++i) res[i] = a[i];
263 template <
typename T,
size_t R>
264 constexpr std::array<T, R - 1>
pop(std::array<T, R>
const &a) {
277 template <
int N,
typename T,
size_t R>
278 constexpr std::array<T, R - N>
front_mpop(std::array<T, R>
const &a) {
279 std::array<T, R - N> res;
280 for (
int i = N; i < R; ++i) res[i - N] = a[i];
292 template <
typename T,
size_t R>
293 constexpr std::array<T, R - 1>
front_pop(std::array<T, R>
const &a) {
308 template <
typename T,
size_t R1,
size_t R2>
309 constexpr std::array<T, R1 + R2>
join(std::array<T, R1>
const &a1, std::array<T, R2>
const &a2) {
310 std::array<T, R1 + R2> res;
311 for (
int i = 0; i < R1; ++i) res[i] = a1[i];
312 for (
int i = 0; i < R2; ++i) res[R1 + i] = a2[i];
325 template <
typename T,
size_t R>
326 constexpr auto sum(std::array<T, R>
const &a) {
327 if constexpr (R == 0)
331 for (
int i = 1; i < R; ++i) res += a[i];
344 template <
typename T,
size_t R>
345 constexpr auto product(std::array<T, R>
const &a) {
346 static_assert(R > 0,
"Error in nda::stdutil::product: Only defined for R > 0");
348 for (
int i = 1; i < R; ++i) res *= a[i];
365 template <
typename T,
typename U,
size_t R>
366 constexpr auto dot_product(std::array<T, R>
const &a1, std::array<U, R>
const &a2) {
367 if constexpr (R == 0)
370 auto res = a1[0] * a2[0];
371 for (
int i = 1; i < R; ++i) res += a1[i] * a2[i];
constexpr std::array< T, R > operator*(std::array< T, R > const &lhs, std::array< T, 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.