| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef BASE_BIND_H_ | 5 #ifndef BASE_BIND_H_ |
| 6 #define BASE_BIND_H_ | 6 #define BASE_BIND_H_ |
| 7 | 7 |
| 8 #include "base/bind_internal.h" | 8 #include "base/bind_internal.h" |
| 9 | 9 |
| 10 // ----------------------------------------------------------------------------- | 10 // ----------------------------------------------------------------------------- |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 template <typename Functor, typename... Args> | 63 template <typename Functor, typename... Args> |
| 64 using MakeUnboundRunType = | 64 using MakeUnboundRunType = |
| 65 typename internal::MakeUnboundRunTypeImpl<Functor, Args...>::Type; | 65 typename internal::MakeUnboundRunTypeImpl<Functor, Args...>::Type; |
| 66 | 66 |
| 67 template <typename Functor, typename... Args> | 67 template <typename Functor, typename... Args> |
| 68 base::Callback<MakeUnboundRunType<Functor, Args...>> | 68 base::Callback<MakeUnboundRunType<Functor, Args...>> |
| 69 Bind(Functor functor, Args&&... args) { | 69 Bind(Functor functor, Args&&... args) { |
| 70 // Type aliases for how to store and run the functor. | 70 // Type aliases for how to store and run the functor. |
| 71 using RunnableType = typename internal::FunctorTraits<Functor>::RunnableType; | 71 using RunnableType = typename internal::FunctorTraits<Functor>::RunnableType; |
| 72 using RunType = typename internal::FunctorTraits<Functor>::RunType; | 72 using RunType = typename internal::FunctorTraits<Functor>::RunType; |
| 73 | |
| 74 // Use RunnableType::RunType instead of RunType above because our | |
| 75 // checks below for bound references need to know what the actual | |
| 76 // functor is going to interpret the argument as. | |
| 77 using BoundRunType = typename RunnableType::RunType; | |
| 78 | |
| 79 using BoundArgs = | |
| 80 internal::TakeTypeListItem<sizeof...(Args), | |
| 81 internal::ExtractArgs<BoundRunType>>; | |
| 82 | |
| 83 // Do not allow binding a non-const reference parameter. Non-const reference | |
| 84 // parameters are disallowed by the Google style guide. Also, binding a | |
| 85 // non-const reference parameter can make for subtle bugs because the | |
| 86 // invoked function will receive a reference to the stored copy of the | |
| 87 // argument and not the original. | |
| 88 static_assert(!internal::HasNonConstReferenceItem<BoundArgs>::value, | |
| 89 "do not bind functions with nonconst ref"); | |
| 90 | |
| 91 const bool is_method = internal::HasIsMethodTag<RunnableType>::value; | 73 const bool is_method = internal::HasIsMethodTag<RunnableType>::value; |
| 92 | 74 |
| 93 // For methods, we need to be careful for parameter 1. We do not require | 75 // For methods, we need to be careful for parameter 1. We do not require |
| 94 // a scoped_refptr because BindState<> itself takes care of AddRef() for | 76 // a scoped_refptr because BindState<> itself takes care of AddRef() for |
| 95 // methods. We also disallow binding of an array as the method's target | 77 // methods. We also disallow binding of an array as the method's target |
| 96 // object. | 78 // object. |
| 97 static_assert(!internal::BindsArrayToFirstArg<is_method, Args...>::value, | 79 static_assert(!internal::BindsArrayToFirstArg<is_method, Args...>::value, |
| 98 "first bound argument to method cannot be array"); | 80 "first bound argument to method cannot be array"); |
| 99 static_assert( | 81 static_assert( |
| 100 !internal::HasRefCountedParamAsRawPtr<is_method, Args...>::value, | 82 !internal::HasRefCountedParamAsRawPtr<is_method, Args...>::value, |
| 101 "a parameter is a refcounted type and needs scoped_refptr"); | 83 "a parameter is a refcounted type and needs scoped_refptr"); |
| 102 | 84 |
| 103 using BindState = internal::BindState<RunnableType, RunType, Args...>; | 85 using BindState = internal::BindState<RunnableType, RunType, Args...>; |
| 104 | 86 |
| 105 return Callback<typename BindState::UnboundRunType>( | 87 return Callback<typename BindState::UnboundRunType>( |
| 106 new BindState(internal::MakeRunnable(functor), | 88 new BindState(internal::MakeRunnable(functor), |
| 107 std::forward<Args>(args)...)); | 89 std::forward<Args>(args)...)); |
| 108 } | 90 } |
| 109 | 91 |
| 110 } // namespace base | 92 } // namespace base |
| 111 | 93 |
| 112 #endif // BASE_BIND_H_ | 94 #endif // BASE_BIND_H_ |
| OLD | NEW |