• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef BASE_FUNCTIONAL_NOT_FN_H_
6 #define BASE_FUNCTIONAL_NOT_FN_H_
7 
8 #include <functional>
9 #include <type_traits>
10 #include <utility>
11 
12 namespace base {
13 
14 namespace internal {
15 
16 template <typename F>
17 struct NotFnImpl {
18   F f;
19 
20   template <typename... Args>
decltypeNotFnImpl21   constexpr decltype(auto) operator()(Args&&... args) & noexcept {
22     return !std::invoke(f, std::forward<Args>(args)...);
23   }
24 
25   template <typename... Args>
decltypeNotFnImpl26   constexpr decltype(auto) operator()(Args&&... args) const& noexcept {
27     return !std::invoke(f, std::forward<Args>(args)...);
28   }
29 
30   template <typename... Args>
decltypeNotFnImpl31   constexpr decltype(auto) operator()(Args&&... args) && noexcept {
32     return !std::invoke(std::move(f), std::forward<Args>(args)...);
33   }
34 
35   template <typename... Args>
decltypeNotFnImpl36   constexpr decltype(auto) operator()(Args&&... args) const&& noexcept {
37     return !std::invoke(std::move(f), std::forward<Args>(args)...);
38   }
39 };
40 
41 }  // namespace internal
42 
43 // Implementation of C++17's std::not_fn.
44 //
45 // Reference:
46 // - https://en.cppreference.com/w/cpp/utility/functional/not_fn
47 // - https://wg21.link/func.not.fn
48 template <typename F>
not_fn(F && f)49 constexpr internal::NotFnImpl<std::decay_t<F>> not_fn(F&& f) {
50   return {std::forward<F>(f)};
51 }
52 
53 }  // namespace base
54 
55 #endif  // BASE_FUNCTIONAL_NOT_FN_H_
56