compact_flat_map.h 3.4 KB

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