// Copyright 2012 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // This file contains utility functions and classes that help the // implementation, and management of the Callback objects. #ifndef BASE_FUNCTIONAL_CALLBACK_INTERNAL_H_ #define BASE_FUNCTIONAL_CALLBACK_INTERNAL_H_ #include <type_traits> #include <utility> #include "base/base_export.h" #include "base/compiler_specific.h" #include "base/functional/callback_forward.h" #include "base/memory/ref_counted.h" namespace base { struct FakeBindState; namespace internal { class BindStateBase; template <bool is_method, bool is_nullable, bool is_callback, typename Functor, typename... BoundArgs> struct BindState; struct BASE_EXPORT BindStateBaseRefCountTraits { … }; PassingType; // BindStateBase is used to provide an opaque handle that the Callback // class can use to represent a function object with bound arguments. It // behaves as an existential type that is used by a corresponding // DoInvoke function to perform the function execution. This allows // us to shield the Callback class from the types of the bound argument via // "type erasure." // At the base level, the only task is to add reference counting data. Avoid // using or inheriting any virtual functions. Creating a vtable for every // BindState template instantiation results in a lot of bloat. Its only task is // to call the destructor which can be done with a function pointer. class BASE_EXPORT BindStateBase : public RefCountedThreadSafe<BindStateBase, BindStateBaseRefCountTraits> { … }; // Minimal wrapper around a `scoped_refptr<BindStateBase>`. It allows more // expensive operations (such as ones that destroy `BindStateBase` or manipulate // refcounts) to be defined out-of-line to reduce binary size. class BASE_EXPORT TRIVIAL_ABI BindStateHolder { … }; constexpr BindStateHolder::BindStateHolder() noexcept = default; // TODO(dcheng): Try plumbing a scoped_refptr all the way through, since // scoped_refptr is marked as TRIVIAL_ABI. BindStateHolder::BindStateHolder(BindStateBase* bind_state) : … { … } // Unlike the copy constructor, copy assignment operator, and move assignment // operator, the move constructor is defaulted in the header because it // generates minimal code: move construction does not change any refcounts, nor // does it potentially destroy `BindStateBase`. BindStateHolder::BindStateHolder(BindStateHolder&&) noexcept = default; // Helpers for the `Then()` implementation. template <typename OriginalCallback, typename ThenCallback> struct ThenHelper; // Specialization when original callback returns `void`. ThenHelper<OriginalCallback<void (OriginalArgs...)>, ThenCallback<ThenR (ThenArgs...)>>; // Specialization when original callback returns a non-void type. ThenHelper<OriginalCallback<OriginalR (OriginalArgs...)>, ThenCallback<ThenR (ThenArgs...)>>; } // namespace internal } // namespace base #endif // BASE_FUNCTIONAL_CALLBACK_INTERNAL_H_