Commit b7ceff06 by Dino Radakovic Committed by Copybara-Service

Release absl::AnyInvocable

AnyInvocable is a C++11 compatible equivalent of the C++23 [std::move_only_function](https://en.cppreference.com/w/cpp/utility/functional/move_only_function/move_only_function).
Although this implementation matches an intermediate draft revision of the standard (http://wg21.link/p0288r5), it is neither a standard tracking type nor a seamless backfill type.

PiperOrigin-RevId: 455494585
Change-Id: If01565f8eecc78eee38fb794ef142b32b31abc7c
parent 53a90f07
......@@ -109,9 +109,11 @@ set(ABSL_INTERNAL_DLL_FILES
"debugging/internal/symbolize.h"
"debugging/internal/vdso_support.cc"
"debugging/internal/vdso_support.h"
"functional/any_invocable.h"
"functional/internal/front_binder.h"
"functional/bind_front.h"
"functional/function_ref.h"
"functional/internal/any_invocable.h"
"functional/internal/function_ref.h"
"hash/hash.h"
"hash/internal/city.h"
......@@ -388,6 +390,7 @@ set(ABSL_INTERNAL_DLL_TARGETS
"kernel_timeout_internal"
"synchronization"
"thread_pool"
"any_invocable"
"bind_front"
"function_ref"
"atomic_hook"
......
......@@ -26,6 +26,40 @@ package(default_visibility = ["//visibility:public"])
licenses(["notice"])
cc_library(
name = "any_invocable",
srcs = ["internal/any_invocable.h"],
hdrs = ["any_invocable.h"],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
"//absl/base:base_internal",
"//absl/base:config",
"//absl/base:core_headers",
"//absl/meta:type_traits",
"//absl/utility",
],
)
cc_test(
name = "any_invocable_test",
srcs = [
"any_invocable_test.cc",
"internal/any_invocable.h",
],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":any_invocable",
"//absl/base:base_internal",
"//absl/base:config",
"//absl/base:core_headers",
"//absl/meta:type_traits",
"//absl/utility",
"@com_google_googletest//:gtest_main",
],
)
cc_library(
name = "bind_front",
srcs = ["internal/front_binder.h"],
hdrs = ["bind_front.h"],
......@@ -86,6 +120,7 @@ cc_test(
tags = ["benchmark"],
visibility = ["//visibility:private"],
deps = [
":any_invocable",
":function_ref",
"//absl/base:core_headers",
"@com_github_google_benchmark//:benchmark_main",
......
......@@ -16,6 +16,42 @@
absl_cc_library(
NAME
any_invocable
SRCS
"internal/any_invocable.h"
HDRS
"any_invocable.h"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
absl::base_internal
absl::config
absl::core_headers
absl::type_traits
absl::utility
PUBLIC
)
absl_cc_test(
NAME
any_invocable_test
SRCS
"any_invocable_test.cc"
"internal/any_invocable.h"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
absl::any_invocable
absl::base_internal
absl::config
absl::core_headers
absl::type_traits
absl::utility
GTest::gmock_main
)
absl_cc_library(
NAME
bind_front
SRCS
"internal/front_binder.h"
......
......@@ -18,6 +18,7 @@
#include "benchmark/benchmark.h"
#include "absl/base/attributes.h"
#include "absl/functional/any_invocable.h"
#include "absl/functional/function_ref.h"
namespace absl {
......@@ -62,6 +63,12 @@ void BM_TrivialFunctionRef(benchmark::State& state) {
}
BENCHMARK(BM_TrivialFunctionRef);
void BM_TrivialAnyInvocable(benchmark::State& state) {
ConstructAndCallFunctionBenchmark<AnyInvocable<void()>>(state,
TrivialFunctor{});
}
BENCHMARK(BM_TrivialAnyInvocable);
void BM_LargeStdFunction(benchmark::State& state) {
ConstructAndCallFunctionBenchmark<std::function<void()>>(state,
LargeFunctor{});
......@@ -73,6 +80,13 @@ void BM_LargeFunctionRef(benchmark::State& state) {
}
BENCHMARK(BM_LargeFunctionRef);
void BM_LargeAnyInvocable(benchmark::State& state) {
ConstructAndCallFunctionBenchmark<AnyInvocable<void()>>(state,
LargeFunctor{});
}
BENCHMARK(BM_LargeAnyInvocable);
void BM_FunPtrStdFunction(benchmark::State& state) {
ConstructAndCallFunctionBenchmark<std::function<void()>>(state, FreeFunction);
}
......@@ -83,6 +97,11 @@ void BM_FunPtrFunctionRef(benchmark::State& state) {
}
BENCHMARK(BM_FunPtrFunctionRef);
void BM_FunPtrAnyInvocable(benchmark::State& state) {
ConstructAndCallFunctionBenchmark<AnyInvocable<void()>>(state, FreeFunction);
}
BENCHMARK(BM_FunPtrAnyInvocable);
// Doesn't include construction or copy overhead in the loop.
template <typename Function, typename Callable, typename... Args>
void CallFunctionBenchmark(benchmark::State& state, const Callable& c,
......@@ -114,6 +133,12 @@ void BM_TrivialArgsFunctionRef(benchmark::State& state) {
}
BENCHMARK(BM_TrivialArgsFunctionRef);
void BM_TrivialArgsAnyInvocable(benchmark::State& state) {
CallFunctionBenchmark<AnyInvocable<void(int, int, int)>>(
state, FunctorWithTrivialArgs{}, 1, 2, 3);
}
BENCHMARK(BM_TrivialArgsAnyInvocable);
struct FunctorWithNonTrivialArgs {
void operator()(std::string a, std::string b, std::string c) const {
benchmark::DoNotOptimize(&a);
......@@ -138,6 +163,14 @@ void BM_NonTrivialArgsFunctionRef(benchmark::State& state) {
}
BENCHMARK(BM_NonTrivialArgsFunctionRef);
void BM_NonTrivialArgsAnyInvocable(benchmark::State& state) {
std::string a, b, c;
CallFunctionBenchmark<
AnyInvocable<void(std::string, std::string, std::string)>>(
state, FunctorWithNonTrivialArgs{}, a, b, c);
}
BENCHMARK(BM_NonTrivialArgsAnyInvocable);
} // namespace
ABSL_NAMESPACE_END
} // namespace absl
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