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.
This commit is contained in:
Jon Ross-Perkins
2025-05-16 01:39:19 +00:00
committed by GitHub
parent 5a3a977df4
commit dbf12eb3fc
7 changed files with 41 additions and 21 deletions
+7
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}