19 #include <unordered_map>
20 #include <unordered_set>
38 namespace is_container_impl {
50 template <
typename T, std::
size_t N>
56 template <
typename... Args>
62 template <
typename... Args>
68 template <
typename... Args>
74 template <
typename... Args>
75 struct is_container<std::unordered_set<Args...>> : std::true_type {};
96 template <
class Container>
97 [[nodiscard]] std::string
to_string(
const Container& container,
const std::string& delimiter =
", ",
98 const std::array<std::string, 2>& surround = {
"[",
"]"}) {
99 auto iter = std::cbegin(container);
100 const auto end = std::cend(container);
102 return surround[0] + surround[1];
104 std::ostringstream strStream;
105 strStream << surround[0] << *iter;
106 for (++iter; iter != end; ++iter) {
107 strStream << delimiter << *iter;
109 strStream << surround[1];
110 return strStream.str();
126 template <
class Container,
class F>
127 inline Container
elementWisePairOp(
const Container& lhs,
const Container& rhs, F binaryFunction) {
129 auto retIter = std::begin(ret);
130 auto lhsIter = std::cbegin(lhs);
131 const auto lhsEnd = std::cend(lhs);
132 auto rhsIter = std::cbegin(rhs);
133 const auto rhsEnd = std::cend(rhs);
135 for (; lhsIter != lhsEnd and rhsIter != rhsEnd; ++lhsIter, ++rhsIter, ++retIter) {
136 *retIter = binaryFunction(*lhsIter, *rhsIter);
153 template <
class Scalar,
class Container,
class F>
156 auto retIter = std::begin(ret);
157 auto rhsIter = std::cbegin(rhs);
158 const auto rhsEnd = std::cend(rhs);
160 for (; rhsIter != rhsEnd; ++rhsIter, ++retIter) {
161 *retIter = binaryFunction(lhs, *rhsIter);
173 template <
class Container>
175 return std::sqrt(std::accumulate(std::cbegin(c), std::cend(c), 0.0, [](
auto a,
auto b) {
return a + b * b; }));
183 inline auto L2Norm<std::array<double, 3>>(
const std::array<double, 3>& c) {
184 return std::sqrt(c[0] * c[0] + c[1] * c[1] + c[2] * c[2]);
193 template <
class Container>
195 return std::accumulate(std::cbegin(c), std::cend(c), 0.0, [](
auto a,
auto b) {
return a + b * b; });
203 inline auto L2NormSquared<std::array<double, 3>>(
const std::array<double, 3>& c) {
204 return c[0] * c[0] + c[1] * c[1] + c[2] * c[2];
219 template <
class Container>
220 std::enable_if_t<ArrayUtils::is_container<Container>::value, std::ostream&>
operator<<(std::ostream& os,
const Container& container) {
232 template <
class Container>
233 std::enable_if_t<ArrayUtils::is_container<Container>::value, Container>
operator+(
const Container& lhs,
const Container& rhs) {
244 template <
class Container>
245 std::enable_if_t<ArrayUtils::is_container<Container>::value, Container>
operator-(
const Container& lhs,
const Container& rhs) {
256 template <
class Container>
257 std::enable_if_t<ArrayUtils::is_container<Container>::value, Container>
operator*(
const Container& lhs,
const Container& rhs) {
268 template <
class Scalar,
class Container>
269 std::enable_if_t<ArrayUtils::is_container<Container>::value, Container>
operator*(
const Scalar& lhs,
const Container& rhs) {
281 template <
class Container>
282 std::enable_if_t<ArrayUtils::is_container<Container>::value,
bool>
operator==(
const Container& lhs,
const Container& rhs) {
283 if (lhs.size() != rhs.size()) {
287 auto lhsIter = std::cbegin(lhs);
288 const auto lhsEnd = std::cend(lhs);
289 auto rhsIter = std::cbegin(rhs);
291 for (; lhsIter != lhsEnd; ++lhsIter, ++rhsIter) {
292 if (*lhsIter != *rhs) {
std::enable_if_t< ArrayUtils::is_container< Container >::value, Container > operator-(const Container &lhs, const Container &rhs)
std::enable_if_t< ArrayUtils::is_container< Container >::value, std::ostream & > operator<<(std::ostream &os, const Container &container)
std::enable_if_t< ArrayUtils::is_container< Container >::value, bool > operator==(const Container &lhs, const Container &rhs)
std::enable_if_t< ArrayUtils::is_container< Container >::value, Container > operator*(const Container &lhs, const Container &rhs)
std::enable_if_t< ArrayUtils::is_container< Container >::value, Container > operator+(const Container &lhs, const Container &rhs)
Collection of utility functions and operators for iterable data containers.
auto L2NormSquared(const Container &c)
std::string to_string(const Container &container, const std::string &delimiter=", ", const std::array< std::string, 2 > &surround={"[", "]"})
auto L2Norm(const Container &c)
Container elementWiseScalarOp(const Scalar &lhs, const Container &rhs, F binaryFunction)
Container elementWisePairOp(const Container &lhs, const Container &rhs, F binaryFunction)
static constexpr bool const value