Last active
March 23, 2016 18:13
-
-
Save vesim987/a73327f352982244a039 to your computer and use it in GitHub Desktop.
easy bind
This file contains 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
#include <functional> | |
#include <utility> | |
#include "functor_traits.hpp" | |
namespace vtl { | |
template<int> struct placeholder{ }; | |
}//vtl | |
namespace std { | |
template<int Id> | |
struct is_placeholder<vtl::placeholder<Id>> : std::integral_constant<int, Id>{ }; | |
}//std | |
namespace vtl{ | |
namespace detail { | |
template<std::size_t... I, class Func, class... Args> | |
auto bind(std::index_sequence<I...>, const Func &f, Args&&... args) { | |
return std::bind(f, std::forward<Args>(args)..., placeholder<I + 1>{}...); | |
} | |
template<class Func, class... Args> | |
auto bind(placeholder<0>, const Func &f, Args&&... args) { | |
return std::bind(f, std::forward<Args>(args)...); | |
} | |
}//detail | |
template<class Func, class... Args, std::size_t number_of_func_args = functor_traits<Func>::number_of_args> | |
auto bind(const Func & f, Args&&... args){ | |
return detail::bind( | |
std::conditional_t<number_of_func_args == sizeof...(Args), placeholder<0>, | |
std::make_index_sequence <number_of_func_args - sizeof...(Args)>>{}, | |
f, std::forward<Args>(args)...); | |
} | |
}//vtl | |
This file contains 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
#include <utility> | |
#include <functional> | |
#include <tuple> | |
namespace vtl { | |
enum class functor_type { | |
normal = 0, | |
reference = 1, | |
pointer = 2 | |
}; | |
namespace detail { | |
template<functor_type Type, class Ret, class... Args> | |
struct functor_traits { | |
constexpr static functor_type type = Type; | |
constexpr static std::size_t number_of_args = sizeof...(Args); | |
using functor = std::conditional_t<type == functor_type::normal, | |
Ret(Args...), | |
std::conditional_t<type == functor_type::reference, | |
Ret(&)(Args...), | |
Ret(*)(Args...)>>; | |
using clean_functor = Ret(Args...); | |
using return_type = Ret; | |
using arguments = std::tuple<Args...>; | |
template<std::size_t N> | |
using arg_by_id = typename std::tuple_element<N, arguments>::value; | |
}; | |
}//detail | |
template<class Func> | |
struct functor_traits; | |
template<class Ret, class... Args> | |
struct functor_traits<Ret(Args...)> : | |
detail::functor_traits<functor_type::normal, Ret, Args...> {}; | |
template<class Ret, class... Args> | |
struct functor_traits<Ret(&)(Args...)> : | |
detail::functor_traits<functor_type::reference, Ret, Args...> {}; | |
template<class Ret, class... Args> | |
struct functor_traits<Ret(*)(Args...)> : | |
detail::functor_traits<functor_type::pointer, Ret, Args...> {}; | |
template<class Class, class Ret, class... Args> | |
struct functor_traits<Ret(Class::*)(Args...)> : | |
detail::functor_traits<functor_type::pointer, Ret, Class*, Args...> {}; | |
}//vtl |
This file contains 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
#include <iostream> | |
#include "bind.hpp" | |
struct foo { | |
void bar(int a, int b) { std::cout << a << " " << b << std::endl; }; | |
}; | |
int main() { | |
foo f; | |
vtl::bind(&foo::bar)(&f, 10, 20); | |
vtl::bind(&foo::bar, &f)(10, 20); | |
vtl::bind(&foo::bar, &f, 10)(20); | |
vtl::bind(&foo::bar, &f, 10, 20)(); | |
return 0; | |
} | |
//$ ./a.exe | |
//10 20 | |
//10 20 | |
//10 20 | |
//10 20 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment