How to implement an easy_bind() that automagically inserts implied placeholders?
With the indices trick and the ability to tell std::bind
about your own placeholder types, here's what I came up with:
#include <functional>
#include <type_traits>
#include <utility>
template<int I> struct placeholder{};
namespace std{
template<int I>
struct is_placeholder< ::placeholder<I>> : std::integral_constant<int, I>{};
} // std::
namespace detail{
template<std::size_t... Is, class F, class... Args>
auto easy_bind(indices<Is...>, F const& f, Args&&... args)
-> decltype(std::bind(f, std::forward<Args>(args)..., placeholder<Is + 1>{}...))
{
return std::bind(f, std::forward<Args>(args)..., placeholder<Is + 1>{}...);
}
} // detail::
template<class R, class... FArgs, class... Args>
auto easy_bind(std::function<R(FArgs...)> const& f, Args&&... args)
-> decltype(detail::easy_bind(build_indices<sizeof...(FArgs) - sizeof...(Args)>{}, f, std::forward<Args>(args)...))
{
return detail::easy_bind(build_indices<sizeof...(FArgs) - sizeof...(Args)>{}, f, std::forward<Args>(args)...);
}
Live example.
Take note that I require the function argument to easy_bind
to be either of type std::function
, or convertible to it, so that I have a definite signature available.