YOrch 1.0.0
Loading...
Searching...
No Matches
forward_prev.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cstddef>
4#include <tuple>
5#include <type_traits>
6#include <utility>
7
8#include "../../executor/prev_access_specs.hpp"
9#include "../traits.hpp"
10#include "common.hpp"
11
12namespace yorch::detail {
13
14template <typename... Specs>
15inline constexpr std::size_t forward_prev_prev_access_count_v =
17
30
42
43template <typename... Specs>
47
48template <typename Spec, typename... Rest>
50private:
51 using spec_t = std::remove_cvref_t<Spec>;
52 using rest_t = typename forward_prev_unique_prev_payload<Rest...>::type;
53
54public:
55 using type = std::conditional_t<
57 std::conditional_t<
58 std::is_void_v<rest_t>,
60 void>,
61 rest_t>;
62};
63
64template <typename... Specs>
66 typename forward_prev_unique_prev_payload<Specs...>::type;
67
68template <typename T, typename Arg, typename Spec>
71 std::is_same_v<typename normalized_prev_access_spec_traits<Spec>::payload_type, T> &&
72 std::is_same_v<Arg, T&>);
73
74template <typename T, typename F, typename... Specs, std::size_t... I>
75[[nodiscard]] consteval bool forward_prev_bindings_supported_impl(std::index_sequence<I...>) {
76 return (((!is_prev_access_spec_v<std::remove_cvref_t<Specs>>) ||
78 T,
79 nth_arg_t<I, std::remove_cvref_t<F>>,
80 std::remove_cvref_t<Specs>>) &&
81 ...);
82}
83
84template <typename T, typename F, typename... Specs>
86 std::is_same_v<T, forward_prev_unique_prev_payload_t<Specs...>>;
87
88template <typename T, typename F, typename... Specs>
91 std::index_sequence_for<Specs...> {});
92
93template <typename T, typename F, typename ReceiverSpec>
96 (is_borrow_prev_mut_spec_v<std::remove_cvref_t<ReceiverSpec>> &&
97 std::is_same_v<
98 typename normalized_prev_access_spec_traits<std::remove_cvref_t<ReceiverSpec>>::payload_type,
99 T> &&
100 member_receiver_prev_access_valid_v<std::remove_cvref_t<ReceiverSpec>, F>);
101
102template <typename T, typename F, typename ReceiverSpec, typename... Specs, std::size_t... I>
103[[nodiscard]] consteval bool forward_prev_member_bindings_supported_impl(std::index_sequence<I...>) {
107 T,
108 member_nth_arg_t<I, std::remove_cvref_t<F>>,
109 std::remove_cvref_t<Specs>>) &&
110 ...);
111}
112
113template <typename T, typename F, typename ReceiverSpec, typename... Specs>
116
117template <typename T, typename F, typename ReceiverSpec, typename... Specs>
120 std::index_sequence_for<Specs...> {});
121
122template <typename T, typename F, typename... Specs>
124 using fn_t = std::remove_cvref_t<F>;
125
126 if constexpr (std::is_reference_v<T> || std::is_void_v<T>) {
128 } else if constexpr (member_bind_callable<fn_t>) {
130 } else if constexpr (inferable_direct_output_callable<fn_t>) {
132 } else if constexpr (!ordinary_bind_callable<fn_t>) {
134 } else if constexpr (sizeof...(Specs) != function_traits<fn_t>::arity) {
136 } else if constexpr (!(std::is_void_v<result_t<fn_t>> ||
137 std::is_same_v<result_t<fn_t>, step_result>)) {
139 } else if constexpr (forward_prev_prev_access_count_v<std::decay_t<Specs>...> != 1) {
145 } else {
147 }
148}
149
150template <typename T, typename F, typename... Specs>
152 constexpr auto error = validate_bind_forward_prev<T, F, Specs...>();
153 using diagnostic_t = std::tuple<
154 std::type_identity<T>,
155 std::type_identity<std::remove_cvref_t<F>>,
156 std::type_identity<std::remove_cvref_t<Specs>>...>;
157
158 if constexpr (error == bind_forward_prev_error::ok) {
159 return;
160 } else if constexpr (error == bind_forward_prev_error::invalid_output_type) {
162 "bind_forward_prev<T>(...) requires a non-void owned payload type T");
165 "bind_forward_prev<T>(...) does not support member function pointers in v1");
168 "bind_forward_prev<T>(...) does not accept callables with yorch::direct_out<T>; use bind_into(...) for direct-output materialization");
171 "bind_forward_prev<T>(...) requires a callable with one non-overloaded concrete signature");
172 } else if constexpr (error == bind_forward_prev_error::arity_mismatch) {
174 "bind_forward_prev<T>(...) requires exactly one spec per function parameter");
175 } else if constexpr (error == bind_forward_prev_error::invalid_result_type) {
177 "bind_forward_prev<T>(...) callable must return void or yorch::step_result");
180 "bind_forward_prev<T>(...) requires exactly one prev-access binding");
183 "bind_forward_prev<T>(...) requires the forwarded prev payload type to match T exactly");
184 } else {
186 "bind_forward_prev<T>(...) only supports borrow_prev_mut<T>() -> T&");
187 }
188}
189
190template <typename T, typename F, typename ReceiverSpec, typename... Specs>
192 using fn_t = std::remove_cvref_t<F>;
193
194 if constexpr (std::is_reference_v<T> || std::is_void_v<T>) {
196 } else if constexpr (!member_bind_callable<fn_t>) {
198 } else if constexpr (!ordinary_member_bind_callable<fn_t>) {
200 } else if constexpr (sizeof...(Specs) != member_function_traits<fn_t>::arity) {
202 } else if constexpr (!(std::is_void_v<member_result_t<fn_t>> ||
203 std::is_same_v<member_result_t<fn_t>, step_result>)) {
205 } else if constexpr (forward_prev_prev_access_count_v<std::decay_t<ReceiverSpec>, std::decay_t<Specs>...> != 1) {
207 } else if constexpr (!bind_forward_prev_member_payload_matches_v<
208 T,
209 fn_t,
210 std::decay_t<ReceiverSpec>,
211 std::decay_t<Specs>...>) {
214 T,
215 fn_t,
216 std::decay_t<ReceiverSpec>,
217 std::decay_t<Specs>...>) {
219 } else {
221 }
222}
223
224template <typename T, typename F, typename ReceiverSpec, typename... Specs>
227 using diagnostic_t = std::tuple<
228 std::type_identity<T>,
229 std::type_identity<std::remove_cvref_t<F>>,
230 std::type_identity<std::remove_cvref_t<ReceiverSpec>>,
231 std::type_identity<std::remove_cvref_t<Specs>>...>;
232
233 if constexpr (error == bind_forward_prev_member_error::ok) {
234 return;
237 "bind_forward_prev_member<T>(...) requires a non-void owned payload type T");
240 "bind_forward_prev_member(...) requires a non-static member function pointer");
243 "bind_forward_prev_member(...) does not accept direct-output member functions; use bind_into_member(...) instead");
246 "bind_forward_prev_member(...) requires one receiver binding plus exactly one spec per member-function parameter");
249 "bind_forward_prev_member(...) callable must return void or yorch::step_result");
252 "bind_forward_prev_member<T>(...) requires exactly one prev-access binding across receiver and member-function parameters");
255 "bind_forward_prev_member<T>(...) requires the forwarded prev payload type to match T exactly");
256 } else {
258 "bind_forward_prev_member<T>(...) only supports borrow_prev_mut<T>() -> T&");
259 }
260}
261
262} // namespace yorch::detail
typename member_function_traits< std::remove_cvref_t< F > >::template arg< I > member_nth_arg_t
Definition traits.hpp:141
consteval void emit_bind_forward_prev_member_diagnostic()
constexpr bool forward_prev_member_receiver_binding_supported_v
consteval bind_forward_prev_error validate_bind_forward_prev()
constexpr bool is_prev_access_spec_v
typename function_traits< std::remove_cvref_t< F > >::template arg< I > nth_arg_t
Definition traits.hpp:118
constexpr bool forward_prev_spec_matches_binding_v
constexpr std::size_t forward_prev_prev_access_count_v
consteval bool forward_prev_bindings_supported_impl(std::index_sequence< I... >)
constexpr bool member_receiver_prev_access_valid_v
consteval bind_forward_prev_member_error validate_bind_forward_prev_member()
constexpr bool bind_forward_prev_bindings_supported_v
consteval bool forward_prev_member_bindings_supported_impl(std::index_sequence< I... >)
typename forward_prev_unique_prev_payload< Specs... >::type forward_prev_unique_prev_payload_t
consteval void emit_bind_forward_prev_diagnostic()
constexpr bool bind_forward_prev_payload_matches_v
constexpr bool bind_forward_prev_member_bindings_supported_v
constexpr bool is_borrow_prev_mut_spec_v
constexpr bool is_adapter_descriptor_v
Definition adapters.hpp:63
constexpr bool bind_forward_prev_member_payload_matches_v
std::conditional_t< is_prev_access_spec_v< spec_t >, std::conditional_t< std::is_void_v< rest_t >, typename normalized_prev_access_spec_traits< spec_t >::payload_type, void >, rest_t > type
Extracts the canonical function signature information of a callable.
Definition traits.hpp:23
Represents the basic outcome of a task step.
Definition result.hpp:42