#ifndef BASE_FUNCTIONAL_CALLBACK_H_
#define BASE_FUNCTIONAL_CALLBACK_H_
#include <stddef.h>
#include <type_traits>
#include <utility>
#include "base/check.h"
#include "base/compiler_specific.h"
#include "base/functional/bind.h"
#include "base/functional/callback_forward.h"
#include "base/functional/callback_internal.h"
#include "base/functional/callback_tags.h"
#include "base/functional/function_ref.h"
#include "base/notreached.h"
namespace base {
namespace internal {
template <bool is_once,
typename R,
typename... UnboundArgs,
typename... BoundArgs>
auto ToDoNothingCallback(
DoNothingCallbackTag::WithBoundArguments<BoundArgs...> t);
}
template <typename R, typename... Args>
class TRIVIAL_ABI OnceCallback<R(Args...)> {
public:
using ResultType = R;
using RunType = R(Args...);
using PolymorphicInvoke = R (*)(internal::BindStateBase*,
internal::PassingType<Args>...);
constexpr OnceCallback() = default;
OnceCallback(std::nullptr_t) = delete;
OnceCallback(const OnceCallback&) = delete;
OnceCallback& operator=(const OnceCallback&) = delete;
OnceCallback(OnceCallback&&) noexcept = default;
OnceCallback& operator=(OnceCallback&&) noexcept = default;
~OnceCallback() = default;
OnceCallback(RepeatingCallback<RunType> other)
: holder_(std::move(other.holder_)) {}
OnceCallback& operator=(RepeatingCallback<RunType> other) {
holder_ = std::move(other.holder_);
return *this;
}
explicit operator bool() const { return !!holder_; }
bool is_null() const { return holder_.is_null(); }
bool IsCancelled() const { return holder_.IsCancelled(); }
bool MaybeValid() const { return holder_.MaybeValid(); }
REINITIALIZES_AFTER_MOVE void Reset() { holder_.Reset(); }
R Run(Args... args) const& {
static_assert(!sizeof(*this),
"OnceCallback::Run() may only be invoked on a non-const "
"rvalue, i.e. std::move(callback).Run().");
NOTREACHED();
}
R Run(Args... args) && {
CHECK(!is_null());
internal::BindStateHolder holder = std::move(holder_);
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(holder.polymorphic_invoke());
return f(holder.bind_state().get(), std::forward<Args>(args)...);
}
template <typename ThenR, typename... ThenArgs>
OnceCallback<ThenR(Args...)> Then(OnceCallback<ThenR(ThenArgs...)> then) && {
CHECK(then);
return base::BindOnce(
internal::ThenHelper<
OnceCallback, OnceCallback<ThenR(ThenArgs...)>>::CreateTrampoline(),
std::move(*this), std::move(then));
}
template <typename ThenR, typename... ThenArgs>
OnceCallback<ThenR(Args...)> Then(
RepeatingCallback<ThenR(ThenArgs...)> then) && {
CHECK(then);
return base::BindOnce(
internal::ThenHelper<
OnceCallback,
RepeatingCallback<ThenR(ThenArgs...)>>::CreateTrampoline(),
std::move(*this), std::move(then));
}
constexpr OnceCallback(internal::NullCallbackTag) : OnceCallback() {}
constexpr OnceCallback& operator=(internal::NullCallbackTag) {
*this = OnceCallback();
return *this;
}
constexpr OnceCallback(internal::NullCallbackTag::WithSignature<RunType>)
: OnceCallback(internal::NullCallbackTag()) {}
constexpr OnceCallback& operator=(
internal::NullCallbackTag::WithSignature<RunType>) {
*this = internal::NullCallbackTag();
return *this;
}
constexpr OnceCallback(internal::DoNothingCallbackTag)
requires(std::is_void_v<R>)
: OnceCallback(BindOnce([](Args... args) {})) {}
constexpr OnceCallback& operator=(internal::DoNothingCallbackTag)
requires(std::is_void_v<R>)
{
*this = BindOnce([](Args... args) {});
return *this;
}
constexpr OnceCallback(internal::DoNothingCallbackTag::WithSignature<RunType>)
requires(std::is_void_v<R>)
: OnceCallback(internal::DoNothingCallbackTag()) {}
constexpr OnceCallback& operator=(
internal::DoNothingCallbackTag::WithSignature<RunType>)
requires(std::is_void_v<R>)
{
*this = internal::DoNothingCallbackTag();
return *this;
}
template <typename... BoundArgs>
constexpr OnceCallback(
internal::DoNothingCallbackTag::WithBoundArguments<BoundArgs...> tag)
requires(std::is_void_v<R>)
: OnceCallback(
internal::ToDoNothingCallback<true, R, Args...>(std::move(tag))) {}
template <typename... BoundArgs>
constexpr OnceCallback& operator=(
internal::DoNothingCallbackTag::WithBoundArguments<BoundArgs...> tag)
requires(std::is_void_v<R>)
{
*this = internal::ToDoNothingCallback<true, R, Args...>(std::move(tag));
return *this;
}
explicit OnceCallback(internal::BindStateBase* bind_state)
: holder_(bind_state) {}
template <typename Signature>
operator FunctionRef<Signature>() & {
static_assert(
false,
"need to convert a base::OnceCallback to base::FunctionRef? "
"Please bring up this use case on #cxx (Slack) or cxx@chromium.org.");
}
template <typename Signature>
operator FunctionRef<Signature>() && {
static_assert(
false,
"using base::BindOnce() is not necessary with base::FunctionRef; is it "
"possible to use a capturing lambda directly? If not, please bring up "
"this use case on #cxx (Slack) or cxx@chromium.org.");
}
private:
internal::BindStateHolder holder_;
};
template <typename R, typename... Args>
class TRIVIAL_ABI RepeatingCallback<R(Args...)> {
public:
using ResultType = R;
using RunType = R(Args...);
using PolymorphicInvoke = R (*)(internal::BindStateBase*,
internal::PassingType<Args>...);
constexpr RepeatingCallback() = default;
RepeatingCallback(std::nullptr_t) = delete;
RepeatingCallback(const RepeatingCallback&) = default;
RepeatingCallback& operator=(const RepeatingCallback&) = default;
RepeatingCallback(RepeatingCallback&&) noexcept = default;
RepeatingCallback& operator=(RepeatingCallback&&) noexcept = default;
~RepeatingCallback() = default;
explicit operator bool() const { return !!holder_; }
bool is_null() const { return holder_.is_null(); }
bool IsCancelled() const { return holder_.IsCancelled(); }
bool MaybeValid() const { return holder_.MaybeValid(); }
friend bool operator==(const RepeatingCallback&,
const RepeatingCallback&) = default;
REINITIALIZES_AFTER_MOVE void Reset() { holder_.Reset(); }
R Run(Args... args) const& {
CHECK(!is_null());
scoped_refptr<internal::BindStateBase> bind_state = holder_.bind_state();
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(holder_.polymorphic_invoke());
return f(bind_state.get(), std::forward<Args>(args)...);
}
R Run(Args... args) && {
CHECK(!holder_.is_null());
internal::BindStateHolder holder = std::move(holder_);
PolymorphicInvoke f =
reinterpret_cast<PolymorphicInvoke>(holder.polymorphic_invoke());
return f(holder.bind_state().get(), std::forward<Args>(args)...);
}
template <typename ThenR, typename... ThenArgs>
RepeatingCallback<ThenR(Args...)> Then(
RepeatingCallback<ThenR(ThenArgs...)> then) const& {
CHECK(then);
return BindRepeating(
internal::ThenHelper<
RepeatingCallback,
RepeatingCallback<ThenR(ThenArgs...)>>::CreateTrampoline(),
*this, std::move(then));
}
template <typename ThenR, typename... ThenArgs>
RepeatingCallback<ThenR(Args...)> Then(
RepeatingCallback<ThenR(ThenArgs...)> then) && {
CHECK(then);
return BindRepeating(
internal::ThenHelper<
RepeatingCallback,
RepeatingCallback<ThenR(ThenArgs...)>>::CreateTrampoline(),
std::move(*this), std::move(then));
}
constexpr RepeatingCallback(internal::NullCallbackTag)
: RepeatingCallback() {}
constexpr RepeatingCallback& operator=(internal::NullCallbackTag) {
*this = RepeatingCallback();
return *this;
}
constexpr RepeatingCallback(internal::NullCallbackTag::WithSignature<RunType>)
: RepeatingCallback(internal::NullCallbackTag()) {}
constexpr RepeatingCallback& operator=(
internal::NullCallbackTag::WithSignature<RunType>) {
*this = internal::NullCallbackTag();
return *this;
}
constexpr RepeatingCallback(internal::DoNothingCallbackTag)
requires(std::is_void_v<R>)
: RepeatingCallback(BindRepeating([](Args... args) {})) {}
constexpr RepeatingCallback& operator=(internal::DoNothingCallbackTag)
requires(std::is_void_v<R>)
{
*this = BindRepeating([](Args... args) {});
return *this;
}
constexpr RepeatingCallback(
internal::DoNothingCallbackTag::WithSignature<RunType>)
requires(std::is_void_v<R>)
: RepeatingCallback(internal::DoNothingCallbackTag()) {}
constexpr RepeatingCallback& operator=(
internal::DoNothingCallbackTag::WithSignature<RunType>)
requires(std::is_void_v<R>)
{
*this = internal::DoNothingCallbackTag();
return *this;
}
template <typename... BoundArgs>
constexpr RepeatingCallback(
internal::DoNothingCallbackTag::WithBoundArguments<BoundArgs...> tag)
requires(std::is_void_v<R>)
: RepeatingCallback(
internal::ToDoNothingCallback<false, R, Args...>(std::move(tag))) {}
template <typename... BoundArgs>
constexpr RepeatingCallback& operator=(
internal::DoNothingCallbackTag::WithBoundArguments<BoundArgs...> tag)
requires(std::is_void_v<R>)
{
*this = internal::ToDoNothingCallback<false, R, Args...>(std::move(tag));
return this;
}
explicit RepeatingCallback(internal::BindStateBase* bind_state)
: holder_(bind_state) {}
template <typename Signature>
operator FunctionRef<Signature>() & {
static_assert(
false,
"need to convert a base::RepeatingCallback to base::FunctionRef? "
"Please bring up this use case on #cxx (Slack) or cxx@chromium.org.");
}
template <typename Signature>
operator FunctionRef<Signature>() && {
static_assert(
false,
"using base::BindRepeating() is not necessary with base::FunctionRef; "
"is it possible to use a capturing lambda directly? If not, please "
"bring up this use case on #cxx (Slack) or cxx@chromium.org.");
}
private:
friend class OnceCallback<R(Args...)>;
internal::BindStateHolder holder_;
};
namespace internal {
template <bool is_once,
typename R,
typename... UnboundArgs,
typename... BoundArgs>
auto ToDoNothingCallback(
DoNothingCallbackTag::WithBoundArguments<BoundArgs...> t) {
return std::apply(
[](auto&&... args) {
if constexpr (is_once) {
return base::BindOnce(
[](TransformToUnwrappedType<is_once, BoundArgs>...,
UnboundArgs...) {},
std::move(args)...);
} else {
return base::BindRepeating(
[](TransformToUnwrappedType<is_once, BoundArgs>...,
UnboundArgs...) {},
std::move(args)...);
}
},
std::move(t.bound_args));
}
}
}
#endif