Commit b40c57bd by Patrick Palka

libstdc++: Convert the ranges algorithm entities into function objects

This is the standard way to inhibit ADL for these entities, which is required as
per [algorithms.requirements] p2 and [specialized.algorithms] p4.  The
conversion was done mostly mechanically with a custom Vim macro.

libstdc++-v3/ChangeLog:

	* include/bits/ranges_algo.h: (adjacent_find, all_of, any_of,
	binary_search, copy_if, count, count_if, equal_range, find, find_end,
	find_first_of, find_if, find_if_not, for_each, generate, generate_n,
	includes, inplace_merge, is_heap, is_heap_until, is_partitioned,
	is_permutation, is_sorted, is_sorted_until, lexicographical_compare,
	lower_bound, make_heap, max, max_element, merge, min, min_element,
	minmax, minmax_element, mismatch, next_permutation, none_of,
	nth_element, partial_sort, partial_sort_copy, partition, partition_copy,
	partition_point, pop_heap, prev_permutation, push_heap, remove,
	remove_copy, remove_copy_if, remove_if, replace, replace_copy,
	replace_copy_if, replace_if, reverse, reverse_copy, rotate, rotate_copy,
	search, search_n, set_difference, set_intersection,
	set_symmetric_difference, set_union, shuffle, sort, sort_heap,
	stable_partition, stable_sort, swap_ranges, transform, unique,
	unique_copy, upper_bound): Convert into function objects.
	* include/bits/ranges_algobase.h: (equal, copy, move, copy_n, fill_n,
	fill, move_backward, copy_backward): Likewise.
	* include/bits/ranges_uninitialized.h (uninitialized_default_construct,
	uninitialized_default_construct_n, uninitialized_value_construct,
	uninitialized_value_construct_n, uninitialized_copy,
	uninitialized_copy_n, uninitialized_move, uninitialized_move_n,
	uninitialized_fill, uninitialized_fill_n, construct_at, destroy_at,
	destroy, destroy_n): Likewise.
