Line data Source code
1 0 : // 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 1 : 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 1 : 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 1 : 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 0 : 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 1 : 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 1 : 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
|