Repository: carbon-language/carbon-lang
File: toolchain/base/fixed_size_value_store.h (C/C++)

Code before:
    store.values_.resize_for_overwrite(size);
    return store;
  }

  // Makes a ValueStore of the same size as a source `ValueStoreT`, but without
  // initializing values. Entries must be set before reading.
  template <typename ValueStoreT>
    requires std::same_as<IdT, typename ValueStoreT::IdType>
  static auto MakeForOverwrite(const ValueStoreT& size_source)
      -> FixedSizeValueStore {
    FixedSizeValueStore store;
    store.values_.resize_for_overwrite(size_source.size());
    return store;
  }

  // Makes a ValueStore of the specified size, initialized to a default.
  static auto MakeWithExplicitSize(size_t size, ConstRefType default_value)
      -> FixedSizeValueStore {
    FixedSizeValueStore store;
    store.values_.resize(size, default_value);
    return store;
  }

  // Makes a ValueStore from the given range. When possible, use the constructor
  // that takes a `factory_fn` instead, because it verifies that the `IdType`s
  // match.
  template <typename RangeT>
  static auto MakeWithRange(const llvm::iterator_range<RangeT>& range)
      -> FixedSizeValueStore {
    return FixedSizeValueStore(range);
  }

  // Makes a ValueStore of the same size as a source `ValueStoreT`. This is
  // the safest constructor to use, since it ensures everything's initialized to
  // a default, and verifies a matching `IdT` for the size.
  template <typename ValueStoreT>
    requires std::same_as<IdT, typename ValueStoreT::IdType>
  explicit FixedSizeValueStore(const ValueStoreT& size_source,
                               ConstRefType default_value) {
    values_.resize(size_source.size(), default_value);
  }

  // Makes a ValueStore using a mapped range of `source`. The `factory_fn`
  // receives each enumerated entry for construction of `ValueType`.
  template <typename ValueStoreT>
    requires std::same_as<IdT, typename ValueStoreT::IdType>
  explicit FixedSizeValueStore(
      const ValueStoreT& source,
      llvm::function_ref<
          auto(IdT, typename ValueStoreT::ConstRefType)->ValueType>
          factory_fn)

Review comment (suggestion):
[Continuing the previous comment thread, which seems to have been eaten by a force-push]

This phrasing is confusing, because it's not clear what other `IdType` it's referring to (aside from `this->IdType`). That's why I suggested rephrasing to refer to the constructor that takes a `ValueStoreT`. I didn't notice that there are two such constructors, but I think the fix there is to say "use _a_ constructor" instead of "use _the_ constructor". As I understand it, the point of this sentence is to tell people to prefer constructors that verify matching `IdType`s, and they both do that.

Code after:
    store.values_.resize_for_overwrite(size);
    return store;
  }

  // Makes a ValueStore of the same size as a source `ValueStoreT`, but without
  // initializing values. Entries must be set before reading.
  template <typename ValueStoreT>
    requires std::same_as<IdT, typename ValueStoreT::IdType>
  static auto MakeForOverwrite(const ValueStoreT& size_source)
      -> FixedSizeValueStore {
    FixedSizeValueStore store;
    store.values_.resize_for_overwrite(size_source.size());
    return store;
  }

  // Makes a ValueStore of the specified size, initialized to a default.
  static auto MakeWithExplicitSize(size_t size, ConstRefType default_value)
      -> FixedSizeValueStore {
    FixedSizeValueStore store;
    store.values_.resize(size, default_value);
    return store;
  }

  // Makes a ValueStore of the same size as a source `ValueStoreT`. This is
  // the safest constructor to use, since it ensures everything's initialized to
  // a default, and verifies a matching `IdT` for the size.
  template <typename ValueStoreT>
    requires std::same_as<IdT, typename ValueStoreT::IdType>
  explicit FixedSizeValueStore(const ValueStoreT& size_source,
                               ConstRefType default_value) {
    values_.resize(size_source.size(), default_value);
  }

  // Makes a ValueStore using a mapped range of `source`. The `factory_fn`
  // receives each enumerated entry for construction of `ValueType`.
  template <typename ValueStoreT>
    requires std::same_as<IdT, typename ValueStoreT::IdType>
  explicit FixedSizeValueStore(
      const ValueStoreT& source,
      llvm::function_ref<
          auto(IdT, typename ValueStoreT::ConstRefType)->ValueType>
          factory_fn)
      : values_(llvm::map_range(source.enumerate(), factory_fn)) {}

  // Move-only.
  FixedSizeValueStore(FixedSizeValueStore&&) noexcept = default;
  auto operator=(FixedSizeValueStore&&) noexcept
      -> FixedSizeValueStore& = default;

  // Sets the value for an ID.
  auto Set(IdT id, ValueType value) -> void {