libtcspc C++ API
Streaming TCSPC and time tag data processing
Loading...
Searching...
No Matches
stop.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 "errors.hpp"
11#include "event.hpp"
12#include "introspect.hpp"
13#include "processor.hpp"
14#include "type_list.hpp"
15
16#include <sstream>
17#include <stdexcept>
18#include <string>
19#include <type_traits>
20#include <utility>
21
22namespace tcspc {
23
24namespace internal {
25
26template <typename EventList, typename Exception, typename Downstream>
27 requires processor<Downstream>
28class stop {
29 static_assert(type_list_like<EventList>);
30
31 Downstream downstream;
32
33 // Cold data after downstream.
34 std::string message_prefix;
35
36 template <typename Event>
37 [[noreturn]] LIBTCSPC_NOINLINE void handle_stop(Event const &event) {
38 if constexpr (std::is_same_v<Exception, end_of_processing>)
39 downstream.flush();
40 std::ostringstream stream;
41 if constexpr (internal::ostreamable<Event>) {
42 if (not message_prefix.empty())
43 stream << message_prefix << ": ";
44 stream << event;
45 } else {
46 stream << message_prefix;
47 }
48 throw Exception(stream.str());
49 }
50
51 public:
52 explicit stop(std::string prefix, Downstream downstream)
53 : downstream(std::move(downstream)),
54 message_prefix(std::move(prefix)) {}
55
56 [[nodiscard]] auto introspect_node() const -> processor_info {
57 return processor_info(this, "stop");
58 }
59
60 [[nodiscard]] auto introspect_graph() const -> processor_graph {
61 return downstream.introspect_graph().push_entry_point(this);
62 }
63
64 template <typename Event>
65 requires convertible_to_type_list_member<std::remove_cvref_t<Event>,
66 EventList>
67 [[noreturn]] void handle(Event &&event) {
68 handle_stop(event);
69 }
70
71 template <typename Event>
72 requires(not convertible_to_type_list_member<
73 std::remove_cvref_t<Event>, EventList> and
74 handler_for<Downstream, std::remove_cvref_t<Event>>)
75 void handle(Event &&event) {
76 downstream.handle(std::forward<Event>(event));
77 }
78
79 void flush() { downstream.flush(); }
80};
81
82} // namespace internal
83
114template <typename EventList, typename Exception = std::runtime_error,
115 typename Downstream>
116auto stop_with_error(std::string message_prefix, Downstream downstream) {
117 static_assert(not std::is_same_v<Exception, end_of_processing>);
118 return internal::stop<EventList, Exception, Downstream>(
119 std::move(message_prefix), std::move(downstream));
120}
121
150template <typename EventList, typename Downstream>
151auto stop(std::string message_prefix, Downstream downstream) {
152 return internal::stop<EventList, end_of_processing, Downstream>(
153 std::move(message_prefix), std::move(downstream));
154}
155
156} // namespace tcspc
auto stop(std::string message_prefix, Downstream downstream)
Create a processor that ends the stream when a given event type is received.
Definition stop.hpp:151
auto stop_with_error(std::string message_prefix, Downstream downstream)
Create a processor that ends the stream with an error when a given event type is received.
Definition stop.hpp:116
libtcspc namespace.
Definition acquire.hpp:30