libtcspc C++ API
Streaming TCSPC and time tag data processing
Loading...
Searching...
No Matches
multiplex.hpp
1/*
2 * This file is part of libtcspc
3 * Copyright 2019-2026 Board of Regents of the University of Wisconsin System
4 * SPDX-License-Identifier: MIT
5 */
6
7#pragma once
8
9#include "common.hpp"
10#include "introspect.hpp"
11#include "processor.hpp"
12#include "type_list.hpp"
13#include "variant_event.hpp"
14
15#include <type_traits>
16#include <utility>
17#include <variant>
18
19namespace tcspc {
20
21namespace internal {
22
23template <typename EventList, typename Downstream> class multiplex {
24 static_assert(processor<Downstream, variant_event<EventList>>);
25
26 Downstream downstream;
27
28 public:
29 explicit multiplex(Downstream downstream)
30 : downstream(std::move(downstream)) {}
31
32 [[nodiscard]] auto introspect_node() const -> processor_info {
33 return processor_info(this, "multiplex");
34 }
35
36 [[nodiscard]] auto introspect_graph() const -> processor_graph {
37 return downstream.introspect_graph().push_entry_point(this);
38 }
39
40 template <typename Event>
41 requires convertible_to_type_list_member<std::remove_cvref_t<Event>,
42 EventList>
43 void handle(Event &&event) {
44 downstream.handle(
45 variant_event<EventList>(std::forward<Event>(event)));
46 }
47
48 void flush() { downstream.flush(); }
49};
50
51template <typename Downstream> class demultiplex {
52 static_assert(flushable<Downstream>);
53
54 Downstream downstream;
55
56 public:
57 explicit demultiplex(Downstream downstream)
58 : downstream(std::move(downstream)) {}
59
60 [[nodiscard]] auto introspect_node() const -> processor_info {
61 return processor_info(this, "demultiplex");
62 }
63
64 [[nodiscard]] auto introspect_graph() const -> processor_graph {
65 return downstream.introspect_graph().push_entry_point(this);
66 }
67
68 template <typename EL>
70 void handle(variant_event<EL> const &event) {
71 std::visit([&](auto const &e) { downstream.handle(e); }, event);
72 }
73
74 template <typename EL>
76 void handle(variant_event<EL> &&event) {
77 std::visit(
78 [&]<typename E>(E &&e) { downstream.handle(std::forward<E>(e)); },
79 std::move(event));
80 }
81
82 void flush() { downstream.flush(); }
83};
84
85} // namespace internal
86
111template <typename EventList, typename Downstream>
112auto multiplex(Downstream downstream) {
113 static_assert(type_list_size_v<EventList> > 0,
114 "multiplex requires non-empty event list");
115 return internal::multiplex<EventList, Downstream>(std::move(downstream));
116}
117
142template <typename Downstream> auto demultiplex(Downstream downstream) {
143 return internal::demultiplex<Downstream>(std::move(downstream));
144}
145
146} // namespace tcspc
constexpr bool handles_event_list_v
Trait variable to check whether a processor handles a list of event types.
Definition processor.hpp:194
auto multiplex(Downstream downstream)
Create a processor that passes events as a single variant type.
Definition multiplex.hpp:112
auto demultiplex(Downstream downstream)
Create a processor that transforms an event variant type back to individual event types.
Definition multiplex.hpp:142
constexpr std::size_t type_list_size_v
Helper variable template for tcspc::type_list_size.
Definition type_list.hpp:97
libtcspc namespace.
Definition acquire.hpp:29