Просмотр исходного кода

Add a SameAsOneOf helper (#5490)

Trying to make repeated `std::same_as` easier to write. Calling it
"concepts.h" because I figure we'll maybe have a couple more things like
this.

Was looking at this because I may add a couple more similar constructs.
Jon Ross-Perkins 11 месяцев назад
Родитель
Сommit
dbf12eb3fc

+ 7 - 0
common/BUILD

@@ -111,6 +111,11 @@ cc_test(
     ],
 )
 
+cc_library(
+    name = "concepts",
+    hdrs = ["concepts.h"],
+)
+
 cc_library(
     name = "enum_base",
     hdrs = ["enum_base.h"],
@@ -307,6 +312,7 @@ cc_library(
     hdrs = ["map.h"],
     deps = [
         ":check",
+        ":concepts",
         ":hashtable_key_context",
         ":raw_hashtable",
         "@llvm-project//llvm:Support",
@@ -374,6 +380,7 @@ cc_library(
     hdrs = ["raw_hashtable.h"],
     deps = [
         ":check",
+        ":concepts",
         ":hashing",
         ":hashtable_key_context",
         ":raw_hashtable_metadata_group",

+ 18 - 0
common/concepts.h

@@ -0,0 +1,18 @@
+// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#ifndef CARBON_COMMON_CONCEPTS_H_
+#define CARBON_COMMON_CONCEPTS_H_
+
+#include <concepts>
+
+namespace Carbon {
+
+// True if `T` is the same as one of `OtherT`.
+template <typename T, typename... OtherT>
+concept SameAsOneOf = (std::same_as<T, OtherT> || ...);
+
+}  // namespace Carbon
+
+#endif  // CARBON_COMMON_CONCEPTS_H_

+ 5 - 8
common/map.h

@@ -10,6 +10,7 @@
 #include <utility>
 
 #include "common/check.h"
+#include "common/concepts.h"
 #include "common/hashtable_key_context.h"
 #include "common/raw_hashtable.h"
 #include "llvm/Support/Compiler.h"
@@ -90,10 +91,8 @@ class MapView
   template <typename OtherKeyT, typename OtherValueT>
   // NOLINTNEXTLINE(google-explicit-constructor)
   MapView(MapView<OtherKeyT, OtherValueT, KeyContextT> other_view)
-    requires(std::same_as<KeyT, OtherKeyT> ||
-             std::same_as<KeyT, const OtherKeyT>) &&
-            (std::same_as<ValueT, OtherValueT> ||
-             std::same_as<ValueT, const OtherValueT>)
+    requires(SameAsOneOf<KeyT, OtherKeyT, const OtherKeyT> &&
+             SameAsOneOf<ValueT, OtherValueT, const OtherValueT>)
       : ImplT(other_view) {}
 
   // Tests whether a key is present in the map.
@@ -193,10 +192,8 @@ class MapBase : protected RawHashtable::BaseImpl<InputKeyT, InputValueT,
   template <typename OtherKeyT, typename OtherValueT>
   // NOLINTNEXTLINE(google-explicit-constructor)
   operator MapView<OtherKeyT, OtherValueT, KeyContextT>() const
-    requires(std::same_as<KeyT, OtherKeyT> ||
-             std::same_as<const KeyT, OtherKeyT>) &&
-            (std::same_as<ValueT, OtherValueT> ||
-             std::same_as<const ValueT, OtherValueT>)
+    requires(SameAsOneOf<OtherKeyT, KeyT, const KeyT> &&
+             SameAsOneOf<OtherValueT, ValueT, const ValueT>)
   {
     return ViewT(*this);
   }

+ 3 - 4
common/raw_hashtable.h

@@ -15,6 +15,7 @@
 #include <utility>
 
 #include "common/check.h"
+#include "common/concepts.h"
 #include "common/hashing.h"
 #include "common/raw_hashtable_metadata_group.h"
 #include "llvm/Support/Compiler.h"
@@ -374,10 +375,8 @@ class ViewImpl {
   template <typename OtherKeyT, typename OtherValueT>
   // NOLINTNEXTLINE(google-explicit-constructor)
   ViewImpl(ViewImpl<OtherKeyT, OtherValueT, KeyContextT> other_view)
-    requires(std::same_as<KeyT, OtherKeyT> ||
-             std::same_as<KeyT, const OtherKeyT>) &&
-                (std::same_as<ValueT, OtherValueT> ||
-                 std::same_as<ValueT, const OtherValueT>)
+    requires(SameAsOneOf<KeyT, OtherKeyT, const OtherKeyT> &&
+             SameAsOneOf<ValueT, OtherValueT, const OtherValueT>)
       : alloc_size_(other_view.alloc_size_), storage_(other_view.storage_) {}
 
   // Looks up an entry in the hashtable and returns its address or null if not

+ 2 - 0
toolchain/sem_ir/BUILD

@@ -139,6 +139,7 @@ cc_library(
         ":file",
         ":typed_insts",
         "//common:check",
+        "//common:concepts",
         "//common:raw_string_ostream",
         "//toolchain/base:kind_switch",
         "@llvm-project//llvm:Support",
@@ -158,6 +159,7 @@ cc_library(
     deps = [
         ":file",
         ":typed_insts",
+        "//common:concepts",
         "//common:ostream",
         "//common:raw_string_ostream",
         "//toolchain/base:kind_switch",

+ 4 - 6
toolchain/sem_ir/inst_fingerprinter.cpp

@@ -8,6 +8,7 @@
 #include <utility>
 #include <variant>
 
+#include "common/concepts.h"
 #include "common/ostream.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallVector.h"
@@ -298,18 +299,15 @@ struct Worklist {
   }
 
   template <typename T>
-    requires(std::same_as<T, BoolValue> ||
-             std::same_as<T, CompileTimeBindIndex> ||
-             std::same_as<T, ElementIndex> || std::same_as<T, FloatKind> ||
-             std::same_as<T, IntKind> || std::same_as<T, CallParamIndex>)
+    requires(SameAsOneOf<T, BoolValue, CompileTimeBindIndex, ElementIndex,
+                         FloatKind, IntKind, CallParamIndex>)
   auto Add(T arg) -> void {
     // Index-like ID: just include the value directly.
     contents.push_back(arg.index);
   }
 
   template <typename T>
-    requires(std::same_as<T, AnyRawId> || std::same_as<T, ExprRegionId> ||
-             std::same_as<T, LocId> || std::same_as<T, RealId>)
+    requires(SameAsOneOf<T, AnyRawId, ExprRegionId, LocId, RealId>)
   auto Add(T /*arg*/) -> void {
     CARBON_FATAL("Unexpected instruction operand kind {0}", typeid(T).name());
   }

+ 2 - 3
toolchain/sem_ir/stringify.cpp

@@ -9,6 +9,7 @@
 #include <utility>
 #include <variant>
 
+#include "common/concepts.h"
 #include "common/raw_string_ostream.h"
 #include "toolchain/base/kind_switch.h"
 #include "toolchain/sem_ir/entity_with_params_base.h"
@@ -269,9 +270,7 @@ class Stringifier {
   }
 
   template <typename InstT>
-    requires(std::same_as<InstT, BindAlias> ||
-             std::same_as<InstT, BindSymbolicName> ||
-             std::same_as<InstT, ExportDecl>)
+    requires(SameAsOneOf<InstT, BindAlias, BindSymbolicName, ExportDecl>)
   auto StringifyInst(InstId /*inst_id*/, InstT inst) -> void {
     step_stack_->PushEntityNameId(inst.entity_name_id);
   }