Skip to content

Commit bf099f4

Browse files
authored
[llvm][ADT] Structured bindings for move-only types in StringMap (#114676)
This PR implements destructuring of `StringMapEntry<T>` where `T` is a move-only type. Also adds the non-const version.
1 parent 5091a35 commit bf099f4

File tree

2 files changed

+40
-9
lines changed

2 files changed

+40
-9
lines changed

llvm/include/llvm/ADT/StringMapEntry.h

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#define LLVM_ADT_STRINGMAPENTRY_H
1818

1919
#include "llvm/ADT/StringRef.h"
20-
#include <optional>
20+
#include <utility>
2121

2222
namespace llvm {
2323

@@ -147,25 +147,33 @@ class StringMapEntry final : public StringMapEntryStorage<ValueTy> {
147147
};
148148

149149
// Allow structured bindings on StringMapEntry.
150+
151+
template <std::size_t Index, typename ValueTy>
152+
decltype(auto) get(StringMapEntry<ValueTy> &E) {
153+
static_assert(Index < 2);
154+
if constexpr (Index == 0)
155+
return E.getKey();
156+
else
157+
return E.getValue();
158+
}
159+
150160
template <std::size_t Index, typename ValueTy>
151161
decltype(auto) get(const StringMapEntry<ValueTy> &E) {
152162
static_assert(Index < 2);
153163
if constexpr (Index == 0)
154-
return E.first();
164+
return E.getKey();
155165
else
156-
return E.second;
166+
return E.getValue();
157167
}
158168

159169
} // end namespace llvm
160170

161-
namespace std {
162171
template <typename ValueTy>
163-
struct tuple_size<llvm::StringMapEntry<ValueTy>>
172+
struct std::tuple_size<llvm::StringMapEntry<ValueTy>>
164173
: std::integral_constant<std::size_t, 2> {};
165174

166-
template <std::size_t I, typename ValueTy>
167-
struct tuple_element<I, llvm::StringMapEntry<ValueTy>>
168-
: std::conditional<I == 0, llvm::StringRef, ValueTy> {};
169-
} // namespace std
175+
template <std::size_t Index, typename ValueTy>
176+
struct std::tuple_element<Index, llvm::StringMapEntry<ValueTy>>
177+
: std::tuple_element<Index, std::pair<llvm::StringRef, ValueTy>> {};
170178

171179
#endif // LLVM_ADT_STRINGMAPENTRY_H

llvm/unittests/ADT/StringMapTest.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,9 @@ struct MoveOnly {
381381
return *this;
382382
}
383383

384+
bool operator==(const MoveOnly &RHS) const { return i == RHS.i; }
385+
bool operator!=(const MoveOnly &RHS) const { return i != RHS.i; }
386+
384387
private:
385388
MoveOnly(const MoveOnly &) = delete;
386389
MoveOnly &operator=(const MoveOnly &) = delete;
@@ -550,6 +553,26 @@ TEST_F(StringMapTest, StructuredBindings) {
550553
EXPECT_EQ("a", Key);
551554
EXPECT_EQ(42, Value);
552555
}
556+
557+
for (const auto &[Key, Value] : A) {
558+
EXPECT_EQ("a", Key);
559+
EXPECT_EQ(42, Value);
560+
}
561+
}
562+
563+
TEST_F(StringMapTest, StructuredBindingsMoveOnly) {
564+
StringMap<MoveOnly> A;
565+
A.insert(std::make_pair("a", MoveOnly(42)));
566+
567+
for (auto &[Key, Value] : A) {
568+
EXPECT_EQ("a", Key);
569+
EXPECT_EQ(MoveOnly(42), Value);
570+
}
571+
572+
for (const auto &[Key, Value] : A) {
573+
EXPECT_EQ("a", Key);
574+
EXPECT_EQ(MoveOnly(42), Value);
575+
}
553576
}
554577

555578
namespace {

0 commit comments

Comments
 (0)