qubit_atomic/atomic/atomic_f32.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025 - 2026 Haixing Hu.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10
11//! # Atomic 32-bit Floating Point
12//!
13//! Provides an easy-to-use atomic 32-bit floating point type with sensible
14//! default memory orderings. Implemented using bit conversion with AtomicU32.
15//!
16
17use std::sync::atomic::AtomicU32;
18use std::sync::atomic::Ordering;
19
20use crate::atomic::atomic_number_ops::AtomicNumberOps;
21use crate::atomic::atomic_ops::AtomicOps;
22
23/// Atomic 32-bit floating point number.
24///
25/// Provides easy-to-use atomic operations with automatic memory ordering
26/// selection. Implemented using `AtomicU32` with bit conversion.
27///
28/// # Memory Ordering Strategy
29///
30/// This type uses the same memory ordering strategy as atomic integers:
31///
32/// - **Read operations** (`load`): Use `Acquire` ordering to ensure
33/// visibility of prior writes from other threads.
34///
35/// - **Write operations** (`store`): Use `Release` ordering to ensure
36/// visibility of prior writes to other threads.
37///
38/// - **Read-Modify-Write operations** (`swap`, `compare_set`): Use
39/// `AcqRel` ordering for full synchronization.
40///
41/// - **CAS-based arithmetic** (`fetch_add`, `fetch_sub`, etc.): Use
42/// `AcqRel` on success and `Acquire` on failure within the CAS loop.
43/// The loop ensures eventual consistency.
44///
45/// # Implementation Details
46///
47/// Since hardware doesn't provide native atomic floating-point operations,
48/// this type is implemented using `AtomicU32` with `f32::to_bits()` and
49/// `f32::from_bits()` conversions. This preserves bit patterns exactly,
50/// including special values like NaN and infinity.
51///
52/// # Features
53///
54/// - Automatic memory ordering selection
55/// - Arithmetic operations via CAS loops
56/// - Zero-cost abstraction with inline methods
57/// - Access to underlying type via `inner()` for advanced use cases
58///
59/// # Limitations
60///
61/// - Arithmetic operations use CAS loops (slower than integer operations)
62/// - CAS comparisons use exact IEEE-754 bit patterns, so different NaN
63/// payloads and `0.0`/`-0.0` are treated as different values
64/// - No max/min operations (complex floating point semantics)
65///
66/// # Example
67///
68/// ```rust
69/// use qubit_atomic::Atomic;
70/// use std::sync::Arc;
71/// use std::thread;
72///
73/// let sum = Arc::new(Atomic::<f32>::new(0.0));
74/// let mut handles = vec![];
75///
76/// for _ in 0..10 {
77/// let sum = sum.clone();
78/// let handle = thread::spawn(move || {
79/// for _ in 0..100 {
80/// sum.fetch_add(0.1);
81/// }
82/// });
83/// handles.push(handle);
84/// }
85///
86/// for handle in handles {
87/// handle.join().unwrap();
88/// }
89///
90/// // Note: Due to floating point precision, result may not be exactly 100.0
91/// let result = sum.load();
92/// assert!((result - 100.0).abs() < 0.01);
93/// ```
94///
95#[repr(transparent)]
96pub struct AtomicF32 {
97 /// Raw-bit atomic storage for the `f32` value.
98 inner: AtomicU32,
99}
100
101impl AtomicF32 {
102 /// Creates a new atomic floating point number.
103 ///
104 /// # Parameters
105 ///
106 /// * `value` - The initial value.
107 ///
108 /// # Returns
109 ///
110 /// An atomic `f32` initialized to `value`.
111 ///
112 /// # Example
113 ///
114 /// ```rust
115 /// use qubit_atomic::Atomic;
116 ///
117 /// let atomic = Atomic::<f32>::new(3.14);
118 /// assert_eq!(atomic.load(), 3.14);
119 /// ```
120 #[inline]
121 pub const fn new(value: f32) -> Self {
122 Self {
123 inner: AtomicU32::new(value.to_bits()),
124 }
125 }
126
127 /// Gets the current value.
128 ///
129 /// # Memory Ordering
130 ///
131 /// Uses `Acquire` ordering on the underlying `AtomicU32`. This ensures
132 /// that all writes from other threads that happened before a `Release`
133 /// store are visible after this load.
134 ///
135 /// # Returns
136 ///
137 /// The current value.
138 ///
139 /// # Example
140 ///
141 /// ```rust
142 /// use qubit_atomic::Atomic;
143 ///
144 /// let atomic = Atomic::<f32>::new(3.14);
145 /// assert_eq!(atomic.load(), 3.14);
146 /// ```
147 #[inline]
148 pub fn load(&self) -> f32 {
149 f32::from_bits(self.inner.load(Ordering::Acquire))
150 }
151
152 /// Sets a new value.
153 ///
154 /// # Memory Ordering
155 ///
156 /// Uses `Release` ordering on the underlying `AtomicU32`. This ensures
157 /// that all prior writes in this thread are visible to other threads
158 /// that perform an `Acquire` load.
159 ///
160 /// # Parameters
161 ///
162 /// * `value` - The new value to set.
163 ///
164 /// # Example
165 ///
166 /// ```rust
167 /// use qubit_atomic::Atomic;
168 ///
169 /// let atomic = Atomic::<f32>::new(0.0);
170 /// atomic.store(3.14);
171 /// assert_eq!(atomic.load(), 3.14);
172 /// ```
173 #[inline]
174 pub fn store(&self, value: f32) {
175 self.inner.store(value.to_bits(), Ordering::Release);
176 }
177
178 /// Swaps the current value with a new value, returning the old value.
179 ///
180 /// # Memory Ordering
181 ///
182 /// Uses `AcqRel` ordering on the underlying `AtomicU32`. This provides
183 /// full synchronization for this read-modify-write operation.
184 ///
185 /// # Parameters
186 ///
187 /// * `value` - The new value to swap in.
188 ///
189 /// # Returns
190 ///
191 /// The old value.
192 ///
193 /// # Example
194 ///
195 /// ```rust
196 /// use qubit_atomic::Atomic;
197 ///
198 /// let atomic = Atomic::<f32>::new(1.0);
199 /// let old = atomic.swap(2.0);
200 /// assert_eq!(old, 1.0);
201 /// assert_eq!(atomic.load(), 2.0);
202 /// ```
203 #[inline]
204 pub fn swap(&self, value: f32) -> f32 {
205 f32::from_bits(self.inner.swap(value.to_bits(), Ordering::AcqRel))
206 }
207
208 /// Compares and sets the value atomically.
209 ///
210 /// If the current value equals `current`, sets it to `new` and returns
211 /// `Ok(())`. Otherwise, returns `Err(actual)` where `actual` is the
212 /// current value.
213 ///
214 /// Comparison uses the exact raw bit pattern produced by
215 /// [`f32::to_bits`], not [`PartialEq`].
216 ///
217 /// # Memory Ordering
218 ///
219 /// - **Success**: Uses `AcqRel` ordering on the underlying `AtomicU32`
220 /// to ensure full synchronization when the exchange succeeds.
221 /// - **Failure**: Uses `Acquire` ordering to observe the actual value
222 /// written by another thread.
223 ///
224 /// # Parameters
225 ///
226 /// * `current` - The expected current value.
227 /// * `new` - The new value to set if current matches.
228 ///
229 /// # Returns
230 ///
231 /// `Ok(())` when the value was replaced.
232 ///
233 /// # Errors
234 ///
235 /// Returns `Err(actual)` with the observed value when the raw-bit
236 /// comparison fails. In that case, `new` is not stored.
237 ///
238 /// # Warning
239 ///
240 /// NaN values compare by raw bits. A stored NaN and `current` must have
241 /// the same payload bits for the CAS to succeed.
242 ///
243 /// # Example
244 ///
245 /// ```rust
246 /// use qubit_atomic::Atomic;
247 ///
248 /// let atomic = Atomic::<f32>::new(1.0);
249 /// assert!(atomic.compare_set(1.0, 2.0).is_ok());
250 /// assert_eq!(atomic.load(), 2.0);
251 /// ```
252 #[inline]
253 pub fn compare_set(&self, current: f32, new: f32) -> Result<(), f32> {
254 self.inner
255 .compare_exchange(current.to_bits(), new.to_bits(), Ordering::AcqRel, Ordering::Acquire)
256 .map(|_| ())
257 .map_err(f32::from_bits)
258 }
259
260 /// Weak version of compare-and-set.
261 ///
262 /// May spuriously fail even when the comparison succeeds. Should be used
263 /// in a loop.
264 ///
265 /// Uses `AcqRel` ordering on success and `Acquire` ordering on failure.
266 /// Comparison uses the exact raw bit pattern produced by
267 /// [`f32::to_bits`].
268 ///
269 /// # Parameters
270 ///
271 /// * `current` - The expected current value.
272 /// * `new` - The new value to set if current matches.
273 ///
274 /// # Returns
275 ///
276 /// `Ok(())` when the value was replaced.
277 ///
278 /// # Errors
279 ///
280 /// Returns `Err(actual)` with the observed value when the raw-bit
281 /// comparison fails, including possible spurious failures. In that case,
282 /// `new` is not stored.
283 ///
284 /// # Example
285 ///
286 /// ```rust
287 /// use qubit_atomic::Atomic;
288 ///
289 /// let atomic = Atomic::<f32>::new(1.0);
290 /// let mut current = atomic.load();
291 /// loop {
292 /// match atomic.compare_set_weak(current, current + 1.0) {
293 /// Ok(_) => break,
294 /// Err(actual) => current = actual,
295 /// }
296 /// }
297 /// assert_eq!(atomic.load(), 2.0);
298 /// ```
299 #[inline]
300 pub fn compare_set_weak(&self, current: f32, new: f32) -> Result<(), f32> {
301 self.inner
302 .compare_exchange_weak(current.to_bits(), new.to_bits(), Ordering::AcqRel, Ordering::Acquire)
303 .map(|_| ())
304 .map_err(f32::from_bits)
305 }
306
307 /// Compares and exchanges the value atomically, returning the previous
308 /// value.
309 ///
310 /// If the current value equals `current`, sets it to `new` and returns
311 /// the old value. Otherwise, returns the actual current value.
312 ///
313 /// Uses `AcqRel` ordering on success and `Acquire` ordering on failure.
314 ///
315 /// # Parameters
316 ///
317 /// * `current` - The expected current value.
318 /// * `new` - The new value to set if current matches.
319 ///
320 /// # Returns
321 ///
322 /// The value observed before the operation completed. If the returned
323 /// value has the same raw bits as `current`, the exchange succeeded;
324 /// otherwise it is the actual value that prevented the exchange.
325 ///
326 /// # Example
327 ///
328 /// ```rust
329 /// use qubit_atomic::Atomic;
330 ///
331 /// let atomic = Atomic::<f32>::new(1.0);
332 /// let prev = atomic.compare_and_exchange(1.0, 2.0);
333 /// assert_eq!(prev, 1.0);
334 /// assert_eq!(atomic.load(), 2.0);
335 /// ```
336 #[inline]
337 pub fn compare_and_exchange(&self, current: f32, new: f32) -> f32 {
338 match self
339 .inner
340 .compare_exchange(current.to_bits(), new.to_bits(), Ordering::AcqRel, Ordering::Acquire)
341 {
342 Ok(prev_bits) => f32::from_bits(prev_bits),
343 Err(actual_bits) => f32::from_bits(actual_bits),
344 }
345 }
346
347 /// Weak version of compare-and-exchange.
348 ///
349 /// May spuriously fail even when the comparison succeeds. Should be used
350 /// in a loop.
351 ///
352 /// Uses `AcqRel` ordering on success and `Acquire` ordering on failure.
353 ///
354 /// # Parameters
355 ///
356 /// * `current` - The expected current value.
357 /// * `new` - The new value to set if current matches.
358 ///
359 /// # Returns
360 ///
361 /// `Ok(previous)` when the value was replaced, or `Err(actual)` when the
362 /// comparison failed, including possible spurious failure. Values preserve
363 /// their exact raw bit patterns.
364 ///
365 /// # Example
366 ///
367 /// ```rust
368 /// use qubit_atomic::Atomic;
369 ///
370 /// let atomic = Atomic::<f32>::new(1.0);
371 /// let mut current = atomic.load();
372 /// loop {
373 /// match atomic.compare_and_exchange_weak(current, current + 1.0) {
374 /// Ok(_) => break,
375 /// Err(actual) => current = actual,
376 /// }
377 /// }
378 /// assert_eq!(atomic.load(), 2.0);
379 /// ```
380 #[inline]
381 pub fn compare_and_exchange_weak(&self, current: f32, new: f32) -> Result<f32, f32> {
382 self.inner
383 .compare_exchange_weak(current.to_bits(), new.to_bits(), Ordering::AcqRel, Ordering::Acquire)
384 .map(f32::from_bits)
385 .map_err(f32::from_bits)
386 }
387
388 /// Atomically adds a value, returning the old value.
389 ///
390 /// # Memory Ordering
391 ///
392 /// Internally uses a CAS loop with `compare_set_weak`, which uses
393 /// `AcqRel` on success and `Acquire` on failure. The loop ensures
394 /// eventual consistency even under high contention.
395 ///
396 /// # Performance
397 ///
398 /// May be slow in high-contention scenarios due to the CAS loop.
399 /// Consider using atomic integers if performance is critical.
400 ///
401 /// # Parameters
402 ///
403 /// * `delta` - The value to add.
404 ///
405 /// # Returns
406 ///
407 /// The old value before adding.
408 ///
409 /// # Example
410 ///
411 /// ```rust
412 /// use qubit_atomic::Atomic;
413 ///
414 /// let atomic = Atomic::<f32>::new(10.0);
415 /// let old = atomic.fetch_add(5.5);
416 /// assert_eq!(old, 10.0);
417 /// assert_eq!(atomic.load(), 15.5);
418 /// ```
419 #[inline]
420 pub fn fetch_add(&self, delta: f32) -> f32 {
421 self.fetch_update(|current| current + delta)
422 }
423
424 /// Atomically subtracts a value, returning the old value.
425 ///
426 /// # Memory Ordering
427 ///
428 /// Internally uses a CAS loop with `compare_set_weak`, which uses
429 /// `AcqRel` on success and `Acquire` on failure. The loop ensures
430 /// eventual consistency even under high contention.
431 ///
432 /// # Parameters
433 ///
434 /// * `delta` - The value to subtract.
435 ///
436 /// # Returns
437 ///
438 /// The old value before subtracting.
439 ///
440 /// # Example
441 ///
442 /// ```rust
443 /// use qubit_atomic::Atomic;
444 ///
445 /// let atomic = Atomic::<f32>::new(10.0);
446 /// let old = atomic.fetch_sub(3.5);
447 /// assert_eq!(old, 10.0);
448 /// assert_eq!(atomic.load(), 6.5);
449 /// ```
450 #[inline]
451 pub fn fetch_sub(&self, delta: f32) -> f32 {
452 self.fetch_update(|current| current - delta)
453 }
454
455 /// Atomically multiplies by a factor, returning the old value.
456 ///
457 /// # Memory Ordering
458 ///
459 /// Internally uses a CAS loop with `compare_set_weak`, which uses
460 /// `AcqRel` on success and `Acquire` on failure. The loop ensures
461 /// eventual consistency even under high contention.
462 ///
463 /// # Parameters
464 ///
465 /// * `factor` - The factor to multiply by.
466 ///
467 /// # Returns
468 ///
469 /// The old value before multiplying.
470 ///
471 /// # Example
472 ///
473 /// ```rust
474 /// use qubit_atomic::Atomic;
475 ///
476 /// let atomic = Atomic::<f32>::new(10.0);
477 /// let old = atomic.fetch_mul(2.5);
478 /// assert_eq!(old, 10.0);
479 /// assert_eq!(atomic.load(), 25.0);
480 /// ```
481 #[inline]
482 pub fn fetch_mul(&self, factor: f32) -> f32 {
483 self.fetch_update(|current| current * factor)
484 }
485
486 /// Atomically divides by a divisor, returning the old value.
487 ///
488 /// # Memory Ordering
489 ///
490 /// Internally uses a CAS loop with `compare_set_weak`, which uses
491 /// `AcqRel` on success and `Acquire` on failure. The loop ensures
492 /// eventual consistency even under high contention.
493 ///
494 /// # Parameters
495 ///
496 /// * `divisor` - The divisor to divide by.
497 ///
498 /// # Returns
499 ///
500 /// The old value before dividing.
501 ///
502 /// # Example
503 ///
504 /// ```rust
505 /// use qubit_atomic::Atomic;
506 ///
507 /// let atomic = Atomic::<f32>::new(10.0);
508 /// let old = atomic.fetch_div(2.0);
509 /// assert_eq!(old, 10.0);
510 /// assert_eq!(atomic.load(), 5.0);
511 /// ```
512 #[inline]
513 pub fn fetch_div(&self, divisor: f32) -> f32 {
514 self.fetch_update(|current| current / divisor)
515 }
516
517 /// Updates the value using a function, returning the old value.
518 ///
519 /// # Memory Ordering
520 ///
521 /// Internally uses a CAS loop with `compare_set_weak`, which uses
522 /// `AcqRel` on success and `Acquire` on failure. The loop ensures
523 /// eventual consistency even under high contention.
524 ///
525 /// # Parameters
526 ///
527 /// * `f` - A function that takes the current value and returns the new
528 /// value.
529 ///
530 /// # Returns
531 ///
532 /// The old value before the update.
533 ///
534 /// The closure may be called more than once when concurrent updates cause
535 /// CAS retries.
536 ///
537 /// # Example
538 ///
539 /// ```rust
540 /// use qubit_atomic::Atomic;
541 ///
542 /// let atomic = Atomic::<f32>::new(10.0);
543 /// let old = atomic.fetch_update(|x| x * 2.0);
544 /// assert_eq!(old, 10.0);
545 /// assert_eq!(atomic.load(), 20.0);
546 /// ```
547 #[inline]
548 pub fn fetch_update<F>(&self, mut f: F) -> f32
549 where
550 F: FnMut(f32) -> f32,
551 {
552 let mut current = self.load();
553 loop {
554 let new = f(current);
555 match self.compare_set_weak(current, new) {
556 Ok(_) => return current,
557 Err(actual) => current = actual,
558 }
559 }
560 }
561
562 /// Updates the value using a function, returning the new value.
563 ///
564 /// Internally uses a CAS loop until the update succeeds.
565 ///
566 /// # Parameters
567 ///
568 /// * `f` - A function that takes the current value and returns the new
569 /// value.
570 ///
571 /// # Returns
572 ///
573 /// The value committed by the successful update.
574 ///
575 /// The closure may be called more than once when concurrent updates cause
576 /// CAS retries.
577 ///
578 /// # Example
579 ///
580 /// ```rust
581 /// use qubit_atomic::Atomic;
582 ///
583 /// let atomic = Atomic::<f32>::new(10.0);
584 /// let new = atomic.update_and_get(|x| x * 2.0);
585 /// assert_eq!(new, 20.0);
586 /// assert_eq!(atomic.load(), 20.0);
587 /// ```
588 #[inline]
589 pub fn update_and_get<F>(&self, mut f: F) -> f32
590 where
591 F: FnMut(f32) -> f32,
592 {
593 let mut current = self.load();
594 loop {
595 let new = f(current);
596 match self.compare_set_weak(current, new) {
597 Ok(_) => return new,
598 Err(actual) => current = actual,
599 }
600 }
601 }
602
603 /// Conditionally updates the value using a function.
604 ///
605 /// Internally uses a CAS loop until the update succeeds or the closure
606 /// rejects the current value by returning `None`.
607 ///
608 /// # Parameters
609 ///
610 /// * `f` - A function that takes the current value and returns the new
611 /// value, or `None` to leave the value unchanged.
612 ///
613 /// # Returns
614 ///
615 /// `Some(old_value)` when the update succeeds, or `None` when `f` rejects
616 /// the observed current value.
617 ///
618 /// The closure may be called more than once when concurrent updates cause
619 /// CAS retries.
620 ///
621 /// # Example
622 ///
623 /// ```rust
624 /// use qubit_atomic::Atomic;
625 ///
626 /// let atomic = Atomic::<f32>::new(1.5);
627 /// assert_eq!(atomic.try_update(|x| (x > 0.0).then_some(x * 2.0)), Some(1.5));
628 /// assert_eq!(atomic.load(), 3.0);
629 /// assert_eq!(atomic.try_update(|x| (x < 0.0).then_some(x * 2.0)), None);
630 /// assert_eq!(atomic.load(), 3.0);
631 /// ```
632 #[inline]
633 pub fn try_update<F>(&self, mut f: F) -> Option<f32>
634 where
635 F: FnMut(f32) -> Option<f32>,
636 {
637 let mut current = self.load();
638 loop {
639 let new = f(current)?;
640 match self.compare_set_weak(current, new) {
641 Ok(_) => return Some(current),
642 Err(actual) => current = actual,
643 }
644 }
645 }
646
647 /// Conditionally updates the value using a function, returning the new value.
648 ///
649 /// Internally uses a CAS loop until the update succeeds or the closure
650 /// rejects the current value by returning `None`.
651 ///
652 /// # Parameters
653 ///
654 /// * `f` - A function that takes the current value and returns the new
655 /// value, or `None` to leave the value unchanged.
656 ///
657 /// # Returns
658 ///
659 /// `Some(new_value)` when the update succeeds, or `None` when `f` rejects
660 /// the observed current value.
661 ///
662 /// The closure may be called more than once when concurrent updates cause
663 /// CAS retries.
664 ///
665 /// # Example
666 ///
667 /// ```rust
668 /// use qubit_atomic::Atomic;
669 ///
670 /// let atomic = Atomic::<f32>::new(1.5);
671 /// assert_eq!(
672 /// atomic.try_update_and_get(|x| (x > 0.0).then_some(x * 2.0)),
673 /// Some(3.0),
674 /// );
675 /// assert_eq!(atomic.load(), 3.0);
676 /// assert_eq!(
677 /// atomic.try_update_and_get(|x| (x < 0.0).then_some(x * 2.0)),
678 /// None,
679 /// );
680 /// assert_eq!(atomic.load(), 3.0);
681 /// ```
682 #[inline]
683 pub fn try_update_and_get<F>(&self, mut f: F) -> Option<f32>
684 where
685 F: FnMut(f32) -> Option<f32>,
686 {
687 let mut current = self.load();
688 loop {
689 let new = f(current)?;
690 match self.compare_set_weak(current, new) {
691 Ok(_) => return Some(new),
692 Err(actual) => current = actual,
693 }
694 }
695 }
696
697 /// Gets a reference to the underlying standard library atomic type.
698 ///
699 /// This allows direct access to the standard library's atomic operations
700 /// for advanced use cases that require fine-grained control over memory
701 /// ordering.
702 ///
703 /// # Memory Ordering
704 ///
705 /// When using the returned reference, you have full control over memory
706 /// ordering. Remember to use `f32::to_bits()` and `f32::from_bits()` for
707 /// conversions.
708 ///
709 /// # Returns
710 ///
711 /// A reference to the underlying `std::sync::atomic::AtomicU32`.
712 ///
713 /// # Example
714 ///
715 /// ```rust
716 /// use qubit_atomic::Atomic;
717 /// use std::sync::atomic::Ordering;
718 ///
719 /// let atomic = Atomic::<f32>::new(0.0);
720 /// atomic.inner().store(3.14_f32.to_bits(), Ordering::Relaxed);
721 /// let bits = atomic.inner().load(Ordering::Relaxed);
722 /// assert_eq!(f32::from_bits(bits), 3.14);
723 /// ```
724 #[inline]
725 pub fn inner(&self) -> &AtomicU32 {
726 &self.inner
727 }
728}
729
730impl AtomicOps for AtomicF32 {
731 type Value = f32;
732
733 #[inline]
734 fn load(&self) -> f32 {
735 self.load()
736 }
737
738 #[inline]
739 fn store(&self, value: f32) {
740 self.store(value);
741 }
742
743 #[inline]
744 fn swap(&self, value: f32) -> f32 {
745 self.swap(value)
746 }
747
748 #[inline]
749 fn compare_set(&self, current: f32, new: f32) -> Result<(), f32> {
750 self.compare_set(current, new)
751 }
752
753 #[inline]
754 fn compare_set_weak(&self, current: f32, new: f32) -> Result<(), f32> {
755 self.compare_set_weak(current, new)
756 }
757
758 #[inline]
759 fn compare_exchange(&self, current: f32, new: f32) -> f32 {
760 self.compare_and_exchange(current, new)
761 }
762
763 #[inline]
764 fn compare_exchange_weak(&self, current: f32, new: f32) -> Result<f32, f32> {
765 self.compare_and_exchange_weak(current, new)
766 }
767
768 #[inline]
769 fn fetch_update<F>(&self, f: F) -> f32
770 where
771 F: FnMut(f32) -> f32,
772 {
773 self.fetch_update(f)
774 }
775
776 #[inline]
777 fn update_and_get<F>(&self, f: F) -> f32
778 where
779 F: FnMut(f32) -> f32,
780 {
781 self.update_and_get(f)
782 }
783
784 #[inline]
785 fn try_update<F>(&self, f: F) -> Option<f32>
786 where
787 F: FnMut(f32) -> Option<f32>,
788 {
789 self.try_update(f)
790 }
791
792 #[inline]
793 fn try_update_and_get<F>(&self, f: F) -> Option<f32>
794 where
795 F: FnMut(f32) -> Option<f32>,
796 {
797 self.try_update_and_get(f)
798 }
799}
800
801impl AtomicNumberOps for AtomicF32 {
802 #[inline]
803 fn fetch_add(&self, delta: f32) -> f32 {
804 self.fetch_add(delta)
805 }
806
807 #[inline]
808 fn fetch_sub(&self, delta: f32) -> f32 {
809 self.fetch_sub(delta)
810 }
811
812 #[inline]
813 fn fetch_mul(&self, factor: f32) -> f32 {
814 self.fetch_mul(factor)
815 }
816
817 #[inline]
818 fn fetch_div(&self, divisor: f32) -> f32 {
819 self.fetch_div(divisor)
820 }
821}