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 [index, value] : 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,8 +70,8 @@ // 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()); } @@ -87,6 +87,16 @@ EXPECT_EQ('b', foo[0]); EXPECT_EQ('c', foo[1]); EXPECT_EQ('d', foo[2]); + + // Also test if this works with structured bindings. + foo = {'a', 'b', 'c'}; + + for (auto [index, value] : llvm::enumerate(foo)) { + ++value; + } + EXPECT_EQ('b', foo[0]); + EXPECT_EQ('c', foo[1]); + EXPECT_EQ('d', foo[2]); } TEST(STLExtrasTest, EnumerateRValueRef) {