Molecular Dynamics  v0.4
Project for the Practical hosted by the Scientific Computing Chair
ArrayUtils.h
Go to the documentation of this file.
1 
7 #pragma once
8 
9 #include <array>
10 #include <cmath>
11 #include <list>
12 #include <numeric>
13 #include <set>
14 #include <sstream>
15 #include <unordered_map>
16 #include <unordered_set>
17 #include <vector>
18 
23 namespace ArrayUtils {
24 
25 // specialize a type for all of the STL containers.
30 namespace is_container_impl {
35 template <typename T> struct is_container : std::false_type {};
41 template <typename T, std::size_t N>
42 struct is_container<std::array<T, N>> : std::true_type {};
47 template <typename... Args>
48 struct is_container<std::vector<Args...>> : std::true_type {};
53 template <typename... Args>
54 struct is_container<std::list<Args...>> : std::true_type {};
59 template <typename... Args>
60 struct is_container<std::set<Args...>> : std::true_type {};
65 template <typename... Args>
66 struct is_container<std::unordered_set<Args...>> : std::true_type {};
67 } // namespace is_container_impl
68 
73 template <typename T> struct is_container {
74  static constexpr bool const value =
76 };
77 
88 template <class Container>
89 [[nodiscard]] std::string
90 to_string(const Container &container, const std::string &delimiter = ", ",
91  const std::array<std::string, 2> &surround = {"[", "]"}) {
92  auto iter = std::cbegin(container);
93  const auto end = std::cend(container);
94  if (iter == end) {
95  return surround[0] + surround[1];
96  }
97  std::ostringstream strStream;
98  strStream << surround[0] << *iter;
99  for (++iter; iter != end; ++iter) {
100  strStream << delimiter << *iter;
101  }
102  strStream << surround[1];
103  return strStream.str();
104 }
105 
119 template <class Container, class F>
120 inline Container elementWisePairOp(const Container &lhs, const Container &rhs,
121  F binaryFunction) {
122  Container ret = lhs;
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);
128 
129  for (; lhsIter != lhsEnd and rhsIter != rhsEnd;
130  ++lhsIter, ++rhsIter, ++retIter) {
131  *retIter = binaryFunction(*lhsIter, *rhsIter);
132  }
133 
134  return ret;
135 }
136 
148 template <class Scalar, class Container, class F>
149 inline Container elementWiseScalarOp(const Scalar &lhs, const Container &rhs,
150  F binaryFunction) {
151  Container ret = rhs;
152  auto retIter = std::begin(ret);
153  auto rhsIter = std::cbegin(rhs);
154  const auto rhsEnd = std::cend(rhs);
155 
156  for (; rhsIter != rhsEnd; ++rhsIter, ++retIter) {
157  *retIter = binaryFunction(lhs, *rhsIter);
158  }
159 
160  return ret;
161 }
162 
169 template <class Container> auto L2Norm(const Container &c) {
170  return std::sqrt(std::accumulate(std::cbegin(c), std::cend(c), 0.0,
171  [](auto a, auto b) { return a + b * b; }));
172 }
173 } // namespace ArrayUtils
174 
175 
186 template <class Container>
187 std::enable_if_t<ArrayUtils::is_container<Container>::value, std::ostream &>
188 operator<<(std::ostream &os, const Container &container) {
190  return os;
191 }
192 
200 template <class Container>
201 std::enable_if_t<ArrayUtils::is_container<Container>::value, Container>
202 operator+(const Container &lhs, const Container &rhs) {
203  return ArrayUtils::elementWisePairOp(lhs, rhs, std::plus<>());
204 }
205 
213 template <class Container>
214 std::enable_if_t<ArrayUtils::is_container<Container>::value, Container>
215 operator-(const Container &lhs, const Container &rhs) {
216  return ArrayUtils::elementWisePairOp(lhs, rhs, std::minus<>());
217 }
218 
226 template <class Container>
227 std::enable_if_t<ArrayUtils::is_container<Container>::value, Container>
228 operator*(const Container &lhs, const Container &rhs) {
229  return ArrayUtils::elementWisePairOp(lhs, rhs, std::multiplies<>());
230 }
231 
239 template <class Scalar, class Container>
240 std::enable_if_t<ArrayUtils::is_container<Container>::value, Container>
241 operator*(const Scalar &lhs, const Container &rhs) {
242  return ArrayUtils::elementWiseScalarOp(lhs, rhs, std::multiplies<>());
243 }
244 
253 template <class Container>
254 std::enable_if_t<ArrayUtils::is_container<Container>::value, bool>
255 operator==(const Container &lhs, const Container &rhs) {
256  if (lhs.size() != rhs.size()) {
257  return false;
258  }
259 
260  auto lhsIter = std::cbegin(lhs);
261  const auto lhsEnd = std::cend(lhs);
262  auto rhsIter = std::cbegin(rhs);
263 
264  for (; lhsIter != lhsEnd; ++lhsIter, ++rhsIter) {
265  if (*lhsIter != *rhs) {
266  return false;
267  }
268  }
269  return true;
270 }
std::enable_if_t< ArrayUtils::is_container< Container >::value, Container > operator-(const Container &lhs, const Container &rhs)
Definition: ArrayUtils.h:215
std::enable_if_t< ArrayUtils::is_container< Container >::value, bool > operator==(const Container &lhs, const Container &rhs)
Definition: ArrayUtils.h:255
std::enable_if_t< ArrayUtils::is_container< Container >::value, std::ostream & > operator<<(std::ostream &os, const Container &container)
Definition: ArrayUtils.h:188
std::enable_if_t< ArrayUtils::is_container< Container >::value, Container > operator*(const Container &lhs, const Container &rhs)
Definition: ArrayUtils.h:228
std::enable_if_t< ArrayUtils::is_container< Container >::value, Container > operator+(const Container &lhs, const Container &rhs)
Definition: ArrayUtils.h:202
Definition: ArrayUtils.h:23
std::string to_string(const Container &container, const std::string &delimiter=", ", const std::array< std::string, 2 > &surround={"[", "]"})
Definition: ArrayUtils.h:90
auto L2Norm(const Container &c)
Definition: ArrayUtils.h:169
Container elementWiseScalarOp(const Scalar &lhs, const Container &rhs, F binaryFunction)
Definition: ArrayUtils.h:149
Container elementWisePairOp(const Container &lhs, const Container &rhs, F binaryFunction)
Definition: ArrayUtils.h:120
::xsd::cxx::tree::string< char, simple_type > string
C++ type corresponding to the string XML Schema built-in type.
Definition: vtk-unstructured.h:270
::xsd::cxx::tree::type container
Alias for the anyType type.
Definition: vtk-unstructured.h:130
Definition: ArrayUtils.h:73
static constexpr bool const value
Definition: ArrayUtils.h:74