Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions stl/inc/algorithm
Original file line number Diff line number Diff line change
Expand Up @@ -8238,14 +8238,13 @@ void inplace_merge(_BidIt _First, _BidIt _Mid, _BidIt _Last, _Pr _Pred) {

++_ULast;

using _Diff = _Iter_diff_t<_BidIt>;
const _Diff _Count1 = _STD distance(_UFirst, _UMid);
const auto _Count1 = _STD distance(_UFirst, _UMid);
if (_Count1 == 1) { // rotate only element remaining in left partition to the end, without allocating
_STD _Rotate_one_left(_UFirst, _UMid, _ULast);
return;
}

const _Diff _Count2 = _STD distance(_UMid, _ULast);
const auto _Count2 = _STD distance(_UMid, _ULast);
_Optimistic_temporary_buffer<_Iter_value_t<_BidIt>> _Temp_buf{(_STD min)(_Count1, _Count2)};
_STD _Buffered_inplace_merge_unchecked_impl(
_UFirst, _UMid, _ULast, _Count1, _Count2, _Temp_buf._Data, _Temp_buf._Capacity, _STD _Pass_fn(_Pred));
Expand Down
5 changes: 0 additions & 5 deletions stl/inc/flat_map
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,6 @@ _STL_DISABLE_CLANG_WARNINGS
#undef new

_STD_BEGIN
template <class _Compare, class _Key_container>
concept _Valid_compare_for_container = _Not_allocator_for_container<_Compare>
&& is_invocable_v<const _Compare&, const typename _Key_container::value_type&,
const typename _Key_container::value_type&>;

template <class _Key, class _Mapped, class _KeyCompare>
struct _Flat_map_value_compare_provider {
struct value_compare {
Expand Down
159 changes: 94 additions & 65 deletions stl/inc/flat_set
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,16 @@ public:
explicit _Base_flat_set(const _Alloc& _Al)
: _Mycont(_STD make_obj_using_allocator<container_type>(_Al)), _Mycomp() {}

template <input_iterator _Iter>
template <_Iterator_for_container _Iter>
_Base_flat_set(_Iter _First, _Iter _Last, const key_compare& _Comp = key_compare())
: _Base_flat_set(container_type(_First, _Last), _Comp) {}
template <input_iterator _Iter, _Usable_allocator_for<container_type> _Alloc>
template <_Iterator_for_container _Iter, _Usable_allocator_for<container_type> _Alloc>
_Base_flat_set(_Iter _First, _Iter _Last, const key_compare& _Comp, const _Alloc& _Al)
: _Mycont(_STD make_obj_using_allocator<container_type>(_Al)), _Mycomp(_Comp) {
_Mycont.assign(_First, _Last);
_Make_invariants_fulfilled();
}
template <input_iterator _Iter, _Usable_allocator_for<container_type> _Alloc>
template <_Iterator_for_container _Iter, _Usable_allocator_for<container_type> _Alloc>
_Base_flat_set(_Iter _First, _Iter _Last, const _Alloc& _Al)
: _Mycont(_STD make_obj_using_allocator<container_type>(_Al)), _Mycomp() {
_Mycont.assign(_First, _Last);
Expand All @@ -129,13 +129,13 @@ public:
_Make_invariants_fulfilled();
}

template <input_iterator _Iter>
template <_Iterator_for_container _Iter>
_Base_flat_set(_Tsorted _Tsort, _Iter _First, _Iter _Last, const key_compare& _Comp = key_compare())
: _Base_flat_set(_Tsort, container_type(_First, _Last), _Comp) {}
template <input_iterator _Iter, _Usable_allocator_for<container_type> _Alloc>
template <_Iterator_for_container _Iter, _Usable_allocator_for<container_type> _Alloc>
_Base_flat_set(_Tsorted _Tsort, _Iter _First, _Iter _Last, const key_compare& _Comp, const _Alloc& _Al)
: _Base_flat_set(_Tsort, _STD make_obj_using_allocator<container_type>(_Al, _First, _Last), _Comp) {}
template <input_iterator _Iter, _Usable_allocator_for<container_type> _Alloc>
template <_Iterator_for_container _Iter, _Usable_allocator_for<container_type> _Alloc>
_Base_flat_set(_Tsorted _Tsort, _Iter _First, _Iter _Last, const _Alloc& _Al)
: _Base_flat_set(_Tsort, _STD make_obj_using_allocator<container_type>(_Al, _First, _Last)) {}

Expand Down Expand Up @@ -208,10 +208,10 @@ public:
}

_NODISCARD const_iterator cbegin() const noexcept {
return _Mycont.cbegin();
return _Mycont.begin();
}
_NODISCARD const_iterator cend() const noexcept {
return _Mycont.cend();
return _Mycont.end();
}
_NODISCARD const_reverse_iterator crbegin() const noexcept {
return rbegin();
Expand Down Expand Up @@ -277,11 +277,11 @@ public:
return _Emplace_hint(_Hint, _STD forward<_Other>(_Val));
}

template <input_iterator _Iter>
template <_Iterator_for_container _Iter>
void insert(_Iter _First, _Iter _Last) {
_Insert_range<false>(_First, _Last);
}
template <input_iterator _Iter>
template <_Iterator_for_container _Iter>
void insert(_Tsorted, _Iter _First, _Iter _Last) {
_Insert_range<true>(_First, _Last);
}
Expand Down Expand Up @@ -447,7 +447,7 @@ private:
}

_NODISCARD bool _Is_sorted(const container_type& _Cont) const {
return _Is_sorted(_Cont.cbegin(), _Cont.cend());
return _Is_sorted(_Cont.begin(), _Cont.end());
}

static constexpr const char* _Msg_not_sorted = _Multi ? "Input was not sorted!" : "Input was not sorted-unique!";
Expand Down Expand Up @@ -678,6 +678,14 @@ public:
flat_set(const flat_set&) = default;
flat_set(flat_set&&) = default;

#if 1 // TRANSITION, P2582R1 (MSVC, Clang, EDG)
template <_Usable_allocator_for<_Container> _Allocator>
flat_set(const flat_set& _Other, const _Allocator& _Al) : _Mybase(_Other, _Al) {}

template <_Usable_allocator_for<_Container> _Allocator>
flat_set(flat_set&& _Other, const _Allocator& _Al) : _Mybase(_STD move(_Other), _Al) {}
#endif // ^^^ workaround ^^^

using _Mybase::operator=;
flat_set& operator=(const flat_set&) = default;
flat_set& operator=(flat_set&&) = default;
Expand All @@ -694,6 +702,14 @@ public:
flat_multiset(const flat_multiset&) = default;
flat_multiset(flat_multiset&&) = default;

#if 1 // TRANSITION, P2582R1 (MSVC, Clang, EDG)
template <_Usable_allocator_for<_Container> _Allocator>
flat_multiset(const flat_multiset& _Other, const _Allocator& _Al) : _Mybase(_Other, _Al) {}

template <_Usable_allocator_for<_Container> _Allocator>
flat_multiset(flat_multiset&& _Other, const _Allocator& _Al) : _Mybase(_STD move(_Other), _Al) {}
#endif // ^^^ workaround ^^^

using _Mybase::operator=;
flat_multiset& operator=(const flat_multiset&) = default;
flat_multiset& operator=(flat_multiset&&) = default;
Expand Down Expand Up @@ -727,76 +743,89 @@ template <class _Kty, class _Keylt, class _Container, class _Alloc>
struct uses_allocator<flat_multiset<_Kty, _Keylt, _Container>, _Alloc>
: bool_constant<uses_allocator_v<_Container, _Alloc>> {};

template <class _Container, class _Keylt = less<typename _Container::value_type>>
flat_set(_Container, _Keylt = _Keylt()) -> flat_set<typename _Container::value_type, _Keylt, _Container>;
template <class _Container, class _Alloc>
template <_Not_allocator_for_container _Container,
_Valid_compare_for_container<_Container> _Compare = less<typename _Container::value_type>>
flat_set(_Container, _Compare = _Compare()) -> flat_set<typename _Container::value_type, _Compare, _Container>;
template <_Not_allocator_for_container _Container, _Usable_allocator_for<_Container> _Alloc>
flat_set(_Container, _Alloc)
-> flat_set<typename _Container::value_type, less<typename _Container::value_type>, _Container>;
template <class _Container, class _Keylt, class _Alloc>
flat_set(_Container, _Keylt, _Alloc) -> flat_set<typename _Container::value_type, _Keylt, _Container>;

template <class _Container, class _Keylt = less<typename _Container::value_type>>
flat_set(sorted_unique_t, _Container, _Keylt = _Keylt())
-> flat_set<typename _Container::value_type, _Keylt, _Container>;
template <class _Container, class _Alloc>
template <_Not_allocator_for_container _Container, _Valid_compare_for_container<_Container> _Compare,
_Usable_allocator_for<_Container> _Alloc>
flat_set(_Container, _Compare, _Alloc) -> flat_set<typename _Container::value_type, _Compare, _Container>;

template <_Not_allocator_for_container _Container,
_Valid_compare_for_container<_Container> _Compare = less<typename _Container::value_type>>
flat_set(sorted_unique_t, _Container, _Compare = _Compare())
-> flat_set<typename _Container::value_type, _Compare, _Container>;
template <_Not_allocator_for_container _Container, _Usable_allocator_for<_Container> _Alloc>
flat_set(sorted_unique_t, _Container, _Alloc)
-> flat_set<typename _Container::value_type, less<typename _Container::value_type>, _Container>;
template <class _Container, class _Keylt, class _Alloc>
flat_set(sorted_unique_t, _Container, _Keylt, _Alloc) -> flat_set<typename _Container::value_type, _Keylt, _Container>;

template <class _Iter, class _Keylt = less<iter_value_t<_Iter>>>
flat_set(_Iter, _Iter, _Keylt = _Keylt()) -> flat_set<iter_value_t<_Iter>, _Keylt>;
template <class _Iter, class _Keylt = less<iter_value_t<_Iter>>>
flat_set(sorted_unique_t, _Iter, _Iter, _Keylt = _Keylt()) -> flat_set<iter_value_t<_Iter>, _Keylt>;
template <_RANGES input_range _Range, class _Keylt = less<_RANGES range_value_t<_Range>>,
class _Alloc = allocator<_RANGES range_value_t<_Range>>>
flat_set(from_range_t, _Range&&, _Keylt = _Keylt(), _Alloc = _Alloc()) -> flat_set<_RANGES range_value_t<_Range>,
_Keylt, vector<_RANGES range_value_t<_Range>, _Rebind_alloc_t<_Alloc, _RANGES range_value_t<_Range>>>>;
template <_RANGES input_range _Range, class _Alloc>
template <_Not_allocator_for_container _Container, _Valid_compare_for_container<_Container> _Compare,
_Usable_allocator_for<_Container> _Alloc>
flat_set(sorted_unique_t, _Container, _Compare, _Alloc)
-> flat_set<typename _Container::value_type, _Compare, _Container>;

template <_Iterator_for_container _Iter, _Not_allocator_for_container _Compare = less<iter_value_t<_Iter>>>
flat_set(_Iter, _Iter, _Compare = _Compare()) -> flat_set<iter_value_t<_Iter>, _Compare>;
template <_Iterator_for_container _Iter, _Not_allocator_for_container _Compare = less<iter_value_t<_Iter>>>
flat_set(sorted_unique_t, _Iter, _Iter, _Compare = _Compare()) -> flat_set<iter_value_t<_Iter>, _Compare>;
// TRANSITION, CWG-2369, should just use constrained template parameters.
template <_RANGES input_range _Range, _Not_allocator_for_container _Compare = less<_RANGES range_value_t<_Range>>,
class _Alloc = allocator<_RANGES range_value_t<_Range>>, enable_if_t<_Allocator_for_container<_Alloc>, int> = 0>
flat_set(from_range_t, _Range&&, _Compare = _Compare(), _Alloc = _Alloc()) -> flat_set<_RANGES range_value_t<_Range>,
_Compare, vector<_RANGES range_value_t<_Range>, _Rebind_alloc_t<_Alloc, _RANGES range_value_t<_Range>>>>;
// TRANSITION, CWG-2369, should just use constrained template parameters.
template <_RANGES input_range _Range, class _Alloc, enable_if_t<_Allocator_for_container<_Alloc>, int> = 0>
flat_set(from_range_t, _Range&&, _Alloc) -> flat_set<_RANGES range_value_t<_Range>, less<_RANGES range_value_t<_Range>>,
vector<_RANGES range_value_t<_Range>, _Rebind_alloc_t<_Alloc, _RANGES range_value_t<_Range>>>>;
template <class _Kty, class _Keylt = less<_Kty>>
flat_set(initializer_list<_Kty>, _Keylt = _Keylt()) -> flat_set<_Kty, _Keylt>;
template <class _Kty, class _Keylt = less<_Kty>>
flat_set(sorted_unique_t, initializer_list<_Kty>, _Keylt = _Keylt()) -> flat_set<_Kty, _Keylt>;
template <class _Kty, _Not_allocator_for_container _Compare = less<_Kty>>
flat_set(initializer_list<_Kty>, _Compare = _Compare()) -> flat_set<_Kty, _Compare>;
template <class _Kty, _Not_allocator_for_container _Compare = less<_Kty>>
flat_set(sorted_unique_t, initializer_list<_Kty>, _Compare = _Compare()) -> flat_set<_Kty, _Compare>;


template <class _Container, class _Keylt = less<typename _Container::value_type>>
flat_multiset(_Container, _Keylt = _Keylt()) -> flat_multiset<typename _Container::value_type, _Keylt, _Container>;
template <class _Container, class _Alloc>
template <_Not_allocator_for_container _Container,
_Valid_compare_for_container<_Container> _Compare = less<typename _Container::value_type>>
flat_multiset(_Container, _Compare = _Compare())
-> flat_multiset<typename _Container::value_type, _Compare, _Container>;
template <_Not_allocator_for_container _Container, _Usable_allocator_for<_Container> _Alloc>
flat_multiset(_Container, _Alloc)
-> flat_multiset<typename _Container::value_type, less<typename _Container::value_type>, _Container>;
template <class _Container, class _Keylt, class _Alloc>
flat_multiset(_Container, _Keylt, _Alloc) -> flat_multiset<typename _Container::value_type, _Keylt, _Container>;

template <class _Container, class _Keylt = less<typename _Container::value_type>>
flat_multiset(sorted_equivalent_t, _Container, _Keylt = _Keylt())
-> flat_multiset<typename _Container::value_type, _Keylt, _Container>;
template <class _Container, class _Alloc>
template <_Not_allocator_for_container _Container, _Valid_compare_for_container<_Container> _Compare,
_Usable_allocator_for<_Container> _Alloc>
flat_multiset(_Container, _Compare, _Alloc) -> flat_multiset<typename _Container::value_type, _Compare, _Container>;

template <_Not_allocator_for_container _Container,
_Valid_compare_for_container<_Container> _Compare = less<typename _Container::value_type>>
flat_multiset(sorted_equivalent_t, _Container, _Compare = _Compare())
-> flat_multiset<typename _Container::value_type, _Compare, _Container>;
template <_Not_allocator_for_container _Container, _Usable_allocator_for<_Container> _Alloc>
flat_multiset(sorted_equivalent_t, _Container, _Alloc)
-> flat_multiset<typename _Container::value_type, less<typename _Container::value_type>, _Container>;
template <class _Container, class _Keylt, class _Alloc>
flat_multiset(sorted_equivalent_t, _Container, _Keylt, _Alloc)
-> flat_multiset<typename _Container::value_type, _Keylt, _Container>;

template <class _Iter, class _Keylt = less<iter_value_t<_Iter>>>
flat_multiset(_Iter, _Iter, _Keylt = _Keylt()) -> flat_multiset<iter_value_t<_Iter>, iter_value_t<_Iter>, _Keylt>;
template <class _Iter, class _Keylt = less<iter_value_t<_Iter>>>
flat_multiset(sorted_equivalent_t, _Iter, _Iter, _Keylt = _Keylt())
-> flat_multiset<iter_value_t<_Iter>, iter_value_t<_Iter>, _Keylt>;
template <_RANGES input_range _Range, class _Keylt = less<_RANGES range_value_t<_Range>>,
class _Alloc = allocator<_RANGES range_value_t<_Range>>>
flat_multiset(from_range_t, _Range&&, _Keylt = _Keylt(), _Alloc = _Alloc())
-> flat_multiset<_RANGES range_value_t<_Range>, _Keylt,
template <_Not_allocator_for_container _Container, _Valid_compare_for_container<_Container> _Compare,
_Usable_allocator_for<_Container> _Alloc>
flat_multiset(sorted_equivalent_t, _Container, _Compare, _Alloc)
-> flat_multiset<typename _Container::value_type, _Compare, _Container>;

template <_Iterator_for_container _Iter, _Not_allocator_for_container _Compare = less<iter_value_t<_Iter>>>
flat_multiset(_Iter, _Iter, _Compare = _Compare()) -> flat_multiset<iter_value_t<_Iter>, _Compare>;
template <_Iterator_for_container _Iter, _Not_allocator_for_container _Compare = less<iter_value_t<_Iter>>>
flat_multiset(sorted_equivalent_t, _Iter, _Iter, _Compare = _Compare()) -> flat_multiset<iter_value_t<_Iter>, _Compare>;
// TRANSITION, CWG-2369, should just use constrained template parameters.
template <_RANGES input_range _Range, _Not_allocator_for_container _Compare = less<_RANGES range_value_t<_Range>>,
class _Alloc = allocator<_RANGES range_value_t<_Range>>, enable_if_t<_Allocator_for_container<_Alloc>, int> = 0>
flat_multiset(from_range_t, _Range&&, _Compare = _Compare(), _Alloc = _Alloc())
-> flat_multiset<_RANGES range_value_t<_Range>, _Compare,
vector<_RANGES range_value_t<_Range>, _Rebind_alloc_t<_Alloc, _RANGES range_value_t<_Range>>>>;
template <_RANGES input_range _Range, class _Alloc>
// TRANSITION, CWG-2369, should just use constrained template parameters.
template <_RANGES input_range _Range, class _Alloc, enable_if_t<_Allocator_for_container<_Alloc>, int> = 0>
flat_multiset(from_range_t, _Range&&, _Alloc)
-> flat_multiset<_RANGES range_value_t<_Range>, less<_RANGES range_value_t<_Range>>,
vector<_RANGES range_value_t<_Range>, _Rebind_alloc_t<_Alloc, _RANGES range_value_t<_Range>>>>;
template <class _Kty, class _Keylt = less<_Kty>>
flat_multiset(initializer_list<_Kty>, _Keylt = _Keylt()) -> flat_multiset<_Kty, _Keylt>;
template <class _Kty, class _Keylt = less<_Kty>>
flat_multiset(sorted_equivalent_t, initializer_list<_Kty>, _Keylt = _Keylt()) -> flat_multiset<_Kty, _Keylt>;
template <class _Kty, _Not_allocator_for_container _Compare = less<_Kty>>
flat_multiset(initializer_list<_Kty>, _Compare = _Compare()) -> flat_multiset<_Kty, _Compare>;
template <class _Kty, _Not_allocator_for_container _Compare = less<_Kty>>
flat_multiset(sorted_equivalent_t, initializer_list<_Kty>, _Compare = _Compare()) -> flat_multiset<_Kty, _Compare>;

_STD_END

Expand Down
5 changes: 5 additions & 0 deletions stl/inc/vector
Original file line number Diff line number Diff line change
Expand Up @@ -4022,6 +4022,11 @@ constexpr bool _Has_guaranteed_push_back<vector<_Ty, _Alloc>> = !is_same_v<_Ty,
template <class _Alloc, class... _Containers>
concept _Usable_allocator_for = (uses_allocator_v<_Containers, _Alloc> && ...);

template <class _Compare, class _KeyContainer>
concept _Valid_compare_for_container = _Not_allocator_for_container<_Compare>
&& is_invocable_v<const _Compare&, const typename _KeyContainer::value_type&,
const typename _KeyContainer::value_type&>;

template <class _Ty>
struct _NODISCARD _Clear_guard {
_Ty* _Target;
Expand Down