[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