mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 20:30:14 +01:00
This injects a customization point for hashtable-specific equality testing that the key context uses by default. While this is rarely needed, there are LLVM types where it is necessary and it seems a good general tool to have to avoid unnecessary complexity from custom key contexts when a simple customization of equality is all that is required. This also adds a CRTP mixin for implementing a common pattern of key contexts where the context provides translation of some key types into another type, potentially using state. Rather than having to implement the entire key context API, code can derive from this template and simply provide a set of overloads for the types it wants to translate. Any key types used which can be passed to one of those overloads will get translated before following the same logic as the default key context. While this updates the only usage so far of this pattern, a subsequent PR will add several more users making the pattern worth abstracting here.
46 lines
1.3 KiB
C++
46 lines
1.3 KiB
C++
// 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
|
|
|
|
#include "toolchain/sem_ir/generic.h"
|
|
|
|
namespace Carbon::SemIR {
|
|
|
|
class GenericInstanceStore::KeyContext
|
|
: public TranslatingKeyContext<KeyContext> {
|
|
public:
|
|
// A lookup key for a generic instance.
|
|
struct Key {
|
|
GenericId generic_id;
|
|
InstBlockId args_id;
|
|
|
|
friend auto operator==(const Key&, const Key&) -> bool = default;
|
|
};
|
|
|
|
explicit KeyContext(llvm::ArrayRef<GenericInstance> instances)
|
|
: instances_(instances) {}
|
|
|
|
auto TranslateKey(GenericInstanceId id) const -> Key {
|
|
const auto& instance = instances_[id.index];
|
|
return {.generic_id = instance.generic_id, .args_id = instance.args_id};
|
|
}
|
|
|
|
private:
|
|
llvm::ArrayRef<GenericInstance> instances_;
|
|
};
|
|
|
|
auto GenericInstanceStore::GetOrAdd(GenericId generic_id, InstBlockId args_id)
|
|
-> GenericInstanceId {
|
|
return lookup_table_
|
|
.Insert(
|
|
KeyContext::Key{.generic_id = generic_id, .args_id = args_id},
|
|
[&] {
|
|
return generic_instances_.Add(
|
|
{.generic_id = generic_id, .args_id = args_id});
|
|
},
|
|
KeyContext(generic_instances_.array_ref()))
|
|
.key();
|
|
}
|
|
|
|
} // namespace Carbon::SemIR
|