23#include <unordered_map>
24#include <unordered_set>
38namespace is_container_impl {
49template <
typename T, std::
size_t N>
struct is_container<std::array<T, N>> : std::true_type {};
54template <
typename... Args>
struct is_container<std::vector<Args...>> : std::true_type {};
59template <
typename... Args>
struct is_container<std::list<Args...>> : std::true_type {};
64template <
typename... Args>
struct is_container<std::set<Args...>> : std::true_type {};
69template <
typename... Args>
struct is_container<std::unordered_set<Args...>> : std::true_type {};
90template <
class Container>
91[[nodiscard]] std::string
to_string(
const Container &container,
const std::string &delimiter =
", ",
92 const std::array<std::string, 2> &surround = {
"[",
"]"}) {
93 auto iter = std::cbegin(container);
94 const auto end = std::cend(container);
96 return surround[0] + surround[1];
98 std::ostringstream strStream;
99 strStream << surround[0] << *iter;
100 for (++iter; iter != end; ++iter) {
101 strStream << delimiter << *iter;
103 strStream << surround[1];
104 return strStream.str();
120template <
class Container,
class F>
121inline Container
elementWisePairOp(
const Container &lhs,
const Container &rhs, F binaryFunction) {
123 auto retIter = std::begin(ret);
124 auto lhsIter = std::cbegin(lhs);
125 const auto lhsEnd = std::cend(lhs);
126 auto rhsIter = std::cbegin(rhs);
127 const auto rhsEnd = std::cend(rhs);
129 for (; lhsIter != lhsEnd && rhsIter != rhsEnd; ++lhsIter, ++rhsIter, ++retIter) {
130 *retIter = binaryFunction(*lhsIter, *rhsIter);
147template <
class Scalar,
class Container,
class F>
150 auto retIter = std::begin(ret);
151 auto rhsIter = std::cbegin(rhs);
152 const auto rhsEnd = std::cend(rhs);
154 for (; rhsIter != rhsEnd; ++rhsIter, ++retIter) {
155 *retIter = binaryFunction(lhs, *rhsIter);
168 return std::accumulate(std::cbegin(c), std::cend(c), 0.0, [](
auto a,
auto b) {
return a + b * b; });
177template <
class Container>
auto L2Norm(
const Container &c) {
178 return std::sqrt(std::accumulate(std::cbegin(c), std::cend(c), 0.0, [](
auto a,
auto b) {
return a + b * b; }));
193template <
class Container>
194std::enable_if_t<ArrayUtils::is_container<Container>::value, std::ostream &>
operator<<(std::ostream &os,
195 const Container &container) {
207template <
class Container>
208std::enable_if_t<ArrayUtils::is_container<Container>::value, Container>
operator+(
const Container &lhs,
209 const Container &rhs) {
220template <
class Container>
221std::enable_if_t<ArrayUtils::is_container<Container>::value, Container>
operator-(
const Container &lhs,
222 const Container &rhs) {
233template <
class Container>
234std::enable_if_t<ArrayUtils::is_container<Container>::value, Container>
operator*(
const Container &lhs,
235 const Container &rhs) {
246template <
class Scalar,
class Container>
247std::enable_if_t<ArrayUtils::is_container<Container>::value, Container>
operator*(
const Scalar &lhs,
248 const Container &rhs) {
260template <
class Container>
261std::enable_if_t<ArrayUtils::is_container<Container>::value,
bool>
operator==(
const Container &lhs,
262 const Container &rhs) {
263 if (lhs.size() != rhs.size()) {
267 auto lhsIter = std::cbegin(lhs);
268 const auto lhsEnd = std::cend(lhs);
269 auto rhsIter = std::cbegin(rhs);
271 for (; lhsIter != lhsEnd; ++lhsIter, ++rhsIter) {
272 if (*lhsIter != *rhs) {
std::enable_if_t< ArrayUtils::is_container< Container >::value, Container > operator*(const Container &lhs, const Container &rhs)
Element wise multiplication of two containers.
Definition ArrayUtils.h:234
std::enable_if_t< ArrayUtils::is_container< Container >::value, bool > operator==(const Container &lhs, const Container &rhs)
Element wise comparison of two containers.
Definition ArrayUtils.h:261
std::enable_if_t< ArrayUtils::is_container< Container >::value, Container > operator+(const Container &lhs, const Container &rhs)
Element wise addition of two containers.
Definition ArrayUtils.h:208
std::enable_if_t< ArrayUtils::is_container< Container >::value, std::ostream & > operator<<(std::ostream &os, const Container &container)
Stream operator for containers.
Definition ArrayUtils.h:194
std::enable_if_t< ArrayUtils::is_container< Container >::value, Container > operator-(const Container &lhs, const Container &rhs)
Element wise subtraction of two containers.
Definition ArrayUtils.h:221
Collection of utility functions and operators for iterable data containers like std::array,...
Definition ArrayUtils.h:31
auto L2NormSquared(const Container &c)
Calculates the square of the L2 norm for a given container.
Definition ArrayUtils.h:167
std::string to_string(const Container &container, const std::string &delimiter=", ", const std::array< std::string, 2 > &surround={"[", "]"})
Generates a string representation of a container which fulfills the Container requirement (provide cb...
Definition ArrayUtils.h:91
auto L2Norm(const Container &c)
Calculates the L2 norm for a given container.
Definition ArrayUtils.h:177
Container elementWiseScalarOp(const Scalar &lhs, const Container &rhs, F binaryFunction)
Applies a binary function F to with a scalar to every element in a container.
Definition ArrayUtils.h:148
Container elementWisePairOp(const Container &lhs, const Container &rhs, F binaryFunction)
Applies an element wise binary function F to two containers.
Definition ArrayUtils.h:121
Default case: T is not a container.
Definition ArrayUtils.h:43
Type trait to check if a given type is a container.
Definition ArrayUtils.h:76
static constexpr bool const value
Definition ArrayUtils.h:77