| 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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 | 44 |
| 45 template <size_t... Ns> | 45 template <size_t... Ns> |
| 46 struct MakeIndexSequenceImpl<0, Ns...> { | 46 struct MakeIndexSequenceImpl<0, Ns...> { |
| 47 using Type = IndexSequence<Ns...>; | 47 using Type = IndexSequence<Ns...>; |
| 48 }; | 48 }; |
| 49 | 49 |
| 50 template <size_t N, size_t... Ns> | 50 template <size_t N, size_t... Ns> |
| 51 struct MakeIndexSequenceImpl<N, Ns...> | 51 struct MakeIndexSequenceImpl<N, Ns...> |
| 52 : MakeIndexSequenceImpl<N - 1, N - 1, Ns...> {}; | 52 : MakeIndexSequenceImpl<N - 1, N - 1, Ns...> {}; |
| 53 | 53 |
| 54 // std::get() in <=libstdc++-4.6 returns an lvalue-reference for | |
| 55 // rvalue-reference of a tuple, where an rvalue-reference is expected. | |
| 56 template <size_t I, typename... Ts> | |
| 57 typename std::tuple_element<I, std::tuple<Ts...>>::type&& get( | |
| 58 std::tuple<Ts...>&& t) { | |
| 59 using ElemType = typename std::tuple_element<I, std::tuple<Ts...>>::type; | |
| 60 return std::forward<ElemType>(std::get<I>(t)); | |
| 61 } | |
| 62 | |
| 63 template <size_t I, typename T> | |
| 64 auto get(T& t) -> decltype(std::get<I>(t)) { | |
| 65 return std::get<I>(t); | |
| 66 } | |
| 67 | |
| 68 template <size_t N> | 54 template <size_t N> |
| 69 using MakeIndexSequence = typename MakeIndexSequenceImpl<N>::Type; | 55 using MakeIndexSequence = typename MakeIndexSequenceImpl<N>::Type; |
| 70 | 56 |
| 71 template <typename T> | 57 template <typename T> |
| 72 using MakeIndexSequenceForTuple = | 58 using MakeIndexSequenceForTuple = |
| 73 MakeIndexSequence<std::tuple_size<typename std::decay<T>::type>::value>; | 59 MakeIndexSequence<std::tuple_size<typename std::decay<T>::type>::value>; |
| 74 | 60 |
| 75 // Dispatchers ---------------------------------------------------------------- | 61 // Dispatchers ---------------------------------------------------------------- |
| 76 // | 62 // |
| 77 // Helper functions that call the given method on an object, with the unpacked | 63 // Helper functions that call the given method on an object, with the unpacked |
| 78 // tuple arguments. Notice that they all have the same number of arguments, | 64 // tuple arguments. Notice that they all have the same number of arguments, |
| 79 // so you need only write: | 65 // so you need only write: |
| 80 // DispatchToMethod(object, &Object::method, args); | 66 // DispatchToMethod(object, &Object::method, args); |
| 81 // This is very useful for templated dispatchers, since they don't need to know | 67 // This is very useful for templated dispatchers, since they don't need to know |
| 82 // what type |args| is. | 68 // what type |args| is. |
| 83 | 69 |
| 84 // Non-Static Dispatchers with no out params. | 70 // Non-Static Dispatchers with no out params. |
| 85 | 71 |
| 86 template <typename ObjT, typename Method, typename Tuple, size_t... Ns> | 72 template <typename ObjT, typename Method, typename Tuple, size_t... Ns> |
| 87 inline void DispatchToMethodImpl(const ObjT& obj, | 73 inline void DispatchToMethodImpl(const ObjT& obj, |
| 88 Method method, | 74 Method method, |
| 89 Tuple&& args, | 75 Tuple&& args, |
| 90 IndexSequence<Ns...>) { | 76 IndexSequence<Ns...>) { |
| 91 (obj->*method)(base::get<Ns>(std::forward<Tuple>(args))...); | 77 (obj->*method)(std::get<Ns>(std::forward<Tuple>(args))...); |
| 92 } | 78 } |
| 93 | 79 |
| 94 template <typename ObjT, typename Method, typename Tuple> | 80 template <typename ObjT, typename Method, typename Tuple> |
| 95 inline void DispatchToMethod(const ObjT& obj, | 81 inline void DispatchToMethod(const ObjT& obj, |
| 96 Method method, | 82 Method method, |
| 97 Tuple&& args) { | 83 Tuple&& args) { |
| 98 DispatchToMethodImpl(obj, method, std::forward<Tuple>(args), | 84 DispatchToMethodImpl(obj, method, std::forward<Tuple>(args), |
| 99 MakeIndexSequenceForTuple<Tuple>()); | 85 MakeIndexSequenceForTuple<Tuple>()); |
| 100 } | 86 } |
| 101 | 87 |
| 102 // Static Dispatchers with no out params. | 88 // Static Dispatchers with no out params. |
| 103 | 89 |
| 104 template <typename Function, typename Tuple, size_t... Ns> | 90 template <typename Function, typename Tuple, size_t... Ns> |
| 105 inline void DispatchToFunctionImpl(Function function, | 91 inline void DispatchToFunctionImpl(Function function, |
| 106 Tuple&& args, | 92 Tuple&& args, |
| 107 IndexSequence<Ns...>) { | 93 IndexSequence<Ns...>) { |
| 108 (*function)(base::get<Ns>(std::forward<Tuple>(args))...); | 94 (*function)(std::get<Ns>(std::forward<Tuple>(args))...); |
| 109 } | 95 } |
| 110 | 96 |
| 111 template <typename Function, typename Tuple> | 97 template <typename Function, typename Tuple> |
| 112 inline void DispatchToFunction(Function function, Tuple&& args) { | 98 inline void DispatchToFunction(Function function, Tuple&& args) { |
| 113 DispatchToFunctionImpl(function, std::forward<Tuple>(args), | 99 DispatchToFunctionImpl(function, std::forward<Tuple>(args), |
| 114 MakeIndexSequenceForTuple<Tuple>()); | 100 MakeIndexSequenceForTuple<Tuple>()); |
| 115 } | 101 } |
| 116 | 102 |
| 117 // Dispatchers with out parameters. | 103 // Dispatchers with out parameters. |
| 118 | 104 |
| 119 template <typename ObjT, | 105 template <typename ObjT, |
| 120 typename Method, | 106 typename Method, |
| 121 typename InTuple, | 107 typename InTuple, |
| 122 typename OutTuple, | 108 typename OutTuple, |
| 123 size_t... InNs, | 109 size_t... InNs, |
| 124 size_t... OutNs> | 110 size_t... OutNs> |
| 125 inline void DispatchToMethodImpl(const ObjT& obj, | 111 inline void DispatchToMethodImpl(const ObjT& obj, |
| 126 Method method, | 112 Method method, |
| 127 InTuple&& in, | 113 InTuple&& in, |
| 128 OutTuple* out, | 114 OutTuple* out, |
| 129 IndexSequence<InNs...>, | 115 IndexSequence<InNs...>, |
| 130 IndexSequence<OutNs...>) { | 116 IndexSequence<OutNs...>) { |
| 131 (obj->*method)(base::get<InNs>(std::forward<InTuple>(in))..., | 117 (obj->*method)(std::get<InNs>(std::forward<InTuple>(in))..., |
| 132 &std::get<OutNs>(*out)...); | 118 &std::get<OutNs>(*out)...); |
| 133 } | 119 } |
| 134 | 120 |
| 135 template <typename ObjT, typename Method, typename InTuple, typename OutTuple> | 121 template <typename ObjT, typename Method, typename InTuple, typename OutTuple> |
| 136 inline void DispatchToMethod(const ObjT& obj, | 122 inline void DispatchToMethod(const ObjT& obj, |
| 137 Method method, | 123 Method method, |
| 138 InTuple&& in, | 124 InTuple&& in, |
| 139 OutTuple* out) { | 125 OutTuple* out) { |
| 140 DispatchToMethodImpl(obj, method, std::forward<InTuple>(in), out, | 126 DispatchToMethodImpl(obj, method, std::forward<InTuple>(in), out, |
| 141 MakeIndexSequenceForTuple<InTuple>(), | 127 MakeIndexSequenceForTuple<InTuple>(), |
| 142 MakeIndexSequenceForTuple<OutTuple>()); | 128 MakeIndexSequenceForTuple<OutTuple>()); |
| 143 } | 129 } |
| 144 | 130 |
| 145 } // namespace base | 131 } // namespace base |
| 146 | 132 |
| 147 #endif // BASE_TUPLE_H_ | 133 #endif // BASE_TUPLE_H_ |
| OLD | NEW |