Struct CounterU16

Source
pub struct CounterU16 { /* private fields */ }
Expand description

An atomic counter using AtomicU16 / (core::u16).

§Behavior

  1. The default ordering is Sequentially Consistent.
  2. The ordering used for atomic operations is customizable for operations ending in with_ordering.
  3. The choice of ordering intentionally impacts ALMOST EVERYTHING about how this counter works, including de/serialization, incrementing, decrementing, equality comparisons, partial ordering comparisons, etc.
  4. Total (non-partial) ordering comparisons always use the default ordering.
  5. Unlike the underlying AtomicU16, this will not wrap on overflow unless the cyclic behavior mode is set.
  6. The default behavior is non-monotonic, so the counter can increment and decrement.

§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<u16>

Implementations§

Source§

impl CounterU16

Source

pub const MAX: u16 = 65_535u16

Source

pub const MIN: u16 = 0u16

Source

pub const DEFAULT_ORDERING: Ordering = Ordering::SeqCst

Source

pub const DEFAULT_COUNTING_BEHAVIOR: BitFlags<CountingBehavior>

Source

pub fn new() -> Self

Instantiate

Source

pub fn new_with_ordering(ordering: Ordering) -> Self

Instantiate with ordering

Source

pub fn new_from_offset(offset: u16) -> Self

Instantiate with offset value

Source

pub fn new_from_offset_with_ordering(offset: u16, ordering: Ordering) -> Self

Instantiate with offset value and ordering

Source

pub fn set_counting_behavior<B: Into<BitFlags<CountingBehavior>>>( &mut self, counting_behavior: B, )

Set counting behavior

Source

pub fn new_with_counting_behavior<B: Into<BitFlags<CountingBehavior>>>( counting_behavior: B, ) -> Self

Instantiate with counting behaviors

Source

pub fn new_from_offset_with_counting_behavior<B: Into<BitFlags<CountingBehavior>>>( offset: u16, counting_behavior: B, ) -> Self

Instantiate with offset value and counting behavior

Source

pub fn get(&self) -> u16

Get current value with the default ordering

use width_counters::{ *, CounterU16 as C };
use u16 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");
Source

pub fn get_with_ordering(&self, ordering: Ordering) -> u16

Get current value with a specific ordering

Source

pub fn get_i128(&self) -> i128

Convenience method for getting the current value as i128

Source

pub fn to_x<X: From<u16>>(&self) -> X

Convert to some type that impls From u16.

Source§

impl CounterU16

Source

pub fn inc_one_with_ordering(&self, ordering: Ordering)

Increment by one with ordering

Source

pub fn inc_by(&self, amount: u16)

Increment by specified amount

use width_counters::{ *, CounterU16 as C };
use core::ops::*; 
use u16 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");
Source

pub fn inc_by_with_ordering(&self, amount: u16, ordering: Ordering)

Increment by specified amount with ordering

use width_counters::{ *, CounterU16 as C };
use u16 as U;
use core::ops::*; 
let m = 3u16;
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

pub fn get_and_inc_one(&self) -> u16

Combine the increment (by one) and get operations

Returns the value before the increment operation

Source

pub fn get_and_inc_by(&self, amount: u16) -> u16

Combine the increment (by the given amount) and get operations

Returns the value before the incrementoperation

Source

pub fn get_and_inc_by_with_ordering( &self, amount: u16, ordering: Ordering, ) -> u16

Combine the increment (by the given amount) and get operations

Returns the value before the increment operation

Source§

impl CounterU16

Source

pub fn dec_one_with_ordering(&self, ordering: Ordering)

Decrement by one with ordering

Source

pub fn dec_by(&self, amount: u16)

Decrement by specified amount

use width_counters::{ *, CounterU16 as C };
use core::ops::*; 
use u16 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");
Source

pub fn dec_by_with_ordering(&self, amount: u16, ordering: Ordering)

Decrement by specified amount with ordering

use width_counters::{ *, CounterU16 as C };
use u16 as U;
use core::ops::*; 
let m = 3u16;
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");
Source

pub fn get_and_dec_one(&self) -> u16

Combine the decrement (by one) and get operations

Returns the value before the decrement operation

Source

pub fn get_and_dec_by(&self, amount: u16) -> u16

Combine the decrement (by the given amount) and get operations

Returns the value before the decrementoperation

Source

pub fn get_and_dec_by_with_ordering( &self, amount: u16, ordering: Ordering, ) -> u16

Combine the decrement (by the given amount) and get operations

Returns the value before the decrement operation

Trait Implementations§

Source§

impl Add for CounterU16

Source§

fn add(self, rhs: Self) -> Self::Output

  • This operation is implemented with saturating arithmetic
  • This operation IGNORES dissimilar atomic orderings!
