diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h index 099bef288b953..02705fbc8f2c4 100644 --- a/llvm/include/llvm/ADT/STLExtras.h +++ b/llvm/include/llvm/ADT/STLExtras.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -1694,6 +1695,12 @@ template constexpr size_t range_size(R &&Range) { return static_cast(std::distance(adl_begin(Range), adl_end(Range))); } +/// Wrapper for std::accumulate. +template auto accumulate(R &&Range, E &&Init) { + return std::accumulate(adl_begin(Range), adl_end(Range), + std::forward(Init)); +} + /// Provide wrappers to std::for_each which take ranges instead of having to /// pass begin/end explicitly. template diff --git a/llvm/unittests/ADT/STLExtrasTest.cpp b/llvm/unittests/ADT/STLExtrasTest.cpp index 9fda0d912a2f5..d355a59973f9a 100644 --- a/llvm/unittests/ADT/STLExtrasTest.cpp +++ b/llvm/unittests/ADT/STLExtrasTest.cpp @@ -1602,6 +1602,16 @@ TEST(STLExtrasTest, Fill) { EXPECT_THAT(V2, ElementsAre(Val, Val, Val, Val)); } +TEST(STLExtrasTest, Accumulate) { + EXPECT_EQ(accumulate(std::vector(), 0), 0); + EXPECT_EQ(accumulate(std::vector(), 3), 3); + std::vector V1 = {1, 2, 3, 4, 5}; + EXPECT_EQ(accumulate(V1, 0), std::accumulate(V1.begin(), V1.end(), 0)); + EXPECT_EQ(accumulate(V1, 10), std::accumulate(V1.begin(), V1.end(), 10)); + EXPECT_EQ(accumulate(drop_begin(V1), 7), + std::accumulate(V1.begin() + 1, V1.end(), 7)); +} + struct Foo; struct Bar {};