From 78ec9c15be7e34eb2b8c1faaea3e15b7740322df Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Wed, 5 Oct 2016 13:01:36 +0100 Subject: [PATCH] PR 70564 disambiguate constructors for not_fn call wrapper PR libstdc++/70564 * include/experimental/functional (_Not_fn): Remove. (not_fn): Use std::_Not_fn. * include/std/functional (_Not_fn): Add second parameter to disambiguate copying from initialization by not_fn. Define for C++14. (not_fn): Add second argument to initialization. * testsuite/20_util/not_fn/1.cc: Copy call wrapper using direct-initialization. From-SVN: r240778 --- libstdc++-v3/ChangeLog | 11 ++++ libstdc++-v3/include/experimental/functional | 53 +------------------ libstdc++-v3/include/std/functional | 28 +++++----- libstdc++-v3/testsuite/20_util/not_fn/1.cc | 7 +++ .../experimental/functional/not_fn.cc | 7 +++ 5 files changed, 40 insertions(+), 66 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 65637dc9071..20bbc5e13d6 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,14 @@ +2016-10-05 Jonathan Wakely + + PR libstdc++/70564 + * include/experimental/functional (_Not_fn): Remove. + (not_fn): Use std::_Not_fn. + * include/std/functional (_Not_fn): Add second parameter to + disambiguate copying from initialization by not_fn. Define for C++14. + (not_fn): Add second argument to initialization. + * testsuite/20_util/not_fn/1.cc: Copy call wrapper using + direct-initialization. + 2016-10-03 François Dumont * src/c++11/shared_ptr.cc (mask, invalid, get_mutex): Move diff --git a/libstdc++-v3/include/experimental/functional b/libstdc++-v3/include/experimental/functional index 082e58ccd07..db45665d150 100644 --- a/libstdc++-v3/include/experimental/functional +++ b/libstdc++-v3/include/experimental/functional @@ -378,64 +378,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #define __cpp_lib_experimental_not_fn 201406 - /// Generalized negator. - template - class _Not_fn - { - _Fn _M_fn; - - public: - template - explicit - _Not_fn(_Fn2&& __fn) - : _M_fn(std::forward<_Fn2>(__fn)) { } - - _Not_fn(const _Not_fn& __fn) = default; - _Not_fn(_Not_fn&& __fn) = default; - ~_Not_fn() = default; - - template - auto - operator()(_Args&&... __args) & - noexcept(__is_nothrow_callable<_Fn&(_Args&&...)>::value) - -> decltype(!std::declval>()) - { return !std::__invoke(_M_fn, std::forward<_Args>(__args)...); } - - template - auto - operator()(_Args&&... __args) const & - noexcept(__is_nothrow_callable::value) - -> decltype(!std::declval>()) - { return !std::__invoke(_M_fn, std::forward<_Args>(__args)...); } - - template - auto - operator()(_Args&&... __args) && - noexcept(__is_nothrow_callable<_Fn&&(_Args&&...)>::value) - -> decltype(!std::declval>()) - { - return !std::__invoke(std::move(_M_fn), - std::forward<_Args>(__args)...); - } - - template - auto - operator()(_Args&&... __args) const && - noexcept(__is_nothrow_callable::value) - -> decltype(!std::declval>()) - { - return !std::__invoke(std::move(_M_fn), - std::forward<_Args>(__args)...); - } - }; - /// [func.not_fn] Function template not_fn template inline auto not_fn(_Fn&& __fn) noexcept(std::is_nothrow_constructible, _Fn&&>::value) { - return _Not_fn>{std::forward<_Fn>(__fn)}; + return std::_Not_fn>{std::forward<_Fn>(__fn), 0}; } _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index 74e65c7b96f..1c7523e89af 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -2139,19 +2139,14 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) swap(function<_Res(_Args...)>& __x, function<_Res(_Args...)>& __y) noexcept { __x.swap(__y); } - -#if __cplusplus > 201402L - -#define __cpp_lib_not_fn 201603 - - /// Generalized negator. +#if __cplusplus >= 201402L + /// Generalized negator. template class _Not_fn { public: template - explicit - _Not_fn(_Fn2&& __fn) + _Not_fn(_Fn2&& __fn, int) : _M_fn(std::forward<_Fn2>(__fn)) { } _Not_fn(const _Not_fn& __fn) = default; @@ -2161,21 +2156,21 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) template auto operator()(_Args&&... __args) & - noexcept(is_nothrow_callable_v<_Fn&(_Args&&...)>) + noexcept(__is_nothrow_callable<_Fn&(_Args&&...)>::value) -> decltype(!std::declval>()) { return !std::__invoke(_M_fn, std::forward<_Args>(__args)...); } template auto operator()(_Args&&... __args) const & - noexcept(is_nothrow_callable_v) + noexcept(__is_nothrow_callable::value) -> decltype(!std::declval>()) { return !std::__invoke(_M_fn, std::forward<_Args>(__args)...); } template auto operator()(_Args&&... __args) && - noexcept(is_nothrow_callable_v<_Fn&&(_Args&&...)>) + noexcept(__is_nothrow_callable<_Fn&&(_Args&&...)>::value) -> decltype(!std::declval>()) { return !std::__invoke(std::move(_M_fn), @@ -2185,7 +2180,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) template auto operator()(_Args&&... __args) const && - noexcept(is_nothrow_callable_v) + noexcept(__is_nothrow_callable::value) -> decltype(!std::declval>()) { return !std::__invoke(std::move(_M_fn), @@ -2195,6 +2190,11 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) private: _Fn _M_fn; }; +#endif // C++14 + +#if __cplusplus > 201402L + +#define __cpp_lib_not_fn 201603 /// [func.not_fn] Function template not_fn template @@ -2202,7 +2202,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) not_fn(_Fn&& __fn) noexcept(std::is_nothrow_constructible, _Fn&&>::value) { - return _Not_fn>{std::forward<_Fn>(__fn)}; + return _Not_fn>{std::forward<_Fn>(__fn), 0}; } // Searchers @@ -2515,7 +2515,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) return std::make_pair(__last, __last); } -#endif +#endif // C++17 _GLIBCXX_END_NAMESPACE_VERSION } // namespace std diff --git a/libstdc++-v3/testsuite/20_util/not_fn/1.cc b/libstdc++-v3/testsuite/20_util/not_fn/1.cc index 375c7cc1367..8d6e9eccee1 100644 --- a/libstdc++-v3/testsuite/20_util/not_fn/1.cc +++ b/libstdc++-v3/testsuite/20_util/not_fn/1.cc @@ -84,6 +84,12 @@ test04() VERIFY( not_fn(f)(d) ); } +void +test05() +{ + auto nf{ std::not_fn([] { return false; }) }; +} + int main() { @@ -91,4 +97,5 @@ main() test02(); test03(); test04(); + test05(); } diff --git a/libstdc++-v3/testsuite/experimental/functional/not_fn.cc b/libstdc++-v3/testsuite/experimental/functional/not_fn.cc index d5080288e31..59d7621fb93 100644 --- a/libstdc++-v3/testsuite/experimental/functional/not_fn.cc +++ b/libstdc++-v3/testsuite/experimental/functional/not_fn.cc @@ -84,6 +84,12 @@ test04() VERIFY( not_fn(f)(d) ); } +void +test05() +{ + auto nf{ not_fn([] { return false; }) }; +} + int main() { @@ -91,4 +97,5 @@ main() test02(); test03(); test04(); + test05(); }