diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h --- a/llvm/include/llvm/ADT/STLExtras.h +++ b/llvm/include/llvm/ADT/STLExtras.h @@ -1535,6 +1535,13 @@ return std::copy(adl_begin(Range), adl_end(Range), Out); } +/// Provide wrappers to std::move which take ranges instead of having to +/// pass begin/end explicitly. +template +OutputIt move(R &&Range, OutputIt Out) { + return std::move(adl_begin(Range), adl_end(Range), Out); +} + /// Wrapper function around std::find to detect if an element exists /// in a container. template diff --git a/llvm/unittests/ADT/STLExtrasTest.cpp b/llvm/unittests/ADT/STLExtrasTest.cpp --- a/llvm/unittests/ADT/STLExtrasTest.cpp +++ b/llvm/unittests/ADT/STLExtrasTest.cpp @@ -568,4 +568,56 @@ EXPECT_FALSE( hasNItemsOrLess(V3.begin(), V3.end(), 2, [](int x) { return x < 10; })); } + +TEST(STLExtras, MoveRange) { + class Foo { + bool A; + + public: + Foo() : A(true) {} + Foo(const Foo &) = delete; + Foo(Foo &&Other) : A(Other.A) { Other.A = false; } + Foo &operator=(const Foo &) = delete; + Foo &operator=(Foo &&Other) { + if (this != &Other) { + A = Other.A; + Other.A = false; + } + return *this; + } + operator bool() const { return A; } + }; + + constexpr size_t ItemCount = 4; + SmallVector V1, V2, V3, V4; + auto HasVal = [](const Foo &Item) { return static_cast(Item); }; + auto Build = [&] { + SmallVector Foos; + Foos.resize(ItemCount); + return Foos; + }; + + V1.resize(ItemCount); + EXPECT_TRUE(llvm::all_of(V1, HasVal)); + + llvm::move(V1, std::back_inserter(V2)); + + // Ensure input container is same size, but its contents were moved out. + EXPECT_EQ(V1.size(), ItemCount); + EXPECT_TRUE(llvm::none_of(V1, HasVal)); + + // Ensure output container has the contents of the input container. + EXPECT_EQ(V2.size(), ItemCount); + EXPECT_TRUE(llvm::all_of(V2, HasVal)); + + llvm::move(std::move(V2), std::back_inserter(V3)); + + EXPECT_TRUE(llvm::none_of(V2, HasVal)); + EXPECT_EQ(V3.size(), ItemCount); + EXPECT_TRUE(llvm::all_of(V3, HasVal)); + + llvm::move(Build(), std::back_inserter(V4)); + EXPECT_EQ(V4.size(), ItemCount); + EXPECT_TRUE(llvm::all_of(V4, HasVal)); +} } // namespace