std::not_fn(3)

NAME
std::not_fn - std::not_fn

Synopsis
   Defined in header <functional>
   template< class F> (since C++17)
   /*unspecified*/ not_fn( F&& f ); (until C++20)
   template< class F> (since C++20)
   constexpr /*unspecified*/ not_fn( F&& f );
   Creates a forwarding call wrapper that returns the negation of the callable object
   it holds.

Parameters
   f - the object from which the Callable object held by the wrapper is
               constructed

Type requirements
   -
   std::decay_t<F> must meet the requirements of Callable and MoveConstructible.
   -
   std::is_constructible_v<std::decay_t<F>, F> is required to be true

Return value
   A function object of unspecified type T. It has the following members: std::not_fn return type

Member objects
   The return type of std::not_fn holds a member object of type std::decay_t<F>.
    Constructors
   explicit T(F&& f); // exposition only (since C++17)
                        (until C++20)
   explicit constexpr T(F&& f); // exposition only (1) (since C++20)
   T(T&& f) = default; (2)
   T(const T& f) = default;
   1) The constructor direct-non-list-initializes the member object (of type
   std::decay_t<F>) from std::forward<F>(f). Throws any exception thrown by the
   constructor selected
   2) Because std::decay_t<F> is required to be MoveConstructible, the returned call
   wrapper is always MoveConstructible, and is CopyConstructible if std::decay_t<F> is
   CopyConstructible.

Member function operator()
   template<class... Args> auto operator()(Args&&... args) &
   -> decltype(
   !std::declval<std::invoke_result_t<std::decay_t<F>&, (since
   Args...>>()); C++17)
   template<class... Args> auto operator()(Args&&... args) (until
   const& C++20)
   -> decltype(
   !std::declval<std::invoke_result_t<std::decay_t<F> const&,
   Args...>>());
   template<class... Args> constexpr auto operator()(Args&&...
   args) &
   noexcept(/*see below*/)
   -> decltype(
   !std::declval<std::invoke_result_t<std::decay_t<F>&,
   Args...>>()); (since
   template<class... Args> constexpr auto operator()(Args&&... C++20)
   args) const&
   noexcept(/*see below*/)
   -> decltype(
   !std::declval<std::invoke_result_t<std::decay_t<F> const&,
   Args...>>()); (1)
   template<class... Args> auto operator()(Args&&... args) &&
   -> decltype(
   !std::declval<std::invoke_result_t<std::decay_t<F>, (since
   Args...>>()); C++17)
   template<class... Args> auto operator()(Args&&... args) (until
   const&& C++20)
   -> decltype(
   !std::declval<std::invoke_result_t<std::decay_t<F> const,
   Args...>>());
   template<class... Args> constexpr auto operator()(Args&&...
   args) && (2)
   noexcept(/*see below*/)
   -> decltype(
   !std::declval<std::invoke_result_t<std::decay_t<F>,
   Args...>>()); (since
   template<class... Args> constexpr auto operator()(Args&&... C++20)
   args) const&&
   noexcept(/*see below*/)
   -> decltype(
   !std::declval<std::invoke_result_t<std::decay_t<F> const,
   Args...>>());
   1) Equivalent to return !std::invoke(fd, std::forward<Args>(args)...); (since C++17)
   2) Equivalent to return !std::invoke(std::move(fd), (until C++20)
   std::forward<Args>(args)...);
   1) Expression-equivalent to !std::invoke(fd,
   std::forward<Args>(args)...) (since C++20)
   2) Expression-equivalent to !std::invoke(std::move(fd),
   std::forward<Args>(args)...)
   where fd is the member object of type std::decay_t<F>
  Expression-equivalent
   Expression e is expression-equivalent to expression f, if
     * e and f have the same effects, and
     * either both are constant subexpressions or else neither is a constant
       subexpression, and
     * either both are potentially-throwing or else neither is potentially-throwing
       (i.e. noexcept(e) == noexcept(f)).

Exceptions
   Throws no exceptions, unless the construction of fd throws.

Possible implementation
   namespace detail {
       template<class F>
       struct not_fn_t {
           F f;
           template<class... Args>
           constexpr auto operator()(Args&&... args) &
               noexcept(noexcept(!std::invoke(f, std::forward<Args>(args)...)))
               -> decltype(!std::invoke(f, std::forward<Args>(args)...))
           {
               return !std::invoke(f, std::forward<Args>(args)...);
           }
           template<class... Args>
           constexpr auto operator()(Args&&... args) const&
               noexcept(noexcept(!std::invoke(f, std::forward<Args>(args)...)))
               -> decltype(!std::invoke(f, std::forward<Args>(args)...))
           {
               return !std::invoke(f, std::forward<Args>(args)...);
           }
           template<class... Args>
           constexpr auto operator()(Args&&... args) &&
               noexcept(noexcept(!std::invoke(std::move(f), std::forward<Args>(args)...)))
               -> decltype(!std::invoke(std::move(f), std::forward<Args>(args)...))
           {
               return !std::invoke(std::move(f), std::forward<Args>(args)...);
           }
           template<class... Args>
           constexpr auto operator()(Args&&... args) const&&
               noexcept(noexcept(!std::invoke(std::move(f), std::forward<Args>(args)...)))
               -> decltype(!std::invoke(std::move(f), std::forward<Args>(args)...))
           {
               return !std::invoke(std::move(f), std::forward<Args>(args)...);
           }
       };
   }
   template<class F>
   constexpr detail::not_fn_t<std::decay_t<F>> not_fn(F&& f)
   {
       return { std::forward<F>(f) };
   }

Notes
   not_fn is intended to replace the C++03-era negators std::not1 and std::not2.
   Feature-test macro: __cpp_lib_not_fn

Example
    This section is incomplete
    Reason: no example

See also
   not1 constructs custom std::unary_negate object
   (deprecated in C++17) (function template)
   (removed in C++20)
   not2 constructs custom std::binary_negate object
   (deprecated in C++17) (function template)
   (removed in C++20)