Created
November 16, 2013 22:20
-
-
Save LB--/7506118 to your computer and use it in GitHub Desktop.
Just some code snippets I used for planning while I only had access to a computer that was not mine and had no internet access.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//fix for void returns | |
template<> | |
struct Enforce32bit<void> final | |
{ | |
struct void_0 | |
{ | |
void_0(...) | |
{ | |
} | |
operator std::int32_t() | |
{ | |
return 0; | |
} | |
}; | |
using type = void; | |
using to32 = void_0; | |
using fr32 = void; | |
}; | |
//recursive bind args version | |
template<std::size_t> | |
std::uint32_t GetParam() | |
{ | |
return GetNextParam(); | |
} | |
template<> | |
std::uint32_t GetParam<0> | |
{ | |
return GetFirstParam(); | |
} | |
template<std::size_t I, typename R, typename First, typename... Rest> | |
auto bind_args(std::function<Enforce32bit<R>::to32 (First, Rest...)> f) | |
-> std::function<Enforce32bit<R>::to32 ()> | |
{ | |
auto bf = std::bind(f, Enforce32bit<First>::fr32(GetParam<i>())); | |
return bind_args<I+1, R, Rest...>(bf); | |
} | |
template<std::size_t I, typename R> | |
auto bind_args<I, R>(std::function<Enforce32bit<R>::to32 ()> f) | |
-> std::function<Enforce32bit<R>::to32 ()> | |
{ | |
return f; | |
} | |
std::int32_t operator()(std::int32_t, std::int32_t) | |
{ | |
return std::bind(bind_args<0>(mfp), ext)(); | |
} | |
//tuple_cat version | |
template<std::size_t I, typename First, typename... Rest> | |
auto tuple_gen() | |
-> decltype(std::tuple_cat | |
( | |
std::make_tuple<Enforce32bit<First>::fr32>(GetParam<I>()), | |
tuple_gen<I+1, Enforce32bit<Rest>::fr32...>() | |
)) | |
{ | |
return std::tuple_cat | |
( | |
std::make_tuple<Enforce32bit<First>::fr32>(GetParam<I>()), | |
tuple_gen<I+1, Enforce32bit<Rest>::fr32...>() | |
); | |
} | |
template<std::size_t I, typename Last> | |
auto tuple_gen() -> std::tuple<Enforce32bit<Last>::fr32> | |
{ | |
return std::make_tuple<Enforce32bit<Last>::fr32>(GetParam<I>()); | |
} | |
template<int...> struct seq {}; | |
template<int N, int... S> struct gens : gens<N-1, N-1, S...> {}; | |
template<int... S> struct gens<0, S...> | |
{ | |
using type = seq<S...>; | |
}; | |
template<int... S> | |
auto call(seq<S...>) -> Enforce32bit<R>::to32 | |
{ | |
auto params = tuple_gen<0, Args...>(); | |
return (ext.*mfp)(std::get<S>(params)...); | |
} | |
std::int32_t operator()(std::int32_t, std::int32_t) | |
{ | |
return call(typename gens<sizeof...(Args)>::type()); | |
} | |
//implementation | |
template<typename R, typename... Args, std::size_t I = sizeof...(Args)> | |
struct caller | |
{ | |
ExtT &ext; | |
ExtMFP<ExtT, R, Args...> mfp; | |
caller(ExtT &e, ExtMFP<ExtT, R, Args...> mf, std::int32_t, std::int32_t) | |
: ext(e) | |
, mfp(mf) | |
{ | |
} | |
//one of above impls | |
}; | |
template<typename R, typename... Args> | |
struct caller<R, Args..., 0> | |
{ | |
ExtT &ext; | |
ExtMFP<ExtT, R, Args...> mfp; | |
caller(ExtT &e, ExtMFP<ExtT, R, Args...> mf, std::int32_t, std::int32_t) | |
: ext(e) | |
, mfp(mf) | |
{ | |
} | |
std::int32_t operator()(std::int32_t, std::int32_t) | |
{ | |
return Enforce32bit<R>::to32((ext.*mfp)()); | |
} | |
}; | |
template<typename R, typename... Args> | |
struct caller<R, Args..., 1> | |
{ | |
ExtT &ext; | |
ExtMFP<ExtT, R, Args...> mfp; | |
std::int32_t param1; | |
caller(ExtT &e, ExtMFP<ExtT, R, Args...> mf, std::int32_t p1, std::int32_t) | |
: ext(e) | |
, mfp(mf) | |
, param1(p1) | |
{ | |
} | |
template<typename First, typename...> | |
using A1_t = First; | |
std::int32_t operator()(std::int32_t param1, std::int32_t) | |
{ | |
return Enforce32bit<R>::to32((ext.*mfp) | |
( | |
Enforce32bit<A1_t<Args...>>::fr32(param1) | |
)); | |
} | |
}; | |
template<typename R, typename... Args> | |
struct caller<R, Args..., 2> | |
{ | |
ExtT &ext; | |
ExtMFP<ExtT, R, Args...> mfp; | |
std::int32_t param1, param2; | |
caller(ExtT &e, ExtMFP<ExtT, R, Args...> mf) | |
: ext(e) | |
, mfp(mf) | |
{ | |
} | |
template<typename First, typename...> | |
using A1_t = First; | |
template<typename, typename Second, typename...> | |
using A2_t = Second; | |
std::int32_t operator()(std::int32_t param1, std::int32_t param2) | |
{ | |
return Enforce32bit<R>::to32((ext.*mfp) | |
( | |
Enforce32bit<A1_t<Args...>>::fr32(param1), | |
Enforce32bit<A2_t<Args...>>::fr32(param2) | |
)); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment