- How to inspect the types of a function's parameters?
- template<typename Function, typename... Args>
- void marshal_and_apply(Function f, Args... args);
- void func1(int x, int y);
- void func2(marshal_me<int> x, int y);
- void func3(marshal_me<int> x, marshal_me<int> y, marshal_me<int> z);
- // this call would be equivalent to:
- // func1(7,13)
- marshal_and_apply(func1, 7, 13);
- // this call would be equivalent to:
- // auto storage = my_allocator(sizeof(int));
- // auto x = marshal_me<int>(7, storage);
- // func2(x, 13);
- marshal_and_apply(func2, 7, 13);
- // this call would be equivalent to:
- // auto storage = my_allocator(sizeof(int) + sizeof(int) + sizeof(int));
- // auto x = marshal_me<int>(7, storage);
- // auto y = marshal_me<int>(13, storage + sizeof(int));
- // auto z = marshal_me<int>(42, storage + sizeof(int) + sizeof(int));
- // func3(x,y,z);
- marshal_and_apply(func3, 7, 13, 42);
- template<typename Function, typename... Args>
- void marshal_and_apply(Function f, Args &&... args)
- {
- f(InspectAndModify<Args>::process(sizeof...(Args), std::forward<Args>(args))...);
- }
- template <typename T> struct InspectAndModify
- {
- static T&& process(unsigned int N, T && t)
- {
- return std::forward<T>(t);
- }
- };
- template <typename T> struct InspectAndModify<marshal_me<T>>
- {
- static T&& process(unsigned int N, marshal_me<T> && m)
- {
- /* ... */
- }
- };
- template <typename T> struct marshal_me { marshal_me(T) { } };
- template <typename To, typename From> struct static_transform;
- template <typename T> struct static_transform<T, T>
- {
- static T go(T t) { return t; }
- };
- template <typename T> struct static_transform<T, T&>
- {
- static T go(T & t) { return t; }
- };
- template <typename T> struct static_transform<marshal_me<T>, T>
- {
- static marshal_me<T> go(T && t) { return std::forward<T>(t); }
- };
- template<typename T, typename... Args>
- struct marshal_impl
- {
- template <typename ...Urgs>
- static T go(T(*f)(Urgs...), Args &&... args)
- {
- return f(static_transform<Urgs, Args>::go(std::forward<Args>(args))...);
- }
- };
- template<typename Function, typename... Args>
- void marshal_and_apply(Function f, Args &&... args)
- {
- marshal_impl<void, Args...>::go(static_cast<typename std::decay<Function>::type>(f),
- std::forward<Args>(args)...);
- }