Skip to content

Instantly share code, notes, and snippets.

@LB--
Created November 16, 2013 22:20
Show Gist options
  • Save LB--/7506118 to your computer and use it in GitHub Desktop.
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.
//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