Add C++17 std::not_fn negator.
Summary:
Exactly what it sounds like.
I plan to commit this in a couple of days assuming no objections.
Reviewers: mclow.lists, EricWF
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D20799
llvm-svn: 271464
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: 5725756791452eb91e23e37cb9958687771cb10a
diff --git a/include/functional b/include/functional
index 4fcd4b5..9e4d5db 100644
--- a/include/functional
+++ b/include/functional
@@ -207,6 +207,8 @@
template <class Predicate> binary_negate<Predicate> not2(const Predicate& pred);
+template <class F> unspecified not_fn(F&& f); // C++17
+
template<class T> struct is_bind_expression;
template<class T> struct is_placeholder;
@@ -2585,11 +2587,54 @@
#if _LIBCPP_STD_VER > 14
+
template <class _Fn, class ..._Args>
result_of_t<_Fn&&(_Args&&...)>
-invoke(_Fn&& __f, _Args&&... __args) {
- return __invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...);
+invoke(_Fn&& __f, _Args&&... __args)
+ noexcept(noexcept(_VSTD::__invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...)))
+{
+ return _VSTD::__invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...);
}
+
+template <class _DecayFunc>
+class _LIBCPP_TYPE_VIS_ONLY __not_fn_imp {
+ _DecayFunc __fd;
+
+public:
+ __not_fn_imp() = delete;
+
+ template <class ..._Args>
+ _LIBCPP_INLINE_VISIBILITY
+ auto operator()(_Args&& ...__args)
+ noexcept(noexcept(!_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...)))
+ -> decltype(!_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...))
+ { return !_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...); }
+
+ template <class ..._Args>
+ _LIBCPP_INLINE_VISIBILITY
+ auto operator()(_Args&& ...__args) const
+ noexcept(noexcept(!_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...)))
+ -> decltype(!_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...))
+ { return !_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...); }
+
+private:
+ template <class _RawFunc,
+ class = enable_if_t<!is_same<decay_t<_RawFunc>, __not_fn_imp>::value>>
+ _LIBCPP_INLINE_VISIBILITY
+ explicit __not_fn_imp(_RawFunc&& __rf)
+ : __fd(_VSTD::forward<_RawFunc>(__rf)) {}
+
+ template <class _RawFunc>
+ friend inline _LIBCPP_INLINE_VISIBILITY
+ __not_fn_imp<decay_t<_RawFunc>> not_fn(_RawFunc&&);
+};
+
+template <class _RawFunc>
+inline _LIBCPP_INLINE_VISIBILITY
+__not_fn_imp<decay_t<_RawFunc>> not_fn(_RawFunc&& __fn) {
+ return __not_fn_imp<decay_t<_RawFunc>>(_VSTD::forward<_RawFunc>(__fn));
+}
+
#endif
// struct hash<T*> in <memory>