TRIQS/nda 1.3.0
Multi-dimensional array library for C++
Loading...
Searching...
No Matches
array.hpp
Go to the documentation of this file.
1// Copyright (c) 2018--present, The Simons Foundation
2// This file is part of TRIQS/nda and is licensed under the Apache License, Version 2.0.
3// SPDX-License-Identifier: Apache-2.0
4// See LICENSE in the root of this distribution for details.
5
10
11#ifndef STDUTILS_ARRAY_H
12#define STDUTILS_ARRAY_H
13
14#include <array>
15#include <ostream>
16#include <sstream>
17#include <string>
18#include <type_traits>
19#include <vector>
20#include <utility>
21
22namespace std { // has to be in the right namespace for ADL
23
28
38 template <typename T, size_t R>
39 std::ostream &operator<<(std::ostream &out, std::array<T, R> const &a) {
40 return out << to_string(a);
41 }
42
51 template <typename T, size_t R>
52 std::string to_string(std::array<T, R> const &a) {
53 std::stringstream fs;
54 fs << "(";
55 for (int i = 0; i < R; ++i) fs << (i == 0 ? "" : " ") << a[i];
56 fs << ")";
57 return fs.str();
58 }
59
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) {
71 std::array<T, R> res;
72 for (int i = 0; i < R; ++i) res[i] = lhs[i] + rhs[i];
73 return res;
74 }
75
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) {
87 std::array<T, R> res;
88 for (int i = 0; i < R; ++i) res[i] = lhs[i] - rhs[i];
89 return res;
90 }
91
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>());
105
106 std::array<TU, R> res;
107 for (int i = 0; i < R; ++i) res[i] = lhs[i] * rhs[i];
108 return res;
109 }
110
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];
123 return res;
124 }
125
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];
139 return res;
140 }
141
142} // namespace std
143
144namespace nda::stdutil {
145
154 template <size_t R, typename T>
155 constexpr std::array<T, R> make_initialized_array(T v) {
156 return [&v]<size_t... Is>(std::index_sequence<Is...>) {
157 return std::array<T, R>{((void)Is, v)...}; // NOLINT (always v, just a trick to have the pack)
158 }(std::make_index_sequence<R>{});
159 }
160
170 template <typename T, typename U, size_t R>
171 constexpr std::array<T, R> make_std_array(std::array<U, R> const &a) {
172 static_assert(std::is_constructible_v<T, U>, "Error in nda::stdutil::make_std_array: T must be constructible from U");
173 std::array<T, R> result = make_initialized_array<R>(T{});
174 for (int u = 0; u < R; ++u) result[u] = a[u];
175 return result;
176 }
177
186 template <typename T, size_t R>
187 constexpr std::vector<T> to_vector(std::array<T, R> const &a) {
188 std::vector<T> V(R);
189 for (int i = 0; i < R; ++i) V[i] = a[i];
190 return V;
191 }
192
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];
207 res[R] = x;
208 return res;
209 }
210
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;
224 res[0] = x;
225 for (int i = 0; i < R; ++i) res[i + 1] = a[i];
226 return res;
227 }
228
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];
242 return res;
243 }
244
253 template <typename T, size_t R>
254 constexpr std::array<T, R - 1> pop(std::array<T, R> const &a) {
255 return mpop<1>(a);
256 }
257
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];
271 return res;
272 }
273
282 template <typename T, size_t R>
283 constexpr std::array<T, R - 1> front_pop(std::array<T, R> const &a) {
284 return front_mpop<1>(a);
285 }
286
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];
303 return res;
304 }
305
315 template <typename T, size_t R>
316 constexpr auto sum(std::array<T, R> const &a) {
317 if constexpr (R == 0)
318 return T{};
319 else {
320 auto res = a[0];
321 for (int i = 1; i < R; ++i) res += a[i];
322 return res;
323 }
324 }
325
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");
337 auto res = a[0];
338 for (int i = 1; i < R; ++i) res *= a[i];
339 return res;
340 }
341
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)
358 return T{};
359 else {
360 auto res = a1[0] * a2[0];
361 for (int i = 1; i < R; ++i) res += a1[i] * a2[i];
362 return res;
363 }
364 }
365
367
368} // namespace nda::stdutil
369
370#endif // STDUTILS_ARRAY_H
constexpr auto operator*(std::array< T, R > const &lhs, std::array< U, R > const &rhs)
Multiply two std::array objects element-wise.
Definition array.hpp:103
std::ostream & operator<<(std::ostream &out, std::array< T, R > const &a)
Write a std::array to an output stream.
Definition array.hpp:39
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.
Definition array.hpp:268
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.
Definition array.hpp:204
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.
Definition array.hpp:222
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.
Definition array.hpp:254
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.
Definition array.hpp:70
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.
Definition array.hpp:299
constexpr std::vector< T > to_vector(std::array< T, R > const &a)
Convert a std::array to a std::vector.
Definition array.hpp:187
constexpr std::array< T, R > make_initialized_array(T v)
Create a new std::array object initialized with a specific value.
Definition array.hpp:155
constexpr auto sum(std::array< T, R > const &a)
Calculate the sum of all elements in a std::array.
Definition array.hpp:316
std::string to_string(std::array< T, R > const &a)
Get a string representation of a std::array.
Definition array.hpp:52
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.
Definition array.hpp:86
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.
Definition array.hpp:171
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.
Definition array.hpp:283
constexpr auto product(std::array< T, R > const &a)
Calculate the product of all elements in a std::array.
Definition array.hpp:335
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.
Definition array.hpp:356
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.
Definition array.hpp:239