10#include "data_types.hpp"
12#include "int_arith.hpp"
13#include "introspect.hpp"
14#include "type_erased_processor.hpp"
15#include "type_list.hpp"
37template <
typename RoutedEventList,
typename Router, std::size_t N,
39class route_homogeneous {
40 static_assert(type_list_like<RoutedEventList>);
42 static_assert(processor<Downstream>);
45 std::array<Downstream, N> downstreams;
47 LIBTCSPC_NOINLINE
void flush_all_but(Downstream &excluded) {
48 for (
auto &d : downstreams) {
49 if (&d != &excluded) {
52 }
catch (end_of_processing
const &) {
60 explicit route_homogeneous(Router router,
61 std::array<Downstream, N> downstreams)
62 : router(std::move(router)), downstreams(std::move(downstreams)) {}
64 [[nodiscard]]
auto introspect_node() const -> processor_info {
65 return processor_info(
this,
"route_homogeneous");
68 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
69 return std::transform_reduce(
70 downstreams.begin(), downstreams.end(), processor_graph(),
72 return d.introspect_graph().push_entry_point(
this);
76 template <
typename Event>
77 requires(convertible_to_type_list_member<std::remove_cvref_t<Event>,
79 handler_for<Downstream, std::remove_cvref_t<Event>>)
80 void handle(Event &&event) {
81 std::size_t index = router(std::as_const(event));
85 downstreams[index].handle(std::forward<Event>(event));
86 }
catch (end_of_processing
const &) {
87 flush_all_but(downstreams[index]);
92 template <
typename Event>
93 requires(not convertible_to_type_list_member<
94 std::remove_cvref_t<Event>, RoutedEventList> and
95 handler_for<Downstream, std::remove_cvref_t<Event>>)
96 void handle(Event &&event) {
97 for (
auto &d : downstreams) {
99 d.handle(std::as_const(event));
100 }
catch (end_of_processing
const &) {
108 std::exception_ptr end;
109 for (
auto &d : downstreams) {
112 }
catch (end_of_processing
const &) {
114 end = std::current_exception();
118 std::rethrow_exception(end);
161template <
typename RoutedEventList,
typename Router, std::size_t N,
164 return internal::route_homogeneous<RoutedEventList, Router, N, Downstream>(
165 std::move(router), std::move(downstreams));
204template <
typename RoutedEventList,
typename Router,
typename... Downstreams>
207 std::move(router), std::array{std::move(downstreams)...});
248template <
typename RoutedEventList,
typename BroadcastEventList = type_list<>,
249 typename Router,
typename... Downstreams>
250auto route(Router router, Downstreams... downstreams) {
257 "routed event list and broadcast event list must not overlap");
261 type_erased_downstream>(
263 std::array<type_erased_downstream,
sizeof...(Downstreams)>{
264 type_erased_downstream(std::move(downstreams))...});
280 template <
typename Event>
282 return std::size_t(-1);
295template <std::
size_t N,
typename DataTypes = default_data_types>
297 std::array<typename DataTypes::channel_type, N> channels;
298 std::array<std::size_t, N> indices;
310 template <
typename ChannelIndexPair>
312 std::array<ChannelIndexPair, N>
const &channel_indices)
313 : channels(std::invoke([&] {
314 std::array<typename DataTypes::channel_type, N> ret{};
315 std::transform(channel_indices.begin(), channel_indices.end(),
317 [](
auto p) { return std::get<0>(p); });
320 indices(std::invoke([&] {
321 std::array<std::size_t, N> ret{};
322 std::transform(channel_indices.begin(), channel_indices.end(),
324 [](
auto p) { return std::get<1>(p); });
329 std::is_convertible_v<decltype(std::get<0>(channel_indices[0])),
330 typename DataTypes::channel_type> &&
331 std::is_convertible_v<
332 decltype(std::get<1>(channel_indices[0])), std::size_t>,
333 "channel_indices must be an array of pair-like convertible to (channel, std::size_t)");
337 template <
typename Event>
339 static_assert(std::is_same_v<
decltype(
event.channel),
340 typename DataTypes::channel_type>);
341 auto it = std::find(channels.begin(), channels.end(), event.channel);
342 if (it == channels.end())
343 return std::numeric_limits<std::size_t>::max();
344 return indices[internal::as_unsigned(
345 std::distance(channels.begin(), it))];
370template <std::
size_t N,
typename Downstream>
396template <
typename... Downstreams>
398 auto arr = std::array{std::move(downstreams)...};
423template <
typename BroadcastEventList,
typename... Downstreams>
auto operator()(Event const &event) const -> std::size_t
Implements router requirement.
Definition route.hpp:338
channel_router(std::array< ChannelIndexPair, N > const &channel_indices)
Construct with channels and corresponding downstream indices.
Definition route.hpp:311
Router that does not route.
Definition route.hpp:274
auto operator()(Event const &) const -> std::size_t
Implements router requirement; always returns std::numeric_limits<std::size_t>::max().
Definition route.hpp:281
Processor that type-erases the downstream processor.
Definition type_erased_processor.hpp:120
Concept that is satisfied when a type is a tcspc::type_list specialization.
Definition type_list.hpp:64
auto merge_processor_graphs(processor_graph const &a, processor_graph const &b) -> processor_graph
Create a new processor graph by merging two existing ones.
Definition introspect.hpp:357
auto broadcast(Downstreams... downstreams)
Create a processor that broadcasts events to multiple downstream processors.
Definition route.hpp:424
auto route_homogeneous(Router router, std::array< Downstream, N > downstreams)
Create a processor that routes events to multiple downstreams of the same type.
Definition route.hpp:163
auto broadcast_homogeneous(std::array< Downstream, N > downstreams)
Create a processor that broadcasts events to multiple downstream processors of the same type.
Definition route.hpp:371
auto route(Router router, Downstreams... downstreams)
Create a processor that routes events to different downstreams.
Definition route.hpp:250
typename type_list_intersection< TL0, TL1 >::type type_list_intersection_t
Helper type for tcspc::type_list_intersection.
Definition type_list.hpp:419
constexpr std::size_t type_list_size_v
Helper variable template for tcspc::type_list_size.
Definition type_list.hpp:97
typename type_list_union< TL0, TL1 >::type type_list_union_t
Helper type for tcspc::type_list_union.
Definition type_list.hpp:363
libtcspc namespace.
Definition acquire.hpp:29