parent 90b7eb65
2020-02-15 Patrick Palka <ppalka@redhat.com>
* include/bits/ranges_algo.h: (adjacent_find, all_of, any_of,
binary_search, copy_if, count, count_if, equal_range, find, find_end,
find_first_of, find_if, find_if_not, for_each, generate, generate_n,
includes, inplace_merge, is_heap, is_heap_until, is_partitioned,
is_permutation, is_sorted, is_sorted_until, lexicographical_compare,
lower_bound, make_heap, max, max_element, merge, min, min_element,
minmax, minmax_element, mismatch, next_permutation, none_of,
nth_element, partial_sort, partial_sort_copy, partition, partition_copy,
partition_point, pop_heap, prev_permutation, push_heap, remove,
remove_copy, remove_copy_if, remove_if, replace, replace_copy,
replace_copy_if, replace_if, reverse, reverse_copy, rotate, rotate_copy,
search, search_n, set_difference, set_intersection,
set_symmetric_difference, set_union, shuffle, sort, sort_heap,
stable_partition, stable_sort, swap_ranges, transform, unique,
unique_copy, upper_bound): Convert into function objects.
* include/bits/ranges_algobase.h: (equal, copy, move, copy_n, fill_n,
fill, move_backward, copy_backward): Likewise.
* include/bits/ranges_uninitialized.h (uninitialized_default_construct,
uninitialized_default_construct_n, uninitialized_value_construct,
uninitialized_value_construct_n, uninitialized_copy,
uninitialized_copy_n, uninitialized_move, uninitialized_move_n,
uninitialized_fill, uninitialized_fill_n, construct_at, destroy_at,
destroy, destroy_n): Likewise.
* include/bits/ranges_algo.h (ranges::__find_end): Fold into ...
(ranges::find_end): ... here.
(ranges::__lexicographical_compare): Fold into ...
......
......@@ -71,20 +71,22 @@ namespace ranges
__is_move_iterator<move_iterator<_Iterator>> = true;
} // namespace __detail
struct __equal_fn
{
template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
typename _Pred = ranges::equal_to,
typename _Proj1 = identity, typename _Proj2 = identity>
requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
constexpr bool
equal(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2,
_Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {})
operator()(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2,
_Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
{
// TODO: implement more specializations to at least have parity with
// std::equal.
if constexpr (__detail::__is_normal_iterator<_Iter1>
|| __detail::__is_normal_iterator<_Iter2>)
return ranges::equal(std::__niter_base(std::move(__first1)),
return (*this)(std::__niter_base(std::move(__first1)),
std::__niter_base(std::move(__last1)),
std::__niter_base(std::move(__first2)),
std::__niter_base(std::move(__last2)),
......@@ -145,14 +147,17 @@ namespace ranges
requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
_Pred, _Proj1, _Proj2>
constexpr bool
equal(_Range1&& __r1, _Range2&& __r2,
_Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {})
operator()(_Range1&& __r1, _Range2&& __r2,
_Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
{
return ranges::equal(ranges::begin(__r1), ranges::end(__r1),
return (*this)(ranges::begin(__r1), ranges::end(__r1),
ranges::begin(__r2), ranges::end(__r2),
std::move(__pred),
std::move(__proj1), std::move(__proj2));
}
};
inline constexpr __equal_fn equal{};
template<typename _Iter, typename _Out>
struct copy_result
......@@ -288,11 +293,13 @@ namespace ranges
}
}
struct __copy_fn
{
template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
weakly_incrementable _Out>
requires indirectly_copyable<_Iter, _Out>
constexpr copy_result<_Iter, _Out>
copy(_Iter __first, _Sent __last, _Out __result)
operator()(_Iter __first, _Sent __last, _Out __result) const
{
return ranges::__copy_or_move<false>(std::move(__first),
std::move(__last),
......@@ -302,17 +309,22 @@ namespace ranges
template<input_range _Range, weakly_incrementable _Out>
requires indirectly_copyable<iterator_t<_Range>, _Out>
constexpr copy_result<safe_iterator_t<_Range>, _Out>
copy(_Range&& __r, _Out __result)
operator()(_Range&& __r, _Out __result) const
{
return ranges::copy(ranges::begin(__r), ranges::end(__r),
return (*this)(ranges::begin(__r), ranges::end(__r),
std::move(__result));
}
};
inline constexpr __copy_fn copy{};
struct __move_fn
{
template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
weakly_incrementable _Out>
requires indirectly_movable<_Iter, _Out>
constexpr move_result<_Iter, _Out>
move(_Iter __first, _Sent __last, _Out __result)
operator()(_Iter __first, _Sent __last, _Out __result) const
{
return ranges::__copy_or_move<true>(std::move(__first),
std::move(__last),
......@@ -322,11 +334,14 @@ namespace ranges
template<input_range _Range, weakly_incrementable _Out>
requires indirectly_movable<iterator_t<_Range>, _Out>
constexpr move_result<safe_iterator_t<_Range>, _Out>
move(_Range&& __r, _Out __result)
operator()(_Range&& __r, _Out __result) const
{
return ranges::move(ranges::begin(__r), ranges::end(__r),
return (*this)(ranges::begin(__r), ranges::end(__r),
std::move(__result));
}
};
inline constexpr __move_fn move{};
template<bool _IsMove,
bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent,
......@@ -420,11 +435,13 @@ namespace ranges
}
}
struct __copy_backward_fn
{
template<bidirectional_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
bidirectional_iterator _Iter2>
requires indirectly_copyable<_Iter1, _Iter2>
constexpr copy_backward_result<_Iter1, _Iter2>
copy_backward(_Iter1 __first, _Sent1 __last, _Iter2 __result)
operator()(_Iter1 __first, _Sent1 __last, _Iter2 __result) const
{
return ranges::__copy_or_move_backward<false>(std::move(__first),
std::move(__last),
......@@ -434,17 +451,22 @@ namespace ranges
template<bidirectional_range _Range, bidirectional_iterator _Iter>
requires indirectly_copyable<iterator_t<_Range>, _Iter>
constexpr copy_backward_result<safe_iterator_t<_Range>, _Iter>
copy_backward(_Range&& __r, _Iter __result)
operator()(_Range&& __r, _Iter __result) const
{
return ranges::copy_backward(ranges::begin(__r), ranges::end(__r),
return (*this)(ranges::begin(__r), ranges::end(__r),
std::move(__result));
}
};
inline constexpr __copy_backward_fn copy_backward{};
struct __move_backward_fn
{
template<bidirectional_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
bidirectional_iterator _Iter2>
requires indirectly_movable<_Iter1, _Iter2>
constexpr move_backward_result<_Iter1, _Iter2>
move_backward(_Iter1 __first, _Sent1 __last, _Iter2 __result)
operator()(_Iter1 __first, _Sent1 __last, _Iter2 __result) const
{
return ranges::__copy_or_move_backward<true>(std::move(__first),
std::move(__last),
......@@ -454,19 +476,24 @@ namespace ranges
template<bidirectional_range _Range, bidirectional_iterator _Iter>
requires indirectly_movable<iterator_t<_Range>, _Iter>
constexpr move_backward_result<safe_iterator_t<_Range>, _Iter>
move_backward(_Range&& __r, _Iter __result)
operator()(_Range&& __r, _Iter __result) const
{
return ranges::move_backward(ranges::begin(__r), ranges::end(__r),
return (*this)(ranges::begin(__r), ranges::end(__r),
std::move(__result));
}
};
inline constexpr __move_backward_fn move_backward{};
template<typename _Iter, typename _Out>
using copy_n_result = copy_result<_Iter, _Out>;
struct __copy_n_fn
{
template<input_iterator _Iter, weakly_incrementable _Out>
requires indirectly_copyable<_Iter, _Out>
constexpr copy_n_result<_Iter, _Out>
copy_n(_Iter __first, iter_difference_t<_Iter> __n, _Out __result)
operator()(_Iter __first, iter_difference_t<_Iter> __n, _Out __result) const
{
if constexpr (random_access_iterator<_Iter>)
return ranges::copy(__first, __first + __n, std::move(__result));
......@@ -477,10 +504,15 @@ namespace ranges
return {std::move(__first), std::move(__result)};
}
}
};
inline constexpr __copy_n_fn copy_n{};
struct __fill_n_fn
{
template<typename _Tp, output_iterator<const _Tp&> _Out>
constexpr _Out
fill_n(_Out __first, iter_difference_t<_Out> __n, const _Tp& __value)
operator()(_Out __first, iter_difference_t<_Out> __n, const _Tp& __value) const
{
// TODO: implement more specializations to be at least on par with
// std::fill_n
......@@ -507,11 +539,16 @@ namespace ranges
return __first;
}
}
};
inline constexpr __fill_n_fn fill_n{};
struct __fill_fn
{
template<typename _Tp,
output_iterator<const _Tp&> _Out, sentinel_for<_Out> _Sent>
constexpr _Out
fill(_Out __first, _Sent __last, const _Tp& __value)
operator()(_Out __first, _Sent __last, const _Tp& __value) const
{
// TODO: implement more specializations to be at least on par with
// std::fill
......@@ -537,10 +574,13 @@ namespace ranges
template<typename _Tp, output_range<const _Tp&> _Range>
constexpr safe_iterator_t<_Range>
fill(_Range&& __r, const _Tp& __value)
operator()(_Range&& __r, const _Tp& __value) const
{
return ranges::fill(ranges::begin(__r), ranges::end(__r), __value);
return (*this)(ranges::begin(__r), ranges::end(__r), __value);
}
};
inline constexpr __fill_fn fill{};
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment