Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ADL-proof implementation of [alg.min.max], [alg.clamp], [alg.lex.comparison], and [alg.three.way] #4216

Merged
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
45 changes: 24 additions & 21 deletions stl/inc/algorithm
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,13 @@ _STD pair<_Ty*, _Ty*> __std_minmax_element(_Ty* _First, _Ty* _Last) noexcept {
_Min_max_element_t _Res;

if constexpr (sizeof(_Ty) == 1) {
_Res = __std_minmax_element_1(_First, _Last, _Signed);
_Res = ::__std_minmax_element_1(_First, _Last, _Signed);
} else if constexpr (sizeof(_Ty) == 2) {
_Res = __std_minmax_element_2(_First, _Last, _Signed);
_Res = ::__std_minmax_element_2(_First, _Last, _Signed);
} else if constexpr (sizeof(_Ty) == 4) {
_Res = __std_minmax_element_4(_First, _Last, _Signed);
_Res = ::__std_minmax_element_4(_First, _Last, _Signed);
} else if constexpr (sizeof(_Ty) == 8) {
_Res = __std_minmax_element_8(_First, _Last, _Signed);
_Res = ::__std_minmax_element_8(_First, _Last, _Signed);
} else {
static_assert(_STD _Always_false<_Ty>, "Unexpected size");
}
Expand Down Expand Up @@ -9729,8 +9729,8 @@ constexpr pair<_FwdIt, _FwdIt> _Minmax_element_unchecked(_FwdIt _First, _FwdIt _
#if _USE_STD_VECTOR_ALGORITHMS
if constexpr (_Is_min_max_optimization_safe<_FwdIt, _Pr>) {
if (!_Is_constant_evaluated()) {
const auto _First_ptr = _To_address(_First);
const auto _Result = _STD __std_minmax_element(_First_ptr, _To_address(_Last));
const auto _First_ptr = _STD _To_address(_First);
const auto _Result = _STD __std_minmax_element(_First_ptr, _STD _To_address(_Last));
if constexpr (is_pointer_v<_FwdIt>) {
return _Result;
} else {
Expand Down Expand Up @@ -9781,10 +9781,11 @@ constexpr pair<_FwdIt, _FwdIt> _Minmax_element_unchecked(_FwdIt _First, _FwdIt _
_EXPORT_STD template <class _FwdIt, class _Pr>
_NODISCARD constexpr pair<_FwdIt, _FwdIt> minmax_element(_FwdIt _First, _FwdIt _Last, _Pr _Pred) {
// find smallest and largest elements
_Adl_verify_range(_First, _Last);
const auto _Result = _STD _Minmax_element_unchecked(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Pass_fn(_Pred));
_Seek_wrapped(_Last, _Result.second);
_Seek_wrapped(_First, _Result.first);
_STD _Adl_verify_range(_First, _Last);
const auto _Result =
_STD _Minmax_element_unchecked(_STD _Get_unwrapped(_First), _STD _Get_unwrapped(_Last), _STD _Pass_fn(_Pred));
_STD _Seek_wrapped(_Last, _Result.second);
_STD _Seek_wrapped(_First, _Result.first);
return {_First, _Last};
}

Expand All @@ -9801,7 +9802,7 @@ _NODISCARD pair<_FwdIt, _FwdIt> minmax_element(_ExPo&&, _FwdIt _First, _FwdIt _L
// find smallest and largest elements
// not parallelized at present, parallelism expected to be feasible in a future release
_REQUIRE_PARALLEL_ITERATOR(_FwdIt);
return _STD minmax_element(_First, _Last, _Pass_fn(_Pred));
return _STD minmax_element(_First, _Last, _STD _Pass_fn(_Pred));
}

_EXPORT_STD template <class _ExPo, class _FwdIt, _Enable_if_execution_policy_t<_ExPo> = 0>
Expand Down Expand Up @@ -9838,8 +9839,8 @@ namespace ranges {
_Rng&& _Range, _Pr _Pred = {}, _Pj _Proj = {}) const {
auto _UResult = _Minmax_element_fwd_unchecked(
_RANGES _Ubegin(_Range), _RANGES _Uend(_Range), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj));
return {
_Rewrap_iterator(_Range, _STD move(_UResult.min)), _Rewrap_iterator(_Range, _STD move(_UResult.max))};
return {_RANGES _Rewrap_iterator(_Range, _STD move(_UResult.min)),
_RANGES _Rewrap_iterator(_Range, _STD move(_UResult.max))};
}

private:
Expand Down Expand Up @@ -9929,7 +9930,8 @@ _NODISCARD constexpr pair<const _Ty&, const _Ty&> minmax(const _Ty& _Left _MSVC_
_EXPORT_STD template <class _Ty, class _Pr>
_NODISCARD constexpr pair<_Ty, _Ty> minmax(initializer_list<_Ty> _Ilist, _Pr _Pred) {
// return {leftmost/smallest, rightmost/largest}
pair<const _Ty*, const _Ty*> _Res = _STD _Minmax_element_unchecked(_Ilist.begin(), _Ilist.end(), _Pass_fn(_Pred));
pair<const _Ty*, const _Ty*> _Res =
_STD _Minmax_element_unchecked(_Ilist.begin(), _Ilist.end(), _STD _Pass_fn(_Pred));
return pair<_Ty, _Ty>(*_Res.first, *_Res.second);
}

Expand Down Expand Up @@ -10498,12 +10500,13 @@ namespace ranges {
indirect_strict_weak_order<projected<_It1, _Pj1>, projected<_It2, _Pj2>> _Pr = ranges::less>
_NODISCARD constexpr bool operator()(_It1 _First1, _Se1 _Last1, _It2 _First2, _Se2 _Last2, _Pr _Pred = {},
_Pj1 _Proj1 = {}, _Pj2 _Proj2 = {}) const {
_Adl_verify_range(_First1, _Last1);
_Adl_verify_range(_First2, _Last2);
_STD _Adl_verify_range(_First1, _Last1);
_STD _Adl_verify_range(_First2, _Last2);

return _Lexicographical_compare_unchecked(_Unwrap_iter<_Se1>(_STD move(_First1)),
_Unwrap_sent<_It1>(_STD move(_Last1)), _Unwrap_iter<_Se2>(_STD move(_First2)),
_Unwrap_sent<_It2>(_STD move(_Last2)), _Pass_fn(_Pred), _Pass_fn(_Proj1), _Pass_fn(_Proj2));
return _Lexicographical_compare_unchecked(_RANGES _Unwrap_iter<_Se1>(_STD move(_First1)),
_RANGES _Unwrap_sent<_It1>(_STD move(_Last1)), _RANGES _Unwrap_iter<_Se2>(_STD move(_First2)),
_RANGES _Unwrap_sent<_It2>(_STD move(_Last2)), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj1),
_STD _Pass_fn(_Proj2));
}

template <input_range _Rng1, input_range _Rng2, class _Pj1 = identity, class _Pj2 = identity,
Expand All @@ -10512,7 +10515,7 @@ namespace ranges {
_NODISCARD constexpr bool operator()(
_Rng1&& _Range1, _Rng2&& _Range2, _Pr _Pred = {}, _Pj1 _Proj1 = {}, _Pj2 _Proj2 = {}) const {
return _Lexicographical_compare_unchecked(_Ubegin(_Range1), _Uend(_Range1), _Ubegin(_Range2),
_Uend(_Range2), _Pass_fn(_Pred), _Pass_fn(_Proj1), _Pass_fn(_Proj2));
_Uend(_Range2), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj1), _STD _Pass_fn(_Proj2));
}

private:
Expand Down Expand Up @@ -10546,7 +10549,7 @@ namespace ranges {
_Num2 = SIZE_MAX;
}

const int _Ans = _Memcmp_count(_First1, _First2, (_STD min)(_Num1, _Num2));
const int _Ans = _STD _Memcmp_count(_First1, _First2, (_STD min)(_Num1, _Num2));
return _Memcmp_classification_pred{}(_Ans, 0) || (_Ans == 0 && _Num1 < _Num2);
}
}
Expand Down
Loading