[PATCH] D103223: [ADT][WIP] Proof of concept impl of generic visit for PointerUnion

Scott Linder via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 4 17:08:24 PDT 2021


scott.linder updated this revision to Diff 350000.
scott.linder added a comment.

Rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103223/new/

https://reviews.llvm.org/D103223

Files:
  llvm/include/llvm/ADT/PointerUnion.h
  llvm/unittests/ADT/PointerUnionTest.cpp


Index: llvm/unittests/ADT/PointerUnionTest.cpp
===================================================================
--- llvm/unittests/ADT/PointerUnionTest.cpp
+++ llvm/unittests/ADT/PointerUnionTest.cpp
@@ -156,4 +156,26 @@
   EXPECT_TRUE((void *)n.getAddrOfPtr1() == (void *)&n);
 }
 
+TEST_F(PointerUnionTest, Visitor) {
+  void *ptr;
+
+  visit(makeVisitor([&](int *intPtr) { ptr = intPtr; },
+                    [&](float *floatPtr) { ptr = floatPtr; }),
+        a);
+  EXPECT_EQ(&f, ptr);
+
+  visit(makeVisitor([&](int *intPtr) { ptr = intPtr; },
+                    [&](float *floatPtr) { ptr = floatPtr; },
+                    [&](long long *longPtr) { ptr = longPtr; }),
+        i3);
+  EXPECT_EQ(&i, ptr);
+
+  visit(makeVisitor([&](int *intPtr) { ptr = intPtr; },
+                    [&](float *floatPtr) { ptr = floatPtr; },
+                    [&](long long *longPtr) { ptr = longPtr; },
+                    [&](double *doublePtr) { ptr = doublePtr; }),
+        d4);
+  EXPECT_EQ(&d, ptr);
+}
+
 } // end anonymous namespace
Index: llvm/include/llvm/ADT/PointerUnion.h
===================================================================
--- llvm/include/llvm/ADT/PointerUnion.h
+++ llvm/include/llvm/ADT/PointerUnion.h
@@ -17,6 +17,7 @@
 #include "llvm/ADT/DenseMapInfo.h"
 #include "llvm/ADT/PointerIntPair.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/VariantTraits.h"
 #include "llvm/Support/PointerLikeTypeTraits.h"
 #include <cassert>
 #include <cstddef>
@@ -162,9 +163,12 @@
 
   explicit operator bool() const { return !isNull(); }
 
+  /// Get index of pointer type currently held by Union.
+  size_t index() const { return this->Val.getInt(); }
+
   /// Test if the Union currently holds the type matching T.
   template <typename T> bool is() const {
-    return this->Val.getInt() == FirstIndexOfType<T, PTs...>{};
+    return index() == FirstIndexOfType<T, PTs...>{};
   }
 
   /// Returns the value of the specified pointer type.
@@ -273,6 +277,18 @@
   }
 };
 
+template <typename... PTs> struct VariantTraits<PointerUnion<PTs...>> {
+  static constexpr size_t size() { return sizeof...(PTs); }
+  static constexpr size_t index(const PointerUnion<PTs...> &Variant) {
+    return Variant.index();
+  }
+  template <size_t Index, typename VariantT = PointerUnion<PTs...>>
+  static constexpr decltype(auto) get(VariantT &&Variant) {
+    return std::forward<VariantT>(Variant)
+        .template get<TypeAtIndex<Index, PTs...>>();
+  }
+};
+
 } // end namespace llvm
 
 #endif // LLVM_ADT_POINTERUNION_H


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D103223.350000.patch
Type: text/x-patch
Size: 2548 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210605/f120b93d/attachment.bin>


More information about the llvm-commits mailing list