Commit 9de7d687 authored by Anton Bikineev's avatar Anton Bikineev Committed by Commit Bot

base/ranges: Explicitly qualify calls to base::invoke to avoid ADL

Otherwise, if proj or pred has base::internal as associated namespace,
ADL can pick up the invoke functions from base::internal, which will
result in ambiguous calls.

Change-Id: I0659762dcb078427e820f5cbb90db807e126601e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2447549Reviewed-by: default avatarPeter Kasting <pkasting@chromium.org>
Reviewed-by: default avatarJan Wilken Dörrie <jdoerrie@chromium.org>
Commit-Queue: Anton Bikineev <bikineev@chromium.org>
Cr-Commit-Position: refs/heads/master@{#816568}
parent 90230246
...@@ -201,7 +201,7 @@ constexpr bool all_of(InputIterator first, ...@@ -201,7 +201,7 @@ constexpr bool all_of(InputIterator first,
Pred pred, Pred pred,
Proj proj = {}) { Proj proj = {}) {
for (; first != last; ++first) { for (; first != last; ++first) {
if (!invoke(pred, invoke(proj, *first))) if (!base::invoke(pred, base::invoke(proj, *first)))
return false; return false;
} }
...@@ -247,7 +247,7 @@ constexpr bool any_of(InputIterator first, ...@@ -247,7 +247,7 @@ constexpr bool any_of(InputIterator first,
Pred pred, Pred pred,
Proj proj = {}) { Proj proj = {}) {
for (; first != last; ++first) { for (; first != last; ++first) {
if (invoke(pred, invoke(proj, *first))) if (base::invoke(pred, base::invoke(proj, *first)))
return true; return true;
} }
...@@ -293,7 +293,7 @@ constexpr bool none_of(InputIterator first, ...@@ -293,7 +293,7 @@ constexpr bool none_of(InputIterator first,
Pred pred, Pred pred,
Proj proj = {}) { Proj proj = {}) {
for (; first != last; ++first) { for (; first != last; ++first) {
if (invoke(pred, invoke(proj, *first))) if (base::invoke(pred, base::invoke(proj, *first)))
return false; return false;
} }
...@@ -344,7 +344,7 @@ constexpr auto for_each(InputIterator first, ...@@ -344,7 +344,7 @@ constexpr auto for_each(InputIterator first,
Fun f, Fun f,
Proj proj = {}) { Proj proj = {}) {
for (; first != last; ++first) for (; first != last; ++first)
invoke(f, invoke(proj, *first)); base::invoke(f, base::invoke(proj, *first));
return for_each_result<InputIterator, Fun>{first, std::move(f)}; return for_each_result<InputIterator, Fun>{first, std::move(f)};
} }
...@@ -389,7 +389,7 @@ template <typename InputIterator, ...@@ -389,7 +389,7 @@ template <typename InputIterator,
typename = internal::iterator_category_t<InputIterator>> typename = internal::iterator_category_t<InputIterator>>
constexpr auto for_each_n(InputIterator first, Size n, Fun f, Proj proj = {}) { constexpr auto for_each_n(InputIterator first, Size n, Fun f, Proj proj = {}) {
while (n > 0) { while (n > 0) {
invoke(f, invoke(proj, *first)); base::invoke(f, base::invoke(proj, *first));
++first; ++first;
--n; --n;
} }
...@@ -420,7 +420,7 @@ constexpr auto find(InputIterator first, ...@@ -420,7 +420,7 @@ constexpr auto find(InputIterator first,
// Note: In order to be able to apply `proj` to each element in [first, last) // Note: In order to be able to apply `proj` to each element in [first, last)
// we are dispatching to std::find_if instead of std::find. // we are dispatching to std::find_if instead of std::find.
return std::find_if(first, last, [&proj, &value](auto&& lhs) { return std::find_if(first, last, [&proj, &value](auto&& lhs) {
return invoke(proj, std::forward<decltype(lhs)>(lhs)) == value; return base::invoke(proj, std::forward<decltype(lhs)>(lhs)) == value;
}); });
} }
...@@ -742,7 +742,7 @@ constexpr auto count(InputIterator first, ...@@ -742,7 +742,7 @@ constexpr auto count(InputIterator first,
// Note: In order to be able to apply `proj` to each element in [first, last) // Note: In order to be able to apply `proj` to each element in [first, last)
// we are dispatching to std::count_if instead of std::count. // we are dispatching to std::count_if instead of std::count.
return std::count_if(first, last, [&proj, &value](auto&& lhs) { return std::count_if(first, last, [&proj, &value](auto&& lhs) {
return invoke(proj, std::forward<decltype(lhs)>(lhs)) == value; return base::invoke(proj, std::forward<decltype(lhs)>(lhs)) == value;
}); });
} }
...@@ -1523,7 +1523,8 @@ constexpr auto transform(InputIterator first1, ...@@ -1523,7 +1523,8 @@ constexpr auto transform(InputIterator first1,
UnaryOperation op, UnaryOperation op,
Proj proj = {}) { Proj proj = {}) {
return std::transform(first1, last1, result, [&op, &proj](auto&& arg) { return std::transform(first1, last1, result, [&op, &proj](auto&& arg) {
return invoke(op, invoke(proj, std::forward<decltype(arg)>(arg))); return base::invoke(op,
base::invoke(proj, std::forward<decltype(arg)>(arg)));
}); });
} }
...@@ -1603,13 +1604,13 @@ constexpr auto transform(ForwardIterator1 first1, ...@@ -1603,13 +1604,13 @@ constexpr auto transform(ForwardIterator1 first1,
// `last1` to ensure to not read past `last2`. // `last1` to ensure to not read past `last2`.
last1 = std::next(first1, std::min(std::distance(first1, last1), last1 = std::next(first1, std::min(std::distance(first1, last1),
std::distance(first2, last2))); std::distance(first2, last2)));
return std::transform(first1, last1, first2, result, return std::transform(
[&binary_op, &proj1, &proj2](auto&& lhs, auto&& rhs) { first1, last1, first2, result,
return invoke( [&binary_op, &proj1, &proj2](auto&& lhs, auto&& rhs) {
binary_op, return base::invoke(
invoke(proj1, std::forward<decltype(lhs)>(lhs)), binary_op, base::invoke(proj1, std::forward<decltype(lhs)>(lhs)),
invoke(proj2, std::forward<decltype(rhs)>(rhs))); base::invoke(proj2, std::forward<decltype(rhs)>(rhs)));
}); });
} }
// Let: // Let:
...@@ -1685,7 +1686,8 @@ constexpr auto replace(ForwardIterator first, ...@@ -1685,7 +1686,8 @@ constexpr auto replace(ForwardIterator first,
std::replace_if( std::replace_if(
first, last, first, last,
[&proj, &old_value](auto&& lhs) { [&proj, &old_value](auto&& lhs) {
return invoke(proj, std::forward<decltype(lhs)>(lhs)) == old_value; return base::invoke(proj, std::forward<decltype(lhs)>(lhs)) ==
old_value;
}, },
new_value); new_value);
return last; return last;
...@@ -1805,7 +1807,8 @@ constexpr auto replace_copy(InputIterator first, ...@@ -1805,7 +1807,8 @@ constexpr auto replace_copy(InputIterator first,
std::replace_copy_if( std::replace_copy_if(
first, last, result, first, last, result,
[&proj, &old_value](auto&& lhs) { [&proj, &old_value](auto&& lhs) {
return invoke(proj, std::forward<decltype(lhs)>(lhs)) == old_value; return base::invoke(proj, std::forward<decltype(lhs)>(lhs)) ==
old_value;
}, },
new_value); new_value);
return last; return last;
...@@ -2065,7 +2068,7 @@ constexpr auto remove(ForwardIterator first, ...@@ -2065,7 +2068,7 @@ constexpr auto remove(ForwardIterator first,
// Note: In order to be able to apply `proj` to each element in [first, last) // Note: In order to be able to apply `proj` to each element in [first, last)
// we are dispatching to std::remove_if instead of std::remove. // we are dispatching to std::remove_if instead of std::remove.
return std::remove_if(first, last, [&proj, &value](auto&& lhs) { return std::remove_if(first, last, [&proj, &value](auto&& lhs) {
return invoke(proj, std::forward<decltype(lhs)>(lhs)) == value; return base::invoke(proj, std::forward<decltype(lhs)>(lhs)) == value;
}); });
} }
...@@ -2172,7 +2175,7 @@ constexpr auto remove_copy(InputIterator first, ...@@ -2172,7 +2175,7 @@ constexpr auto remove_copy(InputIterator first,
// Note: In order to be able to apply `proj` to each element in [first, last) // Note: In order to be able to apply `proj` to each element in [first, last)
// we are dispatching to std::remove_copy_if instead of std::remove_copy. // we are dispatching to std::remove_copy_if instead of std::remove_copy.
return std::remove_copy_if(first, last, result, [&proj, &value](auto&& lhs) { return std::remove_copy_if(first, last, result, [&proj, &value](auto&& lhs) {
return invoke(proj, std::forward<decltype(lhs)>(lhs)) == value; return base::invoke(proj, std::forward<decltype(lhs)>(lhs)) == value;
}); });
} }
...@@ -3219,7 +3222,8 @@ constexpr auto binary_search(ForwardIterator first, ...@@ -3219,7 +3222,8 @@ constexpr auto binary_search(ForwardIterator first,
Comp comp = {}, Comp comp = {},
Proj proj = {}) { Proj proj = {}) {
first = ranges::lower_bound(first, last, value, comp, proj); first = ranges::lower_bound(first, last, value, comp, proj);
return first != last && !invoke(comp, value, invoke(proj, *first)); return first != last &&
!base::invoke(comp, value, base::invoke(proj, *first));
} }
// Preconditions: The elements `e` of `range` are partitioned with // Preconditions: The elements `e` of `range` are partitioned with
...@@ -4447,7 +4451,8 @@ constexpr auto is_heap_until(Range&& range, Comp comp = {}, Proj proj = {}) { ...@@ -4447,7 +4451,8 @@ constexpr auto is_heap_until(Range&& range, Comp comp = {}, Proj proj = {}) {
// Reference: https://wg21.link/alg.min.max#:~:text=ranges::min // Reference: https://wg21.link/alg.min.max#:~:text=ranges::min
template <typename T, typename Comp = ranges::less, typename Proj = identity> template <typename T, typename Comp = ranges::less, typename Proj = identity>
constexpr const T& min(const T& a, const T& b, Comp comp = {}, Proj proj = {}) { constexpr const T& min(const T& a, const T& b, Comp comp = {}, Proj proj = {}) {
return invoke(comp, invoke(proj, b), invoke(proj, a)) ? b : a; return base::invoke(comp, base::invoke(proj, b), base::invoke(proj, a)) ? b
: a;
} }
// Preconditions: `!empty(ilist)`. // Preconditions: `!empty(ilist)`.
...@@ -4496,7 +4501,8 @@ constexpr auto min(Range&& range, Comp comp = {}, Proj proj = {}) { ...@@ -4496,7 +4501,8 @@ constexpr auto min(Range&& range, Comp comp = {}, Proj proj = {}) {
// Reference: https://wg21.link/alg.min.max#:~:text=ranges::max // Reference: https://wg21.link/alg.min.max#:~:text=ranges::max
template <typename T, typename Comp = ranges::less, typename Proj = identity> template <typename T, typename Comp = ranges::less, typename Proj = identity>
constexpr const T& max(const T& a, const T& b, Comp comp = {}, Proj proj = {}) { constexpr const T& max(const T& a, const T& b, Comp comp = {}, Proj proj = {}) {
return invoke(comp, invoke(proj, a), invoke(proj, b)) ? b : a; return base::invoke(comp, base::invoke(proj, a), base::invoke(proj, b)) ? b
: a;
} }
// Preconditions: `!empty(ilist)`. // Preconditions: `!empty(ilist)`.
...@@ -4747,11 +4753,11 @@ constexpr const T& clamp(const T& v, ...@@ -4747,11 +4753,11 @@ constexpr const T& clamp(const T& v,
const T& hi, const T& hi,
Comp comp = {}, Comp comp = {},
Proj proj = {}) { Proj proj = {}) {
auto&& projected_v = invoke(proj, v); auto&& projected_v = base::invoke(proj, v);
if (invoke(comp, projected_v, invoke(proj, lo))) if (base::invoke(comp, projected_v, base::invoke(proj, lo)))
return lo; return lo;
return invoke(comp, invoke(proj, hi), projected_v) ? hi : v; return base::invoke(comp, base::invoke(proj, hi), projected_v) ? hi : v;
} }
// [alg.lex.comparison] Lexicographical comparison // [alg.lex.comparison] Lexicographical comparison
...@@ -4795,11 +4801,11 @@ constexpr bool lexicographical_compare(ForwardIterator1 first1, ...@@ -4795,11 +4801,11 @@ constexpr bool lexicographical_compare(ForwardIterator1 first1,
Proj1 proj1 = {}, Proj1 proj1 = {},
Proj2 proj2 = {}) { Proj2 proj2 = {}) {
for (; first1 != last1 && first2 != last2; ++first1, ++first2) { for (; first1 != last1 && first2 != last2; ++first1, ++first2) {
auto&& projected_first1 = invoke(proj1, *first1); auto&& projected_first1 = base::invoke(proj1, *first1);
auto&& projected_first2 = invoke(proj2, *first2); auto&& projected_first2 = base::invoke(proj2, *first2);
if (invoke(comp, projected_first1, projected_first2)) if (base::invoke(comp, projected_first1, projected_first2))
return true; return true;
if (invoke(comp, projected_first2, projected_first1)) if (base::invoke(comp, projected_first2, projected_first1))
return false; return false;
} }
......
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