| 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 // Use std::tuple as tuple type. This file contains helper functions for | 5 // Use std::tuple as tuple type. This file contains helper functions for |
| 6 // working with std::tuples. | 6 // working with std::tuples. |
| 7 // The functions DispatchToMethod and DispatchToFunction take a function pointer | 7 // The functions DispatchToMethod and DispatchToFunction take a function pointer |
| 8 // or instance and method pointer, and unpack a tuple into arguments to the | 8 // or instance and method pointer, and unpack a tuple into arguments to the |
| 9 // call. | 9 // call. |
| 10 // | 10 // |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 } | 114 } |
| 115 | 115 |
| 116 template <size_t I, typename T> | 116 template <size_t I, typename T> |
| 117 auto get(T& t) -> decltype(std::get<I>(t)) { | 117 auto get(T& t) -> decltype(std::get<I>(t)) { |
| 118 return std::get<I>(t); | 118 return std::get<I>(t); |
| 119 } | 119 } |
| 120 | 120 |
| 121 template <size_t N> | 121 template <size_t N> |
| 122 using MakeIndexSequence = typename MakeIndexSequenceImpl<N>::Type; | 122 using MakeIndexSequence = typename MakeIndexSequenceImpl<N>::Type; |
| 123 | 123 |
| 124 template <typename T> |
| 125 using MakeIndexSequenceForTuple = |
| 126 MakeIndexSequence<std::tuple_size<typename std::decay<T>::type>::value>; |
| 127 |
| 124 // Dispatchers ---------------------------------------------------------------- | 128 // Dispatchers ---------------------------------------------------------------- |
| 125 // | 129 // |
| 126 // Helper functions that call the given method on an object, with the unpacked | 130 // Helper functions that call the given method on an object, with the unpacked |
| 127 // tuple arguments. Notice that they all have the same number of arguments, | 131 // tuple arguments. Notice that they all have the same number of arguments, |
| 128 // so you need only write: | 132 // so you need only write: |
| 129 // DispatchToMethod(object, &Object::method, args); | 133 // DispatchToMethod(object, &Object::method, args); |
| 130 // This is very useful for templated dispatchers, since they don't need to know | 134 // This is very useful for templated dispatchers, since they don't need to know |
| 131 // what type |args| is. | 135 // what type |args| is. |
| 132 | 136 |
| 133 // Non-Static Dispatchers with no out params. | 137 // Non-Static Dispatchers with no out params. |
| 134 | 138 |
| 135 template <typename ObjT, typename Method, typename... Ts, size_t... Ns> | 139 template <typename ObjT, typename Method, typename Tuple, size_t... Ns> |
| 136 inline void DispatchToMethodImpl(const ObjT& obj, | 140 inline void DispatchToMethodImpl(const ObjT& obj, |
| 137 Method method, | 141 Method method, |
| 138 const std::tuple<Ts...>& arg, | 142 Tuple&& args, |
| 139 IndexSequence<Ns...>) { | 143 IndexSequence<Ns...>) { |
| 140 (obj->*method)(internal::Unwrap(std::get<Ns>(arg))...); | 144 (obj->*method)(base::get<Ns>(std::forward<Tuple>(args))...); |
| 141 } | 145 } |
| 142 | 146 |
| 143 template <typename ObjT, typename Method, typename... Ts> | 147 template <typename ObjT, typename Method, typename Tuple> |
| 144 inline void DispatchToMethod(const ObjT& obj, | 148 inline void DispatchToMethod(const ObjT& obj, |
| 145 Method method, | 149 Method method, |
| 146 const std::tuple<Ts...>& arg) { | 150 Tuple&& args) { |
| 147 DispatchToMethodImpl(obj, method, arg, MakeIndexSequence<sizeof...(Ts)>()); | 151 DispatchToMethodImpl(obj, method, std::forward<Tuple>(args), |
| 152 MakeIndexSequenceForTuple<Tuple>()); |
| 148 } | 153 } |
| 149 | 154 |
| 150 // Static Dispatchers with no out params. | 155 // Static Dispatchers with no out params. |
| 151 | 156 |
| 152 template <typename Function, typename... Ts, size_t... Ns> | 157 template <typename Function, typename Tuple, size_t... Ns> |
| 153 inline void DispatchToFunctionImpl(Function function, | 158 inline void DispatchToFunctionImpl(Function function, |
| 154 const std::tuple<Ts...>& arg, | 159 Tuple&& args, |
| 155 IndexSequence<Ns...>) { | 160 IndexSequence<Ns...>) { |
| 156 (*function)(internal::Unwrap(std::get<Ns>(arg))...); | 161 (*function)(base::get<Ns>(std::forward<Tuple>(args))...); |
| 157 } | 162 } |
| 158 | 163 |
| 159 template <typename Function, typename... Ts> | 164 template <typename Function, typename Tuple> |
| 160 inline void DispatchToFunction(Function function, | 165 inline void DispatchToFunction(Function function, Tuple&& args) { |
| 161 const std::tuple<Ts...>& arg) { | 166 DispatchToFunctionImpl(function, std::forward<Tuple>(args), |
| 162 DispatchToFunctionImpl(function, arg, MakeIndexSequence<sizeof...(Ts)>()); | 167 MakeIndexSequenceForTuple<Tuple>()); |
| 163 } | 168 } |
| 164 | 169 |
| 165 // Dispatchers with out parameters. | 170 // Dispatchers with out parameters. |
| 166 | 171 |
| 167 template <typename ObjT, | 172 template <typename ObjT, |
| 168 typename Method, | 173 typename Method, |
| 169 typename... InTs, | 174 typename InTuple, |
| 170 typename... OutTs, | 175 typename OutTuple, |
| 171 size_t... InNs, | 176 size_t... InNs, |
| 172 size_t... OutNs> | 177 size_t... OutNs> |
| 173 inline void DispatchToMethodImpl(const ObjT& obj, | 178 inline void DispatchToMethodImpl(const ObjT& obj, |
| 174 Method method, | 179 Method method, |
| 175 const std::tuple<InTs...>& in, | 180 InTuple&& in, |
| 176 std::tuple<OutTs...>* out, | 181 OutTuple* out, |
| 177 IndexSequence<InNs...>, | 182 IndexSequence<InNs...>, |
| 178 IndexSequence<OutNs...>) { | 183 IndexSequence<OutNs...>) { |
| 179 (obj->*method)(internal::Unwrap(std::get<InNs>(in))..., | 184 (obj->*method)(base::get<InNs>(std::forward<InTuple>(in))..., |
| 180 &std::get<OutNs>(*out)...); | 185 &std::get<OutNs>(*out)...); |
| 181 } | 186 } |
| 182 | 187 |
| 183 template <typename ObjT, typename Method, typename... InTs, typename... OutTs> | 188 template <typename ObjT, typename Method, typename InTuple, typename OutTuple> |
| 184 inline void DispatchToMethod(const ObjT& obj, | 189 inline void DispatchToMethod(const ObjT& obj, |
| 185 Method method, | 190 Method method, |
| 186 const std::tuple<InTs...>& in, | 191 InTuple&& in, |
| 187 std::tuple<OutTs...>* out) { | 192 OutTuple* out) { |
| 188 DispatchToMethodImpl(obj, method, in, out, | 193 DispatchToMethodImpl(obj, method, std::forward<InTuple>(in), out, |
| 189 MakeIndexSequence<sizeof...(InTs)>(), | 194 MakeIndexSequenceForTuple<InTuple>(), |
| 190 MakeIndexSequence<sizeof...(OutTs)>()); | 195 MakeIndexSequenceForTuple<OutTuple>()); |
| 191 } | 196 } |
| 192 | 197 |
| 193 } // namespace base | 198 } // namespace base |
| 194 | 199 |
| 195 #endif // BASE_TUPLE_H_ | 200 #endif // BASE_TUPLE_H_ |
| OLD | NEW |