-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[libc++] Forward std::all_of and std::none_of to std::any_of #167670
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
base: main
Are you sure you want to change the base?
Conversation
5ce7acb to
3f037ba
Compare
|
@llvm/pr-subscribers-libcxx Author: Nikolas Klauser (philnik777) ChangesThis allows propagating optimizations to different algorithms by just optimizing the lowest one. This is especially relevant now that we start optimizing how we're iterating through ranges (e.g. the segmented iterator optimizations) and adding assumptions so the compier can better leverage semantics guaranteed by the standard (e.g. Full diff: https://github.com/llvm/llvm-project/pull/167670.diff 2 Files Affected:
diff --git a/libcxx/include/__algorithm/all_of.h b/libcxx/include/__algorithm/all_of.h
index 6acc117fc47bc..bed6fdb073f80 100644
--- a/libcxx/include/__algorithm/all_of.h
+++ b/libcxx/include/__algorithm/all_of.h
@@ -10,9 +10,11 @@
#ifndef _LIBCPP___ALGORITHM_ALL_OF_H
#define _LIBCPP___ALGORITHM_ALL_OF_H
+#include <__algorithm/any_of.h>
#include <__config>
#include <__functional/identity.h>
#include <__type_traits/invoke.h>
+#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -23,11 +25,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Iter, class _Sent, class _Proj, class _Pred>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
__all_of(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
- for (; __first != __last; ++__first) {
- if (!std::__invoke(__pred, std::__invoke(__proj, *__first)))
- return false;
- }
- return true;
+ using _Ref = decltype(std::__invoke(__proj, *__first));
+ auto __wrapped_pred = [&__pred](_Ref __arg) { return !std::__invoke(__pred, std::forward<_Ref>(__arg)); };
+ return !std::__any_of(std::move(__first), std::move(__last), __wrapped_pred, __proj);
}
template <class _InputIterator, class _Predicate>
diff --git a/libcxx/include/__algorithm/none_of.h b/libcxx/include/__algorithm/none_of.h
index e6bd197622292..0ccdb4e0b0ec0 100644
--- a/libcxx/include/__algorithm/none_of.h
+++ b/libcxx/include/__algorithm/none_of.h
@@ -10,6 +10,7 @@
#ifndef _LIBCPP___ALGORITHM_NONE_OF_H
#define _LIBCPP___ALGORITHM_NONE_OF_H
+#include <__algorithm/any_of.h>
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -21,10 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _InputIterator, class _Predicate>
[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
- for (; __first != __last; ++__first)
- if (__pred(*__first))
- return false;
- return true;
+ return !std::any_of(__first, __last, __pred);
}
_LIBCPP_END_NAMESPACE_STD
|
ldionne
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this makes sense, have a few comments.
libcxx/include/__algorithm/all_of.h
Outdated
| } | ||
| return true; | ||
| using _Ref = decltype(std::__invoke(__proj, *__first)); | ||
| auto __wrapped_pred = [&__pred](_Ref __arg) { return !std::__invoke(__pred, std::forward<_Ref>(__arg)); }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if there is any benefit to spell _Ref out, rather than just taking a forwarding reference? is the bahaviour same if the _Ref is a PR value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, there is: the compiler doesn't crash. (See #145881)
3f037ba to
b5dfb37
Compare
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
libcxx/test/std/algorithms/robust_against_nonbool.compile.pass copy.cpp
Outdated
Show resolved
Hide resolved
92250df to
622f157
Compare
622f157 to
931f27c
Compare
This allows propagating optimizations to different algorithms by just optimizing the lowest one. This is especially relevant now that we start optimizing how we're iterating through ranges (e.g. the segmented iterator optimizations) and adding assumptions so the compier can better leverage semantics guaranteed by the standard (e.g.
__builtin_assume_dereferenceable).