[PATCH] D122079: [ADT] Add Enum matcher

Chris Bieneman via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Mar 19 13:23:09 PDT 2022


beanz created this revision.
beanz added reviewers: MaskRay, tstellar, pete, jdoerfert, sheredom, kuhar, antiagainst, nhaehnle, rnk.
Herald added subscribers: dexonsmith, mgorny.
Herald added a project: All.
beanz requested review of this revision.
Herald added a project: LLVM.

This patch adds a template that is really just a clean way of checking
if an enum is one of several possible values.

This patch doesn't add any uses of this template, but that is coming in
a subsequent patch.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122079

Files:
  llvm/include/llvm/ADT/EnumMatcher.h
  llvm/unittests/ADT/CMakeLists.txt
  llvm/unittests/ADT/EnumMatcherTests.cpp


Index: llvm/unittests/ADT/EnumMatcherTests.cpp
===================================================================
--- /dev/null
+++ llvm/unittests/ADT/EnumMatcherTests.cpp
@@ -0,0 +1,38 @@
+//===- llvm/unittest/ADT/EnumMatcherTests.cpp -------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/EnumMatcher.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+enum Doggos {
+  Floofer,
+  Woofer,
+  SubWoofer,
+  Pupper,
+  Pupperino,
+  Longboi,
+};
+
+TEST(EnumMatcher, MatchCase) {
+  {
+    bool Val = isInEnumSet<Doggos, Woofer, SubWoofer>(Woofer);
+    ASSERT_TRUE(Val);
+  }
+  {
+    bool Val = isInEnumSet<Doggos, Woofer, SubWoofer>(SubWoofer);
+    ASSERT_TRUE(Val);
+  }
+  {
+    bool Val = isInEnumSet<Doggos, Woofer, SubWoofer>(Pupper);
+    ASSERT_FALSE(Val);
+  }
+}
Index: llvm/unittests/ADT/CMakeLists.txt
===================================================================
--- llvm/unittests/ADT/CMakeLists.txt
+++ llvm/unittests/ADT/CMakeLists.txt
@@ -23,6 +23,7 @@
   DepthFirstIteratorTest.cpp
   DirectedGraphTest.cpp
   EnumeratedArrayTest.cpp
+  EnumMatcherTests.cpp
   EquivalenceClassesTest.cpp
   FallibleIteratorTest.cpp
   FloatingPointMode.cpp
Index: llvm/include/llvm/ADT/EnumMatcher.h
===================================================================
--- /dev/null
+++ llvm/include/llvm/ADT/EnumMatcher.h
@@ -0,0 +1,36 @@
+#ifndef LLVM_ADT_ENUMMATCHER_H
+#define LLVM_ADT_ENUMMATCHER_H
+
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+
+namespace detail {
+// This magic blob of code here looks awful, but it is actually pretty clever.
+// If you call isValidForDXIL with a constant value, this should generate an
+// insane AST that will all constant fold down to true or false.
+// If you call it with a non-constant value, it should turn into a nasty switch,
+// which is as good as you're going to do anyways...
+template <typename T>
+LLVM_ATTRIBUTE_ALWAYS_INLINE bool unrollCompare(T Left, T Right) {
+  return Left == Right;
+}
+
+template <typename T, typename... V>
+LLVM_ATTRIBUTE_ALWAYS_INLINE bool unrollCompare(T Left, T Right, V... Vals) {
+  if (Left == Right)
+    return true;
+  return unrollCompare(Left, Vals...);
+}
+} // namespace detail
+
+// TODO: When we update to C++17 we can use auto here to avoid needing to
+// specify the type of the enum.
+template <typename T, T Val, T... Vals>
+LLVM_ATTRIBUTE_ALWAYS_INLINE bool isInEnumSet(T InVal) {
+  return detail::unrollCompare(InVal, Val, Vals...);
+}
+
+} // namespace llvm
+
+#endif // LLVM_ADT_ENUMMATCHER_H


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D122079.416723.patch
Type: text/x-patch
Size: 2915 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220319/0537c21e/attachment.bin>


More information about the llvm-commits mailing list