blob: e4968390a7cd485ee736037b2646c9ab66f1a694 [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CUTTLEFISH_COMMON_COMMON_LIBS_THREADS_THUNKERS_H_
#define CUTTLEFISH_COMMON_COMMON_LIBS_THREADS_THUNKERS_H_
template <typename HalType, typename Impl, typename F> struct ThunkerBase;
/* Handle varying number of arguments with a bunch of specializations.
* The C++11 dream is:
*
* template <typename HalType, typename Impl, typename R, typename... Args>
* struct ThunkerBase<HalType, Impl, R(Args...)> {
* template <R (Impl::*MemFn)(Args...)>
* static R call(HalType* in, Args... args) {
* return (reinterpret_cast<Impl*>(in)->*MemFn)(args...);
* }
* };
*/
template <typename HalType, typename Impl, typename R>
struct ThunkerBase<HalType, Impl, R()> {
template <R (Impl::*MemFn)()>
static R call(HalType* in) {
return (reinterpret_cast<Impl*>(in)->*MemFn)();
}
template <R (Impl::*MemFn)() const>
static R call(const HalType* in) {
return (reinterpret_cast<const Impl*>(in)->*MemFn)();
}
};
template <typename HalType, typename Impl, typename R, typename T1>
struct ThunkerBase<HalType, Impl, R(T1)> {
template <R (Impl::*MemFn)(T1)>
static R call(HalType* in, T1 t1) {
return (reinterpret_cast<Impl*>(in)->*MemFn)(t1);
}
template <R (Impl::*MemFn)(T1) const>
static R call(const HalType* in, T1 t1) {
return (reinterpret_cast<const Impl*>(in)->*MemFn)(t1);
}
};
template <typename HalType, typename Impl, typename R, typename T1, typename T2>
struct ThunkerBase<HalType, Impl, R(T1, T2)> {
template <R (Impl::*MemFn)(T1, T2)>
static R call(HalType* in, T1 t1, T2 t2) {
return (reinterpret_cast<Impl*>(in)->*MemFn)(t1, t2);
}
template <R (Impl::*MemFn)(T1, T2) const>
static R call(const HalType* in, T1 t1, T2 t2) {
return (reinterpret_cast<const Impl*>(in)->*MemFn)(t1, t2);
}
};
template <typename HalType, typename Impl, typename R, typename T1,
typename T2, typename T3>
struct ThunkerBase<HalType, Impl, R(T1, T2, T3)> {
template <R (Impl::*MemFn)(T1, T2, T3)>
static R call(HalType* in, T1 t1, T2 t2, T3 t3) {
return (reinterpret_cast<Impl*>(in)->*MemFn)(t1, t2, t3);
}
template <R (Impl::*MemFn)(T1, T2, T3) const>
static R call(const HalType* in, T1 t1, T2 t2, T3 t3) {
return (reinterpret_cast<const Impl*>(in)->*MemFn)(t1, t2, t3);
}
};
template <typename HalType, typename Impl, typename R, typename T1,
typename T2, typename T3, typename T4>
struct ThunkerBase<HalType, Impl, R(T1, T2, T3, T4)> {
template <R (Impl::*MemFn)(T1, T2, T3, T4)>
static R call(HalType* in, T1 t1, T2 t2, T3 t3, T4 t4) {
return (reinterpret_cast<Impl*>(in)->*MemFn)(t1, t2, t3, t4);
}
template <R (Impl::*MemFn)(T1, T2, T3, T4) const>
static R call(const HalType* in, T1 t1, T2 t2, T3 t3, T4 t4) {
return (reinterpret_cast<const Impl*>(in)->*MemFn)(t1, t2, t3, t4);
}
};
template <typename HalType, typename Impl, typename R, typename T1,
typename T2, typename T3, typename T4, typename T5>
struct ThunkerBase<HalType, Impl, R(T1, T2, T3, T4, T5)> {
template <R (Impl::*MemFn)(T1, T2, T3, T4, T5)>
static R call(HalType* in, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) {
return (reinterpret_cast<Impl*>(in)->*MemFn)(t1, t2, t3, t4, t5);
}
template <R (Impl::*MemFn)(T1, T2, T3, T4, T5) const>
static R call(const HalType* in, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) {
return (reinterpret_cast<const Impl*>(in)->*MemFn)(t1, t2, t3, t4, t5);
}
};
template <typename HalType, typename Impl, typename R, typename T1,
typename T2, typename T3, typename T4, typename T5, typename T6>
struct ThunkerBase<HalType, Impl, R(T1, T2, T3, T4, T5, T6)> {
template <R (Impl::*MemFn)(T1, T2, T3, T4, T5, T6)>
static R call(HalType* in, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) {
return (reinterpret_cast<Impl*>(in)->*MemFn)(t1, t2, t3, t4, t5, t6);
}
template <R (Impl::*MemFn)(T1, T2, T3, T4, T5, T6) const>
static R call(const HalType* in, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) {
return (reinterpret_cast<const Impl*>(in)->*MemFn)(t1, t2, t3, t4, t5, t6);
}
};
template <typename HalType, typename Impl, typename R, typename T1,
typename T2, typename T3, typename T4, typename T5, typename T6,
typename T7>
struct ThunkerBase<HalType, Impl, R(T1, T2, T3, T4, T5, T6, T7)> {
template <R (Impl::*MemFn)(T1, T2, T3, T4, T5, T6, T7)>
static R call(HalType* in, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) {
return (reinterpret_cast<Impl*>(in)->*MemFn)(t1, t2, t3, t4, t5, t6, t7);
}
template <R (Impl::*MemFn)(T1, T2, T3, T4, T5, T6, T7) const>
static R call(const HalType* in, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6,
T7 t7) {
return (reinterpret_cast<const Impl*>(in)->*MemFn)(
t1, t2, t3, t4, t5, t6, t7);
}
};
template <typename HalType, typename Impl, typename R, typename T1,
typename T2, typename T3, typename T4, typename T5, typename T6,
typename T7, typename T8>
struct ThunkerBase<HalType, Impl, R(T1, T2, T3, T4, T5, T6, T7, T8)> {
template <R (Impl::*MemFn)(T1, T2, T3, T4, T5, T6, T7, T8)>
static R call(HalType* in, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7,
T8 t8) {
return (reinterpret_cast<Impl*>(in)->*MemFn)(
t1, t2, t3, t4, t5, t6, t7, t8);
}
template <R (Impl::*MemFn)(T1, T2, T3, T4, T5, T6, T7, T8) const>
static R call(const HalType* in, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6,
T7 t7, T8 t8) {
return (reinterpret_cast<const Impl*>(in)->*MemFn)(
t1, t2, t3, t4, t5, t6, t7, t8);
}
};
#endif // CUTTLEFISH_COMMON_COMMON_LIBS_THREADS_THUNKERS_H_