diff --git a/stl/inc/flat_set b/stl/inc/flat_set index 18fb0f2553b..d39368763f7 100644 --- a/stl/inc/flat_set +++ b/stl/inc/flat_set @@ -172,29 +172,29 @@ public: } _NODISCARD reverse_iterator rbegin() noexcept { - return _Get_cont().rbegin(); + return reverse_iterator(end()); } _NODISCARD const_reverse_iterator rbegin() const noexcept { - return _Get_cont().rbegin(); + return const_reverse_iterator(end()); } _NODISCARD reverse_iterator rend() noexcept { - return _Get_cont().rend(); + return reverse_iterator(begin()); } _NODISCARD const_reverse_iterator rend() const noexcept { - return _Get_cont().rend(); + return const_reverse_iterator(begin()); } _NODISCARD const_iterator cbegin() const noexcept { - return _Get_cont().cbegin(); + return begin(); } _NODISCARD const_iterator cend() const noexcept { - return _Get_cont().cend(); + return end(); } _NODISCARD const_reverse_iterator crbegin() const noexcept { - return _Get_cont().crbegin(); + return rbegin(); } _NODISCARD const_reverse_iterator crend() const noexcept { - return _Get_cont().crend(); + return rend(); } // capacity @@ -339,8 +339,12 @@ public: } _NODISCARD size_type count(const _Kty& _Val) const { - const auto [_First, _Last] = equal_range(_Val); - return static_cast(_Last - _First); + if constexpr (!_Multi) { + return contains(_Val); + } else { + const auto [_First, _Last] = equal_range(_Val); + return static_cast(_Last - _First); + } } template requires _Keylt_transparent @@ -350,66 +354,66 @@ public: } _NODISCARD bool contains(const _Kty& _Val) const { - return _STD binary_search(cbegin(), cend(), _Val, _Get_comp()); + return _STD binary_search(cbegin(), cend(), _Val, _Get_comp_v()); } template requires _Keylt_transparent _NODISCARD bool contains(const _Other& _Val) const { - return _STD binary_search(cbegin(), cend(), _Val, _Get_comp()); + return _STD binary_search(cbegin(), cend(), _Val, _Get_comp_v()); } _NODISCARD iterator lower_bound(const _Kty& _Val) { - return _STD lower_bound(begin(), end(), _Val, _Get_comp()); + return _STD lower_bound(begin(), end(), _Val, _Get_comp_v()); } _NODISCARD const_iterator lower_bound(const _Kty& _Val) const { - return _STD lower_bound(cbegin(), cend(), _Val, _Get_comp()); + return _STD lower_bound(cbegin(), cend(), _Val, _Get_comp_v()); } template requires _Keylt_transparent _NODISCARD iterator lower_bound(const _Other& _Val) { - return _STD lower_bound(begin(), end(), _Val, _Get_comp()); + return _STD lower_bound(begin(), end(), _Val, _Get_comp_v()); } template requires _Keylt_transparent _NODISCARD const_iterator lower_bound(const _Other& _Val) const { - return _STD lower_bound(cbegin(), cend(), _Val, _Get_comp()); + return _STD lower_bound(cbegin(), cend(), _Val, _Get_comp_v()); } _NODISCARD iterator upper_bound(const _Kty& _Val) { - return _STD upper_bound(begin(), end(), _Val, _Get_comp()); + return _STD upper_bound(begin(), end(), _Val, _Get_comp_v()); } _NODISCARD const_iterator upper_bound(const _Kty& _Val) const { - return _STD upper_bound(cbegin(), cend(), _Val, _Get_comp()); + return _STD upper_bound(cbegin(), cend(), _Val, _Get_comp_v()); } template requires _Keylt_transparent _NODISCARD iterator upper_bound(const _Other& _Val) { - return _STD upper_bound(begin(), end(), _Val, _Get_comp()); + return _STD upper_bound(begin(), end(), _Val, _Get_comp_v()); } template requires _Keylt_transparent _NODISCARD const_iterator upper_bound(const _Other& _Val) const { - return _STD upper_bound(cbegin(), cend(), _Val, _Get_comp()); + return _STD upper_bound(cbegin(), cend(), _Val, _Get_comp_v()); } _NODISCARD pair equal_range(const _Kty& _Val) { - return _STD equal_range(begin(), end(), _Val, _Get_comp()); + return _STD equal_range(begin(), end(), _Val, _Get_comp_v()); } _NODISCARD pair equal_range(const _Kty& _Val) const { - return _STD equal_range(cbegin(), cend(), _Val, _Get_comp()); + return _STD equal_range(cbegin(), cend(), _Val, _Get_comp_v()); } template requires _Keylt_transparent _NODISCARD pair equal_range(const _Other& _Val) { - return _STD equal_range(begin(), end(), _Val, _Get_comp()); + return _STD equal_range(begin(), end(), _Val, _Get_comp_v()); } template requires _Keylt_transparent _NODISCARD pair equal_range(const _Other& _Val) const { - return _STD equal_range(cbegin(), cend(), _Val, _Get_comp()); + return _STD equal_range(cbegin(), cend(), _Val, _Get_comp_v()); } _NODISCARD friend bool operator==(const _Deriv& _Lhs, const _Deriv& _Rhs) { @@ -427,7 +431,7 @@ public: private: void _Assert_after_sorted_input() const { - _STL_ASSERT(_STD is_sorted(cbegin(), cend(), _Get_comp()), "Input was not sorted!"); + _STL_ASSERT(_STD is_sorted(cbegin(), cend(), _Get_comp_v()), "Input was not sorted!"); if constexpr (!_Multi) { _STL_ASSERT(_Is_unique(), "Input was sorted but not unique!"); } @@ -449,7 +453,6 @@ private: bool _Check_where(const const_iterator _Where, const _Kty& _Val) const { // check that _Val can be inserted before _Where - const key_compare& _Compare = _Get_comp(); if constexpr (_Multi) { // check that _Where is the upper_bound for _Val // equivalent to checking *(_Where-1) <= _Val < *_Where @@ -472,7 +475,7 @@ private: } else { const iterator _End = end(); const iterator _Where = lower_bound(_Val); - if (_Where != _End && _Keys_equal(*_Where, _Val)) { + if (_Where != _End && !_Compare(_Val, *_Where)) { return pair{_Where, false}; } @@ -491,7 +494,7 @@ private: template iterator _Emplace_hint(const_iterator _Where, _Ty&& _Val) { _Container& _Cont = _Get_cont(); - const key_compare& _Compare = _Get_comp(); + auto _Comp = _Get_comp_v(); const const_iterator _Begin = cbegin(); const const_iterator _End = cend(); @@ -503,11 +506,11 @@ private: // _Val >= *(_Where-1) ~ upper_bound is _Where } else { // _Val < *(_Where-1) ~ upper_bound is in [_Begin,_Where-1] - _Where = _STD upper_bound(_Begin, _Where - 1, _Val, _Compare); + _Where = _STD upper_bound(_Begin, _Where - 1, _Val, _Comp); } } else { // _Val >= *_Where ~ upper_bound is in [_Where+1,_End] - _Where = _STD upper_bound(_Where + 1, _End, _Val, _Compare); + _Where = _STD upper_bound(_Where + 1, _End, _Val, _Comp); } } else { // look for the lower_bound for flat_set @@ -517,11 +520,11 @@ private: // _Val > *(_Where-1) ~ lower_bound is _Where } else { // _Val <= *(_Where-1) ~ lower_bound is in [_Begin,_Where-1] - _Where = _STD lower_bound(_Begin, _Where - 1, _Val, _Compare); + _Where = _STD lower_bound(_Begin, _Where - 1, _Val, _Comp); } } else { // _Val > *_Where ~ lower_bound is in [_Where+1,_End] - _Where = _STD lower_bound(_Where + 1, _End, _Val, _Compare); + _Where = _STD lower_bound(_Where + 1, _End, _Val, _Comp); } } @@ -530,7 +533,7 @@ private: _STL_INTERNAL_CHECK(_Check_where(_Where, _Val)); return _Cont.emplace(_Where, _STD forward<_Ty>(_Val)); } else { - if (_Where != _End && _Keys_equal(_Val, *_Where)) { + if (_Where != _End && !_Compare(_Val, *_Where)) { return _Cont.begin() + (_Where - _Begin); } @@ -556,46 +559,51 @@ private: } template - requires _Keylt_transparent || is_same_v<_Ty, _Kty> size_type _Erase(const _Ty& _Val) { - const auto [_First, _Last] = equal_range(_Val); + _STL_INTERNAL_STATIC_ASSERT(_Keylt_transparent || is_same_v<_Ty, _Kty>); - const auto _Removed = static_cast(_Last - _First); - _Get_cont().erase(_First, _Last); - return _Removed; + if constexpr (!_Multi && is_same_v<_Ty, _Kty>) { + const iterator _Where = lower_bound(_Val); + if (_Where != end() && !_Compare(_Val, *_Where)) { + _Get_cont().erase(_Where); + return 1; + } + return 0; + } else { + const auto [_First, _Last] = equal_range(_Val); + + const auto _Removed = static_cast(_Last - _First); + _Get_cont().erase(_First, _Last); + return _Removed; + } } - template - requires _Keylt_transparent || is_same_v<_Other, _Kty> - _NODISCARD iterator _Find(const _Other& _Val) { + template + _NODISCARD iterator _Find(const _Ty& _Val) { + _STL_INTERNAL_STATIC_ASSERT(_Keylt_transparent || is_same_v<_Ty, _Kty>); + const iterator _End = end(); const iterator _Where = lower_bound(_Val); - if (_Where != _End && _Keys_equal(*_Where, _Val)) { + if (_Where != _End && !_Compare(_Val, *_Where)) { return _Where; } else { return _End; } } - template - requires _Keylt_transparent || is_same_v<_Other, _Kty> - _NODISCARD const_iterator _Find(const _Other& _Val) const { + template + _NODISCARD const_iterator _Find(const _Ty& _Val) const { + _STL_INTERNAL_STATIC_ASSERT(_Keylt_transparent || is_same_v<_Ty, _Kty>); + const const_iterator _End = cend(); const const_iterator _Where = lower_bound(_Val); - if (_Where != _End && _Keys_equal(*_Where, _Val)) { + if (_Where != _End && !_Compare(_Val, *_Where)) { return _Where; } else { return _End; } } - template - requires _Keylt_transparent || (is_same_v<_Kty, _Lhty> && is_same_v<_Lhty, _Rhty>) - _NODISCARD bool _Keys_equal(const _Lhty& _Lhs, const _Rhty& _Rhs) const { - const key_compare& _Compare = _Get_comp(); - return !_Compare(_Lhs, _Rhs) && !_Compare(_Rhs, _Lhs); - } - void _Erase_dupes_if_needed() { if constexpr (!_Multi) { const iterator _End = end(); @@ -609,19 +617,20 @@ private: template void _Restore_invariants_after_insert(const size_type _Old_size) { - const key_compare& _Compare = _Get_comp(); - const iterator _Old_end = begin() + static_cast(_Old_size); - const iterator _New_end = end(); + auto _Comp = _Get_comp_v(); + const iterator _Begin = begin(); + const iterator _Old_end = _Begin + static_cast(_Old_size); + const iterator _New_end = end(); if constexpr (!_Presorted) { - _STD sort(_Old_end, _New_end, _Compare); + _STD sort(_Old_end, _New_end, _Comp); } else { - _STL_ASSERT(_STD is_sorted(_Old_end, _New_end, _Compare), "Input was not sorted!"); + _STL_ASSERT(_STD is_sorted(_Old_end, _New_end, _Comp), "Input was not sorted!"); } - _STD inplace_merge(begin(), _Old_end, _New_end, _Compare); + _STD inplace_merge(_Begin, _Old_end, _New_end, _Comp); - _STL_INTERNAL_CHECK(_STD is_sorted(begin(), end(), _Compare)); + _STL_INTERNAL_CHECK(_STD is_sorted(_Begin, _New_end, _Comp)); _Erase_dupes_if_needed(); } @@ -635,17 +644,33 @@ private: } // O(N) if already sorted. - const key_compare& _Compare = _Get_comp(); - const iterator _Begin_unsorted = _STD is_sorted_until(_Begin, _End, _Compare); + auto _Comp = _Get_comp_v(); + const iterator _Begin_unsorted = _STD is_sorted_until(_Begin, _End, _Comp); - _STD sort(_Begin_unsorted, _End, _Compare); - _STD inplace_merge(_Begin, _Begin_unsorted, _End, _Compare); + _STD sort(_Begin_unsorted, _End, _Comp); + _STD inplace_merge(_Begin, _Begin_unsorted, _End, _Comp); - _STL_INTERNAL_CHECK(_STD is_sorted(_Begin, _End, _Compare)); + _STL_INTERNAL_CHECK(_STD is_sorted(_Begin, _End, _Comp)); _Erase_dupes_if_needed(); } + template + _NODISCARD bool _Compare(const _Lty& _Lhs, const _Rty& _Rhs) const + noexcept(noexcept(_DEBUG_LT_PRED(_My_pair._Get_first(), _Lhs, _Rhs))) { + _STL_INTERNAL_STATIC_ASSERT(_Keylt_transparent || (is_same_v<_Kty, _Lty> && is_same_v<_Kty, _Rty>) ); + + return _DEBUG_LT_PRED(_My_pair._Get_first(), _Lhs, _Rhs); + } + + template + _NODISCARD bool _Keys_equal(const _Lty& _Lhs, const _Rty& _Rhs) const + noexcept(noexcept(!_Compare(_Lhs, _Rhs) && !_Compare(_Rhs, _Lhs))) { + _STL_INTERNAL_STATIC_ASSERT(_Keylt_transparent || (is_same_v<_Kty, _Lty> && is_same_v<_Kty, _Rty>) ); + + return !_Compare(_Lhs, _Rhs) && !_Compare(_Rhs, _Lhs); + } + _NODISCARD const _Container& _Get_cont() const noexcept { return _My_pair._Myval2; } @@ -662,6 +687,10 @@ private: return _My_pair._Get_first(); } + _NODISCARD auto _Get_comp_v() const noexcept { + return _STD _Pass_fn(_My_pair._Get_first()); + } + _Compressed_pair _My_pair; };