diff options
author | shakurov <shakurov@yandex-team.ru> | 2022-02-10 16:49:23 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:49:23 +0300 |
commit | 6750fac04a33847862ab7bfb19145f6f91207be6 (patch) | |
tree | 4ef07665d11f55d011c0cc9ea4b74d03390a5bdb /library/cpp/yt/small_containers | |
parent | eb4b8b8ee0d18f168ae14f4d88a6efe2498e0f78 (diff) | |
download | ydb-6750fac04a33847862ab7bfb19145f6f91207be6.tar.gz |
Restoring authorship annotation for <shakurov@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'library/cpp/yt/small_containers')
-rw-r--r-- | library/cpp/yt/small_containers/compact_flat_map-inl.h | 242 | ||||
-rw-r--r-- | library/cpp/yt/small_containers/compact_flat_map.h | 184 | ||||
-rw-r--r-- | library/cpp/yt/small_containers/compact_set-inl.h | 604 | ||||
-rw-r--r-- | library/cpp/yt/small_containers/compact_set.h | 70 |
4 files changed, 550 insertions, 550 deletions
diff --git a/library/cpp/yt/small_containers/compact_flat_map-inl.h b/library/cpp/yt/small_containers/compact_flat_map-inl.h index 45a4dd1de3..b3ddb14c59 100644 --- a/library/cpp/yt/small_containers/compact_flat_map-inl.h +++ b/library/cpp/yt/small_containers/compact_flat_map-inl.h @@ -1,21 +1,21 @@ #ifndef COMPACT_FLAT_MAP_INL_H_ #error "Direct inclusion of this file is not allowed, include compact_flat_map.h" -// For the sake of sane code completion. +// For the sake of sane code completion. #include "compact_flat_map.h" -#endif - -namespace NYT { - -/////////////////////////////////////////////////////////////////////////////// - -template <class K, class V, unsigned N> -template <class TInputIterator> +#endif + +namespace NYT { + +/////////////////////////////////////////////////////////////////////////////// + +template <class K, class V, unsigned N> +template <class TInputIterator> TCompactFlatMap<K, V, N>::TCompactFlatMap(TInputIterator begin, TInputIterator end) -{ - insert(begin, end); -} - -template <class K, class V, unsigned N> +{ + insert(begin, end); +} + +template <class K, class V, unsigned N> bool TCompactFlatMap<K, V, N>::operator==(const TCompactFlatMap& rhs) const { return Storage_ == rhs.Storage_; @@ -29,73 +29,73 @@ bool TCompactFlatMap<K, V, N>::operator!=(const TCompactFlatMap& rhs) const template <class K, class V, unsigned N> typename TCompactFlatMap<K, V, N>::iterator TCompactFlatMap<K, V, N>::begin() -{ - return Storage_.begin(); -} - -template <class K, class V, unsigned N> +{ + return Storage_.begin(); +} + +template <class K, class V, unsigned N> typename TCompactFlatMap<K, V, N>::const_iterator TCompactFlatMap<K, V, N>::begin() const -{ - return Storage_.begin(); -} - -template <class K, class V, unsigned N> +{ + return Storage_.begin(); +} + +template <class K, class V, unsigned N> typename TCompactFlatMap<K, V, N>::iterator TCompactFlatMap<K, V, N>::end() -{ - return Storage_.end(); -} - -template <class K, class V, unsigned N> +{ + return Storage_.end(); +} + +template <class K, class V, unsigned N> typename TCompactFlatMap<K, V, N>::const_iterator TCompactFlatMap<K, V, N>::end() const -{ - return Storage_.end(); -} - -template <class K, class V, unsigned N> +{ + return Storage_.end(); +} + +template <class K, class V, unsigned N> void TCompactFlatMap<K, V, N>::reserve(size_type n) -{ - Storage_.reserve(n); -} - -template <class K, class V, unsigned N> +{ + Storage_.reserve(n); +} + +template <class K, class V, unsigned N> typename TCompactFlatMap<K, V, N>::size_type TCompactFlatMap<K, V, N>::size() const -{ - return Storage_.size(); -} - -template <class K, class V, unsigned N> +{ + return Storage_.size(); +} + +template <class K, class V, unsigned N> int TCompactFlatMap<K, V, N>::ssize() const -{ - return static_cast<int>(Storage_.size()); -} - -template <class K, class V, unsigned N> +{ + return static_cast<int>(Storage_.size()); +} + +template <class K, class V, unsigned N> bool TCompactFlatMap<K, V, N>::empty() const -{ - return Storage_.empty(); -} - -template <class K, class V, unsigned N> +{ + return Storage_.empty(); +} + +template <class K, class V, unsigned N> void TCompactFlatMap<K, V, N>::clear() -{ - Storage_.clear(); -} - -template <class K, class V, unsigned N> +{ + Storage_.clear(); +} + +template <class K, class V, unsigned N> typename TCompactFlatMap<K, V, N>::iterator TCompactFlatMap<K, V, N>::find(const K& k) -{ - auto [rangeBegin, rangeEnd] = EqualRange(k); - return rangeBegin == rangeEnd ? end() : rangeBegin; -} - -template <class K, class V, unsigned N> +{ + auto [rangeBegin, rangeEnd] = EqualRange(k); + return rangeBegin == rangeEnd ? end() : rangeBegin; +} + +template <class K, class V, unsigned N> typename TCompactFlatMap<K, V, N>::const_iterator TCompactFlatMap<K, V, N>::find(const K& k) const -{ - auto [rangeBegin, rangeEnd] = EqualRange(k); - return rangeBegin == rangeEnd ? end() : rangeBegin; -} - -template <class K, class V, unsigned N> +{ + auto [rangeBegin, rangeEnd] = EqualRange(k); + return rangeBegin == rangeEnd ? end() : rangeBegin; +} + +template <class K, class V, unsigned N> bool TCompactFlatMap<K, V, N>::contains(const K& k) const { return find(k) != end(); @@ -103,26 +103,26 @@ bool TCompactFlatMap<K, V, N>::contains(const K& k) const template <class K, class V, unsigned N> auto TCompactFlatMap<K, V, N>::insert(const value_type& value) -> std::pair<iterator, bool> -{ - auto [rangeBegin, rangeEnd] = EqualRange(value.first); - if (rangeBegin != rangeEnd) { - return {rangeBegin, false}; - } else { +{ + auto [rangeBegin, rangeEnd] = EqualRange(value.first); + if (rangeBegin != rangeEnd) { + return {rangeBegin, false}; + } else { auto it = Storage_.insert(rangeBegin, value); return {it, true}; - } -} - -template <class K, class V, unsigned N> -template <class TInputIterator> + } +} + +template <class K, class V, unsigned N> +template <class TInputIterator> void TCompactFlatMap<K, V, N>::insert(TInputIterator begin, TInputIterator end) -{ - for (auto it = begin; it != end; ++it) { - insert(*it); - } -} - -template <class K, class V, unsigned N> +{ + for (auto it = begin; it != end; ++it) { + insert(*it); + } +} + +template <class K, class V, unsigned N> template <class... TArgs> auto TCompactFlatMap<K, V, N>::emplace(TArgs&&... args) -> std::pair<iterator, bool> { @@ -131,19 +131,19 @@ auto TCompactFlatMap<K, V, N>::emplace(TArgs&&... args) -> std::pair<iterator, b template <class K, class V, unsigned N> V& TCompactFlatMap<K, V, N>::operator[](const K& k) -{ - auto [it, inserted] = insert({k, V()}); - return it->second; -} - -template <class K, class V, unsigned N> +{ + auto [it, inserted] = insert({k, V()}); + return it->second; +} + +template <class K, class V, unsigned N> void TCompactFlatMap<K, V, N>::erase(const K& k) -{ - auto [rangeBegin, rangeEnd] = EqualRange(k); - erase(rangeBegin, rangeEnd); -} - -template <class K, class V, unsigned N> +{ + auto [rangeBegin, rangeEnd] = EqualRange(k); + erase(rangeBegin, rangeEnd); +} + +template <class K, class V, unsigned N> void TCompactFlatMap<K, V, N>::erase(iterator pos) { Storage_.erase(pos); @@ -154,31 +154,31 @@ void TCompactFlatMap<K, V, N>::erase(iterator pos) template <class K, class V, unsigned N> void TCompactFlatMap<K, V, N>::erase(iterator b, iterator e) -{ - Storage_.erase(b, e); +{ + Storage_.erase(b, e); // Try to keep the storage inline. This is why erase doesn't return an iterator. Storage_.shrink_to_small(); -} - -template <class K, class V, unsigned N> +} + +template <class K, class V, unsigned N> std::pair<typename TCompactFlatMap<K, V, N>::iterator, typename TCompactFlatMap<K, V, N>::iterator> TCompactFlatMap<K, V, N>::EqualRange(const K& k) -{ - auto result = std::equal_range(Storage_.begin(), Storage_.end(), k, TKeyComparer()); - YT_ASSERT(std::distance(result.first, result.second) <= 1); - return result; -} - -template <class K, class V, unsigned N> +{ + auto result = std::equal_range(Storage_.begin(), Storage_.end(), k, TKeyComparer()); + YT_ASSERT(std::distance(result.first, result.second) <= 1); + return result; +} + +template <class K, class V, unsigned N> std::pair<typename TCompactFlatMap<K, V, N>::const_iterator, typename TCompactFlatMap<K, V, N>::const_iterator> TCompactFlatMap<K, V, N>::EqualRange(const K& k) const -{ - auto result = std::equal_range(Storage_.begin(), Storage_.end(), k, TKeyComparer()); - YT_ASSERT(std::distance(result.first, result.second) <= 1); - return result; -} - -//////////////////////////////////////////////////////////////////////////////// - -} // namespace NYT +{ + auto result = std::equal_range(Storage_.begin(), Storage_.end(), k, TKeyComparer()); + YT_ASSERT(std::distance(result.first, result.second) <= 1); + return result; +} + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace NYT diff --git a/library/cpp/yt/small_containers/compact_flat_map.h b/library/cpp/yt/small_containers/compact_flat_map.h index 13bdc0e9da..1cd1bfab63 100644 --- a/library/cpp/yt/small_containers/compact_flat_map.h +++ b/library/cpp/yt/small_containers/compact_flat_map.h @@ -1,109 +1,109 @@ -#pragma once - +#pragma once + #include "compact_vector.h" - -namespace NYT { - -/////////////////////////////////////////////////////////////////////////////// - + +namespace NYT { + +/////////////////////////////////////////////////////////////////////////////// + //! A flat map implementation over TCompactVector that tries to keep data inline. -/*! - * Similarly to SmallSet, this is implemented via binary search over a sorted - * vector. Unlike SmallSet, however, this one never falls back to std::map (or - * set) for larger sizes. This means that the flat map is only useful - * - at small sizes, when there's absolutely no chance of it getting big, or - * - when it's filled once and is then only read from. - * - * In return, the flat map provides - * - a smaller size overhead and - * - a guarantee that if data fits into inline storage, it goes there. - * - * Because of the latter, one should be very careful with iterators: virtually - * any call to insert or erase may potentially invalidate all iterators. - */ -template <class K, class V, unsigned N> +/*! + * Similarly to SmallSet, this is implemented via binary search over a sorted + * vector. Unlike SmallSet, however, this one never falls back to std::map (or + * set) for larger sizes. This means that the flat map is only useful + * - at small sizes, when there's absolutely no chance of it getting big, or + * - when it's filled once and is then only read from. + * + * In return, the flat map provides + * - a smaller size overhead and + * - a guarantee that if data fits into inline storage, it goes there. + * + * Because of the latter, one should be very careful with iterators: virtually + * any call to insert or erase may potentially invalidate all iterators. + */ +template <class K, class V, unsigned N> class TCompactFlatMap -{ -public: +{ +public: // NB: can't make this pair<const K, V> as TCompactVector requires its type - // parameter to be copy-assignable. - using value_type = std::pair<K, V>; + // parameter to be copy-assignable. + using value_type = std::pair<K, V>; using key_type = K; using mapped_type = V; - -private: + +private: using TStorage = TCompactVector<value_type, N>; - - struct TKeyComparer - { - bool operator()(const K& lhs, const value_type& rhs) - { - return lhs < rhs.first; - } - - bool operator()(const value_type& lhs, const K& rhs) - { - return lhs.first < rhs; - } - }; - -public: - using iterator = typename TStorage::iterator; - using const_iterator = typename TStorage::const_iterator; - using size_type = size_t; - + + struct TKeyComparer + { + bool operator()(const K& lhs, const value_type& rhs) + { + return lhs < rhs.first; + } + + bool operator()(const value_type& lhs, const K& rhs) + { + return lhs.first < rhs; + } + }; + +public: + using iterator = typename TStorage::iterator; + using const_iterator = typename TStorage::const_iterator; + using size_type = size_t; + TCompactFlatMap() = default; - - template <class TInputIterator> + + template <class TInputIterator> TCompactFlatMap(TInputIterator begin, TInputIterator end); - + bool operator==(const TCompactFlatMap& rhs) const; bool operator!=(const TCompactFlatMap& rhs) const; - - iterator begin(); - const_iterator begin() const; - - iterator end(); - const_iterator end() const; - - void reserve(size_type n); - - size_type size() const; - int ssize() const; - - bool empty() const; - void clear(); - - iterator find(const K& k); - const_iterator find(const K& k) const; - - bool contains(const K& k) const; - - std::pair<iterator, bool> insert(const value_type& value); - - template <class TInputIterator> - void insert(TInputIterator begin, TInputIterator end); - + + iterator begin(); + const_iterator begin() const; + + iterator end(); + const_iterator end() const; + + void reserve(size_type n); + + size_type size() const; + int ssize() const; + + bool empty() const; + void clear(); + + iterator find(const K& k); + const_iterator find(const K& k) const; + + bool contains(const K& k) const; + + std::pair<iterator, bool> insert(const value_type& value); + + template <class TInputIterator> + void insert(TInputIterator begin, TInputIterator end); + template <class... TArgs> std::pair<iterator, bool> emplace(TArgs&&... args); - V& operator[](const K& k); - - void erase(const K& k); - void erase(iterator pos); - void erase(iterator b, iterator e); - -private: - std::pair<iterator, iterator> EqualRange(const K& k); - std::pair<const_iterator, const_iterator> EqualRange(const K& k) const; - - TStorage Storage_; -}; - -//////////////////////////////////////////////////////////////////////////////// - -} // namespace NYT - + V& operator[](const K& k); + + void erase(const K& k); + void erase(iterator pos); + void erase(iterator b, iterator e); + +private: + std::pair<iterator, iterator> EqualRange(const K& k); + std::pair<const_iterator, const_iterator> EqualRange(const K& k) const; + + TStorage Storage_; +}; + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace NYT + #define COMPACT_FLAT_MAP_INL_H_ #include "compact_flat_map-inl.h" #undef COMPACT_FLAT_MAP_INL_H_ diff --git a/library/cpp/yt/small_containers/compact_set-inl.h b/library/cpp/yt/small_containers/compact_set-inl.h index 75b8600175..88180f606c 100644 --- a/library/cpp/yt/small_containers/compact_set-inl.h +++ b/library/cpp/yt/small_containers/compact_set-inl.h @@ -1,322 +1,322 @@ #ifndef COMPACT_SET_INL_H_ #error "Direct inclusion of this file is not allowed, include compact_set.h" -// For the sake of sane code completion. +// For the sake of sane code completion. #include "compact_set.h" -#endif - -namespace NYT { - -//////////////////////////////////////////////////////////////////////////////// - -template <typename T, unsigned N, typename C> +#endif + +namespace NYT { + +//////////////////////////////////////////////////////////////////////////////// + +template <typename T, unsigned N, typename C> class TCompactSet<T, N, C>::const_iterator -{ -private: +{ +private: friend class TCompactSet<T, N, C>; - - union - { - TVectorConstIterator VIter; - TSetConstIterator SIter; - }; - - bool Small; - - const_iterator(TVectorConstIterator it) - : VIter(it) - , Small(true) - { } - - const_iterator(TSetConstIterator it) - : SIter(it) - , Small(false) - { } - - template <class TOther> - void ConstructFrom(TOther&& rhs) - { + + union + { + TVectorConstIterator VIter; + TSetConstIterator SIter; + }; + + bool Small; + + const_iterator(TVectorConstIterator it) + : VIter(it) + , Small(true) + { } + + const_iterator(TSetConstIterator it) + : SIter(it) + , Small(false) + { } + + template <class TOther> + void ConstructFrom(TOther&& rhs) + { Y_VERIFY_DEBUG(Small == rhs.Small); - - if (Small) { - new (&VIter)TVectorConstIterator(std::forward<TOther>(rhs).VIter); - } else { - new (&SIter)TSetConstIterator(std::forward<TOther>(rhs).SIter); - } - } - - template <class TOther> - const_iterator& AssignFrom(TOther&& rhs) - { - if (this == &rhs) { - return *this; - } - - if (Small && rhs.Small) { - VIter = std::forward<TOther>(rhs).VIter; - } else if (!Small && !rhs.Small) { - SIter = std::forward<TOther>(rhs).SIter; - } else { - if (Small) { - VIter.~TVectorConstIterator(); - } else { - SIter.~TSetConstIterator(); - } - - if (rhs.Small) { - new (&VIter)TVectorConstIterator(std::forward<TOther>(rhs).VIter); - } else { - new (&SIter)TSetConstIterator(std::forward<TOther>(rhs).SIter); - } - } - - Small = rhs.Small; - - return *this; - } - -public: - static_assert(std::is_same_v< - typename std::iterator_traits<TVectorConstIterator>::difference_type, - typename std::iterator_traits<TSetConstIterator>::difference_type>); - static_assert(std::is_same_v< - typename std::iterator_traits<TVectorConstIterator>::value_type, - typename std::iterator_traits<TSetConstIterator>::value_type>); - static_assert(std::is_same_v< - typename std::iterator_traits<TVectorConstIterator>::pointer, - typename std::iterator_traits<TSetConstIterator>::pointer>); - static_assert(std::is_same_v< - typename std::iterator_traits<TVectorConstIterator>::reference, - typename std::iterator_traits<TSetConstIterator>::reference>); - - using difference_type = typename std::iterator_traits<TVectorConstIterator>::difference_type; - using value_type = typename std::iterator_traits<TVectorConstIterator>::value_type; - using pointer = typename std::iterator_traits<TVectorConstIterator>::pointer; - using reference = typename std::iterator_traits<TVectorConstIterator>::reference; - using iterator_category = std::bidirectional_iterator_tag; - - const_iterator(const const_iterator& rhs) - : Small(rhs.Small) - { - ConstructFrom(rhs); - } - - const_iterator(const_iterator&& rhs) - : Small(rhs.Small) - { - ConstructFrom(std::move(rhs)); - } - - ~const_iterator() - { - if (Small) { - VIter.~TVectorConstIterator(); - } else { - SIter.~TSetConstIterator(); - } - } - - const_iterator& operator=(const const_iterator& rhs) - { - return AssignFrom(rhs); - } - - const_iterator& operator=(const_iterator&& rhs) - { - return AssignFrom(std::move(rhs)); - } - - const_iterator& operator++() - { - if (Small) { - ++VIter; - } else { - ++SIter; - } - - return *this; - } - - const_iterator operator++(int) - { - auto result = *this; - - if (Small) { - ++VIter; - } else { - ++SIter; - } - - return result; - } - - const_iterator& operator--() - { - if (Small) { - --VIter; - } else { - --SIter; - } - - return *this; - } - - const_iterator operator--(int) - { - auto result = *this; - - if (Small) { - --VIter; - } else { - --SIter; - } - - return result; - } - - bool operator==(const const_iterator& rhs) const - { - if (Small != rhs.Small) { - return false; - } - - return Small ? (VIter == rhs.VIter) : (SIter == rhs.SIter); - } - - bool operator!=(const const_iterator& rhs) const - { - return !(*this == rhs); - } - - const T& operator*() const - { - return Small ? *VIter : *SIter; - } - - const T* operator->() const - { - return &operator*(); - } -}; - -//////////////////////////////////////////////////////////////////////////////// - -template <typename T, unsigned N, typename C> + + if (Small) { + new (&VIter)TVectorConstIterator(std::forward<TOther>(rhs).VIter); + } else { + new (&SIter)TSetConstIterator(std::forward<TOther>(rhs).SIter); + } + } + + template <class TOther> + const_iterator& AssignFrom(TOther&& rhs) + { + if (this == &rhs) { + return *this; + } + + if (Small && rhs.Small) { + VIter = std::forward<TOther>(rhs).VIter; + } else if (!Small && !rhs.Small) { + SIter = std::forward<TOther>(rhs).SIter; + } else { + if (Small) { + VIter.~TVectorConstIterator(); + } else { + SIter.~TSetConstIterator(); + } + + if (rhs.Small) { + new (&VIter)TVectorConstIterator(std::forward<TOther>(rhs).VIter); + } else { + new (&SIter)TSetConstIterator(std::forward<TOther>(rhs).SIter); + } + } + + Small = rhs.Small; + + return *this; + } + +public: + static_assert(std::is_same_v< + typename std::iterator_traits<TVectorConstIterator>::difference_type, + typename std::iterator_traits<TSetConstIterator>::difference_type>); + static_assert(std::is_same_v< + typename std::iterator_traits<TVectorConstIterator>::value_type, + typename std::iterator_traits<TSetConstIterator>::value_type>); + static_assert(std::is_same_v< + typename std::iterator_traits<TVectorConstIterator>::pointer, + typename std::iterator_traits<TSetConstIterator>::pointer>); + static_assert(std::is_same_v< + typename std::iterator_traits<TVectorConstIterator>::reference, + typename std::iterator_traits<TSetConstIterator>::reference>); + + using difference_type = typename std::iterator_traits<TVectorConstIterator>::difference_type; + using value_type = typename std::iterator_traits<TVectorConstIterator>::value_type; + using pointer = typename std::iterator_traits<TVectorConstIterator>::pointer; + using reference = typename std::iterator_traits<TVectorConstIterator>::reference; + using iterator_category = std::bidirectional_iterator_tag; + + const_iterator(const const_iterator& rhs) + : Small(rhs.Small) + { + ConstructFrom(rhs); + } + + const_iterator(const_iterator&& rhs) + : Small(rhs.Small) + { + ConstructFrom(std::move(rhs)); + } + + ~const_iterator() + { + if (Small) { + VIter.~TVectorConstIterator(); + } else { + SIter.~TSetConstIterator(); + } + } + + const_iterator& operator=(const const_iterator& rhs) + { + return AssignFrom(rhs); + } + + const_iterator& operator=(const_iterator&& rhs) + { + return AssignFrom(std::move(rhs)); + } + + const_iterator& operator++() + { + if (Small) { + ++VIter; + } else { + ++SIter; + } + + return *this; + } + + const_iterator operator++(int) + { + auto result = *this; + + if (Small) { + ++VIter; + } else { + ++SIter; + } + + return result; + } + + const_iterator& operator--() + { + if (Small) { + --VIter; + } else { + --SIter; + } + + return *this; + } + + const_iterator operator--(int) + { + auto result = *this; + + if (Small) { + --VIter; + } else { + --SIter; + } + + return result; + } + + bool operator==(const const_iterator& rhs) const + { + if (Small != rhs.Small) { + return false; + } + + return Small ? (VIter == rhs.VIter) : (SIter == rhs.SIter); + } + + bool operator!=(const const_iterator& rhs) const + { + return !(*this == rhs); + } + + const T& operator*() const + { + return Small ? *VIter : *SIter; + } + + const T* operator->() const + { + return &operator*(); + } +}; + +//////////////////////////////////////////////////////////////////////////////// + +template <typename T, unsigned N, typename C> bool TCompactSet<T, N, C>::empty() const -{ - return Vector.empty() && Set.empty(); -} - -template <typename T, unsigned N, typename C> +{ + return Vector.empty() && Set.empty(); +} + +template <typename T, unsigned N, typename C> typename TCompactSet<T, N, C>::size_type TCompactSet<T, N, C>::size() const -{ - return IsSmall() ? Vector.size() : Set.size(); -} - -template <typename T, unsigned N, typename C> +{ + return IsSmall() ? Vector.size() : Set.size(); +} + +template <typename T, unsigned N, typename C> const T& TCompactSet<T, N, C>::front() const -{ - return IsSmall() ? Vector.front() : *Set.begin(); -} - - -template <typename T, unsigned N, typename C> +{ + return IsSmall() ? Vector.front() : *Set.begin(); +} + + +template <typename T, unsigned N, typename C> typename TCompactSet<T, N, C>::size_type TCompactSet<T, N, C>::count(const T& v) const -{ - if (IsSmall()) { - return std::binary_search(Vector.begin(), Vector.end(), v, C()) ? 1 : 0; - } else { - return Set.count(v); - } -} - -template <typename T, unsigned N, typename C> +{ + if (IsSmall()) { + return std::binary_search(Vector.begin(), Vector.end(), v, C()) ? 1 : 0; + } else { + return Set.count(v); + } +} + +template <typename T, unsigned N, typename C> std::pair<typename TCompactSet<T, N, C>::const_iterator, bool> TCompactSet<T, N, C>::insert(const T& v) -{ - if (!IsSmall()) { - auto [it, inserted] = Set.insert(v); - return {const_iterator(std::move(it)), inserted}; - } - - auto it = std::lower_bound(Vector.begin(), Vector.end(), v, C()); - if (it != Vector.end() && !C()(v, *it)) { - return {const_iterator(std::move(it)), false}; // Don't reinsert if it already exists. - } - - if (Vector.size() < N) { - auto newIt = Vector.insert(it, v); - return {const_iterator(std::move(newIt)), true}; - } - - Set.insert(Vector.begin(), Vector.end()); - Vector.clear(); - - auto [newIt, inserted] = Set.insert(v); +{ + if (!IsSmall()) { + auto [it, inserted] = Set.insert(v); + return {const_iterator(std::move(it)), inserted}; + } + + auto it = std::lower_bound(Vector.begin(), Vector.end(), v, C()); + if (it != Vector.end() && !C()(v, *it)) { + return {const_iterator(std::move(it)), false}; // Don't reinsert if it already exists. + } + + if (Vector.size() < N) { + auto newIt = Vector.insert(it, v); + return {const_iterator(std::move(newIt)), true}; + } + + Set.insert(Vector.begin(), Vector.end()); + Vector.clear(); + + auto [newIt, inserted] = Set.insert(v); Y_VERIFY_DEBUG(inserted); - return {const_iterator(std::move(newIt)), true}; -} - -template <typename T, unsigned N, typename C> -template <typename TIter> + return {const_iterator(std::move(newIt)), true}; +} + +template <typename T, unsigned N, typename C> +template <typename TIter> void TCompactSet<T, N, C>::insert(TIter i, TIter e) -{ - for (; i != e; ++i) { - insert(*i); - } -} - -template <typename T, unsigned N, typename C> +{ + for (; i != e; ++i) { + insert(*i); + } +} + +template <typename T, unsigned N, typename C> bool TCompactSet<T, N, C>::erase(const T& v) -{ - if (!IsSmall()) { - return Set.erase(v); - } - - auto [rangeBegin, rangeEnd] = std::equal_range(Vector.begin(), Vector.end(), v, C()); - if (rangeBegin != rangeEnd) { - Vector.erase(rangeBegin, rangeEnd); - return true; - } else { - return false; - } -} - -template <typename T, unsigned N, typename C> +{ + if (!IsSmall()) { + return Set.erase(v); + } + + auto [rangeBegin, rangeEnd] = std::equal_range(Vector.begin(), Vector.end(), v, C()); + if (rangeBegin != rangeEnd) { + Vector.erase(rangeBegin, rangeEnd); + return true; + } else { + return false; + } +} + +template <typename T, unsigned N, typename C> void TCompactSet<T, N, C>::clear() -{ - Vector.clear(); - Set.clear(); -} - -template <typename T, unsigned N, typename C> +{ + Vector.clear(); + Set.clear(); +} + +template <typename T, unsigned N, typename C> typename TCompactSet<T, N, C>::const_iterator TCompactSet<T, N, C>::begin() const -{ - return IsSmall() ? const_iterator(Vector.begin()) : const_iterator(Set.begin()); -} - -template <typename T, unsigned N, typename C> +{ + return IsSmall() ? const_iterator(Vector.begin()) : const_iterator(Set.begin()); +} + +template <typename T, unsigned N, typename C> typename TCompactSet<T, N, C>::const_iterator TCompactSet<T, N, C>::cbegin() const -{ - return begin(); -} - -template <typename T, unsigned N, typename C> +{ + return begin(); +} + +template <typename T, unsigned N, typename C> typename TCompactSet<T, N, C>::const_iterator TCompactSet<T, N, C>::end() const -{ - return IsSmall() ? const_iterator(Vector.end()) : const_iterator(Set.end()); -} - -template <typename T, unsigned N, typename C> +{ + return IsSmall() ? const_iterator(Vector.end()) : const_iterator(Set.end()); +} + +template <typename T, unsigned N, typename C> typename TCompactSet<T, N, C>::const_iterator TCompactSet<T, N, C>::cend() const -{ - return end(); -} - -template <typename T, unsigned N, typename C> +{ + return end(); +} + +template <typename T, unsigned N, typename C> bool TCompactSet<T, N, C>::IsSmall() const -{ - return Set.empty(); -} - -//////////////////////////////////////////////////////////////////////////////// - -} // namespace NYT +{ + return Set.empty(); +} + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace NYT diff --git a/library/cpp/yt/small_containers/compact_set.h b/library/cpp/yt/small_containers/compact_set.h index 2ca8713ea7..f937114cd5 100644 --- a/library/cpp/yt/small_containers/compact_set.h +++ b/library/cpp/yt/small_containers/compact_set.h @@ -17,10 +17,10 @@ #include <util/system/yassert.h> -#include <cstddef> -#include <iterator> +#include <cstddef> +#include <iterator> #include <set> -#include <type_traits> +#include <type_traits> namespace NYT { @@ -29,58 +29,58 @@ namespace NYT { /// maintained with no mallocs. If the set gets large, we expand to using an /// std::set to maintain reasonable lookup times. /// -/// Note that any modification of the set may invalidate *all* iterators. -template <typename T, unsigned N, typename C = std::less<T>> +/// Note that any modification of the set may invalidate *all* iterators. +template <typename T, unsigned N, typename C = std::less<T>> class TCompactSet { -private: +private: /// Use a CompactVector to hold the elements here (even though it will never - /// reach its 'large' stage) to avoid calling the default ctors of elements - /// we will never use. + /// reach its 'large' stage) to avoid calling the default ctors of elements + /// we will never use. TCompactVector<T, N> Vector; - std::set<T, C> Set; - - using TSetConstIterator = typename std::set<T, C>::const_iterator; + std::set<T, C> Set; + + using TSetConstIterator = typename std::set<T, C>::const_iterator; using TVectorConstIterator = typename TCompactVector<T, N>::const_iterator; - + public: - class const_iterator; - using size_type = std::size_t; + class const_iterator; + using size_type = std::size_t; TCompactSet() {} - [[nodiscard]] bool empty() const; - - size_type size() const; + [[nodiscard]] bool empty() const; - const T& front() const; + size_type size() const; - /// count - Return true if the element is in the set. - size_type count(const T& v) const; + const T& front() const; - /// insert - Insert an element into the set if it isn't already there. - std::pair<const_iterator, bool> insert(const T& v); + /// count - Return true if the element is in the set. + size_type count(const T& v) const; - template <typename TIter> - void insert(TIter i, TIter e); + /// insert - Insert an element into the set if it isn't already there. + std::pair<const_iterator, bool> insert(const T& v); - bool erase(const T& v); + template <typename TIter> + void insert(TIter i, TIter e); - void clear(); - - const_iterator begin() const; - const_iterator cbegin() const; - - const_iterator end() const; - const_iterator cend() const; + bool erase(const T& v); + void clear(); + + const_iterator begin() const; + const_iterator cbegin() const; + + const_iterator end() const; + const_iterator cend() const; + private: - bool IsSmall() const; + bool IsSmall() const; }; } // namespace NYT - + #define COMPACT_SET_INL_H_ #include "compact_set-inl.h" #undef COMPACT_SET_INL_H_ - + |