libtcspc C++ API
Streaming TCSPC and time tag data processing
Loading...
Searching...
No Matches
type_erased_processor.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 "core.hpp"
11#include "introspect.hpp"
12#include "processor.hpp"
13#include "type_list.hpp"
14
15#include <concepts>
16#include <memory>
17#include <type_traits>
18#include <utility>
19
20namespace tcspc {
21
22namespace internal {
23
24template <typename EventList> class abstract_processor;
25
26template <> class abstract_processor<type_list<>> {
27 public:
28 abstract_processor() = default;
29 abstract_processor(abstract_processor const &) = delete;
30 auto operator=(abstract_processor const &) = delete;
31 abstract_processor(abstract_processor &&) = delete;
32 auto operator=(abstract_processor &&) = delete;
33 virtual ~abstract_processor() = default;
34 [[nodiscard]] virtual auto introspect_node() const -> processor_info = 0;
35 [[nodiscard]] virtual auto introspect_graph() const -> processor_graph = 0;
36 virtual void flush() = 0;
37};
38
39template <typename Event0>
40class abstract_processor<type_list<Event0>>
41 : public abstract_processor<type_list<>> {
42 public:
43 virtual void handle(Event0 const &) = 0;
44 virtual void handle(Event0 &&) = 0;
45};
46
47template <typename Event0, typename... Events>
48class abstract_processor<type_list<Event0, Events...>>
49 : public abstract_processor<type_list<Events...>> {
50 using base_type = abstract_processor<type_list<Events...>>;
51
52 public:
53 using base_type::handle; // Import overload set
54 virtual void handle(Event0 const &) = 0;
55 virtual void handle(Event0 &&) = 0;
56};
57
58template <typename Interface, typename Proc, typename EventList>
59class virtual_processor_impl;
60
61template <typename Interface, typename Proc>
62class virtual_processor_impl<Interface, Proc, type_list<>> : public Interface {
63 protected:
64 // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes,misc-non-private-member-variables-in-classes)
65 Proc proc;
66
67 public:
68 explicit virtual_processor_impl(Proc proc) : proc(std::move(proc)) {}
69
70 template <typename... Args>
71 explicit virtual_processor_impl(Args &&...args)
72 : proc(std::forward<Args>(args)...) {}
73
74 [[nodiscard]] auto introspect_node() const -> processor_info final {
75 return processor_info(this, "virtual_processor_impl");
76 }
77
78 [[nodiscard]] auto introspect_graph() const -> processor_graph final {
79 return proc.introspect_graph().push_entry_point(this);
80 }
81
82 void flush() final { proc.flush(); }
83};
84
85template <typename Interface, typename Proc, typename Event0,
86 typename... Events>
87class virtual_processor_impl<Interface, Proc, type_list<Event0, Events...>>
88 : public virtual_processor_impl<Interface, Proc, type_list<Events...>> {
89 using base_type =
90 virtual_processor_impl<Interface, Proc, type_list<Events...>>;
91
92 protected:
93 using base_type::proc;
94
95 public:
96 using base_type::base_type;
97
98 using base_type::handle; // Import overload set
99 void handle(Event0 const &event) final { proc.handle(event); }
100 void handle(Event0 &&event) final { proc.handle(std::move(event)); }
101};
102
103template <typename Proc, typename EventList>
104using virtual_processor =
105 virtual_processor_impl<abstract_processor<EventList>, Proc, EventList>;
106
107} // namespace internal
108
120template <typename EventList> class type_erased_processor {
121 using event_list = unique_type_list_t<EventList>;
122 using abstract_processor = internal::abstract_processor<event_list>;
123
124 template <typename Proc>
125 using virtual_processor =
126 typename internal::virtual_processor<Proc, event_list>;
127
128 std::unique_ptr<abstract_processor> proc;
129
130 public:
137 : proc(std::make_unique<virtual_processor<null_sink>>()) {}
138
146 template <typename Downstream>
147 requires(not std::same_as<std::remove_cvref_t<Downstream>,
150 event_list>)
151 explicit type_erased_processor(Downstream downstream)
152 : proc(std::make_unique<virtual_processor<Downstream>>(
153 std::move(downstream))) {}
154
156 [[nodiscard]] auto introspect_node() const -> processor_info {
157 return processor_info(this, "type_erased_processor");
158 }
159
161 [[nodiscard]] auto introspect_graph() const -> processor_graph {
162 return proc->introspect_graph().push_entry_point(this);
163 }
164
166 template <typename Event>
168 event_list>
169 void handle(Event &&event) {
170 proc->handle(std::forward<Event>(event));
171 }
172
174 void flush() { proc->flush(); }
175};
176
177} // namespace tcspc
Processor that sinks any event and the end-of-stream and does nothing.
Definition core.hpp:68
Value type representing a directed acyclic graph of processors.
Definition introspect.hpp:198
auto push_entry_point(Processor const *processor) -> processor_graph &
Add a processor node to this graph, upstream of the current entry point (if any), making it the new e...
Definition introspect.hpp:229
Value type representing metadata of a processor.
Definition introspect.hpp:58
Processor that type-erases the downstream processor.
Definition type_erased_processor.hpp:120
auto introspect_graph() const -> processor_graph
Implements processor requirement.
Definition type_erased_processor.hpp:161
void handle(Event &&event)
Implements processor requirement.
Definition type_erased_processor.hpp:169
auto introspect_node() const -> processor_info
Implements processor requirement.
Definition type_erased_processor.hpp:156
void flush()
Implements processor requirement.
Definition type_erased_processor.hpp:174
type_erased_processor(Downstream downstream)
Construct with the given downstream processor.
Definition type_erased_processor.hpp:151
type_erased_processor()
Construct with a stub downstream processor.
Definition type_erased_processor.hpp:136
Concept that is satisfied when a type is convertible to at least one of the members of a type list.
Definition type_list.hpp:186
constexpr bool is_processor_of_list_v
Trait variable to check whether a processor handles a list of event types and flush.
Definition processor.hpp:246
typename unique_type_list< TypeList >::type unique_type_list_t
Helper type for tcspc::unique_type_list.
Definition type_list.hpp:299
libtcspc namespace.
Definition acquire.hpp:29