14 template <copy_constructible_object Op,
class... Bound>
18 inline constexpr bool is_partial_v =
false;
20 template <copy_constructible_object Op,
class... Bound>
21 inline constexpr bool is_partial_v<
partial<Op, Bound...>> =
true;
23 template <
class Op,
class Tuple, std::size_t... Idx,
class... Args>
24 constexpr auto make_partial_impl(Op&& op, Tuple&& tuple, std::index_sequence<Idx...>, Args&&... args)
noexcept(
25 noexcept(
partial(std::forward<Op>(op), std::get<Idx>(std::forward<Tuple>(tuple))..., std::forward<Args>(args)...)))
26 ->
decltype(
partial(std::forward<Op>(op), std::get<Idx>(std::forward<Tuple>(tuple))..., std::forward<Args>(args)...)) {
27 return partial(std::forward<Op>(op), std::get<Idx>(std::forward<Tuple>(tuple))..., std::forward<Args>(args)...);
30 template <
class Op,
class... Args,
31 class = std::enable_if_t<is_partial_v<std::remove_cvref_t<Op>>>>
32 constexpr auto make_partial(Op&& op, Args&&... args)
noexcept(
33 noexcept( make_partial_impl(forward_like<Op>(op.op_), forward_like<Op>(op.bound_), std::make_index_sequence<std::tuple_size_v<
decltype(op.bound_)>>(), std::forward<Args>(args)...)))
34 ->
decltype(make_partial_impl(forward_like<Op>(op.op_), forward_like<Op>(op.bound_), std::make_index_sequence<std::tuple_size_v<
decltype(op.bound_)>>(), std::forward<Args>(args)...)) {
35 return make_partial_impl(forward_like<Op>(op.op_), forward_like<Op>(op.bound_), std::make_index_sequence<std::tuple_size_v<
decltype(op.bound_)>>(), std::forward<Args>(args)...);
38 template <
class Op,
class... Args,
39 class = std::enable_if_t<!is_partial_v<std::remove_cvref_t<Op>>>>
40 constexpr auto make_partial(Op&& op, Args&&... args)
noexcept(
41 noexcept(
partial(std::forward<Op>(op), std::forward<Args>(args)...)))
42 ->
decltype(
partial(std::forward<Op>(op), std::forward<Args>(args)...)) {
43 return partial(std::forward<Op>(op), std::forward<Args>(args)...);
46 template <
class Op,
class Tuple, std::size_t... Idx,
class... Args,
47 class = std::enable_if_t<std::is_invocable_v<Op, forward_like_t<Tuple, std::tuple_element_t<Idx, std::remove_cvref_t<Tuple>>>..., Args...>>>
48 constexpr auto __call(Op&& op, Tuple&& tuple, std::index_sequence<Idx...>, Args&&... args)
noexcept(
49 noexcept( std::invoke(std::forward<Op>(op), std::get<Idx>(std::forward<Tuple>(tuple))..., std::forward<Args>(args)...)))
50 ->
decltype(std::invoke(std::forward<Op>(op), std::get<Idx>(std::forward<Tuple>(tuple))..., std::forward<Args>(args)...)) {
51 return std::invoke(std::forward<Op>(op), std::get<Idx>(std::forward<Tuple>(tuple))..., std::forward<Args>(args)...);
54 template <
class Op,
class Tuple, std::size_t... Idx,
class... Args,
55 class = std::enable_if_t<!std::is_invocable_v<Op, forward_like_t<Tuple, std::tuple_element_t<Idx, std::remove_cvref_t<Tuple>>>..., Args...>>>
56 constexpr auto __call(Op&& op, Tuple&& tuple, std::index_sequence<Idx...>, Args&&... args)
noexcept(
57 noexcept(
partial(std::forward<Op>(op), std::get<Idx>(std::forward<Tuple>(tuple))..., std::forward<Args>(args)...)))
58 ->
decltype(
partial(std::forward<Op>(op), std::get<Idx>(std::forward<Tuple>(tuple))..., std::forward<Args>(args)...)) {
59 return partial(std::forward<Op>(op), std::get<Idx>(std::forward<Tuple>(tuple))..., std::forward<Args>(args)...);
62 template <copy_constructible_object Op,
class... Bound>
66 std::tuple<Bound...> bound_{};
68 template <
class Op2,
class... Args,
class>
69 friend constexpr auto make_partial(Op2&&, Args&&...);
73 requires std::default_initializable<Op> and (std::default_initializable<Bound> and ...) =
default;
75 template <
class... BoundArgs,
76 class = std::enable_if_t<std::is_constructible_v<std::tuple<Bound...>, BoundArgs&&...>>>
77 constexpr explicit partial(Op
const& op, BoundArgs&&... bound)
78 : op_(std::in_place, op), bound_(std::forward<BoundArgs>(bound)...) {}
80 template <
class... BoundArgs,
81 class = std::enable_if_t<std::is_constructible_v<std::tuple<Bound...>, BoundArgs&&...>>>
82 constexpr explicit partial(Op&& op, BoundArgs&&... bound)
83 : op_(std::in_place, std::move(op)), bound_(std::forward<BoundArgs>(bound)...) {}
92 template <
class... Args>
93 constexpr auto operator()(Args&&... args) &
noexcept(
94 noexcept( __call(*op_, bound_, std::index_sequence_for<Bound...>(), std::forward<Args>(args)...)))
95 ->
decltype(__call(*op_, bound_, std::index_sequence_for<Bound...>(), std::forward<Args>(args)...)) {
96 return __call(*op_, bound_, std::index_sequence_for<Bound...>(), std::forward<Args>(args)...);
99 template <
class... Args>
100 constexpr auto operator()(Args&&... args)
const&
noexcept(
101 noexcept( __call(*op_, bound_, std::index_sequence_for<Bound...>(), std::forward<Args>(args)...)))
102 ->
decltype(__call(*op_, bound_, std::index_sequence_for<Bound...>(), std::forward<Args>(args)...)) {
103 return __call(*op_, bound_, std::index_sequence_for<Bound...>(), std::forward<Args>(args)...);
106 template <
class... Args>
107 constexpr auto operator()(Args&&... args) &&
noexcept(
108 noexcept( __call(*std::move(op_), std::move(bound_), std::index_sequence_for<Bound...>(), std::forward<Args>(args)...)))
109 ->
decltype(__call(*std::move(op_), std::move(bound_), std::index_sequence_for<Bound...>(), std::forward<Args>(args)...)) {
110 return __call(*std::move(op_), std::move(bound_), std::index_sequence_for<Bound...>(), std::forward<Args>(args)...);
113 template <
class... Args>
114 constexpr auto operator()(Args&&... args)
const&&
noexcept(
115 noexcept( __call(*std::move(op_), std::move(bound_), std::index_sequence_for<Bound...>(), std::forward<Args>(args)...)))
116 ->
decltype(__call(*std::move(op_), std::move(bound_), std::index_sequence_for<Bound...>(), std::forward<Args>(args)...)) {
117 return __call(*std::move(op_), std::move(bound_), std::index_sequence_for<Bound...>(), std::forward<Args>(args)...);
122 constexpr auto operator%(Arg&& arg) &
noexcept(
123 noexcept( (*this)(std::forward<Arg>(arg))))
124 ->
decltype((*
this)(std::forward<Arg>(arg))) {
125 return (*
this)(std::forward<Arg>(arg));
129 constexpr auto operator%(Arg&& arg)
const&
noexcept(
130 noexcept( (*this)(std::forward<Arg>(arg))))
131 ->
decltype((*
this)(std::forward<Arg>(arg))) {
132 return (*
this)(std::forward<Arg>(arg));
136 constexpr auto operator%(Arg&& arg) &&
noexcept(
137 noexcept( std::move(*
this)(std::forward<Arg>(arg))))
138 ->
decltype(std::move(*
this)(std::forward<Arg>(arg))) {
139 return std::move(*
this)(std::forward<Arg>(arg));
143 constexpr auto operator%(Arg&& arg)
const&&
noexcept(
144 noexcept( std::move(*
this)(std::forward<Arg>(arg))))
145 ->
decltype(std::move(*
this)(std::forward<Arg>(arg))) {
146 return std::move(*
this)(std::forward<Arg>(arg));
151 template <
class Op,
class... Args>
Makes copy_constructible but not copy_assignable types copy_assignable.
Definition: copyable_box.hpp:28
partial(Op, Args...) -> partial< Op, Args... >
A deduction guide for partial.
Implements a perfect-forwarding call wrapper.
Definition: partial.hpp:63