qubit_atomic/atomic/atomic_f32.rs
1// =============================================================================
2// Copyright (c) 2025 - 2026 Haixing Hu.
3//
4// SPDX-License-Identifier: Apache-2.0
5//
6// Licensed under the Apache License, Version 2.0.
7// =============================================================================
8
9//! # Atomic 32-bit Floating Point
10//!
11//! Provides an easy-to-use atomic 32-bit floating point type with sensible
12//! default memory orderings. Implemented using bit conversion with AtomicU32.
13
14use std::sync::atomic::AtomicU32;
15use std::sync::atomic::Ordering;
16
17use crate::atomic::atomic_number_ops::AtomicNumberOps;
18use crate::atomic::atomic_ops::AtomicOps;
19
20/// Atomic 32-bit floating point number.
21///
22/// Provides easy-to-use atomic operations with automatic memory ordering
23/// selection. Implemented using `AtomicU32` with bit conversion.
24///
25/// # Memory Ordering Strategy
26///
27/// This type uses the same memory ordering strategy as atomic integers:
28///
29/// - **Read operations** (`load`): Use `Acquire` ordering to ensure visibility
30/// of prior writes from other threads.
31///
32/// - **Write operations** (`store`): Use `Release` ordering to ensure
33/// visibility of prior writes to other threads.
34///
35/// - **Read-Modify-Write operations** (`swap`, `compare_set`): Use `AcqRel`
36/// ordering for full synchronization.
37///
38/// - **CAS-based arithmetic** (`fetch_add`, `fetch_sub`, etc.): Use `AcqRel` on
39/// success and `Acquire` on failure within the CAS loop. The loop ensures
40/// eventual consistency.
41///
42/// # Implementation Details
43///
44/// Since hardware doesn't provide native atomic floating-point operations,
45/// this type is implemented using `AtomicU32` with `f32::to_bits()` and
46/// `f32::from_bits()` conversions. This preserves bit patterns exactly,
47/// including special values like NaN and infinity.
48///
49/// # Features
50///
51/// - Automatic memory ordering selection
52/// - Arithmetic operations via CAS loops
53/// - Inline API over raw-bit atomic storage and CAS loops
54/// - Access to underlying type via `inner()` for advanced use cases
55///
56/// # Limitations
57///
58/// - Arithmetic operations use CAS loops (slower than integer operations)
59/// - CAS comparisons use exact IEEE-754 bit patterns, so different NaN payloads
60/// and `0.0`/`-0.0` are treated as different values
61/// - No max/min operations (complex floating point semantics)
62///
63/// # Example
64///
65/// ```rust
66/// use qubit_atomic::Atomic;
67/// use std::sync::Arc;
68/// use std::thread;
69///
70/// let sum = Arc::new(Atomic::<f32>::new(0.0));
71/// let mut handles = vec![];
72///
73/// for _ in 0..10 {
74/// let sum = sum.clone();
75/// let handle = thread::spawn(move || {
76/// for _ in 0..100 {
77/// sum.fetch_add(0.1);
78/// }
79/// });
80/// handles.push(handle);
81/// }
82///
83/// for handle in handles {
84/// handle.join().unwrap();
85/// }
86///
87/// // Note: Due to floating point precision, result may not be exactly 100.0
88/// let result = sum.load();
89/// assert!((result - 100.0).abs() < 0.01);
90/// ```
91#[repr(transparent)]
92pub struct AtomicF32 {
93 /// Raw-bit atomic storage for the `f32` value.
94 inner: AtomicU32,
95}
96
97impl AtomicF32 {
98 /// Creates a new atomic floating point number.
99 ///
100 /// # Parameters
101 ///
102 /// * `value` - The initial value.
103 ///
104 /// # Returns
105 ///
106 /// An atomic `f32` initialized to `value`.
107 ///
108 /// # Example
109 ///
110 /// ```rust
111 /// use qubit_atomic::Atomic;
112 ///
113 /// let atomic = Atomic::<f32>::new(3.14);
114 /// assert_eq!(atomic.load(), 3.14);
115 /// ```
116 #[inline]
117 pub const fn new(value: f32) -> Self {
118 Self {
119 inner: AtomicU32::new(value.to_bits()),
120 }
121 }
122
123 /// Gets the current value.
124 ///
125 /// # Memory Ordering
126 ///
127 /// Uses `Acquire` ordering on the underlying `AtomicU32`. This ensures
128 /// that all writes from other threads that happened before a `Release`
129 /// store are visible after this load.
130 ///
131 /// # Returns
132 ///
133 /// The current value.
134 ///
135 /// # Example
136 ///
137 /// ```rust
138 /// use qubit_atomic::Atomic;
139 ///
140 /// let atomic = Atomic::<f32>::new(3.14);
141 /// assert_eq!(atomic.load(), 3.14);
142 /// ```
143 #[inline]
144 pub fn load(&self) -> f32 {
145 f32::from_bits(self.inner.load(Ordering::Acquire))
146 }
147
148 /// Sets a new value.
149 ///
150 /// # Memory Ordering
151 ///
152 /// Uses `Release` ordering on the underlying `AtomicU32`. This ensures
153 /// that all prior writes in this thread are visible to other threads
154 /// that perform an `Acquire` load.
155 ///
156 /// # Parameters
157 ///
158 /// * `value` - The new value to set.
159 ///
160 /// # Example
161 ///
162 /// ```rust
163 /// use qubit_atomic::Atomic;
164 ///
165 /// let atomic = Atomic::<f32>::new(0.0);
166 /// atomic.store(3.14);
167 /// assert_eq!(atomic.load(), 3.14);
168 /// ```
169 #[inline]
170 pub fn store(&self, value: f32) {
171 self.inner.store(value.to_bits(), Ordering::Release);
172 }
173
174 /// Swaps the current value with a new value, returning the old value.
175 ///
176 /// # Memory Ordering
177 ///
178 /// Uses `AcqRel` ordering on the underlying `AtomicU32`. This provides
179 /// full synchronization for this read-modify-write operation.
180 ///
181 /// # Parameters
182 ///
183 /// * `value` - The new value to swap in.
184 ///
185 /// # Returns
186 ///
187 /// The old value.
188 ///
189 /// # Example
190 ///
191 /// ```rust
192 /// use qubit_atomic::Atomic;
193 ///
194 /// let atomic = Atomic::<f32>::new(1.0);
195 /// let old = atomic.swap(2.0);
196 /// assert_eq!(old, 1.0);
197 /// assert_eq!(atomic.load(), 2.0);
198 /// ```
199 #[inline]
200 pub fn swap(&self, value: f32) -> f32 {
201 f32::from_bits(self.inner.swap(value.to_bits(), Ordering::AcqRel))
202 }
203
204 /// Compares and sets the value atomically.
205 ///
206 /// If the current value equals `current`, sets it to `new` and returns
207 /// `Ok(())`. Otherwise, returns `Err(actual)` where `actual` is the
208 /// current value.
209 ///
210 /// Comparison uses the exact raw bit pattern produced by
211 /// [`f32::to_bits`], not [`PartialEq`].
212 ///
213 /// # Memory Ordering
214 ///
215 /// - **Success**: Uses `AcqRel` ordering on the underlying `AtomicU32` to
216 /// ensure full synchronization when the exchange succeeds.
217 /// - **Failure**: Uses `Acquire` ordering to observe the actual value
218 /// written by another thread.
219 ///
220 /// # Parameters
221 ///
222 /// * `current` - The expected current value.
223 /// * `new` - The new value to set if current matches.
224 ///
225 /// # Returns
226 ///
227 /// `Ok(())` when the value was replaced.
228 ///
229 /// # Errors
230 ///
231 /// Returns `Err(actual)` with the observed value when the raw-bit
232 /// comparison fails. In that case, `new` is not stored.
233 ///
234 /// # Warning
235 ///
236 /// NaN values compare by raw bits. A stored NaN and `current` must have
237 /// the same payload bits for the CAS to succeed.
238 ///
239 /// # Example
240 ///
241 /// ```rust
242 /// use qubit_atomic::Atomic;
243 ///
244 /// let atomic = Atomic::<f32>::new(1.0);
245 /// assert!(atomic.compare_set(1.0, 2.0).is_ok());
246 /// assert_eq!(atomic.load(), 2.0);
247 /// ```
248 #[inline]
249 pub fn compare_set(&self, current: f32, new: f32) -> Result<(), f32> {
250 self.inner
251 .compare_exchange(
252 current.to_bits(),
253 new.to_bits(),
254 Ordering::AcqRel,
255 Ordering::Acquire,
256 )
257 .map(|_| ())
258 .map_err(f32::from_bits)
259 }
260
261 /// Weak version of compare-and-set.
262 ///
263 /// May spuriously fail even when the comparison succeeds. Should be used
264 /// in a loop.
265 ///
266 /// Uses `AcqRel` ordering on success and `Acquire` ordering on failure.
267 /// Comparison uses the exact raw bit pattern produced by
268 /// [`f32::to_bits`].
269 ///
270 /// # Parameters
271 ///
272 /// * `current` - The expected current value.
273 /// * `new` - The new value to set if current matches.
274 ///
275 /// # Returns
276 ///
277 /// `Ok(())` when the value was replaced.
278 ///
279 /// # Errors
280 ///
281 /// Returns `Err(actual)` with the observed value when the raw-bit
282 /// comparison fails, including possible spurious failures. In that case,
283 /// `new` is not stored.
284 ///
285 /// # Example
286 ///
287 /// ```rust
288 /// use qubit_atomic::Atomic;
289 ///
290 /// let atomic = Atomic::<f32>::new(1.0);
291 /// let mut current = atomic.load();
292 /// loop {
293 /// match atomic.compare_set_weak(current, current + 1.0) {
294 /// Ok(_) => break,
295 /// Err(actual) => current = actual,
296 /// }
297 /// }
298 /// assert_eq!(atomic.load(), 2.0);
299 /// ```
300 #[inline]
301 pub fn compare_set_weak(&self, current: f32, new: f32) -> Result<(), f32> {
302 self.inner
303 .compare_exchange_weak(
304 current.to_bits(),
305 new.to_bits(),
306 Ordering::AcqRel,
307 Ordering::Acquire,
308 )
309 .map(|_| ())
310 .map_err(f32::from_bits)
311 }
312
313 /// Compares and exchanges the value atomically, returning the previous
314 /// value.
315 ///
316 /// If the current value equals `current`, sets it to `new` and returns
317 /// the old value. Otherwise, returns the actual current value.
318 ///
319 /// Uses `AcqRel` ordering on success and `Acquire` ordering on failure.
320 ///
321 /// # Parameters
322 ///
323 /// * `current` - The expected current value.
324 /// * `new` - The new value to set if current matches.
325 ///
326 /// # Returns
327 ///
328 /// The value observed before the operation completed. If the returned
329 /// value has the same raw bits as `current`, the exchange succeeded;
330 /// otherwise it is the actual value that prevented the exchange.
331 ///
332 /// # Example
333 ///
334 /// ```rust
335 /// use qubit_atomic::Atomic;
336 ///
337 /// let atomic = Atomic::<f32>::new(1.0);
338 /// let prev = atomic.compare_and_exchange(1.0, 2.0);
339 /// assert_eq!(prev, 1.0);
340 /// assert_eq!(atomic.load(), 2.0);
341 /// ```
342 #[inline]
343 pub fn compare_and_exchange(&self, current: f32, new: f32) -> f32 {
344 match self.inner.compare_exchange(
345 current.to_bits(),
346 new.to_bits(),
347 Ordering::AcqRel,
348 Ordering::Acquire,
349 ) {
350 Ok(prev_bits) => f32::from_bits(prev_bits),
351 Err(actual_bits) => f32::from_bits(actual_bits),
352 }
353 }
354
355 /// Weak version of compare-and-exchange.
356 ///
357 /// May spuriously fail even when the comparison succeeds. Should be used
358 /// in a loop.
359 ///
360 /// Uses `AcqRel` ordering on success and `Acquire` ordering on failure.
361 ///
362 /// # Parameters
363 ///
364 /// * `current` - The expected current value.
365 /// * `new` - The new value to set if current matches.
366 ///
367 /// # Returns
368 ///
369 /// `Ok(previous)` when the value was replaced, or `Err(actual)` when the
370 /// comparison failed, including possible spurious failure. Values preserve
371 /// their exact raw bit patterns.
372 ///
373 /// # Example
374 ///
375 /// ```rust
376 /// use qubit_atomic::Atomic;
377 ///
378 /// let atomic = Atomic::<f32>::new(1.0);
379 /// let mut current = atomic.load();
380 /// loop {
381 /// match atomic.compare_and_exchange_weak(current, current + 1.0) {
382 /// Ok(_) => break,
383 /// Err(actual) => current = actual,
384 /// }
385 /// }
386 /// assert_eq!(atomic.load(), 2.0);
387 /// ```
388 #[inline]
389 pub fn compare_and_exchange_weak(
390 &self,
391 current: f32,
392 new: f32,
393 ) -> 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
665 /// value.
666 ///
667 /// Internally uses a CAS loop until the update succeeds or the closure
668 /// rejects the current value by returning `None`.
669 ///
670 /// # Parameters
671 ///
672 /// * `f` - A function that takes the current value and returns the new
673 /// value, or `None` to leave the value unchanged.
674 ///
675 /// # Returns
676 ///
677 /// `Some(new_value)` when the update succeeds, or `None` when `f` rejects
678 /// the observed current value.
679 ///
680 /// The closure may be called more than once when concurrent updates cause
681 /// CAS retries.
682 ///
683 /// # Example
684 ///
685 /// ```rust
686 /// use qubit_atomic::Atomic;
687 ///
688 /// let atomic = Atomic::<f32>::new(1.5);
689 /// assert_eq!(
690 /// atomic.try_update_and_get(|x| (x > 0.0).then_some(x * 2.0)),
691 /// Some(3.0),
692 /// );
693 /// assert_eq!(atomic.load(), 3.0);
694 /// assert_eq!(
695 /// atomic.try_update_and_get(|x| (x < 0.0).then_some(x * 2.0)),
696 /// None,
697 /// );
698 /// assert_eq!(atomic.load(), 3.0);
699 /// ```
700 #[inline]
701 pub fn try_update_and_get<F>(&self, mut f: F) -> Option<f32>
702 where
703 F: FnMut(f32) -> Option<f32>,
704 {
705 let mut current = self.load();
706 loop {
707 let new = f(current)?;
708 match self.compare_set_weak(current, new) {
709 Ok(_) => return Some(new),
710 Err(actual) => current = actual,
711 }
712 }
713 }
714
715 /// Gets a reference to the underlying standard library atomic type.
716 ///
717 /// This allows direct access to the standard library's atomic operations
718 /// for advanced use cases that require fine-grained control over memory
719 /// ordering.
720 ///
721 /// # Memory Ordering
722 ///
723 /// When using the returned reference, you have full control over memory
724 /// ordering. Remember to use `f32::to_bits()` and `f32::from_bits()` for
725 /// conversions.
726 ///
727 /// # Returns
728 ///
729 /// A reference to the underlying `std::sync::atomic::AtomicU32`.
730 ///
731 /// # Example
732 ///
733 /// ```rust
734 /// use qubit_atomic::Atomic;
735 /// use std::sync::atomic::Ordering;
736 ///
737 /// let atomic = Atomic::<f32>::new(0.0);
738 /// atomic.inner().store(3.14_f32.to_bits(), Ordering::Relaxed);
739 /// let bits = atomic.inner().load(Ordering::Relaxed);
740 /// assert_eq!(f32::from_bits(bits), 3.14);
741 /// ```
742 #[inline]
743 pub fn inner(&self) -> &AtomicU32 {
744 &self.inner
745 }
746}
747
748impl AtomicOps for AtomicF32 {
749 type Value = f32;
750
751 #[inline]
752 fn load(&self) -> f32 {
753 self.load()
754 }
755
756 #[inline]
757 fn store(&self, value: f32) {
758 self.store(value);
759 }
760
761 #[inline]
762 fn swap(&self, value: f32) -> f32 {
763 self.swap(value)
764 }
765
766 #[inline]
767 fn compare_set(&self, current: f32, new: f32) -> Result<(), f32> {
768 self.compare_set(current, new)
769 }
770
771 #[inline]
772 fn compare_set_weak(&self, current: f32, new: f32) -> Result<(), f32> {
773 self.compare_set_weak(current, new)
774 }
775
776 #[inline]
777 fn compare_exchange(&self, current: f32, new: f32) -> f32 {
778 self.compare_and_exchange(current, new)
779 }
780
781 #[inline]
782 fn compare_exchange_weak(
783 &self,
784 current: f32,
785 new: f32,
786 ) -> Result<f32, f32> {
787 self.compare_and_exchange_weak(current, new)
788 }
789
790 #[inline]
791 fn fetch_update<F>(&self, f: F) -> f32
792 where
793 F: FnMut(f32) -> f32,
794 {
795 self.fetch_update(f)
796 }
797
798 #[inline]
799 fn update_and_get<F>(&self, f: F) -> f32
800 where
801 F: FnMut(f32) -> f32,
802 {
803 self.update_and_get(f)
804 }
805
806 #[inline]
807 fn try_update<F>(&self, f: F) -> Option<f32>
808 where
809 F: FnMut(f32) -> Option<f32>,
810 {
811 self.try_update(f)
812 }
813
814 #[inline]
815 fn try_update_and_get<F>(&self, f: F) -> Option<f32>
816 where
817 F: FnMut(f32) -> Option<f32>,
818 {
819 self.try_update_and_get(f)
820 }
821}
822
823impl AtomicNumberOps for AtomicF32 {
824 #[inline]
825 fn fetch_add(&self, delta: f32) -> f32 {
826 self.fetch_add(delta)
827 }
828
829 #[inline]
830 fn fetch_sub(&self, delta: f32) -> f32 {
831 self.fetch_sub(delta)
832 }
833
834 #[inline]
835 fn fetch_mul(&self, factor: f32) -> f32 {
836 self.fetch_mul(factor)
837 }
838
839 #[inline]
840 fn fetch_div(&self, divisor: f32) -> f32 {
841 self.fetch_div(divisor)
842 }
843}