11#include "data_types.hpp"
13#include "introspect.hpp"
14#include "processor.hpp"
26template <
typename DataTypes,
bool RequireStrictlyIncreasing,
28class check_monotonic {
29 static_assert(processor<Downstream, warning_event>);
31 typename DataTypes::abstime_type last_seen =
32 std::numeric_limits<typename DataTypes::abstime_type>::min();
34 Downstream downstream;
36 LIBTCSPC_NOINLINE
void
37 issue_warning(
typename DataTypes::abstime_type abstime) {
38 std::ostringstream stream;
39 stream <<
"non-monotonic abstime: " << last_seen <<
" followed by "
41 downstream.handle(warning_event{stream.str()});
45 explicit check_monotonic(Downstream downstream)
46 : downstream(std::move(downstream)) {}
48 [[nodiscard]]
auto introspect_node() const -> processor_info {
49 return processor_info(
this,
"check_monotonic");
52 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
53 return downstream.introspect_graph().push_entry_point(
this);
56 template <
typename Event>
57 requires handler_for<Downstream, std::remove_cvref_t<Event>>
58 void handle(Event &&event) {
59 if constexpr (abstime_stamped<std::remove_cvref_t<Event>>) {
60 static_assert(std::is_same_v<
decltype(
event.abstime),
61 typename DataTypes::abstime_type>);
62 bool const monotonic = RequireStrictlyIncreasing
63 ?
event.abstime > last_seen
64 :
event.abstime >= last_seen;
66 issue_warning(event.abstime);
67 last_seen =
event.abstime;
69 downstream.handle(std::forward<Event>(event));
72 void flush() { downstream.flush(); }
111 bool RequireStrictlyIncreasing =
false,
typename Downstream>
113 return internal::check_monotonic<DataTypes, RequireStrictlyIncreasing,
114 Downstream>(std::move(downstream));
119template <
typename Event0,
typename Event1,
typename Downstream>
121 static_assert(processor<Downstream, Event0, Event1, warning_event>);
123 bool last_saw_0 =
false;
124 Downstream downstream;
126 LIBTCSPC_NOINLINE
void issue_warning() {
127 downstream.handle(warning_event{
"non-alternating events"});
131 explicit check_alternating(Downstream downstream)
132 : downstream(std::move(downstream)) {}
134 [[nodiscard]]
auto introspect_node() const -> processor_info {
135 return processor_info(
this,
"check_alternating");
138 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
139 return downstream.introspect_graph().push_entry_point(
this);
142 template <
typename E>
143 requires handler_for<Downstream, std::remove_cvref_t<E>>
144 void handle(E &&event) {
145 if constexpr (std::is_convertible_v<std::remove_cvref_t<E>, Event0>) {
149 }
else if constexpr (std::is_convertible_v<std::remove_cvref_t<E>,
155 downstream.handle(std::forward<E>(event));
158 void flush() { downstream.flush(); }
190template <
typename Event0,
typename Event1,
typename Downstream>
192 return internal::check_alternating<Event0, Event1, Downstream>(
193 std::move(downstream));
auto check_alternating(Downstream downstream)
Create a processor that checks that events of two types appear in alternation.
Definition check.hpp:191
auto check_monotonic(Downstream downstream)
Create a processor that checks that abstime is monotonically increasing or nondecreasing.
Definition check.hpp:112
libtcspc namespace.
Definition acquire.hpp:29
The default data type set.
Definition data_types.hpp:24