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

Code before:
  // 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 specified size, initialized to values returned
  // from a callback. This allows initializing non-copyable values.
  template <class F>
    requires requires(F callable) {
      { callable() } -> std::convertible_to<ValueT>;
    }
  static auto MakeWithExplicitSizeFrom(size_t size, F callable)
      -> FixedSizeValueStore {
    FixedSizeValueStore store;
    store.values_.reserve(size);
    for (auto _ : llvm::seq(size)) {
      store.values_.push_back(callable());
    }
    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,

Review comment (suggestion):
Had you considered using `function_ref` here, similar to the constructor below? (also, we typically use `typename` in templates, rather than `class` -- plus `F` is a short typename)

Code after:

  // 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 specified size, initialized to values returned
  // from a callback. This allows initializing non-copyable values.
  static auto MakeWithExplicitSizeFrom(
      size_t size, llvm::function_ref<auto()->ValueT> callable)
      -> FixedSizeValueStore {
    FixedSizeValueStore store;
    store.values_.reserve(size);
    for (auto _ : llvm::seq(size)) {
      store.values_.push_back(callable());
    }
    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>