compact_flat_map.h 4.3 KB

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