[llvm] [llvm][ADT] Structured bindings for move-only types in `StringMap` (PR #114676)

Jan Svoboda via llvm-commits llvm-commits at lists.llvm.org
Sat Nov 2 10:53:47 PDT 2024


================
@@ -147,25 +147,57 @@ class StringMapEntry final : public StringMapEntryStorage<ValueTy> {
 };
 
 // Allow structured bindings on StringMapEntry.
+
+namespace detail {
+template <std::size_t Index> struct StringMapEntryGet;
+
+template <> struct StringMapEntryGet<0> {
+  template <typename ValueTy> static StringRef get(StringMapEntry<ValueTy> &E) {
+    return E.getKey();
+  }
+
+  template <typename ValueTy>
+  static StringRef get(const StringMapEntry<ValueTy> &E) {
+    return E.getKey();
+  }
+};
+
+template <> struct StringMapEntryGet<1> {
+  template <typename ValueTy> static ValueTy &get(StringMapEntry<ValueTy> &E) {
+    return E.getValue();
+  }
+
+  template <typename ValueTy>
+  static const ValueTy &get(const StringMapEntry<ValueTy> &E) {
+    return E.getValue();
+  }
+};
+} // namespace detail
+
+template <std::size_t Index, typename ValueTy>
+decltype(auto) get(StringMapEntry<ValueTy> &E) {
+  return detail::StringMapEntryGet<Index>::get(E);
----------------
jansvoboda11 wrote:

I couldn't make this work properly before - it seemed that `decltype(auto)` always deduces `ValueTy` instead of `ValueTy &`. Template specializations that explicitly use the reference type was the only solution I could find. Trying again now, I realize I could've used `E.getValue()` instead.

https://github.com/llvm/llvm-project/pull/114676


More information about the llvm-commits mailing list