1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #ifndef CUTTLEFISH_COMMON_COMMON_LIBS_THREADS_THUNKERS_H_ 17 #define CUTTLEFISH_COMMON_COMMON_LIBS_THREADS_THUNKERS_H_ 18 19 template <typename HalType, typename Impl, typename F> struct ThunkerBase; 20 21 /* Handle varying number of arguments with a bunch of specializations. 22 * The C++11 dream is: 23 * 24 * template <typename HalType, typename Impl, typename R, typename... Args> 25 * struct ThunkerBase<HalType, Impl, R(Args...)> { 26 * template <R (Impl::*MemFn)(Args...)> 27 * static R call(HalType* in, Args... args) { 28 * return (reinterpret_cast<Impl*>(in)->*MemFn)(args...); 29 * } 30 * }; 31 */ 32 33 template <typename HalType, typename Impl, typename R> 34 struct ThunkerBase<HalType, Impl, R()> { 35 template <R (Impl::*MemFn)()> 36 static R call(HalType* in) { 37 return (reinterpret_cast<Impl*>(in)->*MemFn)(); 38 } 39 40 template <R (Impl::*MemFn)() const> 41 static R call(const HalType* in) { 42 return (reinterpret_cast<const Impl*>(in)->*MemFn)(); 43 } 44 }; 45 46 template <typename HalType, typename Impl, typename R, typename T1> 47 struct ThunkerBase<HalType, Impl, R(T1)> { 48 template <R (Impl::*MemFn)(T1)> 49 static R call(HalType* in, T1 t1) { 50 return (reinterpret_cast<Impl*>(in)->*MemFn)(t1); 51 } 52 53 template <R (Impl::*MemFn)(T1) const> 54 static R call(const HalType* in, T1 t1) { 55 return (reinterpret_cast<const Impl*>(in)->*MemFn)(t1); 56 } 57 }; 58 59 template <typename HalType, typename Impl, typename R, typename T1, typename T2> 60 struct ThunkerBase<HalType, Impl, R(T1, T2)> { 61 template <R (Impl::*MemFn)(T1, T2)> 62 static R call(HalType* in, T1 t1, T2 t2) { 63 return (reinterpret_cast<Impl*>(in)->*MemFn)(t1, t2); 64 } 65 66 template <R (Impl::*MemFn)(T1, T2) const> 67 static R call(const HalType* in, T1 t1, T2 t2) { 68 return (reinterpret_cast<const Impl*>(in)->*MemFn)(t1, t2); 69 } 70 }; 71 72 template <typename HalType, typename Impl, typename R, typename T1, 73 typename T2, typename T3> 74 struct ThunkerBase<HalType, Impl, R(T1, T2, T3)> { 75 template <R (Impl::*MemFn)(T1, T2, T3)> 76 static R call(HalType* in, T1 t1, T2 t2, T3 t3) { 77 return (reinterpret_cast<Impl*>(in)->*MemFn)(t1, t2, t3); 78 } 79 80 template <R (Impl::*MemFn)(T1, T2, T3) const> 81 static R call(const HalType* in, T1 t1, T2 t2, T3 t3) { 82 return (reinterpret_cast<const Impl*>(in)->*MemFn)(t1, t2, t3); 83 } 84 }; 85 86 template <typename HalType, typename Impl, typename R, typename T1, 87 typename T2, typename T3, typename T4> 88 struct ThunkerBase<HalType, Impl, R(T1, T2, T3, T4)> { 89 template <R (Impl::*MemFn)(T1, T2, T3, T4)> 90 static R call(HalType* in, T1 t1, T2 t2, T3 t3, T4 t4) { 91 return (reinterpret_cast<Impl*>(in)->*MemFn)(t1, t2, t3, t4); 92 } 93 94 template <R (Impl::*MemFn)(T1, T2, T3, T4) const> 95 static R call(const HalType* in, T1 t1, T2 t2, T3 t3, T4 t4) { 96 return (reinterpret_cast<const Impl*>(in)->*MemFn)(t1, t2, t3, t4); 97 } 98 }; 99 100 template <typename HalType, typename Impl, typename R, typename T1, 101 typename T2, typename T3, typename T4, typename T5> 102 struct ThunkerBase<HalType, Impl, R(T1, T2, T3, T4, T5)> { 103 template <R (Impl::*MemFn)(T1, T2, T3, T4, T5)> 104 static R call(HalType* in, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) { 105 return (reinterpret_cast<Impl*>(in)->*MemFn)(t1, t2, t3, t4, t5); 106 } 107 108 template <R (Impl::*MemFn)(T1, T2, T3, T4, T5) const> 109 static R call(const HalType* in, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) { 110 return (reinterpret_cast<const Impl*>(in)->*MemFn)(t1, t2, t3, t4, t5); 111 } 112 }; 113 114 template <typename HalType, typename Impl, typename R, typename T1, 115 typename T2, typename T3, typename T4, typename T5, typename T6> 116 struct ThunkerBase<HalType, Impl, R(T1, T2, T3, T4, T5, T6)> { 117 template <R (Impl::*MemFn)(T1, T2, T3, T4, T5, T6)> 118 static R call(HalType* in, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) { 119 return (reinterpret_cast<Impl*>(in)->*MemFn)(t1, t2, t3, t4, t5, t6); 120 } 121 122 template <R (Impl::*MemFn)(T1, T2, T3, T4, T5, T6) const> 123 static R call(const HalType* in, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) { 124 return (reinterpret_cast<const Impl*>(in)->*MemFn)(t1, t2, t3, t4, t5, t6); 125 } 126 }; 127 128 template <typename HalType, typename Impl, typename R, typename T1, 129 typename T2, typename T3, typename T4, typename T5, typename T6, 130 typename T7> 131 struct ThunkerBase<HalType, Impl, R(T1, T2, T3, T4, T5, T6, T7)> { 132 template <R (Impl::*MemFn)(T1, T2, T3, T4, T5, T6, T7)> 133 static R call(HalType* in, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) { 134 return (reinterpret_cast<Impl*>(in)->*MemFn)(t1, t2, t3, t4, t5, t6, t7); 135 } 136 137 template <R (Impl::*MemFn)(T1, T2, T3, T4, T5, T6, T7) const> 138 static R call(const HalType* in, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, 139 T7 t7) { 140 return (reinterpret_cast<const Impl*>(in)->*MemFn)( 141 t1, t2, t3, t4, t5, t6, t7); 142 } 143 }; 144 145 template <typename HalType, typename Impl, typename R, typename T1, 146 typename T2, typename T3, typename T4, typename T5, typename T6, 147 typename T7, typename T8> 148 struct ThunkerBase<HalType, Impl, R(T1, T2, T3, T4, T5, T6, T7, T8)> { 149 template <R (Impl::*MemFn)(T1, T2, T3, T4, T5, T6, T7, T8)> 150 static R call(HalType* in, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, 151 T8 t8) { 152 return (reinterpret_cast<Impl*>(in)->*MemFn)( 153 t1, t2, t3, t4, t5, t6, t7, t8); 154 } 155 156 template <R (Impl::*MemFn)(T1, T2, T3, T4, T5, T6, T7, T8) const> 157 static R call(const HalType* in, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, 158 T7 t7, T8 t8) { 159 return (reinterpret_cast<const Impl*>(in)->*MemFn)( 160 t1, t2, t3, t4, t5, t6, t7, t8); 161 } 162 }; 163 #endif // CUTTLEFISH_COMMON_COMMON_LIBS_THREADS_THUNKERS_H_ 164