Struct width_counters::CounterI64
source · pub struct CounterI64 { /* private fields */ }Expand description
An atomic counter using AtomicI64 / (core::i64).
Behavior
- The default ordering is Sequentially Consistent.
- The ordering used for atomic operations is customizable for operations ending in
with_ordering. - The choice of ordering intentionally impacts ALMOST EVERYTHING about how this counter works, including de/serialization, incrementing, decrementing, equality comparisons, partial ordering comparisons, etc.
- Total (non-partial) ordering comparisons always use the default ordering.
- Unlike the underlying AtomicI64, this will not wrap on overflow.
Ordering
- PartialEq is implemented such that counters with differing orderings are never equal.
- PartialOrd is implemented such that counters with differing (atomic) orderings produce no (comparison) ordering.
- (Saturating) arithmetic operations are implemented such that differing atomic orderings between the operands are ignored!
Miscellaneous
You can use the to_x method to convert to any type that implements From<i64>
Implementations§
source§impl CounterI64
impl CounterI64
sourcepub const MAX: i64 = 9_223_372_036_854_775_807i64
pub const MAX: i64 = 9_223_372_036_854_775_807i64
Largest representable value
sourcepub const MIN: i64 = -9_223_372_036_854_775_808i64
pub const MIN: i64 = -9_223_372_036_854_775_808i64
Smallest representable value
sourcepub const DEFAULT_ORDERING: Ordering = Ordering::SeqCst
pub const DEFAULT_ORDERING: Ordering = Ordering::SeqCst
Default Atomic ordering
sourcepub const fn new_with_ordering(ordering: Ordering) -> Self
pub const fn new_with_ordering(ordering: Ordering) -> Self
Instantiate with ordering
sourcepub const fn new_from_offset(offset: i64) -> Self
pub const fn new_from_offset(offset: i64) -> Self
Instantiate with offset value
sourcepub const fn new_from_offset_with_ordering(
offset: i64,
ordering: Ordering
) -> Self
pub const fn new_from_offset_with_ordering( offset: i64, ordering: Ordering ) -> Self
Instantiate with offset value and ordering
sourcepub fn get(&self) -> i64
pub fn get(&self) -> i64
Get current value with the default ordering
use width_counters::{CounterI64 as C };
use i64 as U;
let c = C::new();
assert_eq!(c.get(), 0, "get returns initial value");
c.inc_one();
c.inc_one();
c.inc_one();
assert_eq!(c.get(), 3, "get returns post-increment value");sourcepub fn get_with_ordering(&self, ordering: Ordering) -> i64
pub fn get_with_ordering(&self, ordering: Ordering) -> i64
Get current value with a specific ordering
source§impl CounterI64
impl CounterI64
sourcepub fn inc_one(&self)
pub fn inc_one(&self)
Increment by one
use width_counters::{CounterI64 as C };
use core::ops::*;
use i64 as U;
let offset = U::MAX/2;
let c = C::new_from_offset(offset);
let m = 20;
(0..m).for_each(|_| { c.inc_one(); });
assert_eq!(c.get(), (offset).add(20), "counter must Increment/add number of times given as per sequential ordering");
let d = C::new_from_offset(U::MAX);
d.inc_one();
d.inc_one();
assert_eq!(d.get(), U::MAX, "counter must stop at MAX ");sourcepub fn inc_one_with_ordering(&self, ordering: Ordering)
pub fn inc_one_with_ordering(&self, ordering: Ordering)
Increment by one with ordering
sourcepub fn inc_by(&self, amount: i64)
pub fn inc_by(&self, amount: i64)
Increment by specified amount
use width_counters::{CounterI64 as C };
use core::ops::*;
use i64 as U;
let offset = U::MAX/2;
let c = C::new_from_offset(offset);
let m = 20;
(0..m).for_each(|_| { c.inc_by(2); });
assert_eq!((c.get() as i128).sub((20*2) as i128), ((offset) as i128), "counter must Increment by specified amount");sourcepub fn inc_by_with_ordering(&self, amount: i64, ordering: Ordering)
pub fn inc_by_with_ordering(&self, amount: i64, ordering: Ordering)
Increment by specified amount with ordering
use width_counters::{CounterI64 as C };
use i64 as U;
use core::ops::*;
let m = 3i64;
let offset = U::MAX/2;
let d = C::new_from_offset(U::MAX.sub(m * 2));
d.inc_by(m);
d.inc_by(m);
d.inc_by(m);
assert_eq!(d.get(), U::MAX, "counter must stop at MAX");source§impl CounterI64
impl CounterI64
sourcepub fn dec_one(&self)
pub fn dec_one(&self)
Decrement by one
use width_counters::{CounterI64 as C };
use core::ops::*;
use i64 as U;
let offset = U::MAX/2;
let c = C::new_from_offset(offset);
let m = 20;
(0..m).for_each(|_| { c.dec_one(); });
assert_eq!(c.get(), (offset).sub(20), "counter must Decrement/sub number of times given as per sequential ordering");
let d = C::new_from_offset(U::MIN);
d.dec_one();
d.dec_one();
assert_eq!(d.get(), U::MIN, "counter must stop at MIN ");sourcepub fn dec_one_with_ordering(&self, ordering: Ordering)
pub fn dec_one_with_ordering(&self, ordering: Ordering)
Decrement by one with ordering
sourcepub fn dec_by(&self, amount: i64)
pub fn dec_by(&self, amount: i64)
Decrement by specified amount
use width_counters::{CounterI64 as C };
use core::ops::*;
use i64 as U;
let offset = U::MAX/2;
let c = C::new_from_offset(offset);
let m = 20;
(0..m).for_each(|_| { c.dec_by(2); });
assert_eq!((c.get() as i128).add((20*2) as i128), ((offset) as i128), "counter must Decrement by specified amount");sourcepub fn dec_by_with_ordering(&self, amount: i64, ordering: Ordering)
pub fn dec_by_with_ordering(&self, amount: i64, ordering: Ordering)
Decrement by specified amount with ordering
use width_counters::{CounterI64 as C };
use i64 as U;
use core::ops::*;
let m = 3i64;
let offset = U::MAX/2;
let d = C::new_from_offset(U::MIN.add(m * 2));
d.dec_by(m);
d.dec_by(m);
d.dec_by(m);
assert_eq!(d.get(), U::MIN, "counter must stop at MIN");Trait Implementations§
source§impl Add<CounterI64> for CounterI64
impl Add<CounterI64> for CounterI64
source§fn add(self, rhs: Self) -> Self::Output
fn add(self, rhs: Self) -> Self::Output
- This operation is implemented with saturating arithmetic
- This operation IGNORES dissimilar atomic orderings!
§type Output = CounterI64
type Output = CounterI64
The resulting type after applying the
+ operator.source§impl AsRef<Ordering> for CounterI64
impl AsRef<Ordering> for CounterI64
source§impl Clone for CounterI64
impl Clone for CounterI64
source§impl Debug for CounterI64
impl Debug for CounterI64
source§impl Default for CounterI64
impl Default for CounterI64
source§impl Display for CounterI64
impl Display for CounterI64
source§impl Div<CounterI64> for CounterI64
impl Div<CounterI64> for CounterI64
source§fn div(self, rhs: Self) -> Self::Output
fn div(self, rhs: Self) -> Self::Output
- This operation is implemented with saturating arithmetic
- This operation IGNORES dissimilar atomic orderings!
§type Output = CounterI64
type Output = CounterI64
The resulting type after applying the
/ operator.source§impl From<&CounterI64> for i64
impl From<&CounterI64> for i64
source§fn from(counter: &CounterI64) -> Self
fn from(counter: &CounterI64) -> Self
Converts to this type from the input type.
source§impl From<i64> for CounterI64
impl From<i64> for CounterI64
source§impl Hash for CounterI64
impl Hash for CounterI64
source§impl Mul<CounterI64> for CounterI64
impl Mul<CounterI64> for CounterI64
source§fn mul(self, rhs: Self) -> Self::Output
fn mul(self, rhs: Self) -> Self::Output
- This operation is implemented with saturating arithmetic
- This operation IGNORES dissimilar atomic orderings!
§type Output = CounterI64
type Output = CounterI64
The resulting type after applying the
* operator.source§impl Ord for CounterI64
impl Ord for CounterI64
source§impl PartialEq<CounterI64> for CounterI64
impl PartialEq<CounterI64> for CounterI64
PartialEq is only equal when orderings are equal
use width_counters::{CounterI64 as C };
use core::sync::atomic::Ordering;
let a = C::new_from_offset_with_ordering(33, Ordering::Relaxed);
let b = C::new_from_offset_with_ordering(33, Ordering::Relaxed);
assert_eq!(a, b, "counters must be equal when counts and orderings are equal");
assert_eq!(a, b, "counters must be equal when counts and orderings are equal");
let m = 20;
(0..m).for_each(|_| { a.inc_one(); b.inc_one(); });
assert_eq!(a, b, "counters must be equal after counting same amount");
assert_eq!(a, b, "counters must be equal after counting same amount");
a.inc_one();
assert_ne!(a, b, "counters must not be equal after counting different amounts");
let c = C::new_from_offset_with_ordering(44, Ordering::Relaxed);
let d = C::new_from_offset_with_ordering(44, Ordering::Release);
assert_ne!(c, d, "ordering-inequal counters must not be equal with same count");source§impl PartialOrd<CounterI64> for CounterI64
impl PartialOrd<CounterI64> for CounterI64
PartialOrd only produces cmp ordering when atomic orderings are equal
use width_counters::{CounterI64 as C };
use core::sync::atomic::Ordering;
let a = C::new_from_offset_with_ordering(32, Ordering::Relaxed);
let b = C::new_from_offset_with_ordering(33, Ordering::Relaxed);
assert!(a < b, "same-cmp::ordering counters must be ordered by when counts");
assert!(b > a, "same-cmp::ordering counters must be ordered by when counts");
let m = 20;
(0..m).for_each(|_| { a.inc_one(); b.inc_one(); });
assert!(a < b, "cmp::ordering preserved after counting same amount");
assert!(b > a, "cmp::ordering preserved after counting same amount");1.0.0 · source§fn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for
self and other) and is used by the <=
operator. Read moresource§impl Sub<CounterI64> for CounterI64
impl Sub<CounterI64> for CounterI64
source§fn sub(self, rhs: Self) -> Self::Output
fn sub(self, rhs: Self) -> Self::Output
- This operation is implemented with saturating arithmetic
- This operation IGNORES dissimilar atomic orderings!
§type Output = CounterI64
type Output = CounterI64
The resulting type after applying the
- operator.impl Eq for CounterI64
Auto Trait Implementations§
impl RefUnwindSafe for CounterI64
impl Send for CounterI64
impl Sync for CounterI64
impl Unpin for CounterI64
impl UnwindSafe for CounterI64
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more