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