Numeric.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <iterator>
7 #include <numeric>
8 
9 #include "Utilities/Gsl.hpp"
10 
11 /// C++ STL code present in C++2b.
12 namespace cpp2b {
13 /*!
14  * \ingroup UtilitiesGroup
15  * Reimplementation of std::iota that is constexpr;
16  * taken from the LLVM source at
17  * https://github.com/llvm-mirror/libcxx/blob/master/include/numeric
18  */
19 template <class ForwardIterator, class T>
20 constexpr void iota(ForwardIterator first, ForwardIterator last, T value) {
21  for (; first != last; ++first, (void)++value) {
22  *first = value;
23  }
24 }
25 
26 /*!
27  * \ingroup UtilitiesGroup
28  * Reimplementation of std::accumulate that is constexpr;
29  * taken from the LLVM source at
30  * https://github.com/llvm-mirror/libcxx/blob/master/include/numeric
31  */
32 template <class InputIt, class T>
33 constexpr T accumulate(InputIt first, InputIt last, T init) {
34  for (; first != last; ++first) {
35  init = std::move(init) + *first; // std::move since C++20
36  }
37  return init;
38 }
39 } // namespace cpp2b
40 
41 namespace alg {
42 template <class Container, class T>
43 constexpr decltype(auto) iota(Container&& c, T value) {
44  for (auto& t : c) {
45  t = value;
46  ++value;
47  }
48  return std::forward<Container>(c);
49 }
50 
51 /// Convenience wrapper around std::accumulate, returns
52 /// `std::accumulate(begin(c), end(c), init)`.
53 template <class Container, class T>
54 decltype(auto) accumulate(const Container& c, T init) {
55  using std::begin;
56  using std::end;
57  return std::accumulate(begin(c), end(c), std::move(init));
58 }
59 
60 /// Convenience wrapper around std::accumulate, returns
61 /// `std::accumulate(begin(c), end(c), init, f)`.
62 template <class Container, class T, class BinaryFunction>
63 decltype(auto) accumulate(const Container& c, T init, BinaryFunction&& f) {
64  using std::begin;
65  using std::end;
66  return std::accumulate(begin(c), end(c), std::move(init),
67  std::forward<BinaryFunction>(f));
68 }
69 } // namespace alg
constexpr void iota(ForwardIterator first, ForwardIterator last, T value)
Definition: Numeric.hpp:20
Utility functions wrapping STL algorithms and additional algorithms.
Definition: Algorithm.hpp:136
C++ STL code present in C++2b.
Definition: Numeric.hpp:12
constexpr T accumulate(InputIt first, InputIt last, T init)
Definition: Numeric.hpp:33
Defines functions and classes from the GSL.