dope_core/driver/schedule/clock/
range.rs1use o3::base::time::DurationExt as _;
2use std::{borrow, time};
3
4use crate::driver::schedule::clock::Origin;
5
6#[derive(Clone, Copy, Eq, PartialEq, Debug)]
8pub struct Range<D = time::Duration> {
9 origin: Origin,
10 duration: D,
11}
12
13impl<D: Copy> Range<D> {
14 pub(super) const fn new(origin: Origin, duration: D) -> Self {
15 Self { origin, duration }
16 }
17
18 pub const fn duration(self) -> D {
19 self.duration
20 }
21
22 pub const fn origin(self) -> time::Instant {
23 self.origin.0
24 }
25
26 #[cold]
27 pub(super) fn furthest(self) -> time::Instant
28 where
29 D: borrow::Borrow<time::Duration>,
30 {
31 let mut lower = time::Duration::ZERO;
32 let mut upper = *self.duration.borrow();
33 let mut at = self.origin.0;
34 while lower < upper {
35 let middle = lower.average::<2>(upper);
36 let next = if middle == lower { upper } else { middle };
37 match self.origin.0.checked_add(next) {
38 Some(value) => {
39 lower = next;
40 at = value;
41 }
42 None => upper = next.saturating_sub(time::Duration::from_nanos(1)),
43 }
44 }
45 at
46 }
47}
48
49const _: () = {
50 use std::mem;
51
52 use o3::base::time::Positive;
53
54 assert!(mem::size_of::<Range<Positive>>() == mem::size_of::<Range>());
55 assert!(mem::align_of::<Range<Positive>>() == mem::align_of::<Range>());
56 assert!(!mem::needs_drop::<Range<Positive>>());
57};