123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477 |
- #ifndef BASE_BIND_H_
- #define BASE_BIND_H_
- #include <functional>
- #include <memory>
- #include <type_traits>
- #include <utility>
- #include "base/bind_internal.h"
- #include "base/compiler_specific.h"
- #include "base/template_util.h"
- #include "build/build_config.h"
- #if defined(OS_APPLE) && !HAS_FEATURE(objc_arc)
- #include "base/mac/scoped_block.h"
- #endif
- namespace base {
- namespace internal {
- template <typename T>
- struct IsOnceCallback : std::false_type {};
- template <typename Signature>
- struct IsOnceCallback<OnceCallback<Signature>> : std::true_type {};
- template <size_t i,
- typename Arg,
- typename Storage,
- typename Unwrapped,
- typename Param>
- struct AssertConstructible {
- private:
- static constexpr bool param_is_forwardable =
- std::is_constructible<Param, Unwrapped>::value;
-
-
-
-
- static_assert(
- param_is_forwardable ||
- !std::is_constructible<Param, std::decay_t<Unwrapped>&&>::value,
- "Bound argument |i| is move-only but will be forwarded by copy. "
- "Ensure |Arg| is bound using base::Passed(), not std::move().");
- static_assert(
- param_is_forwardable,
- "Bound argument |i| of type |Arg| cannot be forwarded as "
- "|Unwrapped| to the bound functor, which declares it as |Param|.");
- static constexpr bool arg_is_storable =
- std::is_constructible<Storage, Arg>::value;
- static_assert(arg_is_storable ||
- !std::is_constructible<Storage, std::decay_t<Arg>&&>::value,
- "Bound argument |i| is move-only but will be bound by copy. "
- "Ensure |Arg| is mutable and bound using std::move().");
- static_assert(arg_is_storable,
- "Bound argument |i| of type |Arg| cannot be converted and "
- "bound as |Storage|.");
- };
- template <typename Index,
- typename Args,
- typename UnwrappedTypeList,
- typename ParamsList>
- struct AssertBindArgsValidity;
- template <size_t... Ns,
- typename... Args,
- typename... Unwrapped,
- typename... Params>
- struct AssertBindArgsValidity<std::index_sequence<Ns...>,
- TypeList<Args...>,
- TypeList<Unwrapped...>,
- TypeList<Params...>>
- : AssertConstructible<Ns, Args, std::decay_t<Args>, Unwrapped, Params>... {
- static constexpr bool ok = true;
- };
- template <bool is_once, typename T>
- struct TransformToUnwrappedTypeImpl;
- template <typename T>
- struct TransformToUnwrappedTypeImpl<true, T> {
- using StoredType = std::decay_t<T>;
- using ForwardType = StoredType&&;
- using Unwrapped = decltype(Unwrap(std::declval<ForwardType>()));
- };
- template <typename T>
- struct TransformToUnwrappedTypeImpl<false, T> {
- using StoredType = std::decay_t<T>;
- using ForwardType = const StoredType&;
- using Unwrapped = decltype(Unwrap(std::declval<ForwardType>()));
- };
- template <bool is_once, typename T>
- using TransformToUnwrappedType =
- typename TransformToUnwrappedTypeImpl<is_once, T>::Unwrapped;
- template <bool is_once, bool is_method, typename... Args>
- struct MakeUnwrappedTypeListImpl {
- using Type = TypeList<TransformToUnwrappedType<is_once, Args>...>;
- };
- template <bool is_once, typename Receiver, typename... Args>
- struct MakeUnwrappedTypeListImpl<is_once, true, Receiver, Args...> {
- using UnwrappedReceiver = TransformToUnwrappedType<is_once, Receiver>;
- using Type = TypeList<decltype(&*std::declval<UnwrappedReceiver>()),
- TransformToUnwrappedType<is_once, Args>...>;
- };
- template <bool is_once, bool is_method, typename... Args>
- using MakeUnwrappedTypeList =
- typename MakeUnwrappedTypeListImpl<is_once, is_method, Args...>::Type;
- template <typename Invoker>
- constexpr auto GetInvokeFunc(std::true_type) {
- return Invoker::RunOnce;
- }
- template <typename Invoker>
- constexpr auto GetInvokeFunc(std::false_type) {
- return Invoker::Run;
- }
- template <template <typename> class CallbackT,
- typename Functor,
- typename... Args>
- decltype(auto) BindImpl(Functor&& functor, Args&&... args) {
-
-
-
- static constexpr bool kIsOnce = IsOnceCallback<CallbackT<void()>>::value;
- using Helper = internal::BindTypeHelper<Functor, Args...>;
- using FunctorTraits = typename Helper::FunctorTraits;
- using BoundArgsList = typename Helper::BoundArgsList;
- using UnwrappedArgsList =
- internal::MakeUnwrappedTypeList<kIsOnce, FunctorTraits::is_method,
- Args&&...>;
- using BoundParamsList = typename Helper::BoundParamsList;
- static_assert(internal::AssertBindArgsValidity<
- std::make_index_sequence<Helper::num_bounds>, BoundArgsList,
- UnwrappedArgsList, BoundParamsList>::ok,
- "The bound args need to be convertible to the target params.");
- using BindState = internal::MakeBindStateType<Functor, Args...>;
- using UnboundRunType = MakeUnboundRunType<Functor, Args...>;
- using Invoker = internal::Invoker<BindState, UnboundRunType>;
- using CallbackType = CallbackT<UnboundRunType>;
-
-
-
- using PolymorphicInvoke = typename CallbackType::PolymorphicInvoke;
- PolymorphicInvoke invoke_func =
- GetInvokeFunc<Invoker>(bool_constant<kIsOnce>());
- using InvokeFuncStorage = internal::BindStateBase::InvokeFuncStorage;
- return CallbackType(BindState::Create(
- reinterpret_cast<InvokeFuncStorage>(invoke_func),
- std::forward<Functor>(functor), std::forward<Args>(args)...));
- }
- }
- template <typename Functor, typename... Args>
- inline OnceCallback<MakeUnboundRunType<Functor, Args...>> BindOnce(
- Functor&& functor,
- Args&&... args) {
- static_assert(!internal::IsOnceCallback<std::decay_t<Functor>>() ||
- (std::is_rvalue_reference<Functor&&>() &&
- !std::is_const<std::remove_reference_t<Functor>>()),
- "BindOnce requires non-const rvalue for OnceCallback binding."
- " I.e.: base::BindOnce(std::move(callback)).");
- return internal::BindImpl<OnceCallback>(std::forward<Functor>(functor),
- std::forward<Args>(args)...);
- }
- template <typename Functor, typename... Args>
- inline RepeatingCallback<MakeUnboundRunType<Functor, Args...>>
- BindRepeating(Functor&& functor, Args&&... args) {
- static_assert(
- !internal::IsOnceCallback<std::decay_t<Functor>>(),
- "BindRepeating cannot bind OnceCallback. Use BindOnce with std::move().");
- return internal::BindImpl<RepeatingCallback>(std::forward<Functor>(functor),
- std::forward<Args>(args)...);
- }
- template <typename Functor, typename... Args>
- inline Callback<MakeUnboundRunType<Functor, Args...>>
- Bind(Functor&& functor, Args&&... args) {
- return base::BindRepeating(std::forward<Functor>(functor),
- std::forward<Args>(args)...);
- }
- template <typename Signature>
- OnceCallback<Signature> BindOnce(OnceCallback<Signature> callback) {
- CHECK(callback);
- return callback;
- }
- template <typename Signature>
- OnceCallback<Signature> BindOnce(RepeatingCallback<Signature> callback) {
- CHECK(callback);
- return callback;
- }
- template <typename Signature>
- RepeatingCallback<Signature> BindRepeating(
- RepeatingCallback<Signature> callback) {
- CHECK(callback);
- return callback;
- }
- template <typename Signature>
- Callback<Signature> Bind(Callback<Signature> callback) {
- CHECK(callback);
- return callback;
- }
- template <typename T>
- static inline internal::UnretainedWrapper<T> Unretained(T* o) {
- return internal::UnretainedWrapper<T>(o);
- }
- template <typename T>
- static inline internal::RetainedRefWrapper<T> RetainedRef(T* o) {
- return internal::RetainedRefWrapper<T>(o);
- }
- template <typename T>
- static inline internal::RetainedRefWrapper<T> RetainedRef(scoped_refptr<T> o) {
- return internal::RetainedRefWrapper<T>(std::move(o));
- }
- template <typename T>
- static inline internal::OwnedWrapper<T> Owned(T* o) {
- return internal::OwnedWrapper<T>(o);
- }
- template <typename T, typename Deleter>
- static inline internal::OwnedWrapper<T, Deleter> Owned(
- std::unique_ptr<T, Deleter>&& ptr) {
- return internal::OwnedWrapper<T, Deleter>(std::move(ptr));
- }
- template <typename T,
- std::enable_if_t<!std::is_lvalue_reference<T>::value>* = nullptr>
- static inline internal::PassedWrapper<T> Passed(T&& scoper) {
- return internal::PassedWrapper<T>(std::move(scoper));
- }
- template <typename T>
- static inline internal::PassedWrapper<T> Passed(T* scoper) {
- return internal::PassedWrapper<T>(std::move(*scoper));
- }
- template <typename T>
- static inline internal::IgnoreResultHelper<T> IgnoreResult(T data) {
- return internal::IgnoreResultHelper<T>(std::move(data));
- }
- #if defined(OS_APPLE) && !HAS_FEATURE(objc_arc)
- template <typename R, typename... Args>
- base::mac::ScopedBlock<R (^)(Args...)> RetainBlock(R (^block)(Args...)) {
- return base::mac::ScopedBlock<R (^)(Args...)>(block,
- base::scoped_policy::RETAIN);
- }
- #endif
- }
- #endif
|