Skip to content

Commit 98eb77a

Browse files
authored
Update bind.hpp
1 parent 1fb2227 commit 98eb77a

1 file changed

Lines changed: 36 additions & 22 deletions

File tree

bind.hpp

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,64 +2,78 @@
22

33
#include <functional>
44
#include <type_traits>
5-
#include <experimental/tuple>
5+
#include <tuple>
66

77
template<class T, class UnBoundArgTpl>
8-
constexpr T& get_final_args(std::reference_wrapper<T> tid, UnBoundArgTpl&& unbound_args)
9-
{
8+
constexpr T& get_final_args(std::reference_wrapper<T> tid, UnBoundArgTpl&& unbound_args) {
109
return tid.get();
1110
}
1211

1312
template<class cvTiD, class UnBoundArgTpl,
14-
int idx = std::is_placeholder<std::remove_cv_t<cvTiD>>{},
13+
std::enable_if_t<std::is_bind_expression_v<std::remove_cv_t<cvTiD>>>* = nullptr>
14+
constexpr decltype(auto) get_final_args(cvTiD& tid, UnBoundArgTpl&& unbound_args) {
15+
return std::apply(tid, std::move(unbound_args));
16+
}
17+
18+
template<class cvTiD, class UnBoundArgTpl,
19+
int idx = std::is_placeholder_v<std::remove_cv_t<cvTiD>>,
1520
std::enable_if_t<(idx > 0)>* = nullptr>
1621
constexpr decltype(auto) get_final_args(cvTiD& tid, UnBoundArgTpl&& unbound_args)
1722
{
1823
return std::get<idx - 1>(unbound_args);
1924
}
2025

2126
template<class cvTiD, class UnBoundArgTpl,
22-
std::enable_if_t<std::is_placeholder<std::remove_cv_t<cvTiD>>{} <= 0>* = nullptr>
27+
std::enable_if_t<!std::is_bind_expression_v<std::remove_cv_t<cvTiD>> &&
28+
std::is_placeholder_v<std::remove_cv_t<cvTiD>> <= 0>* = nullptr>
2329
constexpr cvTiD& get_final_args(cvTiD& tid, UnBoundArgTpl&& unbound_args)
2430
{
2531
return tid;
2632
}
2733

28-
template<class F, class BoundArgTpl, std::size_t... idx, class UnBoundArgTpl>
29-
decltype(auto) bind_apply_unwrap_bound_args(F& f, BoundArgTpl&& bound_args, std::index_sequence<idx...>, UnBoundArgTpl&& unbound_args)
30-
{
31-
return f(get_final_args(std::get<idx>(bound_args), static_cast<UnBoundArgTpl&&>(unbound_args))...);
32-
}
33-
34-
template<class FD, class ArgTpl, class R = void(void)>
34+
template<class FD, class R, class... BoundArgs>
3535
struct Bind {
3636
FD fd;
37-
ArgTpl bound_args;
37+
std::tuple<std::decay_t<BoundArgs>...> bound_args;
3838
private:
39-
static constexpr std::size_t arity = std::tuple_size<ArgTpl>{};
39+
template<class cvFD, class BoundArgTpl, class... UnBoundArgs, std::size_t... idx>
40+
static constexpr decltype(auto) unwrap_bound_args(cvFD& fd,
41+
/* cv std::tuple<TiD...>& */ BoundArgTpl& bound_args,
42+
std::index_sequence<idx...>,
43+
/* std::tuple<Vi&&...>&& */ std::tuple<UnBoundArgs...>&& unbound_args
44+
) {
45+
return fd((get_final_args)(std::get<idx>(bound_args), std::move(unbound_args))...);
46+
}
4047
public:
4148
template<class... UnBoundArgs>
42-
constexpr auto operator()(UnBoundArgs&&... unbound_args)
43-
{
44-
return bind_apply_unwrap_bound_args(fd, bound_args, std::make_index_sequence<arity>{}, std::forward_as_tuple(std::forward<UnBoundArgs>(unbound_args)...));
49+
constexpr decltype(auto) operator()(UnBoundArgs&&... unbound_args) {
50+
return unwrap_bound_args(fd, bound_args,
51+
std::index_sequence_for<BoundArgs...>{},
52+
std::forward_as_tuple(std::forward<UnBoundArgs>(unbound_args)...));
4553
}
4654

4755
template<class... UnBoundArgs>
48-
constexpr auto operator()(UnBoundArgs&&... unbound_args) const
49-
{
50-
return bind_apply_unwrap_bound_args(fd, bound_args, std::make_index_sequence<arity>{}, std::forward_as_tuple(std::forward<UnBoundArgs>(unbound_args)...));
56+
constexpr decltype(auto) operator()(UnBoundArgs&&... unbound_args) const {
57+
return unwrap_bound_args(fd, bound_args,
58+
std::index_sequence_for<BoundArgs...>{},
59+
std::forward_as_tuple(std::forward<UnBoundArgs>(unbound_args)...));
5160
}
5261
};
5362

63+
namespace std {
64+
template<class FD, class R, class... BoundArgs>
65+
struct is_bind_expression<Bind<FD, R, BoundArgs...>> : true_type {};
66+
}
67+
5468
template<class F, class... BoundArgs>
55-
constexpr Bind<std::decay_t<F>, std::tuple<std::decay_t<BoundArgs>...>>
69+
constexpr Bind<std::decay_t<F>, void(void), BoundArgs...>
5670
bind(F&& f, BoundArgs&&... bound_args)
5771
{
5872
return { std::forward<F>(f), { std::forward<BoundArgs>(bound_args)... } };
5973
}
6074

6175
template<class R, class F, class... BoundArgs>
62-
constexpr Bind<std::decay_t<F>, std::tuple<std::decay_t<BoundArgs>...>, R>
76+
constexpr Bind<std::decay_t<F>, R, BoundArgs...>
6377
bind(F&& f, BoundArgs&&... bound_args)
6478
{
6579
return { std::forward<F>(f), { std::forward<BoundArgs>(bound_args)... } };

0 commit comments

Comments
 (0)