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 <type_traits> 9 #include <utility> 10 11 #include "base/functional/invoke.h" 12 13 namespace base { 14 15 namespace internal { 16 17 template <typename F> 18 struct NotFnImpl { 19 F f; 20 21 template <typename... Args> decltypeNotFnImpl22 constexpr decltype(auto) operator()(Args&&... args) & noexcept { 23 return !base::invoke(f, std::forward<Args>(args)...); 24 } 25 26 template <typename... Args> decltypeNotFnImpl27 constexpr decltype(auto) operator()(Args&&... args) const& noexcept { 28 return !base::invoke(f, std::forward<Args>(args)...); 29 } 30 31 template <typename... Args> decltypeNotFnImpl32 constexpr decltype(auto) operator()(Args&&... args) && noexcept { 33 return !base::invoke(std::move(f), std::forward<Args>(args)...); 34 } 35 36 template <typename... Args> decltypeNotFnImpl37 constexpr decltype(auto) operator()(Args&&... args) const&& noexcept { 38 return !base::invoke(std::move(f), std::forward<Args>(args)...); 39 } 40 }; 41 42 } // namespace internal 43 44 // Implementation of C++17's std::not_fn. 45 // 46 // Reference: 47 // - https://en.cppreference.com/w/cpp/utility/functional/not_fn 48 // - https://wg21.link/func.not.fn 49 template <typename F> not_fn(F && f)50constexpr internal::NotFnImpl<std::decay_t<F>> not_fn(F&& f) { 51 return {std::forward<F>(f)}; 52 } 53 54 } // namespace base 55 56 #endif // BASE_FUNCTIONAL_NOT_FN_H_ 57