Molassembler  1.0.0
Molecule graph and conformer library
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Functional.h
Go to the documentation of this file.
1 
13 #ifndef INCLUDE_MOLASSEMBLER_TEMPLE_FUNCTIONAL_H
14 #define INCLUDE_MOLASSEMBLER_TEMPLE_FUNCTIONAL_H
15 
18 
19 #include <numeric>
20 
21 namespace Scine {
22 namespace Molassembler {
23 namespace Temple {
24 
25 template<
26  class Container,
27  std::enable_if_t<Traits::hasSize<Container>::value, int> = 0
28 > auto size(const Container& container) {
29  return container.size();
30 }
31 
32 template<
33  class Container,
34  std::enable_if_t<!Traits::hasSize<Container>::value, int> = 0
35 > auto size(const Container& container) {
36  return std::distance(
37  std::begin(container),
38  std::end(container)
39  );
40 }
41 
68 template<
69  class UnaryFunction,
70  typename T,
71  template<typename, typename...> class Container,
72  template<typename> class ... Dependents
73 > auto map_stl(
74  const Container<T, Dependents<T>...>& container,
75  UnaryFunction&& function
76 ) {
77  using U = decltype(
78  invoke(function, *std::begin(container))
79  );
80 
81  Container<U, Dependents<U>...> returnContainer;
82  reserveIfPossible(returnContainer, container);
83 
84  for(const auto& element : container) {
86  returnContainer,
87  invoke(function, element)
88  );
89  }
90 
91  return returnContainer;
92 }
93 
95 template<
96  template<typename, std::size_t> class ArrayType,
97  typename T,
98  std::size_t size,
99  class UnaryFunction
100 > auto map_stl(
101  const ArrayType<T, size>& container,
102  UnaryFunction&& function
103 ) {
104  using U = decltype(
105  invoke(function, *std::begin(container))
106  );
107 
108  ArrayType<U, size> returnContainer;
109 
110  for(unsigned i = 0; i < size; ++i) {
111  returnContainer[i] = invoke(function, container[i]);
112  }
113 
114  return returnContainer;
115 }
116 
118 template<
119  template<typename, typename> class PairType,
120  typename T,
121  class UnaryFunction
122 > auto map_stl(
123  const PairType<T, T>& pair,
124  UnaryFunction&& function
125 ) {
126  using U = decltype(
127  invoke(function, pair.first)
128  );
129 
130  return PairType<U, U> {
131  function(pair.first),
132  function(pair.second)
133  };
134 }
135 
140 template<class Container, class UnaryFunction>
141 auto map(Container&& container, UnaryFunction&& function) {
142  using U = decltype(
143  invoke(function, *std::begin(container))
144  );
145 
146  std::vector<U> returnContainer;
147  reserveIfPossible(returnContainer, container);
148 
149  for(auto&& value : container) {
150  returnContainer.push_back(
151  invoke(function, std::move(value))
152  );
153  }
154 
155  return returnContainer;
156 }
157 
158 template<class Pairlike, typename Unary>
159 auto mapHomogeneousPairlike(Pairlike p, Unary&& f) {
160  return std::make_pair(f(p.first), f(p.second));
161 }
162 
164 template<class Container, class Callable>
165 void forEach(
166  const Container& container,
167  Callable&& callable
168 ) {
169  for(const auto& value : container) {
170  invoke(callable, value);
171  }
172 }
173 
187 template<
188  class Container,
189  typename ComparisonFunction,
190  typename MappingFunction
191 >
192 typename Container::const_iterator select(
193  const Container& container,
194  ComparisonFunction&& comparator,
195  MappingFunction&& mapFunction
196 ) {
197  auto selection = std::begin(container);
198  auto selectionValue = mapFunction(*selection);
199 
200  auto iter = std::begin(container);
201 
202  while(iter != std::end(container)) {
203  auto currentValue = mapFunction(*iter);
204 
205  // Replace if 'better' according to the comparator
206  if(comparator(currentValue, selectionValue)) {
207  selection = iter;
208  selectionValue = currentValue;
209  }
210 
211  ++iter;
212  }
213 
214  return selection;
215 }
216 
222 template<
223  class Container,
224  typename T,
225  class BinaryFunction
227  const Container& container,
228  T init,
229  BinaryFunction&& reductionFunction
230 ) {
231  for(const auto& value: container) {
232  // Call variadic invoke (no tuple unpacking!)
233  init = invoke(reductionFunction, std::move(init), value);
234  }
235 
236  return init;
237 }
238 
243 template<class Container, class UnaryPredicate = Functor::Identity>
244 bool all_of(const Container& container, UnaryPredicate&& predicate = UnaryPredicate {}) {
245  for(const auto& element : container) {
246  if(!invoke(predicate, element)) {
247  return false;
248  }
249  }
250 
251  return true;
252 }
253 
258 template<class Container, class UnaryPredicate = Functor::Identity>
259 bool any_of(const Container& container, UnaryPredicate&& predicate = UnaryPredicate {}) {
260  for(const auto& element : container) {
261  if(invoke(predicate, element)) {
262  return true;
263  }
264  }
265 
266  return false;
267 }
268 
270 template<class Container>
271 void sort(Container& container) {
272  std::sort(
273  std::begin(container),
274  std::end(container)
275  );
276 }
277 
279 template<class Container, typename Comparator>
280 void sort(Container& container, Comparator&& comparator) {
281  std::sort(
282  std::begin(container),
283  std::end(container),
284  std::forward<Comparator>(comparator)
285  );
286 }
287 
289 template<class Container>
290 void reverse(Container& container) {
291  std::reverse(
292  std::begin(container),
293  std::end(container)
294  );
295 }
296 
298 template<class Container, typename T>
299 void remove(
300  Container& container,
301  const T& value
302 ) {
303  container.erase(
304  std::remove(
305  std::begin(container),
306  std::end(container),
307  value
308  ),
309  std::end(container)
310  );
311 }
312 
314 template<class Container, class UnaryFunction>
316  Container& container,
317  UnaryFunction&& predicate
318 ) {
319  container.erase(
321  std::begin(container),
322  std::end(container),
323  std::forward<UnaryFunction>(predicate)
324  ),
325  std::end(container)
326  );
327 }
328 
329 // C++17 nodiscard
330 template<class Container, class Predicate>
331 Container copy_if(const Container& container, Predicate&& predicate) {
332  Container returnContainer;
333 
334  for(const auto& value : container) {
335  if(invoke(predicate, value)) {
336  addToContainer(returnContainer, value);
337  }
338  }
339 
340  return returnContainer;
341 }
342 
343 // C++17 nodiscard
344 template<class Container>
345 Container sorted(Container container) {
346  sort(container);
347  return container;
348 }
349 
350 // C++17 nodiscard
351 template<class Container, typename Comparator>
352 Container sorted(Container container, Comparator&& comparator) {
353  sort(container, std::forward<Comparator>(comparator));
354  return container;
355 }
356 
358 template<class Container, typename T>
359 auto find(const Container& container, const T& needle) {
360  return std::find(
361  std::begin(container),
362  std::end(container),
363  needle
364  );
365 }
366 
368 template<class Container, typename UnaryPredicate>
369 auto find_if(const Container& container, UnaryPredicate&& predicate) {
370  return std::find_if(
371  std::begin(container),
372  std::end(container),
373  std::forward<UnaryPredicate>(predicate)
374  );
375 }
376 
378 template<typename T>
379 std::vector<T> iota(unsigned upperBound) {
380  std::vector<T> values(upperBound);
381 
382  std::iota(
383  std::begin(values),
384  std::end(values),
385  T(0)
386  );
387 
388  return values;
389 }
390 
392 template<class Container>
393 auto makeContainsPredicate(const Container& container) {
394  using T = Traits::getValueType<Container>;
395 
396  return [&container](const T& element) -> bool {
397  return std::find(
398  std::begin(container),
399  std::end(container),
400  element
401  ) != std::end(container);
402  };
403 }
404 
405 namespace Functor {
406 
407 template<typename Transformation>
408 struct Map {
409  Map(Transformation&& f) : t(f) {}
410 
411  template<typename Container>
412  auto operator() (const Container& c) {
413  return Temple::map(c, t);
414  }
415 
416  Transformation t;
417 };
418 
419 template<typename Transformation>
420 auto map(Transformation&& t) {
421  return Map<Transformation>(std::forward<Transformation>(t));
422 }
423 
424 } // namespace Functor
425 
426 } // namespace Temple
427 } // namespace Molassembler
428 } // namespace Scine
429 
430 #endif
void sort(Container &container)
Calls std::sort on a container.
Definition: Functional.h:271
PURITY_STRONG constexpr std::enable_if_t< std::is_arithmetic< T >::value, ArrayType< T, size >> iota()
Iota for any array type.
Definition: Containers.h:145
Uniform callable invoke from arguments or tuple of arguments.
void remove_if(Container &container, UnaryFunction &&predicate)
Applies erase-remove idiom in-place to container with a predicate function.
Definition: Functional.h:315
auto find_if(const Container &container, UnaryPredicate &&predicate)
std::find_if shorthand
Definition: Functional.h:369
double element(const PositionCollection &normalizedPositions, const Elements::Rotation &rotation)
Returns the CSM for a Rotation symmetry element along the rotation axis without optimizing the coordi...
auto map_stl(const Container< T, Dependents< T >...> &container, UnaryFunction &&function)
Definition: Functional.h:73
void reserveIfPossible(TargetContainer &target, const SourceContainer &source, SizeModifierUnary &&sourceModifierUnary=SizeModifierUnary{})
Rerves the space required in the target container if size can be determined from the source container...
Definition: AddToContainer.h:201
Definition: Functional.h:408
Central interface to add elements to many types of containers.
void remove(Container &container, const T &value)
Applies erase-remove idiom in-place to container.
Definition: Functional.h:299
T accumulate(const Container &container, T init, BinaryFunction &&reductionFunction)
Accumulate shorthand.
Definition: Functional.h:226
Temple::Array< T, size > ArrayType
Definition: Properties.h:143
void forEach(const Container &container, Callable &&callable)
Apply a callable for all values of a container.
Definition: Functional.h:165
void reverse(Container &container)
In-place reversal.
Definition: Functional.h:290
unsigned size(const Shape shape)
Fetch the number of vertices of a shape.
bool any_of(const Container &container, UnaryPredicate &&predicate=UnaryPredicate{})
any_of shorthand
Definition: Functional.h:259
constexpr auto map(const ArrayType< T, size > &array, UnaryFunction &&function)
Maps all elements of any array-like container with a unary function.
Definition: Containers.h:62
auto makeContainsPredicate(const Container &container)
Creates a predicate that uses std::find for the container&#39;s value type.
Definition: Functional.h:393
Container::const_iterator select(const Container &container, ComparisonFunction &&comparator, MappingFunction &&mapFunction)
Select a value from a container.
Definition: Functional.h:192
void addToContainer(Container &container, const T &value)
Adds an lvalue element to a container by calling the container&#39;s insert or push_back member functions...
Definition: AddToContainer.h:179
auto find(const Container &container, const T &needle)
std::find shorthand
Definition: Functional.h:359
auto invoke(Function &&function, const boost::tuples::cons< HT, TT > &tuple)
Invokes a function with all values in a given boost tuple.
Definition: Invoke.h:44
bool all_of(const Container &container, UnaryPredicate &&predicate=UnaryPredicate{})
all_of shorthand
Definition: Functional.h:244