2021-07-10 21:49:17 +01:00
|
|
|
//! limit defines a struct to enforce limits.
|
|
|
|
|
2023-12-05 11:35:09 +01:00
|
|
|
#![warn(rust_2018_idioms, unused_lifetimes)]
|
2022-07-20 14:59:42 +02:00
|
|
|
|
2022-07-31 19:27:20 +02:00
|
|
|
#[cfg(feature = "tracking")]
|
2021-07-31 18:25:45 +03:00
|
|
|
use std::sync::atomic::AtomicUsize;
|
|
|
|
|
2021-07-10 21:49:17 +01:00
|
|
|
/// Represents a struct used to enforce a numerical limit.
|
2023-04-17 17:31:39 +02:00
|
|
|
#[derive(Debug)]
|
2021-07-10 21:49:17 +01:00
|
|
|
pub struct Limit {
|
|
|
|
upper_bound: usize,
|
2022-07-31 19:27:20 +02:00
|
|
|
#[cfg(feature = "tracking")]
|
2021-07-31 18:25:45 +03:00
|
|
|
max: AtomicUsize,
|
2021-07-10 21:49:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Limit {
|
|
|
|
/// Creates a new limit.
|
|
|
|
#[inline]
|
|
|
|
pub const fn new(upper_bound: usize) -> Self {
|
2022-07-31 19:27:20 +02:00
|
|
|
Self {
|
|
|
|
upper_bound,
|
|
|
|
#[cfg(feature = "tracking")]
|
|
|
|
max: AtomicUsize::new(0),
|
|
|
|
}
|
2021-07-31 18:25:45 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Creates a new limit.
|
|
|
|
#[inline]
|
|
|
|
#[cfg(feature = "tracking")]
|
|
|
|
pub const fn new_tracking(upper_bound: usize) -> Self {
|
2022-07-31 19:27:20 +02:00
|
|
|
Self {
|
|
|
|
upper_bound,
|
|
|
|
#[cfg(feature = "tracking")]
|
|
|
|
max: AtomicUsize::new(1),
|
|
|
|
}
|
2021-07-10 21:49:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Gets the underlying numeric limit.
|
|
|
|
#[inline]
|
|
|
|
pub const fn inner(&self) -> usize {
|
|
|
|
self.upper_bound
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Checks whether the given value is below the limit.
|
|
|
|
/// Returns `Ok` when `other` is below `self`, and `Err` otherwise.
|
|
|
|
#[inline]
|
2021-07-31 18:25:45 +03:00
|
|
|
pub fn check(&self, other: usize) -> Result<(), ()> {
|
2021-07-10 21:49:17 +01:00
|
|
|
if other > self.upper_bound {
|
|
|
|
Err(())
|
|
|
|
} else {
|
2021-07-31 18:25:45 +03:00
|
|
|
#[cfg(feature = "tracking")]
|
|
|
|
loop {
|
|
|
|
use std::sync::atomic::Ordering;
|
|
|
|
let old_max = self.max.load(Ordering::Relaxed);
|
|
|
|
if other <= old_max || old_max == 0 {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if self
|
|
|
|
.max
|
2022-01-28 18:19:35 +03:00
|
|
|
.compare_exchange_weak(old_max, other, Ordering::Relaxed, Ordering::Relaxed)
|
2021-07-31 18:25:45 +03:00
|
|
|
.is_ok()
|
|
|
|
{
|
2022-12-23 13:42:58 -05:00
|
|
|
eprintln!("new max: {other}");
|
2021-07-31 18:25:45 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-10 21:49:17 +01:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|