compact_flat_map.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #pragma once
  2. #include "compact_vector.h"
  3. namespace NYT {
  4. namespace NDetail {
  5. template <typename T>
  6. concept CHasIsTransparentFlag = requires {
  7. typename T::is_transparent;
  8. };
  9. template <typename T, typename U, typename TCompare>
  10. concept CComparisonAllowed = std::same_as<T, U> || CHasIsTransparentFlag<TCompare>;
  11. } // namespace NDetail
  12. ///////////////////////////////////////////////////////////////////////////////
  13. //! A flat map implementation over TCompactTValueector that tries to keep data inline.
  14. /*!
  15. * Similarly to SmallSet, this is implemented via binary search over a sorted
  16. * vector. Unlike SmallSet, however, this one never falls back to std::map (or
  17. * set) for larger sizes. This means that the flat map is only useful
  18. * - at small sizes, when there's absolutely no chance of it getting big, or
  19. * - when it's filled once and is then only read from.
  20. *
  21. * In return, the flat map provides
  22. * - a smaller size overhead and
  23. * - a guarantee that if data fits into inline storage, it goes there.
  24. *
  25. * Because of the latter, one should be very careful with iterators: virtually
  26. * any call to insert or erase may potentially invalidate all iterators.
  27. */
  28. template <class TKey, class TValue, size_t N, class TKeyCompare = std::ranges::less>
  29. class TCompactFlatMap
  30. {
  31. public:
  32. // NB: can't make this pair<const TKey, TValue> as TCompactTValueector requires its type
  33. // parameter to be copy-assignable.
  34. using value_type = std::pair<TKey, TValue>;
  35. using key_type = TKey;
  36. using mapped_type = TValue;
  37. using key_compare = TKeyCompare;
  38. private:
  39. using TStorage = TCompactVector<value_type, N>;
  40. public:
  41. using iterator = typename TStorage::iterator;
  42. using const_iterator = typename TStorage::const_iterator;
  43. using size_type = size_t;
  44. TCompactFlatMap() = default;
  45. template <class TInputIterator>
  46. TCompactFlatMap(TInputIterator begin, TInputIterator end);
  47. TCompactFlatMap(std::initializer_list<value_type> values);
  48. bool operator==(const TCompactFlatMap& rhs) const;
  49. bool operator!=(const TCompactFlatMap& rhs) const;
  50. iterator begin();
  51. const_iterator begin() const;
  52. const_iterator cbegin() const;
  53. iterator end();
  54. const_iterator end() const;
  55. const_iterator cend() const;
  56. void reserve(size_type n);
  57. size_type size() const;
  58. int ssize() const;
  59. [[nodiscard]] bool empty() const;
  60. void clear();
  61. void shrink_to_small();
  62. template <NDetail::CComparisonAllowed<TKey, TKeyCompare> TOtherKey>
  63. iterator find(const TOtherKey& k);
  64. template <NDetail::CComparisonAllowed<TKey, TKeyCompare> TOtherKey>
  65. const_iterator find(const TOtherKey& k) const;
  66. template <NDetail::CComparisonAllowed<TKey, TKeyCompare> TOtherKey>
  67. iterator lower_bound(const TOtherKey& k);
  68. template <NDetail::CComparisonAllowed<TKey, TKeyCompare> TOtherKey>
  69. const_iterator lower_bound(const TOtherKey& k) const;
  70. template <NDetail::CComparisonAllowed<TKey, TKeyCompare> TOtherKey>
  71. iterator upper_bound(const TOtherKey& k);
  72. template <NDetail::CComparisonAllowed<TKey, TKeyCompare> TOtherKey>
  73. const_iterator upper_bound(const TOtherKey& k) const;
  74. template <NDetail::CComparisonAllowed<TKey, TKeyCompare> TOtherKey>
  75. std::pair<iterator, iterator> equal_range(const TOtherKey& k);
  76. template <NDetail::CComparisonAllowed<TKey, TKeyCompare> TOtherKey>
  77. std::pair<const_iterator, const_iterator> equal_range(const TOtherKey& k) const;
  78. template <NDetail::CComparisonAllowed<TKey, TKeyCompare> TOtherKey>
  79. bool contains(const TOtherKey& k) const;
  80. std::pair<iterator, bool> insert(const value_type& value);
  81. std::pair<iterator, bool> insert(value_type&& value);
  82. template <class TInputIterator>
  83. void insert(TInputIterator begin, TInputIterator end);
  84. template <class... TArgs>
  85. std::pair<iterator, bool> emplace(TArgs&&... args);
  86. TValue& operator[](const TKey& k);
  87. void erase(const TKey& k);
  88. void erase(iterator pos);
  89. void erase(iterator b, iterator e);
  90. private:
  91. TStorage Storage_;
  92. template <class TArg>
  93. std::pair<iterator, bool> do_insert(TArg&& value);
  94. };
  95. ////////////////////////////////////////////////////////////////////////////////
  96. } // namespace NYT
  97. #define COMPACT_FLAT_MAP_INL_H_
  98. #include "compact_flat_map-inl.h"
  99. #undef COMPACT_FLAT_MAP_INL_H_