fixed_size_value_store.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #ifndef CARBON_TOOLCHAIN_BASE_FIXED_SIZE_VALUE_STORE_H_
  5. #define CARBON_TOOLCHAIN_BASE_FIXED_SIZE_VALUE_STORE_H_
  6. #include "common/check.h"
  7. #include "llvm/ADT/SmallVector.h"
  8. #include "llvm/ADT/StringRef.h"
  9. #include "llvm/ADT/iterator_range.h"
  10. #include "toolchain/base/mem_usage.h"
  11. #include "toolchain/base/value_store_types.h"
  12. namespace Carbon {
  13. // A value store with a predetermined size.
  14. template <typename IdT, typename ValueT>
  15. class FixedSizeValueStore {
  16. public:
  17. using IdType = IdT;
  18. using ValueType = ValueStoreTypes<ValueT>::ValueType;
  19. using RefType = ValueStoreTypes<ValueT>::RefType;
  20. using ConstRefType = ValueStoreTypes<ValueT>::ConstRefType;
  21. // Makes a ValueStore of the specified size, but without initializing values.
  22. // Entries must be set before reading.
  23. static auto MakeForOverwriteWithExplicitSize(size_t size)
  24. -> FixedSizeValueStore {
  25. FixedSizeValueStore store;
  26. store.values_.resize_for_overwrite(size);
  27. return store;
  28. }
  29. // Makes a ValueStore of the same size as a source `ValueStoreT`, but without
  30. // initializing values. Entries must be set before reading.
  31. template <typename ValueStoreT>
  32. requires std::same_as<IdT, typename ValueStoreT::IdType>
  33. static auto MakeForOverwrite(const ValueStoreT& size_source)
  34. -> FixedSizeValueStore {
  35. FixedSizeValueStore store;
  36. store.values_.resize_for_overwrite(size_source.size());
  37. return store;
  38. }
  39. // Makes a ValueStore of the specified size, initialized to a default.
  40. static auto MakeWithExplicitSize(size_t size, ConstRefType default_value)
  41. -> FixedSizeValueStore {
  42. FixedSizeValueStore store;
  43. store.values_.resize(size, default_value);
  44. return store;
  45. }
  46. // Makes a ValueStore of the same size as a source `ValueStoreT`. This is
  47. // the safest constructor to use, since it ensures everything's initialized to
  48. // a default, and verifies a matching `IdT` for the size.
  49. template <typename ValueStoreT>
  50. requires std::same_as<IdT, typename ValueStoreT::IdType>
  51. explicit FixedSizeValueStore(const ValueStoreT& size_source,
  52. ConstRefType default_value) {
  53. values_.resize(size_source.size(), default_value);
  54. }
  55. // Makes a ValueStore using a mapped range of `source`. The `factory_fn`
  56. // receives each enumerated entry for construction of `ValueType`.
  57. template <typename ValueStoreT>
  58. requires std::same_as<IdT, typename ValueStoreT::IdType>
  59. explicit FixedSizeValueStore(
  60. const ValueStoreT& source,
  61. llvm::function_ref<
  62. auto(IdT, typename ValueStoreT::ConstRefType)->ValueType>
  63. factory_fn)
  64. : values_(llvm::map_range(source.enumerate(), factory_fn)) {}
  65. // Move-only.
  66. FixedSizeValueStore(FixedSizeValueStore&&) noexcept = default;
  67. auto operator=(FixedSizeValueStore&&) noexcept
  68. -> FixedSizeValueStore& = default;
  69. // Sets the value for an ID.
  70. auto Set(IdT id, ValueType value) -> void {
  71. CARBON_DCHECK(id.index >= 0, "{0}", id);
  72. values_[id.index] = value;
  73. }
  74. // Returns a mutable value for an ID.
  75. auto Get(IdT id) -> RefType {
  76. CARBON_DCHECK(id.index >= 0, "{0}", id);
  77. return values_[id.index];
  78. }
  79. // Returns the value for an ID.
  80. auto Get(IdT id) const -> ConstRefType {
  81. CARBON_DCHECK(id.index >= 0, "{0}", id);
  82. return values_[id.index];
  83. }
  84. // Collects memory usage of the values.
  85. auto CollectMemUsage(MemUsage& mem_usage, llvm::StringRef label) const
  86. -> void {
  87. mem_usage.Collect(label.str(), values_);
  88. }
  89. auto size() const -> size_t { return values_.size(); }
  90. auto values()
  91. -> llvm::iterator_range<typename llvm::SmallVector<ValueT, 0>::iterator> {
  92. return llvm::make_range(values_.begin(), values_.end());
  93. }
  94. auto values() const -> llvm::iterator_range<
  95. typename llvm::SmallVector<ValueT, 0>::const_iterator> {
  96. return llvm::make_range(values_.begin(), values_.end());
  97. }
  98. private:
  99. // Allow default construction for `Make` functions.
  100. FixedSizeValueStore() = default;
  101. // Storage for the `ValueT` objects, indexed by the id.
  102. llvm::SmallVector<ValueT, 0> values_;
  103. };
  104. } // namespace Carbon
  105. #endif // CARBON_TOOLCHAIN_BASE_FIXED_SIZE_VALUE_STORE_H_