libtcspc C++ API
Streaming TCSPC and time tag data processing
Loading...
Searching...
No Matches
prepend_append.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
13#include <concepts>
14#include <type_traits>
15
16namespace tcspc {
17
18namespace internal {
19
20template <typename Event, typename Downstream>
21 requires processor<Downstream, Event>
22class prepend {
23 static_assert(std::move_constructible<Event>,
24 "prepend requires Event to be move-constructible (the event "
25 "is stored and moved into the stream)");
26
27 bool prepended = false;
28 Downstream downstream;
29
30 // Cold data after downstream:
31 Event evt;
32
33 public:
34 explicit prepend(Event event, Downstream downstream)
35 : downstream(std::move(downstream)), evt(std::move(event)) {}
36
37 [[nodiscard]] auto introspect_node() const -> processor_info {
38 return processor_info(this, "prepend");
39 }
40
41 [[nodiscard]] auto introspect_graph() const -> processor_graph {
42 return downstream.introspect_graph().push_entry_point(this);
43 }
44
45 template <typename AnyEvent>
46 requires handler_for<Downstream, std::remove_cvref_t<AnyEvent>>
47 void handle(AnyEvent &&event) {
48 if (not prepended) {
49 downstream.handle(std::move(evt));
50 prepended = true;
51 }
52 downstream.handle(std::forward<AnyEvent>(event));
53 }
54
55 void flush() { downstream.flush(); }
56};
57
58template <typename Event, typename Downstream>
59 requires processor<Downstream, Event>
60class append {
61 static_assert(std::move_constructible<Event>,
62 "append requires Event to be move-constructible (the event "
63 "is stored and moved into the stream)");
64
65 Downstream downstream;
66
67 // Cold data after downstream:
68 Event evt;
69
70 public:
71 explicit append(Event event, Downstream downstream)
72 : downstream(std::move(downstream)), evt(std::move(event)) {}
73
74 [[nodiscard]] auto introspect_node() const -> processor_info {
75 return processor_info(this, "append");
76 }
77
78 [[nodiscard]] auto introspect_graph() const -> processor_graph {
79 return downstream.introspect_graph().push_entry_point(this);
80 }
81
82 template <typename AnyEvent>
83 requires handler_for<Downstream, std::remove_cvref_t<AnyEvent>>
84 void handle(AnyEvent &&event) {
85 downstream.handle(std::forward<AnyEvent>(event));
86 }
87
88 void flush() {
89 downstream.handle(std::move(evt));
90 downstream.flush();
91 }
92};
93
94} // namespace internal
95
120template <typename Event, typename Downstream>
121auto prepend(Event event, Downstream downstream) {
122 return internal::prepend<Event, Downstream>(std::move(event),
123 std::move(downstream));
124}
125
153template <typename Event, typename Downstream>
154auto append(Event event, Downstream downstream) {
155 return internal::append<Event, Downstream>(std::move(event),
156 std::move(downstream));
157}
158
159} // namespace tcspc
auto append(Event event, Downstream downstream)
Create a processor that inserts an event at the end of the stream.
Definition prepend_append.hpp:154
auto prepend(Event event, Downstream downstream)
Create a processor that inserts an event at the beginning of the stream.
Definition prepend_append.hpp:121
libtcspc namespace.
Definition acquire.hpp:30