Arduino Helpers master
Utility library for Arduino
ArrayHelpers.hpp
Go to the documentation of this file.
1/* ✔ */
2
3#pragma once
4
6
7AH_DIAGNOSTIC_WERROR() // Enable errors on warnings
8
9#include "Array.hpp"
10#include <AH/STL/algorithm>
11
12#if __cplusplus >= 201400L
13#define USE_CONSTEXPR_ARRAY_HELPERS constexpr
14#else
15#define USE_CONSTEXPR_ARRAY_HELPERS
16#endif
17
19
20namespace detail {
21
31template <class T, class V>
33 public:
35 : value(start), increment(increment) {}
37 T temp = value;
39 return temp;
40 }
41
42 private:
44 const V increment;
45};
46
47} // namespace detail
48
51
67template <class T, size_t N, class G>
69 Array<T, N> array{{}};
70 std::generate(array.begin(), array.end(), generator);
71 return array;
72}
73
87template <size_t N, class G>
89 -> Array<decltype(generator()), N> {
90 Array<decltype(generator()), N> array{{}};
91 std::generate(array.begin(), array.end(), generator);
92 return array;
93}
94
108template <class T, size_t N, class U>
110 Array<T, N> dest{{}};
111 std::transform(std::begin(src), std::end(src), std::begin(dest),
112 [](const U &src) { return T(src); });
113 return dest;
114}
115
119template <class F, class U, size_t N>
120USE_CONSTEXPR_ARRAY_HELPERS Array<decltype(F{}(U{})), N>
121apply(const Array<U, N> &src, F f) {
122 Array<decltype(F{}(U{})), N> dest{{}};
123 std::transform(std::begin(src), std::end(src), std::begin(dest), f);
124 return dest;
125}
126
127#if !defined(__GNUC__) || (__GNUC__ > 7) || \
128 (__GNUC__ == 7 && __GNUC_MINOR__ >= 3) || defined(DOXYGEN)
132template <class T, size_t N, class... Args>
134 return generateArray<N>([&]() { return T{args...}; });
135}
136#else
137template <class T, size_t N, class... Args>
139 Array<T, N> array{{}};
140 for (auto &el : array)
141 el = T{args...};
142 return array;
143}
144#endif
145
178template <class T, size_t N, class U, class V = U>
180generateIncrementalArray(U start = 0, V increment = V(1)) {
181 detail::Incrementor<U, V> g(start, increment);
182 return generateArray<T, N>(g);
183}
184
200template <class T, size_t M, size_t N>
202 const Array<T, N> &b) {
203 Array<T, M + N> result{{}};
204 size_t r = 0;
205 for (size_t i = 0; i < M; ++i, ++r)
206 result[r] = a[i];
207 for (size_t i = 0; i < N; ++i, ++r)
208 result[r] = b[i];
209 return result;
210}
211
212template <class T1, class T2, size_t N1, size_t N2, bool Reverse1,
213 bool Reverse2, bool Const1, bool Const2>
214USE_CONSTEXPR_ARRAY_HELPERS Array<decltype(T1() * T2()), N1 + N2 - 1>
217 Array<decltype(T1() * T2()), N1 + N2 - 1> result = {{}};
218 for (size_t i = 0; i < N1; ++i)
219 for (size_t j = 0; j < N2; ++j)
220 result[i + j] += a[i] * b[j];
221 return result;
222}
223
224template <class T1, class T2, size_t N1, size_t N2, bool Reverse1, bool Const1>
225USE_CONSTEXPR_ARRAY_HELPERS Array<decltype(T1() * T2()), N1 + N2 - 1>
227 const Array<T2, N2> &b) {
228 return distribute(a, b.slice());
229}
230
231template <class T1, class T2, size_t N1, size_t N2, bool Reverse2, bool Const2>
232USE_CONSTEXPR_ARRAY_HELPERS Array<decltype(T1() * T2()), N1 + N2 - 1>
235 return distribute(a.slice(), b);
236}
237
238template <class T1, class T2, size_t N1, size_t N2>
239USE_CONSTEXPR_ARRAY_HELPERS Array<decltype(T1() * T2()), N1 + N2 - 1>
241 return distribute(a.slice(), b.slice());
242}
243
245
247
248#ifndef ARDUINO
249
250#include <ostream>
251
252template <class T, size_t N, bool Reverse, bool Const>
253std::enable_if_t<std::is_arithmetic<T>::value, std::ostream &>
254operator<<(std::ostream &os, const AH::ArraySlice<T, N, Reverse, Const> &a) {
255 for (const T &el : a.template slice<0, N - 2>())
256 os << el << ", ";
257 os << a[N - 1];
258 return os;
259}
260
261template <class T, size_t N>
262std::enable_if_t<std::is_arithmetic<T>::value, std::ostream &>
263operator<<(std::ostream &os, const AH::Array<T, N> &a) {
264 return os << a.slice();
265}
266
267#endif
268
270
271template <class T, size_t N, bool Reverse, bool Const>
272std::enable_if_t<std::is_arithmetic<T>::value, Print &>
273operator<<(Print &os, const AH::ArraySlice<T, N, Reverse, Const> &a) {
274 for (const T &el : a.template slice<0, N - 2>())
275 os << el << ", ";
276 os << a[N - 1];
277 return os;
278}
279
280template <class T, size_t N>
281std::enable_if_t<std::is_arithmetic<T>::value, Print &>
282operator<<(Print &os, const AH::Array<T, N> &a) {
283 return os << a.slice();
284}
285
#define USE_CONSTEXPR_ARRAY_HELPERS
#define END_AH_NAMESPACE
#define BEGIN_AH_NAMESPACE
#define AH_DIAGNOSTIC_POP()
Definition: Warnings.hpp:36
#define AH_DIAGNOSTIC_WERROR()
Definition: Warnings.hpp:35
Class for a view on a slice of an array.
Definition: Array.hpp:168
Utility class that acts as a functor to return incremental values.
Incrementor(T start=0, V increment=1)
Array< T, N > generateIncrementalArray(U start=0, V increment=V(1))
Generate an array where the first value is given, and the subsequent values are calculated as the pre...
Array< decltype(T1() *T2()), N1+N2 - 1 > distribute(const ArraySlice< T1, N1, Reverse1, Const1 > &a, const ArraySlice< T2, N2, Reverse2, Const2 > &b)
Array< T, N > copyAs(const Array< U, N > &src)
Copy an Array to an Array of a different type.
Array< T, N > fillArray(Args... args)
Fill the array with the same value for each element.
ArraySlice< T, abs_diff(Start, End)+1,(End< Start), false > slice()
Get a view on a slice of the Array.
Definition: Array.hpp:309
Array< decltype(F{}(U{})), N > apply(const Array< U, N > &src, F f)
Apply a function to all elements of the array and return a copy.
Array< T, N > generateArray(G generator)
Generate an array using the given generator.
Array< T, M+N > cat(const Array< T, M > &a, const Array< T, N > &b)
Concatenate two arrays.
Print & operator<<(Print &os, Quaternion e)
Printing.
Definition: Quaternion.cpp:28
An array wrapper for easy copying, comparing, and iterating.
Definition: Array.hpp:36