On 05/10/16 12:31 +0100, Jonathan Wakely wrote:
Tested powerpc64le-linux, committing to trunk and gcc-6-branch.
And here's the slightly diffeernt patch for the branch (because we only have experimental::not_fn there, not std::not_fn).
commit 2484aeb5b25372c3a7833a000b798e3bf6f41c6b Author: redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Wed Oct 5 12:01:36 2016 +0000 PR 70564 disambiguate constructor for not_fn call wrapper PR libstdc++/70564 * include/experimental/functional (_Not_fn): Add second parameter to disambiguate copying from initialization by not_fn. (not_fn): Add second argument to initialization. * testsuite/experimental/functional/not_fn.cc: Copy call wrapper using direct-initialization. Test abstract class. diff --git a/libstdc++-v3/include/experimental/functional b/libstdc++-v3/include/experimental/functional index 0b91dcd..6a21caf 100644 --- a/libstdc++-v3/include/experimental/functional +++ b/libstdc++-v3/include/experimental/functional @@ -387,7 +387,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION public: template<typename _Fn2> explicit - _Not_fn(_Fn2&& __fn) : _M_fn(std::forward<_Fn2>(__fn)) { } + _Not_fn(_Fn2&& __fn, int) : _M_fn(std::forward<_Fn2>(__fn)) { } _Not_fn(const _Not_fn& __fn) = default; _Not_fn(_Not_fn&& __fn) = default; @@ -431,7 +431,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION noexcept(std::is_nothrow_constructible<std::decay_t<_Fn>, _Fn&&>::value) { using __maybe_type = _Maybe_wrap_member_pointer<std::decay_t<_Fn>>; - return _Not_fn<typename __maybe_type::type>{std::forward<_Fn>(__fn)}; + return _Not_fn<typename __maybe_type::type>{std::forward<_Fn>(__fn), 0}; } _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/testsuite/experimental/functional/not_fn.cc b/libstdc++-v3/testsuite/experimental/functional/not_fn.cc index 3096eaa..b69d3ac 100644 --- a/libstdc++-v3/testsuite/experimental/functional/not_fn.cc +++ b/libstdc++-v3/testsuite/experimental/functional/not_fn.cc @@ -76,10 +76,30 @@ test03() VERIFY( not_fn(&X::b)(x) ); } +void +test04() +{ + struct abstract { virtual void f() = 0; }; + struct derived : abstract { void f() { } }; + struct F { bool operator()(abstract&) { return false; } }; + F f; + derived d; + VERIFY( not_fn(f)(d) ); +} + +void +test05() +{ + auto nf = std::experimental::not_fn([] { return false; }); + auto copy(nf); // PR libstdc++/70564 +} + int main() { test01(); test02(); test03(); + test04(); + test05(); }