Index: llvm/include/llvm/ADT/STLExtras.h =================================================================== --- llvm/include/llvm/ADT/STLExtras.h +++ llvm/include/llvm/ADT/STLExtras.h @@ -1982,6 +1982,16 @@ IterOfRange Iter; }; +template +decltype(auto) get(const result_pair &Pair) { + static_assert(i < 2); + if constexpr (i == 0) { + return Pair.index(); + } else { + return Pair.value(); + } +} + template class enumerator_iter : public iterator_facade_base, std::forward_iterator_tag, @@ -2054,6 +2064,12 @@ /// printf("Item %d - %c\n", X.index(), X.value()); /// } /// +/// or using structured bindings: +/// +/// for (auto [Index, Value] : enumerate(Items)) { +/// printf("Item %d - %c\n", Index, Value); +/// } +/// /// Output: /// Item 0 - A /// Item 1 - B @@ -2192,4 +2208,17 @@ } // end namespace llvm +namespace std { +template +struct tuple_size> + : std::integral_constant {}; + +template +struct tuple_element> + : std::conditional::value_reference> { +}; + +} // namespace std + #endif // LLVM_ADT_STLEXTRAS_H Index: llvm/unittests/ADT/STLExtrasTest.cpp =================================================================== --- llvm/unittests/ADT/STLExtrasTest.cpp +++ llvm/unittests/ADT/STLExtrasTest.cpp @@ -47,8 +47,8 @@ typedef std::pair CharPairType; std::vector CharResults; - for (auto X : llvm::enumerate(foo)) { - CharResults.emplace_back(X.index(), X.value()); + for (auto &[value, index] : llvm::enumerate(foo)) { + CharResults.emplace_back(index, value); } ASSERT_EQ(3u, CharResults.size()); EXPECT_EQ(CharPairType(0u, 'a'), CharResults[0]); @@ -59,8 +59,8 @@ typedef std::pair IntPairType; std::vector IntResults; const std::vector bar = {1, 2, 3}; - for (auto X : llvm::enumerate(bar)) { - IntResults.emplace_back(X.index(), X.value()); + for (auto [index, value] : llvm::enumerate(bar)) { + IntResults.emplace_back(index, value); } ASSERT_EQ(3u, IntResults.size()); EXPECT_EQ(IntPairType(0u, 1), IntResults[0]); @@ -70,10 +70,20 @@ // Test an empty range. IntResults.clear(); const std::vector baz{}; - for (auto X : llvm::enumerate(baz)) { - IntResults.emplace_back(X.index(), X.value()); + for (auto [index, value] : llvm::enumerate(baz)) { + IntResults.emplace_back(index, value); } EXPECT_TRUE(IntResults.empty()); + + // Test forwarding reference through structured binding. + std::vector foobar{1, 2, 3}; + for (auto [index, value] : llvm::enumerate(foobar)) { + value += 3; + } + ASSERT_EQ(3u, foobar.size()); + EXPECT_EQ(4, foobar[0]); + EXPECT_EQ(5, foobar[1]); + EXPECT_EQ(6, foobar[2]); } TEST(STLExtrasTest, EnumerateModifyLValue) {