diff --git a/stl/inc/flat_map b/stl/inc/flat_map index d5d8da367e8..a8a72666874 100644 --- a/stl/inc/flat_map +++ b/stl/inc/flat_map @@ -335,7 +335,6 @@ public: mapped_container_type values; }; -public: // [flat.map.cons] Constructors explicit _Flat_map_base(const key_compare& _Comp) : _Data(), _Key_compare(_Comp) {} _Flat_map_base() : _Flat_map_base(key_compare()) {} @@ -359,14 +358,15 @@ public: template <_Usable_allocator_for _Allocator> _Flat_map_base( const key_container_type& _Key_cont, const mapped_container_type& _Mapped_cont, const _Allocator& _Alloc) - : _Flat_map_base(_Sorted_t{}, _Key_cont, _Mapped_cont, _Alloc) { - _Sort_and_erase_dupes_if_not_multi(); - } + : _Flat_map_base(_Key_cont, _Mapped_cont, key_compare(), _Alloc) {} template <_Usable_allocator_for _Allocator> _Flat_map_base(const key_container_type& _Key_cont, const mapped_container_type& _Mapped_cont, const key_compare& _Comp, const _Allocator& _Alloc) - : _Flat_map_base(_Sorted_t{}, _Key_cont, _Mapped_cont, _Comp, _Alloc) { + : _Data{.keys = _STD make_obj_using_allocator(_Alloc, _Key_cont), + .values = _STD make_obj_using_allocator(_Alloc, _Mapped_cont)}, + _Key_compare(_Comp) { + _STL_ASSERT(_Data.keys.size() == _Data.values.size(), "key_cont.size() != mapped_cont.size()"); _Sort_and_erase_dupes_if_not_multi(); } @@ -374,16 +374,13 @@ public: const key_compare& _Comp = key_compare()) : _Data{.keys = _STD move(_Key_cont), .values = _STD move(_Mapped_cont)}, _Key_compare(_Comp) { _STL_ASSERT(_Data.keys.size() == _Data.values.size(), "key_cont.size() != mapped_cont.size()"); + _STL_ASSERT(_Is_sorted_and_unique(), _Msg_not_sorted); } template <_Usable_allocator_for _Allocator> - _Flat_map_base(_Sorted_t, const key_container_type& _Key_cont, const mapped_container_type& _Mapped_cont, + _Flat_map_base(_Sorted_t _Tag, const key_container_type& _Key_cont, const mapped_container_type& _Mapped_cont, const _Allocator& _Alloc) - : _Data{.keys = _STD make_obj_using_allocator(_Alloc, _Key_cont), - .values = _STD make_obj_using_allocator(_Alloc, _Mapped_cont)}, - _Key_compare(key_compare()) { - _STL_ASSERT(_Data.keys.size() == _Data.values.size(), "key_cont.size() != mapped_cont.size()"); - } + : _Flat_map_base(_Tag, _Key_cont, _Mapped_cont, key_compare(), _Alloc) {} template <_Usable_allocator_for _Allocator> _Flat_map_base(_Sorted_t, const key_container_type& _Key_cont, const mapped_container_type& _Mapped_cont, @@ -392,23 +389,26 @@ public: .values = _STD make_obj_using_allocator(_Alloc, _Mapped_cont)}, _Key_compare(_Comp) { _STL_ASSERT(_Data.keys.size() == _Data.values.size(), "key_cont.size() != mapped_cont.size()"); + _STL_ASSERT(_Is_sorted_and_unique(), _Msg_not_sorted); } template <_Iterator_for_container _InputIterator> - _Flat_map_base(_InputIterator _First, _InputIterator _Last, const key_compare& _Comp = key_compare()) + _Flat_map_base(const _InputIterator _First, const _InputIterator _Last, const key_compare& _Comp = key_compare()) : _Flat_map_base(_Comp) { insert(_First, _Last); } template <_Iterator_for_container _InputIterator, _Usable_allocator_for _Allocator> - _Flat_map_base(_InputIterator _First, _InputIterator _Last, const _Allocator& _Alloc) : _Flat_map_base(_Alloc) { + _Flat_map_base(const _InputIterator _First, const _InputIterator _Last, const _Allocator& _Alloc) + : _Flat_map_base(_Alloc) { insert(_First, _Last); } template <_Iterator_for_container _InputIterator, _Usable_allocator_for _Allocator> - _Flat_map_base(_InputIterator _First, _InputIterator _Last, const key_compare& _Comp, const _Allocator& _Alloc) + _Flat_map_base( + const _InputIterator _First, const _InputIterator _Last, const key_compare& _Comp, const _Allocator& _Alloc) : _Flat_map_base(_Comp, _Alloc) { insert(_First, _Last); } @@ -435,45 +435,46 @@ public: } template <_Iterator_for_container _InputIterator> - _Flat_map_base(_Sorted_t, _InputIterator _First, _InputIterator _Last, const key_compare& _Comp = key_compare()) + _Flat_map_base( + _Sorted_t, const _InputIterator _First, const _InputIterator _Last, const key_compare& _Comp = key_compare()) : _Flat_map_base(_Comp) { _Insert_range(_First, _Last); } template <_Iterator_for_container _InputIterator, _Usable_allocator_for _Allocator> - _Flat_map_base( - _Sorted_t, _InputIterator _First, _InputIterator _Last, const key_compare& _Comp, const _Allocator& _Alloc) + _Flat_map_base(_Sorted_t, const _InputIterator _First, const _InputIterator _Last, const key_compare& _Comp, + const _Allocator& _Alloc) : _Flat_map_base(_Comp, _Alloc) { _Insert_range(_First, _Last); } template <_Iterator_for_container _InputIterator, _Usable_allocator_for _Allocator> - _Flat_map_base(_Sorted_t _Tag, _InputIterator _First, _InputIterator _Last, const _Allocator& _Alloc) + _Flat_map_base(_Sorted_t _Tag, const _InputIterator _First, const _InputIterator _Last, const _Allocator& _Alloc) : _Flat_map_base(_Tag, _First, _Last, key_compare(), _Alloc) {} - _Flat_map_base(initializer_list _Ilist, const key_compare& _Comp = key_compare()) + _Flat_map_base(const initializer_list _Ilist, const key_compare& _Comp = key_compare()) : _Flat_map_base(_Ilist.begin(), _Ilist.end(), _Comp) {} template <_Usable_allocator_for _Allocator> - _Flat_map_base(initializer_list _Ilist, const key_compare& _Comp, const _Allocator& _Alloc) + _Flat_map_base(const initializer_list _Ilist, const key_compare& _Comp, const _Allocator& _Alloc) : _Flat_map_base(_Ilist.begin(), _Ilist.end(), _Comp, _Alloc) {} template <_Usable_allocator_for _Allocator> - _Flat_map_base(initializer_list _Ilist, const _Allocator& _Alloc) + _Flat_map_base(const initializer_list _Ilist, const _Allocator& _Alloc) : _Flat_map_base(_Ilist, key_compare(), _Alloc) {} - _Flat_map_base(_Sorted_t _Tag, initializer_list _Ilist, const key_compare& _Comp = key_compare()) + _Flat_map_base(_Sorted_t _Tag, const initializer_list _Ilist, const key_compare& _Comp = key_compare()) : _Flat_map_base(_Tag, _Ilist.begin(), _Ilist.end(), _Comp) {} template <_Usable_allocator_for _Allocator> _Flat_map_base( - _Sorted_t _Tag, initializer_list _Ilist, const key_compare& _Comp, const _Allocator& _Alloc) + _Sorted_t _Tag, const initializer_list _Ilist, const key_compare& _Comp, const _Allocator& _Alloc) : _Flat_map_base(_Tag, _Ilist.begin(), _Ilist.end(), _Comp, _Alloc) {} template <_Usable_allocator_for _Allocator> - _Flat_map_base(_Sorted_t _Tag, initializer_list _Ilist, const _Allocator& _Alloc) + _Flat_map_base(_Sorted_t _Tag, const initializer_list _Ilist, const _Allocator& _Alloc) : _Flat_map_base(_Tag, _Ilist, key_compare(), _Alloc) {} // Copy constructors @@ -511,10 +512,14 @@ public: _Flat_map_base& operator=(_Flat_map_base&& _Other) noexcept(is_nothrow_copy_assignable_v && is_nothrow_move_assignable_v && is_nothrow_move_assignable_v) { - _Clear_guard _Guard{this}; - _Data = _STD move(_Other).extract(); - _Key_compare = _Other._Key_compare; // intentionally copy comparator, see LWG-2227 - _Guard._Target = nullptr; + + if (this != _STD addressof(_Other)) { + _Clear_guard _Guard{this}; + _Clear_guard _Always_clear{_STD addressof(_Other)}; + _Data = _STD move(_Other._Data); + _Key_compare = _Other._Key_compare; // intentionally copy comparator, see LWG-2227 + _Guard._Target = nullptr; + } return *this; } @@ -628,35 +633,35 @@ public: } template - iterator emplace_hint(const_iterator _Position, _ArgTypes&&... _Args) + iterator emplace_hint(const const_iterator _Position, _ArgTypes&&... _Args) requires is_constructible_v { value_type _Val(_STD forward<_ArgTypes>(_Args)...); return _Emplace_hint(_Position, _STD move(_Val.first), _STD move(_Val.second)); } - iterator insert(const_iterator _Position, const value_type& _Pair_val) { + iterator insert(const const_iterator _Position, const value_type& _Pair_val) { return emplace_hint(_Position, _Pair_val); } - iterator insert(const_iterator _Position, value_type&& _Pair_val) { + iterator insert(const const_iterator _Position, value_type&& _Pair_val) { return emplace_hint(_Position, _STD move(_Pair_val)); } template - iterator insert(const_iterator _Position, _PairValTy&& _Pair_val) + iterator insert(const const_iterator _Position, _PairValTy&& _Pair_val) requires is_constructible_v { return emplace_hint(_Position, _STD forward<_PairValTy>(_Pair_val)); } template <_Iterator_for_container _InputIterator> - void insert(_InputIterator _First, _InputIterator _Last) { + void insert(const _InputIterator _First, const _InputIterator _Last) { _Insert_range(_First, _Last); } template <_Iterator_for_container _InputIterator> - void insert(_Sorted_t, _InputIterator _First, _InputIterator _Last) { + void insert(_Sorted_t, const _InputIterator _First, const _InputIterator _Last) { _Insert_range(_First, _Last); } @@ -670,19 +675,19 @@ public: _Insert_range(_RANGES begin(_Range), _RANGES end(_Range)); } - void insert(initializer_list _Ilist) { + void insert(const initializer_list _Ilist) { _Insert_range(_Ilist.begin(), _Ilist.end()); } - void insert(_Sorted_t, initializer_list _Ilist) { + void insert(_Sorted_t, const initializer_list _Ilist) { _Insert_range(_Ilist.begin(), _Ilist.end()); } - iterator erase(iterator _Position) { + iterator erase(const iterator _Position) { return erase(static_cast(_Position)); } - iterator erase(const_iterator _Position) { + iterator erase(const const_iterator _Position) { _Clear_guard _Guard{this}; auto _Key_it = _Data.keys.erase(_Position._Key_it); auto _Val_it = _Data.values.erase(_Position._Mapped_it); @@ -690,7 +695,7 @@ public: return iterator{_STD move(_Key_it), _STD move(_Val_it)}; } - iterator erase(const_iterator _First, const_iterator _Last) { + iterator erase(const const_iterator _First, const const_iterator _Last) { _Clear_guard _Guard{this}; auto _Key_it = _Data.keys.erase(_First._Key_it, _Last._Key_it); auto _Val_it = _Data.values.erase(_First._Mapped_it, _Last._Mapped_it); @@ -726,7 +731,7 @@ public: void replace(key_container_type&& _Key_cont, mapped_container_type&& _Mapped_cont) { _STL_ASSERT(_Key_cont.size() == _Mapped_cont.size(), "key_cont.size() != mapped_cont.size()"); - _STL_ASSERT(_Is_sorted(_Key_cont), _Msg_not_sorted); + _STL_ASSERT(_Is_sorted_and_unique(_Key_cont), _Msg_not_sorted); _Clear_guard _Guard{this}; _Data.keys = _STD move(_Key_cont); _Data.values = _STD move(_Mapped_cont); @@ -964,7 +969,7 @@ protected: if (_Hint_order == weak_ordering::less) { if (_New_position != _End && !_Key_compare(_Key_val, *_New_position._Key_it)) { const auto _Dist = _New_position._Key_it - _Begin._Key_it; - auto _It = begin() + _Dist; + const auto _It = begin() + _Dist; if constexpr (_OverwriteIfExists) { *_It._Mapped_it = mapped_type(_STD forward<_MappedArgTypes>(_Args)...); } @@ -973,7 +978,7 @@ protected: } else { if (_New_position != _Begin && !_Key_compare(*_STD prev(_New_position._Key_it), _Key_val)) { const auto _Dist = _STD prev(_New_position._Key_it) - _Begin._Key_it; - auto _It = begin() + _Dist; + const auto _It = begin() + _Dist; if constexpr (_OverwriteIfExists) { *_It._Mapped_it = mapped_type(_STD forward<_MappedArgTypes>(_Args)...); } @@ -991,7 +996,7 @@ protected: return begin() + _Dist; } - void _Insert_exact(const_iterator _Position, key_type&& _Key_val, mapped_type&& _Mapped_val) { + void _Insert_exact(const const_iterator _Position, key_type&& _Key_val, mapped_type&& _Mapped_val) { _Clear_guard _Guard{this}; _Data.keys.insert(_Position._Key_it, _STD move(_Key_val)); _Data.values.insert(_Position._Mapped_it, _STD move(_Mapped_val)); @@ -1021,14 +1026,14 @@ private: _NODISCARD size_type _Erase_if(_Predicate _Pred) { auto _View = _View_to_mutate(); auto _Mut_first = _View.begin(); - auto _Mut_last = _View.end(); + const auto _Mut_last = _View.end(); const auto _Old_size = size(); _Clear_guard _Guard{this}; _STD _Seek_wrapped(_Mut_first, _RANGES remove_if(_View, _Pred).begin()); - (void) _Data.keys.erase(_Mut_first._Key_it, _Mut_last._Key_it); - (void) _Data.values.erase(_Mut_first._Mapped_it, _Mut_last._Mapped_it); + _Data.keys.erase(_Mut_first._Key_it, _Mut_last._Key_it); + _Data.values.erase(_Mut_first._Mapped_it, _Mut_last._Mapped_it); _Guard._Target = nullptr; return _Old_size - size(); @@ -1041,8 +1046,14 @@ private: _Mutating_iterator{_Data.keys.end(), _Data.values.end()}}; } - _NODISCARD bool _Is_sorted( - typename key_container_type::const_iterator _It, const typename key_container_type::const_iterator _End) const { +public: + _NODISCARD bool _Is_sorted_and_unique() const { + return _Is_sorted_and_unique(_Data.keys); + } + +private: + _NODISCARD bool _Is_sorted_and_unique( + const key_container_type::const_iterator _It, const key_container_type::const_iterator _End) const { if constexpr (_IsUnique) { // sorted-unique auto _Negated = [this](const key_type& _Lhs, const key_type& _Rhs) { return !_Key_compare(_Lhs, _Rhs); }; @@ -1052,8 +1063,8 @@ private: } } - _NODISCARD bool _Is_sorted(const key_container_type& _Cont) const { - return _Is_sorted(_Cont.begin(), _Cont.end()); + _NODISCARD bool _Is_sorted_and_unique(const key_container_type& _Cont) const { + return _Is_sorted_and_unique(_Cont.begin(), _Cont.end()); } void _Sort_and_erase_dupes_if_not_multi() { @@ -1074,15 +1085,15 @@ private: _Erase_dupes_if_not_multi(); - _STL_INTERNAL_CHECK(_Is_sorted(_Data.keys)); + _STL_INTERNAL_CHECK(_Is_sorted_and_unique()); _Guard._Target = nullptr; } void _Erase_dupes_if_not_multi() { if constexpr (_IsUnique) { - auto _Sorted_view = _View_to_mutate(); - auto _Subrange = _RANGES unique(_Sorted_view, [this](const_reference _Left, const_reference _Right) { + auto _Sorted_view = _View_to_mutate(); + const auto _Subrange = _RANGES unique(_Sorted_view, [this](const_reference _Left, const_reference _Right) { return this->_Key_equal(_Left.first, _Right.first); }); const auto _Remaining_count = _Subrange.begin() - _Sorted_view.begin(); @@ -1096,7 +1107,7 @@ private: } template - void _Insert_range(_InputIterator _First, _Sentinel _Last) { + void _Insert_range(_InputIterator _First, const _Sentinel _Last) { _Clear_guard _Guard{this}; const auto _Old_distance = static_cast(size()); @@ -1123,13 +1134,18 @@ private: auto _Sorted_new_elements = _Sorted_view; _Sorted_new_elements.advance(_Old_distance); _RANGES sort(_Sorted_new_elements, value_compare{_Key_compare}); + } else { + _STL_ASSERT(_Is_sorted_and_unique( + _Data.keys.begin() + static_cast(_Old_distance), + _Data.keys.end()), + _Msg_not_sorted); } // Merge the newly inserted elements with the existing elements _RANGES inplace_merge(_Sorted_view, _Sorted_view.begin() + _Old_distance, value_compare{_Key_compare}); _Erase_dupes_if_not_multi(); - _STL_INTERNAL_CHECK(_Is_sorted(_Data.keys)); + _STL_INTERNAL_CHECK(_Is_sorted_and_unique()); _Guard._Target = nullptr; } @@ -1297,14 +1313,14 @@ public: } template - iterator try_emplace(const_iterator _Position, const key_type& _Key_val, _MappedArgTypes&&... _Mapped_args) + iterator try_emplace(const const_iterator _Position, const key_type& _Key_val, _MappedArgTypes&&... _Mapped_args) requires is_constructible_v { return this->template _Emplace_hint(_Position, _Key_val, _STD forward<_MappedArgTypes>(_Mapped_args)...); } template - iterator try_emplace(const_iterator _Position, key_type&& _Key_val, _MappedArgTypes&&... _Mapped_args) + iterator try_emplace(const const_iterator _Position, key_type&& _Key_val, _MappedArgTypes&&... _Mapped_args) requires is_constructible_v { return this->template _Emplace_hint( @@ -1312,7 +1328,7 @@ public: } template - iterator try_emplace(const_iterator _Position, _OtherKey&& _Key_val, _MappedArgTypes&&... _Mapped_args) + iterator try_emplace(const const_iterator _Position, _OtherKey&& _Key_val, _MappedArgTypes&&... _Mapped_args) requires _Transparent && is_constructible_v && is_constructible_v { @@ -1343,21 +1359,21 @@ public: } template - iterator insert_or_assign(const_iterator _Position, const key_type& _Key_val, _MappedTy&& _Mapped_val) + iterator insert_or_assign(const const_iterator _Position, const key_type& _Key_val, _MappedTy&& _Mapped_val) requires is_assignable_v && is_constructible_v { return this->template _Emplace_hint(_Position, _Key_val, _STD forward<_MappedTy>(_Mapped_val)); } template - iterator insert_or_assign(const_iterator _Position, key_type&& _Key_val, _MappedTy&& _Mapped_val) + iterator insert_or_assign(const const_iterator _Position, key_type&& _Key_val, _MappedTy&& _Mapped_val) requires is_assignable_v && is_constructible_v { return this->template _Emplace_hint(_Position, _STD move(_Key_val), _STD forward<_MappedTy>(_Mapped_val)); } template - iterator insert_or_assign(const_iterator _Position, _OtherKey&& _Key_val, _MappedTy&& _Mapped_val) + iterator insert_or_assign(const const_iterator _Position, _OtherKey&& _Key_val, _MappedTy&& _Mapped_val) requires _Transparent && is_constructible_v && is_assignable_v && is_constructible_v { diff --git a/stl/inc/flat_set b/stl/inc/flat_set index e5395153837..790ab35b20a 100644 --- a/stl/inc/flat_set +++ b/stl/inc/flat_set @@ -109,7 +109,8 @@ public: using reverse_iterator = const_reverse_iterator; using container_type = _Container; - _Flat_set_base() : _Mycont(), _Mycomp() {} + // [flat.set.cons] Constructors + _Flat_set_base() : _Flat_set_base(key_compare()) {} template <_Usable_allocator_for _Alloc> _Flat_set_base(const _Flat_set_base& _Other, const _Alloc& _Al) @@ -133,7 +134,7 @@ public: _Flat_set_base(_Sorted_t, container_type _Cont, const key_compare& _Comp = key_compare()) : _Mycont(_STD move(_Cont)), _Mycomp(_Comp) { - _STL_ASSERT(_Is_sorted(_Mycont), _Msg_not_sorted); + _STL_ASSERT(_Is_sorted_and_unique(), _Msg_not_sorted); } template <_Usable_allocator_for _Alloc> _Flat_set_base(_Sorted_t _Tag, const container_type& _Cont, const _Alloc& _Al) @@ -151,18 +152,19 @@ public: : _Mycont(_STD make_obj_using_allocator(_Al)), _Mycomp() {} template <_Iterator_for_container _Iter> - _Flat_set_base(_Iter _First, _Iter _Last, const key_compare& _Comp = key_compare()) : _Mycont(), _Mycomp(_Comp) { + _Flat_set_base(const _Iter _First, const _Iter _Last, const key_compare& _Comp = key_compare()) + : _Mycont(), _Mycomp(_Comp) { _Mycont.assign(_First, _Last); _Make_invariants_fulfilled(); } template <_Iterator_for_container _Iter, _Usable_allocator_for _Alloc> - _Flat_set_base(_Iter _First, _Iter _Last, const key_compare& _Comp, const _Alloc& _Al) + _Flat_set_base(const _Iter _First, const _Iter _Last, const key_compare& _Comp, const _Alloc& _Al) : _Mycont(_STD make_obj_using_allocator(_Al)), _Mycomp(_Comp) { _Mycont.assign(_First, _Last); _Make_invariants_fulfilled(); } template <_Iterator_for_container _Iter, _Usable_allocator_for _Alloc> - _Flat_set_base(_Iter _First, _Iter _Last, const _Alloc& _Al) + _Flat_set_base(const _Iter _First, const _Iter _Last, const _Alloc& _Al) : _Mycont(_STD make_obj_using_allocator(_Al)), _Mycomp() { _Mycont.assign(_First, _Last); _Make_invariants_fulfilled(); @@ -188,31 +190,31 @@ public: } template <_Iterator_for_container _Iter> - _Flat_set_base(_Sorted_t _Tag, _Iter _First, _Iter _Last, const key_compare& _Comp = key_compare()) + _Flat_set_base(_Sorted_t _Tag, const _Iter _First, const _Iter _Last, const key_compare& _Comp = key_compare()) : _Flat_set_base(_Tag, container_type(_First, _Last), _Comp) {} template <_Iterator_for_container _Iter, _Usable_allocator_for _Alloc> - _Flat_set_base(_Sorted_t _Tag, _Iter _First, _Iter _Last, const key_compare& _Comp, const _Alloc& _Al) + _Flat_set_base(_Sorted_t _Tag, const _Iter _First, const _Iter _Last, const key_compare& _Comp, const _Alloc& _Al) : _Flat_set_base(_Tag, _STD make_obj_using_allocator(_Al, _First, _Last), _Comp) {} template <_Iterator_for_container _Iter, _Usable_allocator_for _Alloc> - _Flat_set_base(_Sorted_t _Tag, _Iter _First, _Iter _Last, const _Alloc& _Al) + _Flat_set_base(_Sorted_t _Tag, const _Iter _First, const _Iter _Last, const _Alloc& _Al) : _Flat_set_base(_Tag, _STD make_obj_using_allocator(_Al, _First, _Last)) {} - _Flat_set_base(initializer_list<_Kty> _Ilist, const key_compare& _Comp = key_compare()) + _Flat_set_base(const initializer_list<_Kty> _Ilist, const key_compare& _Comp = key_compare()) : _Flat_set_base(_Ilist.begin(), _Ilist.end(), _Comp) {} template <_Usable_allocator_for _Alloc> - _Flat_set_base(initializer_list<_Kty> _Ilist, const key_compare& _Comp, const _Alloc& _Al) + _Flat_set_base(const initializer_list<_Kty> _Ilist, const key_compare& _Comp, const _Alloc& _Al) : _Flat_set_base(_Ilist.begin(), _Ilist.end(), _Comp, _Al) {} template <_Usable_allocator_for _Alloc> - _Flat_set_base(initializer_list<_Kty> _Ilist, const _Alloc& _Al) + _Flat_set_base(const initializer_list<_Kty> _Ilist, const _Alloc& _Al) : _Flat_set_base(_Ilist.begin(), _Ilist.end(), _Al) {} - _Flat_set_base(_Sorted_t _Tag, initializer_list<_Kty> _Ilist, const key_compare& _Comp = key_compare()) + _Flat_set_base(_Sorted_t _Tag, const initializer_list<_Kty> _Ilist, const key_compare& _Comp = key_compare()) : _Flat_set_base(_Tag, _Ilist.begin(), _Ilist.end(), _Comp) {} template <_Usable_allocator_for _Alloc> - _Flat_set_base(_Sorted_t _Tag, initializer_list<_Kty> _Ilist, const key_compare& _Comp, const _Alloc& _Al) + _Flat_set_base(_Sorted_t _Tag, const initializer_list<_Kty> _Ilist, const key_compare& _Comp, const _Alloc& _Al) : _Flat_set_base(_Tag, _Ilist.begin(), _Ilist.end(), _Comp, _Al) {} template <_Usable_allocator_for _Alloc> - _Flat_set_base(_Sorted_t _Tag, initializer_list<_Kty> _Ilist, const _Alloc& _Al) + _Flat_set_base(_Sorted_t _Tag, const initializer_list<_Kty> _Ilist, const _Alloc& _Al) : _Flat_set_base(_Tag, _Ilist.begin(), _Ilist.end(), _Al) {} _Flat_set_base(const _Flat_set_base&) = default; @@ -241,7 +243,7 @@ public: return *this; } - _Derived& operator=(initializer_list<_Kty> _Ilist) { + _Derived& operator=(const initializer_list<_Kty> _Ilist) { _Clear_guard _Guard{this}; _Mycont.assign(_Ilist); _Make_invariants_fulfilled(); @@ -301,7 +303,7 @@ public: } } template - iterator emplace_hint(const_iterator _Hint, _Args&&... _Vals) { + iterator emplace_hint(const const_iterator _Hint, _Args&&... _Vals) { constexpr bool _Is_key_type = _In_place_key_extract_set<_Kty, remove_cvref_t<_Args>...>::_Extractable; if constexpr (_Is_key_type) { return _Emplace_hint(_Hint, _STD forward<_Args>(_Vals)...); @@ -322,24 +324,24 @@ public: return _Emplace(_STD forward<_Other>(_Val)); } - iterator insert(const_iterator _Hint, const _Kty& _Val) { + iterator insert(const const_iterator _Hint, const _Kty& _Val) { return _Emplace_hint(_Hint, _Val); } - iterator insert(const_iterator _Hint, _Kty&& _Val) { + iterator insert(const const_iterator _Hint, _Kty&& _Val) { return _Emplace_hint(_Hint, _STD move(_Val)); } template <_Different_from<_Kty> _Other> requires _IsUnique && _Transparent && is_constructible_v<_Kty, _Other> - iterator insert(const_iterator _Hint, _Other&& _Val) { + iterator insert(const const_iterator _Hint, _Other&& _Val) { return _Emplace_hint(_Hint, _STD forward<_Other>(_Val)); } template <_Iterator_for_container _Iter> - void insert(_Iter _First, _Iter _Last) { + void insert(const _Iter _First, const _Iter _Last) { _Insert_range(_First, _Last); } template <_Iterator_for_container _Iter> - void insert(_Sorted_t, _Iter _First, _Iter _Last) { + void insert(_Sorted_t, const _Iter _First, const _Iter _Last) { _Insert_range(_First, _Last); } template <_Container_compatible_range<_Kty> _Rng> @@ -350,10 +352,10 @@ public: void insert_range(_Sorted_t, _Rng&& _Range) { _Insert_range(_STD forward<_Rng>(_Range)); } - void insert(initializer_list<_Kty> _Ilist) { + void insert(const initializer_list<_Kty> _Ilist) { _Insert_range(_Ilist.begin(), _Ilist.end()); } - void insert(_Sorted_t, initializer_list<_Kty> _Ilist) { + void insert(_Sorted_t, const initializer_list<_Kty> _Ilist) { _Insert_range(_Ilist.begin(), _Ilist.end()); } @@ -365,7 +367,7 @@ public: } void replace(container_type&& _Cont) { - _STL_ASSERT(_Is_sorted(_Cont), _Msg_not_sorted); + _STL_ASSERT(_Is_sorted_and_unique(_Cont), _Msg_not_sorted); _Clear_guard _Guard{this}; _Mycont = _STD move(_Cont); _Guard._Target = nullptr; @@ -375,7 +377,7 @@ public: // container doesn't provide the strong guarantee for its "erase" member functions. // NB: `erase(iterator)` is identical to `erase(const_iterator)` - iterator erase(const_iterator _Where) { + iterator erase(const const_iterator _Where) { return _Mycont.erase(_Where); } size_type erase(const _Kty& _Val) { @@ -386,7 +388,7 @@ public: size_type erase(_Other&& _Val) { return _Erase(_Val); } - iterator erase(const_iterator _First, const_iterator _Last) { + iterator erase(const const_iterator _First, const const_iterator _Last) { return _Mycont.erase(_First, _Last); } @@ -486,8 +488,12 @@ public: _Lhs.swap(_Rhs); } + _NODISCARD bool _Is_sorted_and_unique() const { + return _Is_sorted_and_unique(_Mycont); + } + private: - _NODISCARD bool _Is_sorted(const_iterator _It, const const_iterator _End) const { + _NODISCARD bool _Is_sorted_and_unique(const const_iterator _It, const const_iterator _End) const { if constexpr (_IsUnique) { // sorted-unique auto _Negated = [this](const key_type& _Lhs, const key_type& _Rhs) { return !_Compare(_Lhs, _Rhs); }; @@ -497,8 +503,8 @@ private: } } - _NODISCARD bool _Is_sorted(const container_type& _Cont) const { - return _Is_sorted(_Cont.begin(), _Cont.end()); + _NODISCARD bool _Is_sorted_and_unique(const container_type& _Cont) const { + return _Is_sorted_and_unique(_Cont.begin(), _Cont.end()); } template @@ -696,13 +702,13 @@ private: if constexpr (_NeedSorting) { _STD sort(_Old_end, _End, _Pass_comp()); } else { - _STL_INTERNAL_CHECK(_Is_sorted(_Old_end, _End)); + _STL_ASSERT(_Is_sorted_and_unique(_Old_end, _End), _Msg_not_sorted); } _STD inplace_merge(_Begin, _Old_end, _End, _Pass_comp()); _Erase_dupes_if_not_multi(); - _STL_INTERNAL_CHECK(_Is_sorted(_Mycont)); + _STL_INTERNAL_CHECK(_Is_sorted_and_unique()); } void _Make_invariants_fulfilled() { @@ -720,7 +726,7 @@ private: _STD inplace_merge(_Begin, _Begin_unsorted, _End, _Pass_comp()); _Erase_dupes_if_not_multi(); - _STL_INTERNAL_CHECK(_Is_sorted(_Mycont)); + _STL_INTERNAL_CHECK(_Is_sorted_and_unique()); } template diff --git a/tests/std/tests/P1222R4_flat_set/test.cpp b/tests/std/tests/P1222R4_flat_set/test.cpp index 8790079811a..40f7786a126 100644 --- a/tests/std/tests/P1222R4_flat_set/test.cpp +++ b/tests/std/tests/P1222R4_flat_set/test.cpp @@ -243,6 +243,7 @@ void assert_all_requirements(const T& s) { } } } + assert(s._Is_sorted_and_unique()); } template