[llvm] bf099f4 - [llvm][ADT] Structured bindings for move-only types in `StringMap` (#114676)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Nov 2 20:34:56 PDT 2024
Author: Jan Svoboda
Date: 2024-11-02T20:34:52-07:00
New Revision: bf099f4682bf088aaa49b2c72fb1ef3250213fbb
URL: https://github.com/llvm/llvm-project/commit/bf099f4682bf088aaa49b2c72fb1ef3250213fbb
DIFF: https://github.com/llvm/llvm-project/commit/bf099f4682bf088aaa49b2c72fb1ef3250213fbb.diff
LOG: [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.
Added:
Modified:
llvm/include/llvm/ADT/StringMapEntry.h
llvm/unittests/ADT/StringMapTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/ADT/StringMapEntry.h b/llvm/include/llvm/ADT/StringMapEntry.h
index d93af5aedc39d7..842cf704de479d 100644
--- a/llvm/include/llvm/ADT/StringMapEntry.h
+++ b/llvm/include/llvm/ADT/StringMapEntry.h
@@ -17,7 +17,7 @@
#define LLVM_ADT_STRINGMAPENTRY_H
#include "llvm/ADT/StringRef.h"
-#include <optional>
+#include <utility>
namespace llvm {
@@ -147,25 +147,33 @@ class StringMapEntry final : public StringMapEntryStorage<ValueTy> {
};
// Allow structured bindings on StringMapEntry.
+
+template <std::size_t Index, typename ValueTy>
+decltype(auto) get(StringMapEntry<ValueTy> &E) {
+ static_assert(Index < 2);
+ if constexpr (Index == 0)
+ return E.getKey();
+ else
+ return E.getValue();
+}
+
template <std::size_t Index, typename ValueTy>
decltype(auto) get(const StringMapEntry<ValueTy> &E) {
static_assert(Index < 2);
if constexpr (Index == 0)
- return E.first();
+ return E.getKey();
else
- return E.second;
+ return E.getValue();
}
} // end namespace llvm
-namespace std {
template <typename ValueTy>
-struct tuple_size<llvm::StringMapEntry<ValueTy>>
+struct std::tuple_size<llvm::StringMapEntry<ValueTy>>
: std::integral_constant<std::size_t, 2> {};
-template <std::size_t I, typename ValueTy>
-struct tuple_element<I, llvm::StringMapEntry<ValueTy>>
- : std::conditional<I == 0, llvm::StringRef, ValueTy> {};
-} // namespace std
+template <std::size_t Index, typename ValueTy>
+struct std::tuple_element<Index, llvm::StringMapEntry<ValueTy>>
+ : std::tuple_element<Index, std::pair<llvm::StringRef, ValueTy>> {};
#endif // LLVM_ADT_STRINGMAPENTRY_H
diff --git a/llvm/unittests/ADT/StringMapTest.cpp b/llvm/unittests/ADT/StringMapTest.cpp
index c9ef3f8a096ee9..35135cdb297e79 100644
--- a/llvm/unittests/ADT/StringMapTest.cpp
+++ b/llvm/unittests/ADT/StringMapTest.cpp
@@ -381,6 +381,9 @@ struct MoveOnly {
return *this;
}
+ bool operator==(const MoveOnly &RHS) const { return i == RHS.i; }
+ bool operator!=(const MoveOnly &RHS) const { return i != RHS.i; }
+
private:
MoveOnly(const MoveOnly &) = delete;
MoveOnly &operator=(const MoveOnly &) = delete;
@@ -550,6 +553,26 @@ TEST_F(StringMapTest, StructuredBindings) {
EXPECT_EQ("a", Key);
EXPECT_EQ(42, Value);
}
+
+ for (const auto &[Key, Value] : A) {
+ EXPECT_EQ("a", Key);
+ EXPECT_EQ(42, Value);
+ }
+}
+
+TEST_F(StringMapTest, StructuredBindingsMoveOnly) {
+ StringMap<MoveOnly> A;
+ A.insert(std::make_pair("a", MoveOnly(42)));
+
+ for (auto &[Key, Value] : A) {
+ EXPECT_EQ("a", Key);
+ EXPECT_EQ(MoveOnly(42), Value);
+ }
+
+ for (const auto &[Key, Value] : A) {
+ EXPECT_EQ("a", Key);
+ EXPECT_EQ(MoveOnly(42), Value);
+ }
}
namespace {
More information about the llvm-commits
mailing list