Source§

type Output = CounterU16

The resulting type after applying the + operator.
Source§

impl AsRef<Ordering> for CounterU16

Source§

fn as_ref(&self) -> &Ordering

Converts this type into a shared reference of the (usually inferred) input type.
Source§

impl Clone for CounterU16

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl CountsNonmotonically for CounterU16

Source§

fn inc_one(&self)

Increment by one

use width_counters::{ *, CounterU16 as C };
use core::ops::*; 
use enumflags2::{make_bitflags};
use u16 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 ");
Source§

fn can_inc(&self) -> bool

Can the counter increment any further?

  • It halts increment ing at Self::MAX
use width_counters::{*, CounterU16 as C, CountingBehavior as B };
use u16 as U;
use core::ops::*; 
let m = 3u16;
let offset = C::MAX/2;
let d = C::new_from_offset_with_counting_behavior(offset, B::Increment);
assert_eq!(d.can_inc(), true, "counter must detect when it can Increment");
let offset = C::MAX;
let d = C::new_from_offset_with_counting_behavior(offset, B::Increment);
assert_eq!(d.can_inc(), false, "counter must detect when it can no longer Increment");
Source§

fn is_incrementable(&self) -> bool

Is the current index advanceable with the given operation type

Source§

fn is_within_increment_bound(&self) -> bool

Is it within(inclusive) the increment bound

Source§

fn is_at_increment_bound(&self) -> bool

Is it at the increment bound

Source§

fn dec_one(&self)

Decrement by one

use width_counters::{ *, CounterU16 as C };
use core::ops::*; 
use enumflags2::{make_bitflags};
use u16 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 ");
Source§

fn can_dec(&self) -> bool

Can the counter decrement any further?

  • It halts decrement ing at Self::MIN
use width_counters::{*, CounterU16 as C, CountingBehavior as B };
use u16 as U;
use core::ops::*; 
let m = 3u16;
let offset = C::MAX/2;
let d = C::new_from_offset_with_counting_behavior(offset, B::Decrement);
assert_eq!(d.can_dec(), true, "counter must detect when it can Decrement");
let offset = C::MIN;
let d = C::new_from_offset_with_counting_behavior(offset, B::Decrement);
assert_eq!(d.can_dec(), false, "counter must detect when it can no longer Decrement");
Source§

fn is_decrementable(&self) -> bool

Is the current index advanceable with the given operation type

Source§

fn is_within_decrement_bound(&self) -> bool

Is it within(inclusive) the decrement bound

Source§

fn is_at_decrement_bound(&self) -> bool

Is it at the decrement bound

Source§

impl Debug for CounterU16

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for CounterU16

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Display for CounterU16

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Div for CounterU16

Source§

fn div(self, rhs: Self) -> Self::Output

  • This operation is implemented with saturating arithmetic
  • This operation IGNORES dissimilar atomic orderings!
Source§

type Output = CounterU16

The resulting type after applying the / operator.
Source§

impl From<&CounterU16> for u16

Source§

fn from(counter: &CounterU16) -> Self

Converts to this type from the input type.
Source§

impl From<u16> for CounterU16

Source§

fn from(x: u16) -> Self

Converts to this type from the input type.
Source§

impl HasCountingBehavior for CounterU16

Source§

impl Hash for CounterU16

Source§

fn hash<H: Hasher>(&self, state: &mut H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl IsCounter for CounterU16

Source§

type Unit = u16

Source§

fn get_ordering_ref(&self) -> &Ordering

Get the ordering
Source§

fn get_current(&self) -> Self::Unit

Get the current value with the preset ordering
Source§

impl Mul for CounterU16

Source§

fn mul(self, rhs: Self) -> Self::Output

  • This operation is implemented with saturating arithmetic
  • This operation IGNORES dissimilar atomic orderings!
Source§

type Output = CounterU16

The resulting type after applying the * operator.
Source§

impl Ord for CounterU16

Source§

fn cmp(&self, other: &Self) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · Source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · Source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · Source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

impl PartialEq for CounterU16

PartialEq is only equal when orderings and counting behaviors are equal

use width_counters::{ *, CounterU16 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§

fn eq(&self, rhs: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl PartialOrd for CounterU16

PartialOrd only produces cmp ordering when atomic orderings are equal

use width_counters::{ *, CounterU16 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");
Source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl Sub for CounterU16

Source§

fn sub(self, rhs: Self) -> Self::Output

  • This operation is implemented with saturating arithmetic
  • This operation IGNORES dissimilar atomic orderings!
Source§

type Output = CounterU16

The resulting type after applying the - operator.
Source§

impl Eq for CounterU16

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.