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(
256 current.to_bits(),
257 new.to_bits(),
258 Ordering::AcqRel,
259 Ordering::Acquire,
260 )
261 .map(|_| ())
262 .map_err(f32::from_bits)
263 }
264
265 /// Weak version of compare-and-set.
266 ///
267 /// May spuriously fail even when the comparison succeeds. Should be used
268 /// in a loop.
269 ///
270 /// Uses `AcqRel` ordering on success and `Acquire` ordering on failure.
271 /// Comparison uses the exact raw bit pattern produced by
272 /// [`f32::to_bits`].
273 ///
274 /// # Parameters
275 ///
276 /// * `current` - The expected current value.
277 /// * `new` - The new value to set if current matches.
278 ///
279 /// # Returns
280 ///
281 /// `Ok(())` when the value was replaced.
282 ///
283 /// # Errors
284 ///
285 /// Returns `Err(actual)` with the observed value when the raw-bit
286 /// comparison fails, including possible spurious failures. In that case,
287 /// `new` is not stored.
288 ///
289 /// # Example
290 ///
291 /// ```rust
292 /// use qubit_atomic::Atomic;
293 ///
294 /// let atomic = Atomic::<f32>::new(1.0);
295 /// let mut current = atomic.load();
296 /// loop {
297 /// match atomic.compare_set_weak(current, current + 1.0) {
298 /// Ok(_) => break,
299 /// Err(actual) => current = actual,
300 /// }
301 /// }
302 /// assert_eq!(atomic.load(), 2.0);
303 /// ```
304 #[inline]
305 pub fn compare_set_weak(&self, current: f32, new: f32) -> Result<(), f32> {
306 self.inner
307 .compare_exchange_weak(
308 current.to_bits(),
309 new.to_bits(),
310 Ordering::AcqRel,
311 Ordering::Acquire,
312 )
313 .map(|_| ())
314 .map_err(f32::from_bits)
315 }
316
317 /// Compares and exchanges the value atomically, returning the previous
318 /// value.
319 ///
320 /// If the current value equals `current`, sets it to `new` and returns
321 /// the old value. Otherwise, returns the actual current value.
322 ///
323 /// Uses `AcqRel` ordering on success and `Acquire` ordering on failure.
324 ///
325 /// # Parameters
326 ///
327 /// * `current` - The expected current value.
328 /// * `new` - The new value to set if current matches.
329 ///
330 /// # Returns
331 ///
332 /// The value observed before the operation completed. If the returned
333 /// value has the same raw bits as `current`, the exchange succeeded;
334 /// otherwise it is the actual value that prevented the exchange.
335 ///
336 /// # Example
337 ///
338 /// ```rust
339 /// use qubit_atomic::Atomic;
340 ///
341 /// let atomic = Atomic::<f32>::new(1.0);
342 /// let prev = atomic.compare_and_exchange(1.0, 2.0);
343 /// assert_eq!(prev, 1.0);
344 /// assert_eq!(atomic.load(), 2.0);
345 /// ```
346 #[inline]
347 pub fn compare_and_exchange(&self, current: f32, new: f32) -> f32 {
348 match self.inner.compare_exchange(
349 current.to_bits(),
350 new.to_bits(),
351 Ordering::AcqRel,
352 Ordering::Acquire,
353 ) {
354 Ok(prev_bits) => f32::from_bits(prev_bits),
355 Err(actual_bits) => f32::from_bits(actual_bits),
356 }
357 }
358
359 /// Weak version of compare-and-exchange.
360 ///
361 /// May spuriously fail even when the comparison succeeds. Should be used
362 /// in a loop.
363 ///
364 /// Uses `AcqRel` ordering on success and `Acquire` ordering on failure.
365 ///
366 /// # Parameters
367 ///
368 /// * `current` - The expected current value.
369 /// * `new` - The new value to set if current matches.
370 ///
371 /// # Returns
372 ///
373 /// `Ok(previous)` when the value was replaced, or `Err(actual)` when the
374 /// comparison failed, including possible spurious failure. Values preserve
375 /// their exact raw bit patterns.
376 ///
377 /// # Example
378 ///
379 /// ```rust
380 /// use qubit_atomic::Atomic;
381 ///
382 /// let atomic = Atomic::<f32>::new(1.0);
383 /// let mut current = atomic.load();
384 /// loop {
385 /// match atomic.compare_and_exchange_weak(current, current + 1.0) {
386 /// Ok(_) => break,
387 /// Err(actual) => current = actual,
388 /// }
389 /// }
390 /// assert_eq!(atomic.load(), 2.0);
391 /// ```
392 #[inline]
393 pub fn compare_and_exchange_weak(&self, current: f32, new: f32) -> Result<f32, f32> {
394 self.inner
395 .compare_exchange_weak(
396 current.to_bits(),
397 new.to_bits(),
398 Ordering::AcqRel,
399 Ordering::Acquire,
400 )
401 .map(f32::from_bits)
402 .map_err(f32::from_bits)
403 }
404
405 /// Atomically adds a value, returning the old value.
406 ///
407 /// # Memory Ordering
408 ///
409 /// Internally uses a CAS loop with `compare_set_weak`, which uses
410 /// `AcqRel` on success and `Acquire` on failure. The loop ensures
411 /// eventual consistency even under high contention.
412 ///
413 /// # Performance
414 ///
415 /// May be slow in high-contention scenarios due to the CAS loop.
416 /// Consider using atomic integers if performance is critical.
417 ///
418 /// # Parameters
419 ///
420 /// * `delta` - The value to add.
421 ///
422 /// # Returns
423 ///
424 /// The old value before adding.
425 ///
426 /// # Example
427 ///
428 /// ```rust
429 /// use qubit_atomic::Atomic;
430 ///
431 /// let atomic = Atomic::<f32>::new(10.0);
432 /// let old = atomic.fetch_add(5.5);
433 /// assert_eq!(old, 10.0);
434 /// assert_eq!(atomic.load(), 15.5);
435 /// ```
436 #[inline]
437 pub fn fetch_add(&self, delta: f32) -> f32 {
438 self.fetch_update(|current| current + delta)
439 }
440
441 /// Atomically subtracts a value, returning the old value.
442 ///
443 /// # Memory Ordering
444 ///
445 /// Internally uses a CAS loop with `compare_set_weak`, which uses
446 /// `AcqRel` on success and `Acquire` on failure. The loop ensures
447 /// eventual consistency even under high contention.
448 ///
449 /// # Parameters
450 ///
451 /// * `delta` - The value to subtract.
452 ///
453 /// # Returns
454 ///
455 /// The old value before subtracting.
456 ///
457 /// # Example
458 ///
459 /// ```rust
460 /// use qubit_atomic::Atomic;
461 ///
462 /// let atomic = Atomic::<f32>::new(10.0);
463 /// let old = atomic.fetch_sub(3.5);
464 /// assert_eq!(old, 10.0);
465 /// assert_eq!(atomic.load(), 6.5);
466 /// ```
467 #[inline]
468 pub fn fetch_sub(&self, delta: f32) -> f32 {
469 self.fetch_update(|current| current - delta)
470 }
471
472 /// Atomically multiplies by a factor, returning the old value.
473 ///
474 /// # Memory Ordering
475 ///
476 /// Internally uses a CAS loop with `compare_set_weak`, which uses
477 /// `AcqRel` on success and `Acquire` on failure. The loop ensures
478 /// eventual consistency even under high contention.
479 ///
480 /// # Parameters
481 ///
482 /// * `factor` - The factor to multiply by.
483 ///
484 /// # Returns
485 ///
486 /// The old value before multiplying.
487 ///
488 /// # Example
489 ///
490 /// ```rust
491 /// use qubit_atomic::Atomic;
492 ///
493 /// let atomic = Atomic::<f32>::new(10.0);
494 /// let old = atomic.fetch_mul(2.5);
495 /// assert_eq!(old, 10.0);
496 /// assert_eq!(atomic.load(), 25.0);
497 /// ```
498 #[inline]
499 pub fn fetch_mul(&self, factor: f32) -> f32 {
500 self.fetch_update(|current| current * factor)
501 }
502
503 /// Atomically divides by a divisor, returning the old value.
504 ///
505 /// # Memory Ordering
506 ///
507 /// Internally uses a CAS loop with `compare_set_weak`, which uses
508 /// `AcqRel` on success and `Acquire` on failure. The loop ensures
509 /// eventual consistency even under high contention.
510 ///
511 /// # Parameters
512 ///
513 /// * `divisor` - The divisor to divide by.
514 ///
515 /// # Returns
516 ///
517 /// The old value before dividing.
518 ///
519 /// # Example
520 ///
521 /// ```rust
522 /// use qubit_atomic::Atomic;
523 ///
524 /// let atomic = Atomic::<f32>::new(10.0);
525 /// let old = atomic.fetch_div(2.0);
526 /// assert_eq!(old, 10.0);
527 /// assert_eq!(atomic.load(), 5.0);
528 /// ```
529 #[inline]
530 pub fn fetch_div(&self, divisor: f32) -> f32 {
531 self.fetch_update(|current| current / divisor)
532 }
533
534 /// Updates the value using a function, returning the old value.
535 ///
536 /// # Memory Ordering
537 ///
538 /// Internally uses a CAS loop with `compare_set_weak`, which uses
539 /// `AcqRel` on success and `Acquire` on failure. The loop ensures
540 /// eventual consistency even under high contention.
541 ///
542 /// # Parameters
543 ///
544 /// * `f` - A function that takes the current value and returns the new
545 /// value.
546 ///
547 /// # Returns
548 ///
549 /// The old value before the update.
550 ///
551 /// The closure may be called more than once when concurrent updates cause
552 /// CAS retries.
553 ///
554 /// # Example
555 ///
556 /// ```rust
557 /// use qubit_atomic::Atomic;
558 ///
559 /// let atomic = Atomic::<f32>::new(10.0);
560 /// let old = atomic.fetch_update(|x| x * 2.0);
561 /// assert_eq!(old, 10.0);
562 /// assert_eq!(atomic.load(), 20.0);
563 /// ```
564 #[inline]
565 pub fn fetch_update<F>(&self, mut f: F) -> f32
566 where
567 F: FnMut(f32) -> f32,
568 {
569 let mut current = self.load();
570 loop {
571 let new = f(current);
572 match self.compare_set_weak(current, new) {
573 Ok(_) => return current,
574 Err(actual) => current = actual,
575 }
576 }
577 }
578
579 /// Updates the value using a function, returning the new value.
580 ///
581 /// Internally uses a CAS loop until the update succeeds.
582 ///
583 /// # Parameters
584 ///
585 /// * `f` - A function that takes the current value and returns the new
586 /// value.
587 ///
588 /// # Returns
589 ///
590 /// The value committed by the successful update.
591 ///
592 /// The closure may be called more than once when concurrent updates cause
593 /// CAS retries.
594 ///
595 /// # Example
596 ///
597 /// ```rust
598 /// use qubit_atomic::Atomic;
599 ///
600 /// let atomic = Atomic::<f32>::new(10.0);
601 /// let new = atomic.update_and_get(|x| x * 2.0);
602 /// assert_eq!(new, 20.0);
603 /// assert_eq!(atomic.load(), 20.0);
604 /// ```
605 #[inline]
606 pub fn update_and_get<F>(&self, mut f: F) -> f32
607 where
608 F: FnMut(f32) -> f32,
609 {
610 let mut current = self.load();
611 loop {
612 let new = f(current);
613 match self.compare_set_weak(current, new) {
614 Ok(_) => return new,
615 Err(actual) => current = actual,
616 }
617 }
618 }
619
620 /// Conditionally updates the value using a function.
621 ///
622 /// Internally uses a CAS loop until the update succeeds or the closure
623 /// rejects the current value by returning `None`.
624 ///
625 /// # Parameters
626 ///
627 /// * `f` - A function that takes the current value and returns the new
628 /// value, or `None` to leave the value unchanged.
629 ///
630 /// # Returns
631 ///
632 /// `Some(old_value)` when the update succeeds, or `None` when `f` rejects
633 /// the observed current value.
634 ///
635 /// The closure may be called more than once when concurrent updates cause
636 /// CAS retries.
637 ///
638 /// # Example
639 ///
640 /// ```rust
641 /// use qubit_atomic::Atomic;
642 ///
643 /// let atomic = Atomic::<f32>::new(1.5);
644 /// assert_eq!(atomic.try_update(|x| (x > 0.0).then_some(x * 2.0)), Some(1.5));
645 /// assert_eq!(atomic.load(), 3.0);
646 /// assert_eq!(atomic.try_update(|x| (x < 0.0).then_some(x * 2.0)), None);
647 /// assert_eq!(atomic.load(), 3.0);
648 /// ```
649 #[inline]
650 pub fn try_update<F>(&self, mut f: F) -> Option<f32>
651 where
652 F: FnMut(f32) -> Option<f32>,
653 {
654 let mut current = self.load();
655 loop {
656 let new = f(current)?;
657 match self.compare_set_weak(current, new) {
658 Ok(_) => return Some(current),
659 Err(actual) => current = actual,
660 }
661 }
662 }
663
664 /// Conditionally updates the value using a function, returning the new value.
665 ///
666 /// Internally uses a CAS loop until the update succeeds or the closure
667 /// rejects the current value by returning `None`.
668 ///
669 /// # Parameters
670 ///
671 /// * `f` - A function that takes the current value and returns the new
672 /// value, or `None` to leave the value unchanged.
673 ///
674 /// # Returns
675 ///
676 /// `Some(new_value)` when the update succeeds, or `None` when `f` rejects
677 /// the observed current value.
678 ///
679 /// The closure may be called more than once when concurrent updates cause
680 /// CAS retries.
681 ///
682 /// # Example
683 ///
684 /// ```rust
685 /// use qubit_atomic::Atomic;
686 ///
687 /// let atomic = Atomic::<f32>::new(1.5);
688 /// assert_eq!(
689 /// atomic.try_update_and_get(|x| (x > 0.0).then_some(x * 2.0)),
690 /// Some(3.0),
691 /// );
692 /// assert_eq!(atomic.load(), 3.0);
693 /// assert_eq!(
694 /// atomic.try_update_and_get(|x| (x < 0.0).then_some(x * 2.0)),
695 /// None,
696 /// );
697 /// assert_eq!(atomic.load(), 3.0);
698 /// ```
699 #[inline]
700 pub fn try_update_and_get<F>(&self, mut f: F) -> Option<f32>
701 where
702 F: FnMut(f32) -> Option<f32>,
703 {
704 let mut current = self.load();
705 loop {
706 let new = f(current)?;
707 match self.compare_set_weak(current, new) {
708 Ok(_) => return Some(new),
709 Err(actual) => current = actual,
710 }
711 }
712 }
713
714 /// Gets a reference to the underlying standard library atomic type.
715 ///
716 /// This allows direct access to the standard library's atomic operations
717 /// for advanced use cases that require fine-grained control over memory
718 /// ordering.
719 ///
720 /// # Memory Ordering
721 ///
722 /// When using the returned reference, you have full control over memory
723 /// ordering. Remember to use `f32::to_bits()` and `f32::from_bits()` for
724 /// conversions.
725 ///
726 /// # Returns
727 ///
728 /// A reference to the underlying `std::sync::atomic::AtomicU32`.
729 ///
730 /// # Example
731 ///
732 /// ```rust
733 /// use qubit_atomic::Atomic;
734 /// use std::sync::atomic::Ordering;
735 ///
736 /// let atomic = Atomic::<f32>::new(0.0);
737 /// atomic.inner().store(3.14_f32.to_bits(), Ordering::Relaxed);
738 /// let bits = atomic.inner().load(Ordering::Relaxed);
739 /// assert_eq!(f32::from_bits(bits), 3.14);
740 /// ```
741 #[inline]
742 pub fn inner(&self) -> &AtomicU32 {
743 &self.inner
744 }
745}
746
747impl AtomicOps for AtomicF32 {
748 type Value = f32;
749
750 #[inline]
751 fn load(&self) -> f32 {
752 self.load()
753 }
754
755 #[inline]
756 fn store(&self, value: f32) {
757 self.store(value);
758 }
759
760 #[inline]
761 fn swap(&self, value: f32) -> f32 {
762 self.swap(value)
763 }
764
765 #[inline]
766 fn compare_set(&self, current: f32, new: f32) -> Result<(), f32> {
767 self.compare_set(current, new)
768 }
769
770 #[inline]
771 fn compare_set_weak(&self, current: f32, new: f32) -> Result<(), f32> {
772 self.compare_set_weak(current, new)
773 }
774
775 #[inline]
776 fn compare_exchange(&self, current: f32, new: f32) -> f32 {
777 self.compare_and_exchange(current, new)
778 }
779
780 #[inline]
781 fn compare_exchange_weak(&self, current: f32, new: f32) -> Result<f32, f32> {
782 self.compare_and_exchange_weak(current, new)
783 }
784
785 #[inline]
786 fn fetch_update<F>(&self, f: F) -> f32
787 where
788 F: FnMut(f32) -> f32,
789 {
790 self.fetch_update(f)
791 }
792
793 #[inline]
794 fn update_and_get<F>(&self, f: F) -> f32
795 where
796 F: FnMut(f32) -> f32,
797 {
798 self.update_and_get(f)
799 }
800
801 #[inline]
802 fn try_update<F>(&self, f: F) -> Option<f32>
803 where
804 F: FnMut(f32) -> Option<f32>,
805 {
806 self.try_update(f)
807 }
808
809 #[inline]
810 fn try_update_and_get<F>(&self, f: F) -> Option<f32>
811 where
812 F: FnMut(f32) -> Option<f32>,
813 {
814 self.try_update_and_get(f)
815 }
816}
817
818impl AtomicNumberOps for AtomicF32 {
819 #[inline]
820 fn fetch_add(&self, delta: f32) -> f32 {
821 self.fetch_add(delta)
822 }
823
824 #[inline]
825 fn fetch_sub(&self, delta: f32) -> f32 {
826 self.fetch_sub(delta)
827 }
828
829 #[inline]
830 fn fetch_mul(&self, factor: f32) -> f32 {
831 self.fetch_mul(factor)
832 }
833
834 #[inline]
835 fn fetch_div(&self, divisor: f32) -> f32 {
836 self.fetch_div(divisor)
837 }
838}