OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // This file contains utility functions and classes that help the | 5 // This file contains utility functions and classes that help the |
6 // implementation, and management of the Callback objects. | 6 // implementation, and management of the Callback objects. |
7 | 7 |
8 #ifndef BASE_CALLBACK_INTERNAL_H_ | 8 #ifndef BASE_CALLBACK_INTERNAL_H_ |
9 #define BASE_CALLBACK_INTERNAL_H_ | 9 #define BASE_CALLBACK_INTERNAL_H_ |
10 | 10 |
11 #include <stddef.h> | 11 #include <stddef.h> |
| 12 #include <type_traits> |
12 | 13 |
13 #include "base/atomic_ref_count.h" | 14 #include "base/atomic_ref_count.h" |
14 #include "base/base_export.h" | 15 #include "base/base_export.h" |
15 #include "base/macros.h" | 16 #include "base/macros.h" |
16 #include "base/memory/ref_counted.h" | 17 #include "base/memory/ref_counted.h" |
17 #include "base/memory/scoped_ptr.h" | 18 #include "base/memory/scoped_ptr.h" |
18 #include "base/template_util.h" | 19 #include "base/template_util.h" |
19 | 20 |
20 namespace base { | 21 namespace base { |
21 namespace internal { | 22 namespace internal { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 template <typename U> | 99 template <typename U> |
99 static YesType Test(const typename U::MoveOnlyTypeForCPP03*); | 100 static YesType Test(const typename U::MoveOnlyTypeForCPP03*); |
100 | 101 |
101 template <typename U> | 102 template <typename U> |
102 static NoType Test(...); | 103 static NoType Test(...); |
103 | 104 |
104 static const bool value = sizeof((Test<T>(0))) == sizeof(YesType) && | 105 static const bool value = sizeof((Test<T>(0))) == sizeof(YesType) && |
105 !is_const<T>::value; | 106 !is_const<T>::value; |
106 }; | 107 }; |
107 | 108 |
108 // Returns |Then| as SelectType::Type if |condition| is true. Otherwise returns | |
109 // |Else|. | |
110 template <bool condition, typename Then, typename Else> | |
111 struct SelectType { | |
112 typedef Then Type; | |
113 }; | |
114 | |
115 template <typename Then, typename Else> | |
116 struct SelectType<false, Then, Else> { | |
117 typedef Else Type; | |
118 }; | |
119 | |
120 template <typename> | 109 template <typename> |
121 struct CallbackParamTraitsForMoveOnlyType; | 110 struct CallbackParamTraitsForMoveOnlyType; |
122 | 111 |
123 template <typename> | 112 template <typename> |
124 struct CallbackParamTraitsForNonMoveOnlyType; | 113 struct CallbackParamTraitsForNonMoveOnlyType; |
125 | 114 |
126 // TODO(tzik): Use a default parameter once MSVS supports variadic templates | 115 // TODO(tzik): Use a default parameter once MSVS supports variadic templates |
127 // with default values. | 116 // with default values. |
128 // http://connect.microsoft.com/VisualStudio/feedbackdetail/view/957801/compilat
ion-error-with-variadic-templates | 117 // http://connect.microsoft.com/VisualStudio/feedbackdetail/view/957801/compilat
ion-error-with-variadic-templates |
129 // | 118 // |
130 // This is a typetraits object that's used to take an argument type, and | 119 // This is a typetraits object that's used to take an argument type, and |
131 // extract a suitable type for storing and forwarding arguments. | 120 // extract a suitable type for storing and forwarding arguments. |
132 // | 121 // |
133 // In particular, it strips off references, and converts arrays to | 122 // In particular, it strips off references, and converts arrays to |
134 // pointers for storage; and it avoids accidentally trying to create a | 123 // pointers for storage; and it avoids accidentally trying to create a |
135 // "reference of a reference" if the argument is a reference type. | 124 // "reference of a reference" if the argument is a reference type. |
136 // | 125 // |
137 // This array type becomes an issue for storage because we are passing bound | 126 // This array type becomes an issue for storage because we are passing bound |
138 // parameters by const reference. In this case, we end up passing an actual | 127 // parameters by const reference. In this case, we end up passing an actual |
139 // array type in the initializer list which C++ does not allow. This will | 128 // array type in the initializer list which C++ does not allow. This will |
140 // break passing of C-string literals. | 129 // break passing of C-string literals. |
141 template <typename T> | 130 template <typename T> |
142 struct CallbackParamTraits | 131 struct CallbackParamTraits |
143 : SelectType<IsMoveOnlyType<T>::value, | 132 : std::conditional<IsMoveOnlyType<T>::value, |
144 CallbackParamTraitsForMoveOnlyType<T>, | 133 CallbackParamTraitsForMoveOnlyType<T>, |
145 CallbackParamTraitsForNonMoveOnlyType<T> >::Type { | 134 CallbackParamTraitsForNonMoveOnlyType<T>>::type { |
146 }; | 135 }; |
147 | 136 |
148 template <typename T> | 137 template <typename T> |
149 struct CallbackParamTraitsForNonMoveOnlyType { | 138 struct CallbackParamTraitsForNonMoveOnlyType { |
150 typedef const T& ForwardType; | 139 typedef const T& ForwardType; |
151 typedef T StorageType; | 140 typedef T StorageType; |
152 }; | 141 }; |
153 | 142 |
154 // The Storage should almost be impossible to trigger unless someone manually | 143 // The Storage should almost be impossible to trigger unless someone manually |
155 // specifies type of the bind parameters. However, in case they do, | 144 // specifies type of the bind parameters. However, in case they do, |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 | 211 |
223 template <typename T> | 212 template <typename T> |
224 typename enable_if<IsMoveOnlyType<T>::value, T>::type CallbackForward(T& t) { | 213 typename enable_if<IsMoveOnlyType<T>::value, T>::type CallbackForward(T& t) { |
225 return t.Pass(); | 214 return t.Pass(); |
226 } | 215 } |
227 | 216 |
228 } // namespace internal | 217 } // namespace internal |
229 } // namespace base | 218 } // namespace base |
230 | 219 |
231 #endif // BASE_CALLBACK_INTERNAL_H_ | 220 #endif // BASE_CALLBACK_INTERNAL_H_ |
OLD | NEW |