Re: [PATCH] Define std::not_fn for C++17

2016-08-19 Thread Jonathan Wakely

On 19/08/16 16:46 +0100, Jonathan Wakely wrote:

This updates std::experimental::not_fn to match the C++17 semantics
(which are a superset of the Library Fundamentals v2 semantics) and
then copies it to std::not_fn as well.

* doc/xml/manual/status_cxx2017.xml: Update status of not_fn.


Oops, the "fixes for not_fn" row in the table should be shown as done
too.


* doc/html/*: Regenerate.
* include/experimental/functional (_Not_fn, not_fn): Match C++17
semantics.
* include/std/functional (_Not_fn, not_fn): Define for C++17.
* testsuite/20_util/not_fn/1.cc: New.
* testsuite/experimental/functional/not_fn.cc: Test abstract class.
Remove test for volatile-qualified wrapper.

Tested x86_64-linux, committed to trunk.


I wonder if we want to move the experimental::_Not_fn class into
 and have std::not_fn and std::experimental::not_fn return
exactly the same type.




[PATCH] Define std::not_fn for C++17

2016-08-19 Thread Jonathan Wakely

This updates std::experimental::not_fn to match the C++17 semantics
(which are a superset of the Library Fundamentals v2 semantics) and
then copies it to std::not_fn as well.

* doc/xml/manual/status_cxx2017.xml: Update status of not_fn.
* doc/html/*: Regenerate.
* include/experimental/functional (_Not_fn, not_fn): Match C++17
semantics.
* include/std/functional (_Not_fn, not_fn): Define for C++17.
* testsuite/20_util/not_fn/1.cc: New.
* testsuite/experimental/functional/not_fn.cc: Test abstract class.
Remove test for volatile-qualified wrapper.

Tested x86_64-linux, committed to trunk.


commit 8014ab8c2415e84d4b9b9f9de0718633dc8ca7b8
Author: Jonathan Wakely 
Date:   Fri Aug 19 12:33:13 2016 +0100

Define std::not_fn for C++17

* doc/xml/manual/status_cxx2017.xml: Update status of not_fn.
* doc/html/*: Regenerate.
* include/experimental/functional (_Not_fn, not_fn): Match C++17
semantics.
* include/std/functional (_Not_fn, not_fn): Define for C++17.
* testsuite/20_util/not_fn/1.cc: New.
* testsuite/experimental/functional/not_fn.cc: Test abstract class.
Remove test for volatile-qualified wrapper.

diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2017.xml 
b/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
index 331420e..ff96627 100644
--- a/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
+++ b/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
@@ -321,14 +321,13 @@ Feature-testing recommendations for C++.
 
 
 
-  
Adopt not_fn from Library Fundamentals 2 for C++17 

   
http://www.w3.org/1999/xlink; 
xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0005r4.html;>
P0005R4

   
-   No 
+   7 
   __cpp_lib_not_fn >= 201603
 
 
diff --git a/libstdc++-v3/include/experimental/functional 
b/libstdc++-v3/include/experimental/functional
index ed41f5a..eddbcf1 100644
--- a/libstdc++-v3/include/experimental/functional
+++ b/libstdc++-v3/include/experimental/functional
@@ -386,41 +386,46 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 public:
   template
explicit
-   _Not_fn(_Fn2&& __fn) : _M_fn(std::forward<_Fn2>(__fn)) { }
+   _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& operator=(const _Not_fn& __fn) = default;
-  _Not_fn& operator=(_Not_fn&& __fn) = default;
   ~_Not_fn() = default;
 
   template
auto
-   operator()(_Args&&... __args)
-   noexcept(noexcept(!_M_fn(std::forward<_Args>(__args)...)))
-   -> decltype(!_M_fn(std::forward<_Args>(__args)...))
-   { return !_M_fn(std::forward<_Args>(__args)...); }
+   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(noexcept(!_M_fn(std::forward<_Args>(__args)...)))
-   -> decltype(!_M_fn(std::forward<_Args>(__args)...))
-   { return !_M_fn(std::forward<_Args>(__args)...); }
+   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) volatile
-   noexcept(noexcept(!_M_fn(std::forward<_Args>(__args)...)))
-   -> decltype(!_M_fn(std::forward<_Args>(__args)...))
-   { return !_M_fn(std::forward<_Args>(__args)...); }
+   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 volatile
-   noexcept(noexcept(!_M_fn(std::forward<_Args>(__args)...)))
-   -> decltype(!_M_fn(std::forward<_Args>(__args)...))
-   { return !_M_fn(std::forward<_Args>(__args)...); }
+   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
@@ -429,8 +434,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 not_fn(_Fn&& __fn)
 noexcept(std::is_nothrow_constructible, _Fn&&>::value)
 {
-  using __maybe_type =