diff --git a/toolchain/docs/idioms.md b/toolchain/docs/idioms.md index 5301ae51e49c..e4aaf322f271 100644 --- a/toolchain/docs/idioms.md +++ b/toolchain/docs/idioms.md @@ -167,14 +167,25 @@ Some name mirroring examples are: - `strings` is a `ValueStore`, which has an index type of `StringId`, but for copy-related reasons, uses `llvm::StringRef` for values. -A fairly complete list of `ValueStore` uses should be available on -[checking's Context class](https://github.com/search?q=repository%3Acarbon-language%2Fcarbon-lang%20path%3Acheck%2Fcontext.h%20symbol%3Aidentifiers&type=code). +There are also a number of wrappers around `ValueStore` that provide some +additional functionality and which are named with the `Store` suffix, such as +`InstStore` or `CanonicalValueStore`. + +A fairly complete list of `ValueStore` (and `ValueStore` wrapper) uses should be +available on [checking's Context class]. + + + +[checking's Context class]: + https://github.com/search?q=repo%3Acarbon-language%2Fcarbon-lang+path%3Atoolchain%2Fcheck%2Fcontext.h+%2F%5Cw%2BStore%2F&type=code + + ## Template metaprogramming TODO: show example patterns -- TypedInstArgsInfo from toolchain/sem_ir/inst.h +- InstLikeTypeInfo from toolchain/sem_ir/inst.h - templated using - std::declval - decltype @@ -197,41 +208,15 @@ The presence of specific fields in a struct with a specified type is detected using the following idiom: ```cpp -template -constexpr bool HasField = false; -template -constexpr bool HasField = true; -``` - -This is intended to check the same property as the following concept, which we -can't use because we currently need to compile in C++17 mode: - -```cpp +// HasField is true if T has a `U field` field of type FieldType. template concept HasField = requires (T x) { - { x.field } -> std::same_as; + { &T::field } -> std::same_as; }; ``` -To detect a field with a specific name with a type derived from a specified base -type, use this idiom: - -```cpp -// HasField is true if T has a `U field` field, -// where `U` extends `BaseClass`. -template -inline constexpr bool HasField = false; -template -inline constexpr bool HasField< - T, bool(std::is_base_of_v)> = true; -``` - -The equivalent concept is: - -```cpp -template concept HasField = requires (T x) { - { x.field } -> std::derived_from; -}; -``` +See `HasKindMemberAsField` in +[`toolchain/sem_ir/typed_insts.h`](/toolchain/sem_ir/typed_insts.h) for an +example. ## Local lambdas to reduce duplicate code @@ -266,17 +251,17 @@ This can be used for complex initialization, as in: ```cpp // variable declaration static const llvm::ArrayRef entropy_bytes = -// initializer starts with a lambda + // initializer starts with a lambda []() -> llvm::ArrayRef { - static llvm::SmallVector bytes; + static llvm::SmallVector bytes; - // a bunch of code + // a bunch of code - // return the value to initialize the variable with - return bytes; + // return the value to initialize the variable with + return bytes; -// finish defining the lambda, and then immediately invoke it -}(); + // finish defining the lambda, and then immediately invoke it + }(); ``` It can also be used inside a `CARBON_DCHECK` to avoid computation that is only