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 "introspect.hpp"
12#include "processor.hpp"
13#include "type_list.hpp"
14
15#include <sstream>
16#include <stdexcept>
17#include <string>
18#include <type_traits>
19#include <utility>
20
21namespace tcspc {
22
23namespace internal {
24
25template <typename EventList, typename Exception, typename Downstream>
26class stop {
27 static_assert(type_list_like<EventList>);
28 static_assert(processor<Downstream>);
29
30 Downstream downstream;
31
32 // Cold data after downstream.
33 std::string message_prefix;
34
35 template <typename Event>
36 [[noreturn]] LIBTCSPC_NOINLINE void handle_stop(Event const &event) {
37 if constexpr (std::is_same_v<Exception, end_of_processing>)
38 downstream.flush();
39 std::ostringstream stream;
40 if (not message_prefix.empty())
41 stream << message_prefix << ": ";
42 stream << event;
43 throw Exception(stream.str());
44 }
45
46 public:
47 explicit stop(std::string prefix, Downstream downstream)
48 : downstream(std::move(downstream)),
49 message_prefix(std::move(prefix)) {}
50
51 [[nodiscard]] auto introspect_node() const -> processor_info {
52 return processor_info(this, "stop");
53 }
54
55 [[nodiscard]] auto introspect_graph() const -> processor_graph {
56 return downstream.introspect_graph().push_entry_point(this);
57 }
58
59 template <typename Event>
60 requires convertible_to_type_list_member<std::remove_cvref_t<Event>,
61 EventList>
62 [[noreturn]] void handle(Event &&event) {
63 handle_stop(event);
64 }
65
66 template <typename Event>
67 requires(not convertible_to_type_list_member<
68 std::remove_cvref_t<Event>, EventList> and
69 handler_for<Downstream, std::remove_cvref_t<Event>>)
70 void handle(Event &&event) {
71 downstream.handle(std::forward<Event>(event));
72 }
73
74 void flush() { downstream.flush(); }
75};
76
77} // namespace internal
78
105template <typename EventList, typename Exception = std::runtime_error,
106 typename Downstream>
107auto stop_with_error(std::string message_prefix, Downstream downstream) {
108 static_assert(not std::is_same_v<Exception, end_of_processing>);
109 return internal::stop<EventList, Exception, Downstream>(
110 std::move(message_prefix), std::move(downstream));
111}
112
137template <typename EventList, typename Downstream>
138auto stop(std::string message_prefix, Downstream downstream) {
139 return internal::stop<EventList, end_of_processing, Downstream>(
140 std::move(message_prefix), std::move(downstream));
141}
142
143} // 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:138
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:107
libtcspc namespace.
Definition acquire.hpp:29