Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2012 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2012 The WebRTC Project Authors. All rights reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 53 // auto functor = rtc::Bind(&Bar::Test, bar); | 53 // auto functor = rtc::Bind(&Bar::Test, bar); |
| 54 // bar = nullptr; | 54 // bar = nullptr; |
| 55 // // The functor stores an internal scoped_refptr<Bar>, so this is safe. | 55 // // The functor stores an internal scoped_refptr<Bar>, so this is safe. |
| 56 // functor(); | 56 // functor(); |
| 57 // } | 57 // } |
| 58 // | 58 // |
| 59 | 59 |
| 60 #ifndef WEBRTC_BASE_BIND_H_ | 60 #ifndef WEBRTC_BASE_BIND_H_ |
| 61 #define WEBRTC_BASE_BIND_H_ | 61 #define WEBRTC_BASE_BIND_H_ |
| 62 | 62 |
| 63 #include <ciso646> // Small include to detect c++ std lib. | |
| 64 #if defined(_LIBCPP_VERSION) || defined(_MSC_VER) | |
| 65 #include <type_traits> | |
|
magjed_webrtc
2015/10/22 23:54:31
I'm surprised this compiles on all webrtc bots, bu
noahric
2015/10/23 00:34:27
Ah, yeah, good point. And I realized I was being d
magjed_webrtc
2015/10/23 05:17:01
I don't remember why I stripped const-ness, but I
noahric
2015/10/23 06:02:16
Gotcha. Seems to be fine now that they are const a
| |
| 66 #define STD_REMOVE_REFERENCE std::remove_reference | |
| 67 #else | |
| 68 #include <tr1/type_traits> | |
| 69 #define STD_REMOVE_REFERENCE std::tr1::remove_reference | |
| 70 #endif | |
| 71 | |
| 63 #include "webrtc/base/scoped_ref_ptr.h" | 72 #include "webrtc/base/scoped_ref_ptr.h" |
| 64 | 73 |
| 65 #define NONAME | 74 #define NONAME |
| 66 | 75 |
| 67 namespace rtc { | 76 namespace rtc { |
| 68 namespace detail { | 77 namespace detail { |
| 69 // This is needed because the template parameters in Bind can't be resolved | 78 // This is needed because the template parameters in Bind can't be resolved |
| 70 // if they're used both as parameters of the function pointer type and as | 79 // if they're used both as parameters of the function pointer type and as |
| 71 // parameters to Bind itself: the function pointer parameters are exact | 80 // parameters to Bind itself: the function pointer parameters are exact |
| 72 // matches to the function prototype, but the parameters to bind have | 81 // matches to the function prototype, but the parameters to bind have |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 117 | 126 |
| 118 // PointerType<T>::type will be scoped_refptr<T> for ref counted types, and T* | 127 // PointerType<T>::type will be scoped_refptr<T> for ref counted types, and T* |
| 119 // otherwise. | 128 // otherwise. |
| 120 template <class T> | 129 template <class T> |
| 121 struct PointerType { | 130 struct PointerType { |
| 122 typedef typename TernaryTypeOperator<IsRefCounted<T>::value, | 131 typedef typename TernaryTypeOperator<IsRefCounted<T>::value, |
| 123 scoped_refptr<T>, | 132 scoped_refptr<T>, |
| 124 T*>::type type; | 133 T*>::type type; |
| 125 }; | 134 }; |
| 126 | 135 |
| 127 // RemoveScopedPtrRef will capture scoped_refptr by-value instead of | 136 // RemoveAllRef will capture scoped_refptr by-value instead of |
| 128 // by-reference. | 137 // by-reference. It will additionally capture non-refptr T types by value. |
| 129 template <class T> struct RemoveScopedPtrRef { typedef T type; }; | |
| 130 template <class T> | 138 template <class T> |
| 131 struct RemoveScopedPtrRef<const scoped_refptr<T>&> { | 139 struct RemoveAllRef { |
| 140 typedef typename STD_REMOVE_REFERENCE<T>::type type; | |
| 141 }; | |
| 142 template <class T> | |
| 143 struct RemoveAllRef<const scoped_refptr<T>&> { | |
| 132 typedef scoped_refptr<T> type; | 144 typedef scoped_refptr<T> type; |
| 133 }; | 145 }; |
| 134 template <class T> | 146 template <class T> |
| 135 struct RemoveScopedPtrRef<scoped_refptr<T>&> { | 147 struct RemoveAllRef<scoped_refptr<T>&> { |
| 136 typedef scoped_refptr<T> type; | 148 typedef scoped_refptr<T> type; |
| 137 }; | 149 }; |
| 138 | 150 |
| 139 } // namespace detail | 151 } // namespace detail |
| 140 | 152 |
| 141 $var n = 6 | 153 $var n = 9 |
| 142 $range i 0..n | 154 $range i 0..n |
| 143 $for i [[ | 155 $for i [[ |
| 144 $range j 1..i | 156 $range j 1..i |
| 145 | 157 |
| 146 template <class ObjectT, class MethodT, class R$for j [[, | 158 template <class ObjectT, class MethodT, class R$for j [[, |
| 147 class P$j]]> | 159 class P$j]]> |
| 148 class MethodFunctor$i { | 160 class MethodFunctor$i { |
| 149 public: | 161 public: |
| 150 MethodFunctor$i(MethodT method, ObjectT* object$for j [[, | 162 MethodFunctor$i(MethodT method, ObjectT* object$for j [[, |
| 151 P$j p$j]]) | 163 P$j p$j]]) |
| 152 : method_(method), object_(object)$for j [[, | 164 : method_(method), object_(object)$for j [[, |
| 153 p$(j)_(p$j)]] {} | 165 p$(j)_(p$j)]] {} |
| 154 R operator()() const { | 166 R operator()() const { |
| 155 return (object_->*method_)($for j , [[p$(j)_]]); } | 167 return (object_->*method_)($for j , [[p$(j)_]]); } |
| 156 private: | 168 private: |
| 157 MethodT method_; | 169 MethodT method_; |
| 158 typename detail::PointerType<ObjectT>::type object_;$for j [[ | 170 typename detail::PointerType<ObjectT>::type object_;$for j [[ |
| 159 | 171 |
| 160 typename detail::RemoveScopedPtrRef<P$j>::type p$(j)_;]] | 172 typename detail::RemoveAllRef<P$j>::type p$(j)_;]] |
| 161 | 173 |
| 162 }; | 174 }; |
| 163 | 175 |
| 164 template <class FunctorT, class R$for j [[, | 176 template <class FunctorT, class R$for j [[, |
| 165 class P$j]]> | 177 class P$j]]> |
| 166 class Functor$i { | 178 class Functor$i { |
| 167 public: | 179 public: |
| 168 $if i == 0 [[explicit ]] | 180 $if i == 0 [[explicit ]] |
| 169 Functor$i(const FunctorT& functor$for j [[, P$j p$j]]) | 181 Functor$i(const FunctorT& functor$for j [[, P$j p$j]]) |
| 170 : functor_(functor)$for j [[, | 182 : functor_(functor)$for j [[, |
| 171 p$(j)_(p$j)]] {} | 183 p$(j)_(p$j)]] {} |
| 172 R operator()() const { | 184 R operator()() const { |
| 173 return functor_($for j , [[p$(j)_]]); } | 185 return functor_($for j , [[p$(j)_]]); } |
| 174 private: | 186 private: |
| 175 FunctorT functor_;$for j [[ | 187 FunctorT functor_;$for j [[ |
| 176 | 188 |
| 177 typename detail::RemoveScopedPtrRef<P$j>::type p$(j)_;]] | 189 typename detail::RemoveAllRef<P$j>::type p$(j)_;]] |
| 178 | 190 |
| 179 }; | 191 }; |
| 180 | 192 |
| 181 | 193 |
| 182 #define FP_T(x) R (ObjectT::*x)($for j , [[P$j]]) | 194 #define FP_T(x) R (ObjectT::*x)($for j , [[P$j]]) |
| 183 | 195 |
| 184 template <class ObjectT, class R$for j [[, | 196 template <class ObjectT, class R$for j [[, |
| 185 class P$j]]> | 197 class P$j]]> |
| 186 MethodFunctor$i<ObjectT, FP_T(NONAME), R$for j [[, P$j]]> | 198 MethodFunctor$i<ObjectT, FP_T(NONAME), R$for j [[, P$j]]> |
| 187 Bind(FP_T(method), ObjectT* object$for j [[, | 199 Bind(FP_T(method), ObjectT* object$for j [[, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 228 | 240 |
| 229 #undef FP_T | 241 #undef FP_T |
| 230 | 242 |
| 231 ]] | 243 ]] |
| 232 | 244 |
| 233 } // namespace rtc | 245 } // namespace rtc |
| 234 | 246 |
| 235 #undef NONAME | 247 #undef NONAME |
| 236 | 248 |
| 237 #endif // WEBRTC_BASE_BIND_H_ | 249 #endif // WEBRTC_BASE_BIND_H_ |
| OLD | NEW |