#pragma once #include "Array.hpp" #include #if __cplusplus >= 201400L #define USE_CONSTEXPR_ARRAY_HELPERS constexpr #else #define USE_CONSTEXPR_ARRAY_HELPERS #endif BEGIN_AH_NAMESPACE namespace detail { template class Incrementor { public: USE_CONSTEXPR_ARRAY_HELPERS Incrementor(T start = 0, V increment = 1) : value(start), increment(increment) {} USE_CONSTEXPR_ARRAY_HELPERS T operator()() { T temp = value; value += increment; return temp; } private: T value; const V increment; }; } // namespace detail template USE_CONSTEXPR_ARRAY_HELPERS Array generateArray(G generator) { Array array{{}}; std::generate(array.begin(), array.end(), generator); return array; } template USE_CONSTEXPR_ARRAY_HELPERS auto generateArray(G generator) -> Array { Array array{{}}; std::generate(array.begin(), array.end(), generator); return array; } template USE_CONSTEXPR_ARRAY_HELPERS Array copyAs(const Array &src) { Array dest{{}}; std::transform(std::begin(src), std::end(src), std::begin(dest), [](const U &src) { return T(src); }); return dest; } template USE_CONSTEXPR_ARRAY_HELPERS Array apply(const Array &src, F f) { Array dest{{}}; std::transform(std::begin(src), std::end(src), std::begin(dest), f); return dest; } template USE_CONSTEXPR_ARRAY_HELPERS Array fillArray(Args... args) { return generateArray([&]() { return T{args...}; }); } template USE_CONSTEXPR_ARRAY_HELPERS Array generateIncrementalArray(U start = 0, V increment = V(1)) { detail::Incrementor g(start, increment); return generateArray(g); } template USE_CONSTEXPR_ARRAY_HELPERS Array cat(const Array &a, const Array &b) { Array result{{}}; size_t r = 0; for (size_t i = 0; i < M; ++i, ++r) result[r] = a[i]; for (size_t i = 0; i < N; ++i, ++r) result[r] = b[i]; return result; } template USE_CONSTEXPR_ARRAY_HELPERS Array distribute(const ArraySlice &a, const ArraySlice &b) { Array result = {{}}; for (size_t i = 0; i < N1; ++i) for (size_t j = 0; j < N2; ++j) result[i + j] += a[i] * b[j]; return result; } template USE_CONSTEXPR_ARRAY_HELPERS Array distribute(const ArraySlice &a, const Array &b) { return distribute(a, b.slice()); } template USE_CONSTEXPR_ARRAY_HELPERS Array distribute(const Array &a, const ArraySlice &b) { return distribute(a.slice(), b); } template USE_CONSTEXPR_ARRAY_HELPERS Array distribute(const Array &a, const Array &b) { return distribute(a.slice(), b.slice()); } END_AH_NAMESPACE #ifndef ARDUINO #include BEGIN_AH_NAMESPACE template std::enable_if_t::value, std::ostream &> operator<<(std::ostream &os, const AH::ArraySlice &a) { for (const T &el : a.template slice<0, N - 2>()) os << el << ", "; os << a[N - 1]; return os; } template std::enable_if_t::value, std::ostream &> operator<<(std::ostream &os, const AH::Array &a) { return os << a.slice(); } END_AH_NAMESPACE #endif #include BEGIN_AH_NAMESPACE template std::enable_if_t::value, Print &> operator<<(Print &os, const AH::ArraySlice &a) { for (const T &el : a.template slice<0, N - 2>()) os << el << ", "; os << a[N - 1]; return os; } template std::enable_if_t::value, Print &> operator<<(Print &os, const AH::Array &a) { return os << a.slice(); } END_AH_NAMESPACE