Skip to main content

generic_atomics/
atomic_float.rs

1use crate::{
2    atomic_float_wrapper::{
3        Abs, Neg, UseUpdateToAdd, UseUpdateToMax, UseUpdateToMin, UseUpdateToSub,
4    },
5    AtomicNumber, IntoAtomicNumber,
6};
7use atomic_traits::{fetch::Update, AsPtr, Atomic, Bitwise};
8use core::sync::atomic::Ordering::{self};
9use num_primitive::PrimitiveFloat;
10use num_traits::FromPrimitive;
11
12pub trait AtomicFloat<F>:
13    Atomic<Type = F>
14    + Bitwise
15    + AsPtr
16    + Update<Type = F>
17    + Abs<Type = F>
18    + Neg<Type = F>
19    + UseUpdateToAdd<Type = F>
20    + UseUpdateToSub<Type = F>
21    + UseUpdateToMin<Type = F>
22    + UseUpdateToMax<Type = F>
23    + Send
24    + Sync
25where
26    F: PrimitiveFloat,
27{
28}
29
30impl<AF, F> AtomicFloat<F> for AF
31where
32    AF: Atomic<Type = F>
33        + Bitwise
34        + AsPtr
35        + Update<Type = F>
36        + Abs<Type = F>
37        + Neg<Type = F>
38        + UseUpdateToAdd<Type = F>
39        + UseUpdateToSub<Type = F>
40        + UseUpdateToMin<Type = F>
41        + UseUpdateToMax<Type = F>
42        + Send
43        + Sync,
44    F: PrimitiveFloat,
45{
46}
47
48pub trait IntoAtomicFloat: IntoAtomicNumber<AN = Self::AF> + PrimitiveFloat {
49    type AF: AtomicFloat<Self>;
50    fn into_atomic_float(self) -> impl AtomicFloat<Self>;
51}
52
53impl<T, A> IntoAtomicFloat for T
54where
55    T: IntoAtomicNumber<AN = A> + PrimitiveFloat + FromPrimitive,
56    A: AtomicFloat<Self>,
57{
58    type AF = T::AN;
59
60    fn into_atomic_float(self) -> impl AtomicFloat<Self> {
61        Self::AF::new(self)
62    }
63}
64
65pub trait PrimitiveAtomicFloat: PrimitiveFloat + IntoAtomicFloat {}
66impl<T> PrimitiveAtomicFloat for T where T: PrimitiveFloat + IntoAtomicFloat {}
67
68impl<T> Abs for AtomicNumber<T>
69where
70    T: PrimitiveAtomicFloat + FromPrimitive,
71{
72    type Type = T;
73
74    #[inline(always)]
75    fn fetch_abs(&self, order: Ordering) -> Self::Type {
76        self.atomic.fetch_abs(order)
77    }
78}
79
80impl<T> Neg for AtomicNumber<T>
81where
82    T: PrimitiveAtomicFloat + FromPrimitive,
83{
84    type Type = T;
85
86    #[inline(always)]
87    fn fetch_neg(&self, order: Ordering) -> Self::Type {
88        self.atomic.fetch_neg(order)
89    }
90}
91impl<T> UseUpdateToAdd for AtomicNumber<T>
92where
93    T: PrimitiveAtomicFloat + FromPrimitive,
94{
95    type Type = T;
96
97    #[inline(always)]
98    fn fetch_add_via_update(&self, val: Self::Type, order: Ordering) -> Self::Type {
99        self.atomic.fetch_add_via_update(val, order)
100    }
101}
102
103impl<T> UseUpdateToSub for AtomicNumber<T>
104where
105    T: PrimitiveAtomicFloat + FromPrimitive,
106{
107    type Type = T;
108
109    #[inline(always)]
110    fn fetch_sub_via_update(&self, val: Self::Type, order: Ordering) -> Self::Type {
111        self.atomic.fetch_sub_via_update(val, order)
112    }
113}
114
115impl<T> UseUpdateToMin for AtomicNumber<T>
116where
117    T: PrimitiveAtomicFloat + FromPrimitive,
118{
119    type Type = T;
120
121    #[inline(always)]
122    fn fetch_min_via_update(&self, val: Self::Type, order: Ordering) -> Self::Type {
123        self.atomic.fetch_min_via_update(val, order)
124    }
125}
126
127impl<T> UseUpdateToMax for AtomicNumber<T>
128where
129    T: PrimitiveAtomicFloat + FromPrimitive,
130{
131    type Type = T;
132
133    #[inline]
134    fn fetch_max_via_update(&self, val: Self::Type, order: Ordering) -> T {
135        self.atomic.fetch_max_via_update(val, order)
136    }
137}