summaryrefslogtreecommitdiff
path: root/base/bind_internal.h
diff options
context:
space:
mode:
authorJay Civelli <jcivelli@google.com>2017-03-22 17:31:44 -0700
committerTreehugger Robot <treehugger-gerrit@google.com>2017-07-26 01:47:45 +0000
commit0601274935e7f632eb0d6ce0fd223b744349d20b (patch)
tree09642629eabdbeccfd68e6338253228465088c57 /base/bind_internal.h
parentf320c0cf71af274e34404746d4303e6a2452e2d6 (diff)
downloadlibchrome-0601274935e7f632eb0d6ce0fd223b744349d20b.tar.gz
libchrome: Uprev the library to r456626 from Chromium
Pulled the latest and greatest version of libchrome from Chromium. The merge was done against r456626 which corresponds to git commit 08266b3fca707804065a2cfd60331722ade41969 of Mar 14, 2017 Notable changes are: - FOR_EACH_OBSERVER macro removed (replaced by use of C++ 11 range-base for loop) - base::Values no more FundamentalValue - stl_util moved to base namespace - some scoped pointers removed in crypto/ in favor of BoringSSL UniquePtr. - path() accessor renamed to GetPath() in ScopedTempDir (and other classes) - introduction of base::CallbackOnce Test: All unit-tests should still pass. Change-Id: I5c2cb41ea4c037fe69fbb425e711b1399d55d591
Diffstat (limited to 'base/bind_internal.h')
-rw-r--r--base/bind_internal.h114
1 files changed, 102 insertions, 12 deletions
diff --git a/base/bind_internal.h b/base/bind_internal.h
index 3d6ca09c41..8988bdca22 100644
--- a/base/bind_internal.h
+++ b/base/bind_internal.h
@@ -130,7 +130,7 @@ struct ForceVoidReturn<R(Args...)> {
// FunctorTraits<>
//
// See description at top of file.
-template <typename Functor, typename SFINAE = void>
+template <typename Functor, typename SFINAE>
struct FunctorTraits;
// For a callable type that is convertible to the corresponding function type.
@@ -244,14 +244,16 @@ struct FunctorTraits<IgnoreResultHelper<T>> : FunctorTraits<T> {
template <typename IgnoreResultType, typename... RunArgs>
static void Invoke(IgnoreResultType&& ignore_result_helper,
RunArgs&&... args) {
- FunctorTraits<T>::Invoke(ignore_result_helper.functor_,
- std::forward<RunArgs>(args)...);
+ FunctorTraits<T>::Invoke(
+ std::forward<IgnoreResultType>(ignore_result_helper).functor_,
+ std::forward<RunArgs>(args)...);
}
};
// For Callbacks.
-template <typename R, typename... Args, CopyMode copy_mode>
-struct FunctorTraits<Callback<R(Args...), copy_mode>> {
+template <typename R, typename... Args,
+ CopyMode copy_mode, RepeatMode repeat_mode>
+struct FunctorTraits<Callback<R(Args...), copy_mode, repeat_mode>> {
using RunType = R(Args...);
static constexpr bool is_method = false;
static constexpr bool is_nullable = true;
@@ -314,6 +316,19 @@ struct Invoker;
template <typename StorageType, typename R, typename... UnboundArgs>
struct Invoker<StorageType, R(UnboundArgs...)> {
+ static R RunOnce(BindStateBase* base, UnboundArgs&&... unbound_args) {
+ // Local references to make debugger stepping easier. If in a debugger,
+ // you really want to warp ahead and step through the
+ // InvokeHelper<>::MakeItSo() call below.
+ StorageType* storage = static_cast<StorageType*>(base);
+ static constexpr size_t num_bound_args =
+ std::tuple_size<decltype(storage->bound_args_)>::value;
+ return RunImpl(std::move(storage->functor_),
+ std::move(storage->bound_args_),
+ MakeIndexSequence<num_bound_args>(),
+ std::forward<UnboundArgs>(unbound_args)...);
+ }
+
static R Run(BindStateBase* base, UnboundArgs&&... unbound_args) {
// Local references to make debugger stepping easier. If in a debugger,
// you really want to warp ahead and step through the
@@ -372,27 +387,102 @@ IsNull(const Functor&) {
return false;
}
+// Used by ApplyCancellationTraits below.
+template <typename Functor, typename BoundArgsTuple, size_t... indices>
+bool ApplyCancellationTraitsImpl(const Functor& functor,
+ const BoundArgsTuple& bound_args,
+ IndexSequence<indices...>) {
+ return CallbackCancellationTraits<Functor, BoundArgsTuple>::IsCancelled(
+ functor, base::get<indices>(bound_args)...);
+}
+
+// Relays |base| to corresponding CallbackCancellationTraits<>::Run(). Returns
+// true if the callback |base| represents is canceled.
+template <typename BindStateType>
+bool ApplyCancellationTraits(const BindStateBase* base) {
+ const BindStateType* storage = static_cast<const BindStateType*>(base);
+ static constexpr size_t num_bound_args =
+ std::tuple_size<decltype(storage->bound_args_)>::value;
+ return ApplyCancellationTraitsImpl(storage->functor_, storage->bound_args_,
+ MakeIndexSequence<num_bound_args>());
+};
+
+// Template helpers to detect using Bind() on a base::Callback without any
+// additional arguments. In that case, the original base::Callback object should
+// just be directly used.
+template <typename Functor, typename... BoundArgs>
+struct BindingCallbackWithNoArgs {
+ static constexpr bool value = false;
+};
+
+template <typename Signature,
+ typename... BoundArgs,
+ CopyMode copy_mode,
+ RepeatMode repeat_mode>
+struct BindingCallbackWithNoArgs<Callback<Signature, copy_mode, repeat_mode>,
+ BoundArgs...> {
+ static constexpr bool value = sizeof...(BoundArgs) == 0;
+};
+
// BindState<>
//
// This stores all the state passed into Bind().
template <typename Functor, typename... BoundArgs>
struct BindState final : BindStateBase {
+ using IsCancellable = std::integral_constant<
+ bool,
+ CallbackCancellationTraits<Functor,
+ std::tuple<BoundArgs...>>::is_cancellable>;
+
template <typename ForwardFunctor, typename... ForwardBoundArgs>
- explicit BindState(ForwardFunctor&& functor, ForwardBoundArgs&&... bound_args)
- : BindStateBase(&Destroy),
- functor_(std::forward<ForwardFunctor>(functor)),
- bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) {
- DCHECK(!IsNull(functor_));
+ explicit BindState(BindStateBase::InvokeFuncStorage invoke_func,
+ ForwardFunctor&& functor,
+ ForwardBoundArgs&&... bound_args)
+ // IsCancellable is std::false_type if
+ // CallbackCancellationTraits<>::IsCancelled returns always false.
+ // Otherwise, it's std::true_type.
+ : BindState(IsCancellable{},
+ invoke_func,
+ std::forward<ForwardFunctor>(functor),
+ std::forward<ForwardBoundArgs>(bound_args)...) {
+ static_assert(!BindingCallbackWithNoArgs<Functor, BoundArgs...>::value,
+ "Attempting to bind a base::Callback with no additional "
+ "arguments: save a heap allocation and use the original "
+ "base::Callback object");
}
Functor functor_;
std::tuple<BoundArgs...> bound_args_;
private:
+ template <typename ForwardFunctor, typename... ForwardBoundArgs>
+ explicit BindState(std::true_type,
+ BindStateBase::InvokeFuncStorage invoke_func,
+ ForwardFunctor&& functor,
+ ForwardBoundArgs&&... bound_args)
+ : BindStateBase(invoke_func,
+ &Destroy,
+ &ApplyCancellationTraits<BindState>),
+ functor_(std::forward<ForwardFunctor>(functor)),
+ bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) {
+ DCHECK(!IsNull(functor_));
+ }
+
+ template <typename ForwardFunctor, typename... ForwardBoundArgs>
+ explicit BindState(std::false_type,
+ BindStateBase::InvokeFuncStorage invoke_func,
+ ForwardFunctor&& functor,
+ ForwardBoundArgs&&... bound_args)
+ : BindStateBase(invoke_func, &Destroy),
+ functor_(std::forward<ForwardFunctor>(functor)),
+ bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) {
+ DCHECK(!IsNull(functor_));
+ }
+
~BindState() {}
- static void Destroy(BindStateBase* self) {
- delete static_cast<BindState*>(self);
+ static void Destroy(const BindStateBase* self) {
+ delete static_cast<const BindState*>(self);
}
};