Commit 8ce65709 authored by tzik's avatar tzik Committed by Commit bot

Bind: Use Variadic Templates in bind_internal.h

* Introduce TypeList as helpers.
* Drop bind_internal.h.pump and replace generated codes with Variadic Templates version.

BUG=433164

Review URL: https://codereview.chromium.org/743853002

Cr-Commit-Position: refs/heads/master@{#314847}
parent d5626f64
...@@ -52,13 +52,14 @@ base::Callback< ...@@ -52,13 +52,14 @@ base::Callback<
typename internal::BindState< typename internal::BindState<
typename internal::FunctorTraits<Functor>::RunnableType, typename internal::FunctorTraits<Functor>::RunnableType,
typename internal::FunctorTraits<Functor>::RunType, typename internal::FunctorTraits<Functor>::RunType,
void()>::UnboundRunType> internal::TypeList<>>::UnboundRunType>
Bind(Functor functor) { Bind(Functor functor) {
// Typedefs for how to store and run the functor. // Typedefs for how to store and run the functor.
typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType; typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
typedef typename internal::FunctorTraits<Functor>::RunType RunType; typedef typename internal::FunctorTraits<Functor>::RunType RunType;
typedef internal::BindState<RunnableType, RunType, void()> BindState; typedef internal::BindState<RunnableType, RunType,
internal::TypeList<>> BindState;
return Callback<typename BindState::UnboundRunType>( return Callback<typename BindState::UnboundRunType>(
new BindState(internal::MakeRunnable(functor))); new BindState(internal::MakeRunnable(functor)));
...@@ -69,7 +70,8 @@ base::Callback< ...@@ -69,7 +70,8 @@ base::Callback<
typename internal::BindState< typename internal::BindState<
typename internal::FunctorTraits<Functor>::RunnableType, typename internal::FunctorTraits<Functor>::RunnableType,
typename internal::FunctorTraits<Functor>::RunType, typename internal::FunctorTraits<Functor>::RunType,
void(typename internal::CallbackParamTraits<Args>::StorageType...)> internal::TypeList<
typename internal::CallbackParamTraits<Args>::StorageType...>>
::UnboundRunType> ::UnboundRunType>
Bind(Functor functor, const Args&... args) { Bind(Functor functor, const Args&... args) {
// Typedefs for how to store and run the functor. // Typedefs for how to store and run the functor.
...@@ -101,8 +103,10 @@ Bind(Functor functor, const Args&... args) { ...@@ -101,8 +103,10 @@ Bind(Functor functor, const Args&... args) {
!internal::HasRefCountedParamAsRawPtr<is_method, Args...>::value, !internal::HasRefCountedParamAsRawPtr<is_method, Args...>::value,
"a_parameter_is_refcounted_type_and_needs_scoped_refptr"); "a_parameter_is_refcounted_type_and_needs_scoped_refptr");
typedef internal::BindState<RunnableType, RunType, typedef internal::BindState<
void(typename internal::CallbackParamTraits<Args>::StorageType...)> RunnableType, RunType,
internal::TypeList<
typename internal::CallbackParamTraits<Args>::StorageType...>>
BindState; BindState;
return Callback<typename BindState::UnboundRunType>( return Callback<typename BindState::UnboundRunType>(
......
...@@ -435,45 +435,46 @@ struct UnwrapTraits<PassedWrapper<T> > { ...@@ -435,45 +435,46 @@ struct UnwrapTraits<PassedWrapper<T> > {
// Utility for handling different refcounting semantics in the Bind() // Utility for handling different refcounting semantics in the Bind()
// function. // function.
template <bool is_method, typename T> template <bool is_method, typename... T>
struct MaybeRefcount; struct MaybeScopedRefPtr;
template <typename T> template <bool is_method>
struct MaybeRefcount<false, T> { struct MaybeScopedRefPtr<is_method> {
static void AddRef(const T&) {} MaybeScopedRefPtr() {}
static void Release(const T&) {}
}; };
template <typename T, size_t n> template <typename T, typename... Rest>
struct MaybeRefcount<false, T[n]> { struct MaybeScopedRefPtr<false, T, Rest...> {
static void AddRef(const T*) {} MaybeScopedRefPtr(const T&, const Rest&...) {}
static void Release(const T*) {}
}; };
template <typename T> template <typename T, size_t n, typename... Rest>
struct MaybeRefcount<true, T> { struct MaybeScopedRefPtr<false, T[n], Rest...> {
static void AddRef(const T&) {} MaybeScopedRefPtr(const T*, const Rest&...) {}
static void Release(const T&) {}
}; };
template <typename T> template <typename T, typename... Rest>
struct MaybeRefcount<true, T*> { struct MaybeScopedRefPtr<true, T, Rest...> {
static void AddRef(T* o) { o->AddRef(); } MaybeScopedRefPtr(const T& o, const Rest&...) {}
static void Release(T* o) { o->Release(); } };
template <typename T, typename... Rest>
struct MaybeScopedRefPtr<true, T*, Rest...> {
MaybeScopedRefPtr(T* o, const Rest&...) : ref_(o) {}
scoped_refptr<T> ref_;
}; };
// No need to additionally AddRef() and Release() since we are storing a // No need to additionally AddRef() and Release() since we are storing a
// scoped_refptr<> inside the storage object already. // scoped_refptr<> inside the storage object already.
template <typename T> template <typename T, typename... Rest>
struct MaybeRefcount<true, scoped_refptr<T> > { struct MaybeScopedRefPtr<true, scoped_refptr<T>, Rest...> {
static void AddRef(const scoped_refptr<T>& o) {} MaybeScopedRefPtr(const scoped_refptr<T>&, const Rest&...) {}
static void Release(const scoped_refptr<T>& o) {}
}; };
template <typename T> template <typename T, typename... Rest>
struct MaybeRefcount<true, const T*> { struct MaybeScopedRefPtr<true, const T*, Rest...> {
static void AddRef(const T* o) { o->AddRef(); } MaybeScopedRefPtr(const T* o, const Rest&...) : ref_(o) {}
static void Release(const T* o) { o->Release(); } scoped_refptr<const T> ref_;
}; };
// IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a // IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a
...@@ -481,15 +482,89 @@ struct MaybeRefcount<true, const T*> { ...@@ -481,15 +482,89 @@ struct MaybeRefcount<true, const T*> {
// InvokeHelper that will no-op itself in the event the WeakPtr<> for // InvokeHelper that will no-op itself in the event the WeakPtr<> for
// the target object is invalidated. // the target object is invalidated.
// //
// P1 should be the type of the object that will be received of the method. // The first argument should be the type of the object that will be received by
template <bool IsMethod, typename P1> // the method.
template <bool IsMethod, typename... Args>
struct IsWeakMethod : public false_type {}; struct IsWeakMethod : public false_type {};
template <typename T> template <typename T, typename... Args>
struct IsWeakMethod<true, WeakPtr<T> > : public true_type {}; struct IsWeakMethod<true, WeakPtr<T>, Args...> : public true_type {};
template <typename T> template <typename T, typename... Args>
struct IsWeakMethod<true, ConstRefWrapper<WeakPtr<T> > > : public true_type {}; struct IsWeakMethod<true, ConstRefWrapper<WeakPtr<T>>, Args...>
: public true_type {};
// Packs a list of types to hold them in a single type.
template <typename... Types>
struct TypeList {};
// Used for DropTypeListItem implementation.
template <size_t n, typename List>
struct DropTypeListItemImpl;
// Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure.
template <size_t n, typename T, typename... List>
struct DropTypeListItemImpl<n, TypeList<T, List...>>
: DropTypeListItemImpl<n - 1, TypeList<List...>> {};
template <typename T, typename... List>
struct DropTypeListItemImpl<0, TypeList<T, List...>> {
typedef TypeList<T, List...> Type;
};
template <>
struct DropTypeListItemImpl<0, TypeList<>> {
typedef TypeList<> Type;
};
// A type-level function that drops |n| list item from given TypeList.
template <size_t n, typename List>
using DropTypeListItem = typename DropTypeListItemImpl<n, List>::Type;
// Used for ConcatTypeLists implementation.
template <typename List1, typename List2>
struct ConcatTypeListsImpl;
template <typename... Types1, typename... Types2>
struct ConcatTypeListsImpl<TypeList<Types1...>, TypeList<Types2...>> {
typedef TypeList<Types1..., Types2...> Type;
};
// A type-level function that concats two TypeLists.
template <typename List1, typename List2>
using ConcatTypeLists = typename ConcatTypeListsImpl<List1, List2>::Type;
template <size_t n, typename List>
struct NthTypeImpl;
template <size_t n, typename T, typename... Types>
struct NthTypeImpl<n, TypeList<T, Types...>>
: NthTypeImpl<n - 1, TypeList<Types...>> {
};
template <typename T, typename... Types>
struct NthTypeImpl<0, TypeList<T, Types...>> {
typedef T Type;
};
// A type-level function that extracts |n|th type from a TypeList.
template <size_t n, typename List>
using NthType = typename NthTypeImpl<n, List>::Type;
// Used for MakeFunctionType implementation.
template <typename R, typename ArgList>
struct MakeFunctionTypeImpl;
template <typename R, typename... Args>
struct MakeFunctionTypeImpl<R, TypeList<Args...>> {
typedef R(Type)(Args...);
};
// A type-level function that constructs a function type that has |R| as its
// return type and has TypeLists items as its arguments.
template <typename R, typename ArgList>
using MakeFunctionType = typename MakeFunctionTypeImpl<R, ArgList>::Type;
} // namespace internal } // namespace internal
......
This diff is collapsed.
This diff is collapsed.
...@@ -190,7 +190,7 @@ void WontCompile() { ...@@ -190,7 +190,7 @@ void WontCompile() {
weak_ptr_with_non_void_return_type.Run(); weak_ptr_with_non_void_return_type.Run();
} }
#elif defined(NCTEST_DISALLOW_ASSIGN_DIFFERENT_TYPES) // [r"fatal error: no viable conversion from 'Callback<typename internal::BindState<typename internal::FunctorTraits<void \(\*\)\(int\)>::RunnableType, typename internal::FunctorTraits<void \(\*\)\(int\)>::RunType, void \(\)>::UnboundRunType>' to 'Callback<void \(\)>'"] #elif defined(NCTEST_DISALLOW_ASSIGN_DIFFERENT_TYPES) // [r"fatal error: no viable conversion from 'Callback<typename internal::BindState<typename internal::FunctorTraits<void \(\*\)\(int\)>::RunnableType, typename internal::FunctorTraits<void \(\*\)\(int\)>::RunType, internal::TypeList<> >::UnboundRunType>' to 'Callback<void \(\)>'"]
// Bind result cannot be assigned to Callbacks with a mismatching type. // Bind result cannot be assigned to Callbacks with a mismatching type.
void WontCompile() { void WontCompile() {
......
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