diff --git a/common/BUILD b/common/BUILD index dae69b5cea1b..fcc79b961674 100644 --- a/common/BUILD +++ b/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", diff --git a/common/concepts.h b/common/concepts.h new file mode 100644 index 000000000000..9f66ee076a64 --- /dev/null +++ b/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 + +namespace Carbon { + +// True if `T` is the same as one of `OtherT`. +template +concept SameAsOneOf = (std::same_as || ...); + +} // namespace Carbon + +#endif // CARBON_COMMON_CONCEPTS_H_ diff --git a/common/map.h b/common/map.h index fae8a2f3f675..d88c30d8c1f4 100644 --- a/common/map.h +++ b/common/map.h @@ -10,6 +10,7 @@ #include #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 // NOLINTNEXTLINE(google-explicit-constructor) MapView(MapView other_view) - requires(std::same_as || - std::same_as) && - (std::same_as || - std::same_as) + requires(SameAsOneOf && + SameAsOneOf) : ImplT(other_view) {} // Tests whether a key is present in the map. @@ -193,10 +192,8 @@ class MapBase : protected RawHashtable::BaseImpl // NOLINTNEXTLINE(google-explicit-constructor) operator MapView() const - requires(std::same_as || - std::same_as) && - (std::same_as || - std::same_as) + requires(SameAsOneOf && + SameAsOneOf) { return ViewT(*this); } diff --git a/common/raw_hashtable.h b/common/raw_hashtable.h index 9fc498b76cd8..000d4bedb962 100644 --- a/common/raw_hashtable.h +++ b/common/raw_hashtable.h @@ -15,6 +15,7 @@ #include #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 // NOLINTNEXTLINE(google-explicit-constructor) ViewImpl(ViewImpl other_view) - requires(std::same_as || - std::same_as) && - (std::same_as || - std::same_as) + requires(SameAsOneOf && + SameAsOneOf) : 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 diff --git a/toolchain/sem_ir/BUILD b/toolchain/sem_ir/BUILD index 8b32fea95654..7035bf76ff7f 100644 --- a/toolchain/sem_ir/BUILD +++ b/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", diff --git a/toolchain/sem_ir/inst_fingerprinter.cpp b/toolchain/sem_ir/inst_fingerprinter.cpp index b051606325e8..0b5acd0341f0 100644 --- a/toolchain/sem_ir/inst_fingerprinter.cpp +++ b/toolchain/sem_ir/inst_fingerprinter.cpp @@ -8,6 +8,7 @@ #include #include +#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 - requires(std::same_as || - std::same_as || - std::same_as || std::same_as || - std::same_as || std::same_as) + requires(SameAsOneOf) auto Add(T arg) -> void { // Index-like ID: just include the value directly. contents.push_back(arg.index); } template - requires(std::same_as || std::same_as || - std::same_as || std::same_as) + requires(SameAsOneOf) auto Add(T /*arg*/) -> void { CARBON_FATAL("Unexpected instruction operand kind {0}", typeid(T).name()); } diff --git a/toolchain/sem_ir/stringify.cpp b/toolchain/sem_ir/stringify.cpp index c9e1620798bd..2de2fe23d6a7 100644 --- a/toolchain/sem_ir/stringify.cpp +++ b/toolchain/sem_ir/stringify.cpp @@ -9,6 +9,7 @@ #include #include +#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 - requires(std::same_as || - std::same_as || - std::same_as) + requires(SameAsOneOf) auto StringifyInst(InstId /*inst_id*/, InstT inst) -> void { step_stack_->PushEntityNameId(inst.entity_name_id); }