Commit 02a86700 authored by Jan Wilken Dörrie's avatar Jan Wilken Dörrie Committed by Commit Bot

[base] Add base::not_fn

This change adds a C++14 backport of C++17's std::not_fn to
base/functional.

Bug: None
Change-Id: Ib441a7210e9992786c2dc241438dc8ea538ef73e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2498486
Commit-Queue: Jan Wilken Dörrie <jdoerrie@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#822128}
parent 566c7d1c
......@@ -262,6 +262,7 @@ component("base") {
"format_macros.h",
"functional/identity.h",
"functional/invoke.h",
"functional/not_fn.h",
"gtest_prod_util.h",
"guid.cc",
"guid.h",
......@@ -2743,6 +2744,7 @@ test("base_unittests") {
"files/scoped_temp_dir_unittest.cc",
"functional/identity_unittest.cc",
"functional/invoke_unittest.cc",
"functional/not_fn_unittest.cc",
"gmock_unittest.cc",
"guid_unittest.cc",
"hash/hash_unittest.cc",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_FUNCTIONAL_NOT_FN_H_
#define BASE_FUNCTIONAL_NOT_FN_H_
#include <type_traits>
#include <utility>
#include "base/functional/invoke.h"
namespace base {
namespace internal {
template <typename F>
struct NotFnImpl {
F f;
template <typename... Args>
constexpr decltype(auto) operator()(Args&&... args) & noexcept {
return !base::invoke(f, std::forward<Args>(args)...);
}
template <typename... Args>
constexpr decltype(auto) operator()(Args&&... args) const& noexcept {
return !base::invoke(f, std::forward<Args>(args)...);
}
template <typename... Args>
constexpr decltype(auto) operator()(Args&&... args) && noexcept {
return !base::invoke(std::move(f), std::forward<Args>(args)...);
}
template <typename... Args>
constexpr decltype(auto) operator()(Args&&... args) const&& noexcept {
return !base::invoke(std::move(f), std::forward<Args>(args)...);
}
};
} // namespace internal
// Implementation of C++17's std::not_fn.
//
// Reference:
// - https://en.cppreference.com/w/cpp/utility/functional/not_fn
// - https://wg21.link/func.not.fn
template <typename F>
constexpr internal::NotFnImpl<std::decay_t<F>> not_fn(F&& f) {
return {std::forward<F>(f)};
}
} // namespace base
#endif // BASE_FUNCTIONAL_NOT_FN_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/functional/not_fn.h"
#include <functional>
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
TEST(FunctionalTest, NotFn) {
constexpr auto not_less = base::not_fn(std::less<>());
using NotLessT = decltype(not_less);
static_assert(static_cast<const NotLessT&>(not_less)(1, 1), "");
static_assert(static_cast<NotLessT&>(not_less)(2, 1), "");
static_assert(static_cast<const NotLessT&&>(not_less)(2, 2), "");
static_assert(!static_cast<NotLessT&&>(not_less)(1, 2), "");
}
} // namespace base
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment