Repository: carbon-language/carbon-lang
File: toolchain/sem_ir/block_value_store.h (C/C++)

Code before:
    if (content.empty()) {
      return IdT::Empty;
    }
    auto result = canonical_blocks_.Insert(
        content, [&] { return Add(content); }, KeyContext(this));
    return result.key();
  }

  // Promotes an existing block ID to a canonical block ID, or returns an
  // existing canonical block ID if the block was already added. The specified
  // block must not be modified after this point.
  auto MakeCanonical(IdT id) -> IdT {
    // Get the content first so that we don't have unnecessary translation of
    // the `id` into the content during insertion.
    auto result = canonical_blocks_.Insert(
        Get(id), [id] { return id; }, KeyContext(this));
    return result.key();
  }

  auto OutputYaml() const -> Yaml::OutputMapping {
    return Yaml::OutputMapping([&](Yaml::OutputMapping::Map map) {
      for (auto [block_id, block] : values_.enumerate()) {
        map.Add(PrintToString(block_id),
                Yaml::OutputMapping([&](Yaml::OutputMapping::Map map) {
                  for (auto i : llvm::seq(block.size())) {
                    map.Add(llvm::itostr(i), Yaml::OutputScalar(block[i]));
                  }
                }));
      }
    });
  }

  // Collects memory usage of members.
  auto CollectMemUsage(MemUsage& mem_usage, llvm::StringRef label) const
      -> void {
    mem_usage.Collect(MemUsage::ConcatLabel(label, "values_"), values_);
    mem_usage.Collect(MemUsage::ConcatLabel(label, "canonical_blocks_"),
                      canonical_blocks_, KeyContext(this));
  }

  auto size() const -> int { return values_.size(); }

 protected:
  // Reserves and returns a block ID. The contents of the block
  // should be specified by calling Set, or similar.
  auto AddDefaultValue() -> IdT { return values_.AddDefaultValue(); }

  // Adds an uninitialized block of the given size.
  auto AddUninitialized(size_t size) -> IdT {
    return values_.Add(AllocateUninitialized(size));
  }

Review comment (suggestion):
Optional, but while we're enumerating...
```suggestion
                  for (auto [i, elem_id] : llvm::enumerate(block.size())) {
                    map.Add(llvm::itostr(i), Yaml::OutputScalar(elem_id));
```

Code after:
    if (content.empty()) {
      return IdT::Empty;
    }
    auto result = canonical_blocks_.Insert(
        content, [&] { return Add(content); }, KeyContext(this));
    return result.key();
  }

  // Promotes an existing block ID to a canonical block ID, or returns an
  // existing canonical block ID if the block was already added. The specified
  // block must not be modified after this point.
  auto MakeCanonical(IdT id) -> IdT {
    // Get the content first so that we don't have unnecessary translation of
    // the `id` into the content during insertion.
    auto result = canonical_blocks_.Insert(
        Get(id), [id] { return id; }, KeyContext(this));
    return result.key();
  }

  auto OutputYaml() const -> Yaml::OutputMapping {
    return Yaml::OutputMapping([&](Yaml::OutputMapping::Map map) {
      for (auto [block_id, block] : values_.enumerate()) {
        map.Add(PrintToString(block_id),
                Yaml::OutputMapping([&](Yaml::OutputMapping::Map map) {
                  for (auto [i, elem_id] : llvm::enumerate(block)) {
                    map.Add(llvm::itostr(i), Yaml::OutputScalar(elem_id));
                  }
                }));
      }
    });
  }

  // Collects memory usage of members.
  auto CollectMemUsage(MemUsage& mem_usage, llvm::StringRef label) const
      -> void {
    mem_usage.Collect(MemUsage::ConcatLabel(label, "values_"), values_);
    mem_usage.Collect(MemUsage::ConcatLabel(label, "canonical_blocks_"),
                      canonical_blocks_, KeyContext(this));
  }

  auto size() const -> int { return values_.size(); }

 protected:
  // Reserves and returns a block ID. The contents of the block
  // should be specified by calling Set, or similar.
  auto AddDefaultValue() -> IdT { return values_.AddDefaultValue(); }

  // Adds an uninitialized block of the given size.
  auto AddUninitialized(size_t size) -> IdT {
    return values_.Add(AllocateUninitialized(size));
  }