12#include "introspect.hpp"
13#include "numeric_traits.hpp"
14#include "processor.hpp"
26template <
typename NumericTraits,
bool RequireStrictlyIncreasing,
28 requires processor<Downstream, warning_event>
29class check_monotonic {
30 NumericTraits::abstime_type last_seen =
31 std::numeric_limits<typename NumericTraits::abstime_type>::min();
33 Downstream downstream;
35 LIBTCSPC_NOINLINE
void issue_warning(NumericTraits::abstime_type abstime) {
36 std::ostringstream stream;
37 stream <<
"non-monotonic abstime: " << last_seen <<
" followed by "
39 downstream.handle(warning_event{stream.str()});
43 explicit check_monotonic(Downstream downstream)
44 : downstream(std::move(downstream)) {}
46 [[nodiscard]]
auto introspect_node() const -> processor_info {
47 return processor_info(
this,
"check_monotonic");
50 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
51 return downstream.introspect_graph().push_entry_point(
this);
54 template <
typename Event>
55 requires handler_for<Downstream, std::remove_cvref_t<Event>>
56 void handle(Event &&event) {
57 if constexpr (abstime_stamped<std::remove_cvref_t<Event>>) {
59 std::is_same_v<
decltype(
event.abstime),
60 typename NumericTraits::abstime_type>);
61 bool const monotonic = RequireStrictlyIncreasing
62 ?
event.abstime > last_seen
63 :
event.abstime >= last_seen;
65 issue_warning(event.abstime);
66 last_seen =
event.abstime;
68 downstream.handle(std::forward<Event>(event));
71 void flush() { downstream.flush(); }
110 bool RequireStrictlyIncreasing =
false,
typename Downstream>
112 return internal::check_monotonic<NumericTraits, RequireStrictlyIncreasing,
113 Downstream>(std::move(downstream));
118template <
typename Event0,
typename Event1,
typename Downstream>
119 requires processor<Downstream, Event0, Event1, warning_event>
121 bool last_saw_0 =
false;
122 Downstream downstream;
124 LIBTCSPC_NOINLINE
void issue_warning() {
125 downstream.handle(warning_event{
"non-alternating events"});
129 explicit check_alternating(Downstream downstream)
130 : downstream(std::move(downstream)) {}
132 [[nodiscard]]
auto introspect_node() const -> processor_info {
133 return processor_info(
this,
"check_alternating");
136 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
137 return downstream.introspect_graph().push_entry_point(
this);
140 template <
typename E>
141 requires handler_for<Downstream, std::remove_cvref_t<E>>
142 void handle(E &&event) {
143 if constexpr (std::is_convertible_v<std::remove_cvref_t<E>, Event0>) {
147 }
else if constexpr (std::is_convertible_v<std::remove_cvref_t<E>,
153 downstream.handle(std::forward<E>(event));
156 void flush() { downstream.flush(); }
188template <
typename Event0,
typename Event1,
typename Downstream>
190 return internal::check_alternating<Event0, Event1, Downstream>(
191 std::move(downstream));
auto check_alternating(Downstream downstream)
Create a processor that checks that events of two types appear in alternation.
Definition check.hpp:189
auto check_monotonic(Downstream downstream)
Create a processor that checks that abstime is monotonically increasing or nondecreasing.
Definition check.hpp:111
libtcspc namespace.
Definition acquire.hpp:30
The default numeric traits.
Definition numeric_traits.hpp:27