Skip to main content

core/sync/
atomic.rs

1//! Atomic types
2//!
3//! Atomic types provide primitive shared-memory communication between
4//! threads, and are the building blocks of other concurrent
5//! types.
6//!
7//! This module defines atomic versions of a select number of primitive
8//! types, including [`AtomicBool`], [`AtomicIsize`], [`AtomicUsize`],
9//! [`AtomicI8`], [`AtomicU16`], etc.
10//! Atomic types present operations that, when used correctly, synchronize
11//! updates between threads.
12//!
13//! Atomic variables are safe to share between threads (they implement [`Sync`])
14//! but they do not themselves provide the mechanism for sharing and follow the
15//! [threading model](../../../std/thread/index.html#the-threading-model) of Rust.
16//! The most common way to share an atomic variable is to put it into an [`Arc`][arc] (an
17//! atomically-reference-counted shared pointer).
18//!
19//! [arc]: ../../../std/sync/struct.Arc.html
20//!
21//! Atomic types may be stored in static variables, initialized using
22//! the constant initializers like [`AtomicBool::new`]. Atomic statics
23//! are often used for lazy global initialization.
24//!
25//! ## Memory model for atomic accesses
26//!
27//! Rust atomics currently follow the same rules as [C++20 atomics][cpp], specifically the rules
28//! from the [`intro.races`][cpp-intro.races] section, without the "consume" memory ordering. Since
29//! C++ uses an object-based memory model whereas Rust is access-based, a bit of translation work
30//! has to be done to apply the C++ rules to Rust: whenever C++ talks about "the value of an
31//! object", we understand that to mean the resulting bytes obtained when doing a read. When the C++
32//! standard talks about "the value of an atomic object", this refers to the result of doing an
33//! atomic load (via the operations provided in this module). A "modification of an atomic object"
34//! refers to an atomic store.
35//!
36//! The end result is *almost* equivalent to saying that creating a *shared reference* to one of the
37//! Rust atomic types corresponds to creating an `atomic_ref` in C++, with the `atomic_ref` being
38//! destroyed when the lifetime of the shared reference ends. The main difference is that Rust
39//! permits concurrent atomic and non-atomic reads to the same memory as those cause no issue in the
40//! C++ memory model, they are just forbidden in C++ because memory is partitioned into "atomic
41//! objects" and "non-atomic objects" (with `atomic_ref` temporarily converting a non-atomic object
42//! into an atomic object).
43//!
44//! The most important aspect of this model is that *data races* are undefined behavior. A data race
45//! is defined as conflicting non-synchronized accesses where at least one of the accesses is
46//! non-atomic. Here, accesses are *conflicting* if they affect overlapping regions of memory and at
47//! least one of them is a write. (A `compare_exchange` or `compare_exchange_weak` that does not
48//! succeed is not considered a write.) They are *non-synchronized* if neither of them
49//! *happens-before* the other, according to the happens-before order of the memory model.
50//!
51//! The other possible cause of undefined behavior in the memory model are mixed-size accesses: Rust
52//! inherits the C++ limitation that non-synchronized conflicting atomic accesses may not partially
53//! overlap. In other words, every pair of non-synchronized atomic accesses must be either disjoint,
54//! access the exact same memory (including using the same access size), or both be reads.
55//!
56//! Each atomic access takes an [`Ordering`] which defines how the operation interacts with the
57//! happens-before order. These orderings behave the same as the corresponding [C++20 atomic
58//! orderings][cpp_memory_order]. For more information, see the [nomicon].
59//!
60//! [cpp]: https://en.cppreference.com/w/cpp/atomic
61//! [cpp-intro.races]: https://timsong-cpp.github.io/cppwp/n4868/intro.multithread#intro.races
62//! [cpp_memory_order]: https://en.cppreference.com/w/cpp/atomic/memory_order
63//! [nomicon]: ../../../nomicon/atomics.html
64//!
65//! ```rust,no_run undefined_behavior
66//! use std::sync::atomic::{AtomicU16, AtomicU8, Ordering};
67//! use std::mem::transmute;
68//! use std::thread;
69//!
70//! let atomic = AtomicU16::new(0);
71//!
72//! thread::scope(|s| {
73//!     // This is UB: conflicting non-synchronized accesses, at least one of which is non-atomic.
74//!     s.spawn(|| atomic.store(1, Ordering::Relaxed)); // atomic store
75//!     s.spawn(|| unsafe { atomic.as_ptr().write(2) }); // non-atomic write
76//! });
77//!
78//! thread::scope(|s| {
79//!     // This is fine: the accesses do not conflict (as none of them performs any modification).
80//!     // In C++ this would be disallowed since creating an `atomic_ref` precludes
81//!     // further non-atomic accesses, but Rust does not have that limitation.
82//!     s.spawn(|| atomic.load(Ordering::Relaxed)); // atomic load
83//!     s.spawn(|| unsafe { atomic.as_ptr().read() }); // non-atomic read
84//! });
85//!
86//! thread::scope(|s| {
87//!     // This is fine: `join` synchronizes the code in a way such that the atomic
88//!     // store happens-before the non-atomic write.
89//!     let handle = s.spawn(|| atomic.store(1, Ordering::Relaxed)); // atomic store
90//!     handle.join().expect("thread won't panic"); // synchronize
91//!     s.spawn(|| unsafe { atomic.as_ptr().write(2) }); // non-atomic write
92//! });
93//!
94//! thread::scope(|s| {
95//!     // This is UB: non-synchronized conflicting differently-sized atomic accesses.
96//!     s.spawn(|| atomic.store(1, Ordering::Relaxed));
97//!     s.spawn(|| unsafe {
98//!         let differently_sized = transmute::<&AtomicU16, &AtomicU8>(&atomic);
99//!         differently_sized.store(2, Ordering::Relaxed);
100//!     });
101//! });
102//!
103//! thread::scope(|s| {
104//!     // This is fine: `join` synchronizes the code in a way such that
105//!     // the 1-byte store happens-before the 2-byte store.
106//!     let handle = s.spawn(|| atomic.store(1, Ordering::Relaxed));
107//!     handle.join().expect("thread won't panic");
108//!     s.spawn(|| unsafe {
109//!         let differently_sized = transmute::<&AtomicU16, &AtomicU8>(&atomic);
110//!         differently_sized.store(2, Ordering::Relaxed);
111//!     });
112//! });
113//! ```
114//!
115//! # Portability
116//!
117//! All atomic types in this module are guaranteed to be [lock-free] if they're
118//! available. This means they don't internally acquire a global mutex. Atomic
119//! types and operations are not guaranteed to be wait-free. This means that
120//! operations like `fetch_or` may be implemented with a compare-and-swap loop.
121//!
122//! Atomic operations may be implemented at the instruction layer with
123//! larger-size atomics. For example some platforms use 4-byte atomic
124//! instructions to implement `AtomicI8`. Note that this emulation should not
125//! have an impact on correctness of code, it's just something to be aware of.
126//!
127//! The atomic types in this module might not be available on all platforms. The
128//! atomic types here are all widely available, however, and can generally be
129//! relied upon existing. Some notable exceptions are:
130//!
131//! * PowerPC and MIPS platforms with 32-bit pointers do not have `AtomicU64` or
132//!   `AtomicI64` types.
133//! * Legacy ARM platforms like ARMv4T and ARMv5TE have very limited hardware
134//!   support for atomics. The bare-metal targets disable this module
135//!   entirely, but the Linux targets [use the kernel] to assist (which comes
136//!   with a performance penalty). It's not until ARMv6K onwards that ARM CPUs
137//!   have support for load/store and Compare and Swap (CAS) atomics in hardware.
138//! * ARMv6-M and ARMv8-M baseline targets (`thumbv6m-*` and
139//!   `thumbv8m.base-*`) only provide `load` and `store` operations, and do
140//!   not support Compare and Swap (CAS) operations, such as `swap`,
141//!   `fetch_add`, etc. Full CAS support is available on ARMv7-M and ARMv8-M
142//!   Mainline (`thumbv7m-*`, `thumbv7em*` and `thumbv8m.main-*`).
143//!
144//! [use the kernel]: https://www.kernel.org/doc/Documentation/arm/kernel_user_helpers.txt
145//!
146//! Note that future platforms may be added that also do not have support for
147//! some atomic operations. Maximally portable code will want to be careful
148//! about which atomic types are used. `AtomicUsize` and `AtomicIsize` are
149//! generally the most portable, but even then they're not available everywhere.
150//! For reference, the `std` library requires `AtomicBool`s and pointer-sized atomics, although
151//! `core` does not.
152//!
153//! The `#[cfg(target_has_atomic)]` attribute can be used to conditionally
154//! compile based on the target's supported bit widths. It is a key-value
155//! option set for each supported size, with values "8", "16", "32", "64",
156//! "128", and "ptr" for pointer-sized atomics.
157//!
158//! [lock-free]: https://en.wikipedia.org/wiki/Non-blocking_algorithm
159//!
160//! # Atomic accesses to read-only memory
161//!
162//! In general, *all* atomic accesses on read-only memory are undefined behavior. For instance, attempting
163//! to do a `compare_exchange` that will definitely fail (making it conceptually a read-only
164//! operation) can still cause a segmentation fault if the underlying memory page is mapped read-only. Since
165//! atomic `load`s might be implemented using compare-exchange operations, even a `load` can fault
166//! on read-only memory.
167//!
168//! For the purpose of this section, "read-only memory" is defined as memory that is read-only in
169//! the underlying target, i.e., the pages are mapped with a read-only flag and any attempt to write
170//! will cause a page fault. In particular, an `&u128` reference that points to memory that is
171//! read-write mapped is *not* considered to point to "read-only memory". In Rust, almost all memory
172//! is read-write; the only exceptions are memory created by `const` items or `static` items without
173//! interior mutability, and memory that was specifically marked as read-only by the operating
174//! system via platform-specific APIs.
175//!
176//! As an exception from the general rule stated above, "sufficiently small" atomic loads with
177//! `Ordering::Relaxed` are implemented in a way that works on read-only memory, and are hence not
178//! undefined behavior. The exact size limit for what makes a load "sufficiently small" varies
179//! depending on the target:
180//!
181//! | `target_arch` | Size limit |
182//! |---------------|---------|
183//! | `x86`, `arm`, `loongarch32`, `mips`, `mips32r6`, `powerpc`, `riscv32`, `sparc`, `hexagon` | 4 bytes |
184//! | `x86_64`, `aarch64`, `loongarch64`, `mips64`, `mips64r6`, `powerpc64`, `riscv64`, `sparc64`, `s390x` | 8 bytes |
185//!
186//! Atomics loads that are larger than this limit as well as atomic loads with ordering other
187//! than `Relaxed`, as well as *all* atomic loads on targets not listed in the table, might still be
188//! read-only under certain conditions, but that is not a stable guarantee and should not be relied
189//! upon.
190//!
191//! If you need to do an acquire load on read-only memory, you can do a relaxed load followed by an
192//! acquire fence instead.
193//!
194//! # Examples
195//!
196//! A simple spinlock:
197//!
198//! ```ignore-wasm
199//! use std::sync::Arc;
200//! use std::sync::atomic::{AtomicUsize, Ordering};
201//! use std::{hint, thread};
202//!
203//! fn main() {
204//!     let spinlock = Arc::new(AtomicUsize::new(1));
205//!
206//!     let spinlock_clone = Arc::clone(&spinlock);
207//!
208//!     let thread = thread::spawn(move || {
209//!         spinlock_clone.store(0, Ordering::Release);
210//!     });
211//!
212//!     // Wait for the other thread to release the lock
213//!     while spinlock.load(Ordering::Acquire) != 0 {
214//!         hint::spin_loop();
215//!     }
216//!
217//!     if let Err(panic) = thread.join() {
218//!         println!("Thread had an error: {panic:?}");
219//!     }
220//! }
221//! ```
222//!
223//! Keep a global count of live threads:
224//!
225//! ```
226//! use std::sync::atomic::{AtomicUsize, Ordering};
227//!
228//! static GLOBAL_THREAD_COUNT: AtomicUsize = AtomicUsize::new(0);
229//!
230//! // Note that Relaxed ordering doesn't synchronize anything
231//! // except the global thread counter itself.
232//! let old_thread_count = GLOBAL_THREAD_COUNT.fetch_add(1, Ordering::Relaxed);
233//! // Note that this number may not be true at the moment of printing
234//! // because some other thread may have changed static value already.
235//! println!("live threads: {}", old_thread_count + 1);
236//! ```
237
238#![stable(feature = "rust1", since = "1.0.0")]
239#![cfg_attr(not(target_has_atomic_load_store = "8"), allow(dead_code))]
240#![cfg_attr(not(target_has_atomic_load_store = "8"), allow(unused_imports))]
241// Clippy complains about the pattern of "safe function calling unsafe function taking pointers".
242// This happens with AtomicPtr intrinsics but is fine, as the pointers clippy is concerned about
243// are just normal values that get loaded/stored, but not dereferenced.
244#![allow(clippy::not_unsafe_ptr_arg_deref)]
245
246use self::Ordering::*;
247use crate::cell::UnsafeCell;
248use crate::hint::spin_loop;
249use crate::intrinsics::AtomicOrdering as AO;
250use crate::mem::transmute;
251use crate::{fmt, intrinsics};
252
253#[unstable(
254    feature = "atomic_internals",
255    reason = "implementation detail which may disappear or be replaced at any time",
256    issue = "none"
257)]
258#[expect(missing_debug_implementations)]
259mod private {
260    #[cfg(target_has_atomic_load_store = "8")]
261    #[repr(C, align(1))]
262    pub struct Align1<T>(T);
263    #[cfg(target_has_atomic_load_store = "16")]
264    #[repr(C, align(2))]
265    pub struct Align2<T>(T);
266    #[cfg(target_has_atomic_load_store = "32")]
267    #[repr(C, align(4))]
268    pub struct Align4<T>(T);
269    #[cfg(target_has_atomic_load_store = "64")]
270    #[repr(C, align(8))]
271    pub struct Align8<T>(T);
272    #[cfg(any(target_has_atomic_load_store = "128", doc))]
273    #[repr(C, align(16))]
274    pub struct Align16<T>(T);
275}
276
277/// A marker trait for primitive types which can be modified atomically.
278///
279/// This is an implementation detail for <code>[Atomic]\<T></code> which may disappear or be replaced at any time.
280//
281// # Safety
282//
283// Types implementing this trait must be primitives that can be modified atomically.
284//
285// The associated `Self::Storage` type must have the same size, but may have fewer validity
286// invariants or a higher alignment requirement than `Self`.
287#[unstable(
288    feature = "atomic_internals",
289    reason = "implementation detail which may disappear or be replaced at any time",
290    issue = "none"
291)]
292pub impl(self) unsafe trait AtomicPrimitive: Sized + Copy {
293    /// Temporary implementation detail.
294    type Storage: Sized;
295}
296
297macro impl_atomic_primitive {
298    (
299        @impl [$($T:ident)?] $Primitive:ty as $Storage:ident<$Operand:ty>,
300        $cfg:meta
301    ) => {
302        #[unstable(
303            feature = "atomic_internals",
304            reason = "implementation detail which may disappear or be replaced at any time",
305            issue = "none"
306        )]
307        #[cfg($cfg)]
308        unsafe impl $(<$T>)? AtomicPrimitive for $Primitive {
309            type Storage = private::$Storage<$Operand>;
310        }
311    },
312
313    (
314        [$($T:ident)?] $Primitive:ty as $Storage:ident<$Operand:ty>,
315        size($size:literal)
316    ) => {
317        impl_atomic_primitive!(
318            @impl [$($T)?] $Primitive as $Storage<$Operand>,
319            target_has_atomic_load_store = $size
320        );
321    },
322
323    (
324        [$($T:ident)?] $Primitive:ty as $Storage:ident<$Operand:ty>,
325        size($size:literal),
326        doc
327    ) => {
328        impl_atomic_primitive!(
329            @impl [$($T)?] $Primitive as $Storage<$Operand>,
330            any(target_has_atomic_load_store = $size, doc)
331        );
332    },
333}
334
335#[unstable(feature = "atomic_internals", reason =
"implementation detail which may disappear or be replaced at any time", issue
= "none")]
unsafe impl AtomicPrimitive for bool {
    type Storage = private::Align1<u8>;
}impl_atomic_primitive!([] bool as Align1<u8>, size("8"));
336#[unstable(feature = "atomic_internals", reason =
"implementation detail which may disappear or be replaced at any time", issue
= "none")]
unsafe impl AtomicPrimitive for i8 {
    type Storage = private::Align1<i8>;
}impl_atomic_primitive!([] i8 as Align1<i8>, size("8"));
337#[unstable(feature = "atomic_internals", reason =
"implementation detail which may disappear or be replaced at any time", issue
= "none")]
unsafe impl AtomicPrimitive for u8 {
    type Storage = private::Align1<u8>;
}impl_atomic_primitive!([] u8 as Align1<u8>, size("8"));
338#[unstable(feature = "atomic_internals", reason =
"implementation detail which may disappear or be replaced at any time", issue
= "none")]
unsafe impl AtomicPrimitive for i16 {
    type Storage = private::Align2<i16>;
}impl_atomic_primitive!([] i16 as Align2<i16>, size("16"));
339#[unstable(feature = "atomic_internals", reason =
"implementation detail which may disappear or be replaced at any time", issue
= "none")]
unsafe impl AtomicPrimitive for u16 {
    type Storage = private::Align2<u16>;
}impl_atomic_primitive!([] u16 as Align2<u16>, size("16"));
340#[unstable(feature = "atomic_internals", reason =
"implementation detail which may disappear or be replaced at any time", issue
= "none")]
unsafe impl AtomicPrimitive for i32 {
    type Storage = private::Align4<i32>;
}impl_atomic_primitive!([] i32 as Align4<i32>, size("32"));
341#[unstable(feature = "atomic_internals", reason =
"implementation detail which may disappear or be replaced at any time", issue
= "none")]
unsafe impl AtomicPrimitive for u32 {
    type Storage = private::Align4<u32>;
}impl_atomic_primitive!([] u32 as Align4<u32>, size("32"));
342#[unstable(feature = "atomic_internals", reason =
"implementation detail which may disappear or be replaced at any time", issue
= "none")]
unsafe impl AtomicPrimitive for i64 {
    type Storage = private::Align8<i64>;
}impl_atomic_primitive!([] i64 as Align8<i64>, size("64"));
343#[unstable(feature = "atomic_internals", reason =
"implementation detail which may disappear or be replaced at any time", issue
= "none")]
unsafe impl AtomicPrimitive for u64 {
    type Storage = private::Align8<u64>;
}impl_atomic_primitive!([] u64 as Align8<u64>, size("64"));
344impl_atomic_primitive!([] i128 as Align16<i128>, size("128"), doc);
345impl_atomic_primitive!([] u128 as Align16<u128>, size("128"), doc);
346
347#[cfg(target_pointer_width = "16")]
348impl_atomic_primitive!([] isize as Align2<isize>, size("ptr"));
349#[cfg(target_pointer_width = "32")]
350impl_atomic_primitive!([] isize as Align4<isize>, size("ptr"));
351#[cfg(target_pointer_width = "64")]
352#[unstable(feature = "atomic_internals", reason =
"implementation detail which may disappear or be replaced at any time", issue
= "none")]
unsafe impl AtomicPrimitive for isize {
    type Storage = private::Align8<isize>;
}impl_atomic_primitive!([] isize as Align8<isize>, size("ptr"));
353
354#[cfg(target_pointer_width = "16")]
355impl_atomic_primitive!([] usize as Align2<usize>, size("ptr"));
356#[cfg(target_pointer_width = "32")]
357impl_atomic_primitive!([] usize as Align4<usize>, size("ptr"));
358#[cfg(target_pointer_width = "64")]
359#[unstable(feature = "atomic_internals", reason =
"implementation detail which may disappear or be replaced at any time", issue
= "none")]
unsafe impl AtomicPrimitive for usize {
    type Storage = private::Align8<usize>;
}impl_atomic_primitive!([] usize as Align8<usize>, size("ptr"));
360
361#[cfg(target_pointer_width = "16")]
362impl_atomic_primitive!([T] *mut T as Align2<*mut T>, size("ptr"));
363#[cfg(target_pointer_width = "32")]
364impl_atomic_primitive!([T] *mut T as Align4<*mut T>, size("ptr"));
365#[cfg(target_pointer_width = "64")]
366#[unstable(feature = "atomic_internals", reason =
"implementation detail which may disappear or be replaced at any time", issue
= "none")]
unsafe impl<T> AtomicPrimitive for *mut T {
    type Storage = private::Align8<*mut T>;
}impl_atomic_primitive!([T] *mut T as Align8<*mut T>, size("ptr"));
367
368/// A memory location which can be safely modified from multiple threads.
369///
370/// This has the same size and bit validity as the underlying type `T`. However,
371/// the alignment of this type is always equal to its size, even on targets where
372/// `T` has alignment less than its size.
373///
374/// For more about the differences between atomic types and non-atomic types as
375/// well as information about the portability of this type, please see the
376/// [module-level documentation].
377///
378/// **Note:** This type is only available on platforms that support atomic loads
379/// and stores of `T`.
380///
381/// [module-level documentation]: crate::sync::atomic
382#[unstable(feature = "generic_atomic", issue = "130539")]
383#[repr(C)]
384#[rustc_diagnostic_item = "Atomic"]
385pub struct Atomic<T: AtomicPrimitive> {
386    v: UnsafeCell<T::Storage>,
387}
388
389#[stable(feature = "rust1", since = "1.0.0")]
390unsafe impl<T: AtomicPrimitive> Send for Atomic<T> {}
391#[stable(feature = "rust1", since = "1.0.0")]
392unsafe impl<T: AtomicPrimitive> Sync for Atomic<T> {}
393
394// Some architectures don't have byte-sized atomics, which results in LLVM
395// emulating them using a LL/SC loop. However for AtomicBool we can take
396// advantage of the fact that it only ever contains 0 or 1 and use atomic OR/AND
397// instead, which LLVM can emulate using a larger atomic OR/AND operation.
398//
399// This list should only contain architectures which have word-sized atomic-or/
400// atomic-and instructions but don't natively support byte-sized atomics.
401#[cfg(target_has_atomic = "8")]
402const EMULATE_ATOMIC_BOOL: bool = falsecfg!(any(
403    target_arch = "riscv32",
404    target_arch = "riscv64",
405    target_arch = "loongarch32",
406    target_arch = "loongarch64"
407));
408
409/// A boolean type which can be safely shared between threads.
410///
411/// This type has the same size, alignment, and bit validity as a [`bool`].
412///
413/// **Note**: This type is only available on platforms that support atomic
414/// loads and stores of `u8`.
415#[cfg(target_has_atomic_load_store = "8")]
416#[stable(feature = "rust1", since = "1.0.0")]
417pub type AtomicBool = Atomic<bool>;
418
419#[cfg(target_has_atomic_load_store = "8")]
420#[stable(feature = "rust1", since = "1.0.0")]
421impl Default for AtomicBool {
422    /// Creates an `AtomicBool` initialized to `false`.
423    #[inline]
424    fn default() -> Self {
425        Self::new(false)
426    }
427}
428
429/// A raw pointer type which can be safely shared between threads.
430///
431/// This type has the same size and bit validity as a `*mut T`.
432///
433/// **Note**: This type is only available on platforms that support atomic
434/// loads and stores of pointers. Its size depends on the target pointer's size.
435#[cfg(target_has_atomic_load_store = "ptr")]
436#[stable(feature = "rust1", since = "1.0.0")]
437pub type AtomicPtr<T> = Atomic<*mut T>;
438
439#[cfg(target_has_atomic_load_store = "ptr")]
440#[stable(feature = "rust1", since = "1.0.0")]
441impl<T> Default for AtomicPtr<T> {
442    /// Creates a null `AtomicPtr<T>`.
443    fn default() -> AtomicPtr<T> {
444        AtomicPtr::new(crate::ptr::null_mut())
445    }
446}
447
448/// Atomic memory orderings
449///
450/// Memory orderings specify the way atomic operations synchronize memory.
451/// In its weakest [`Ordering::Relaxed`], only the memory directly touched by the
452/// operation is synchronized. On the other hand, a store-load pair of [`Ordering::SeqCst`]
453/// operations synchronize other memory while additionally preserving a total order of such
454/// operations across all threads.
455///
456/// Rust's memory orderings are [the same as those of
457/// C++20](https://en.cppreference.com/w/cpp/atomic/memory_order).
458///
459/// For more information see the [nomicon].
460///
461/// [nomicon]: ../../../nomicon/atomics.html
462#[stable(feature = "rust1", since = "1.0.0")]
463#[derive(#[automatically_derived]
#[stable(feature = "rust1", since = "1.0.0")]
impl crate::marker::Copy for Ordering { }Copy, #[automatically_derived]
#[doc(hidden)]
#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl crate::clone::TrivialClone for Ordering { }
#[automatically_derived]
#[stable(feature = "rust1", since = "1.0.0")]
impl crate::clone::Clone for Ordering {
    #[inline]
    fn clone(&self) -> Ordering { *self }
}Clone, #[automatically_derived]
#[stable(feature = "rust1", since = "1.0.0")]
impl crate::fmt::Debug for Ordering {
    #[inline]
    fn fmt(&self, f: &mut crate::fmt::Formatter) -> crate::fmt::Result {
        crate::fmt::Formatter::write_str(f,
            match self {
                Ordering::Relaxed => "Relaxed",
                Ordering::Release => "Release",
                Ordering::Acquire => "Acquire",
                Ordering::AcqRel => "AcqRel",
                Ordering::SeqCst => "SeqCst",
            })
    }
}Debug, #[automatically_derived]
#[stable(feature = "rust1", since = "1.0.0")]
impl crate::cmp::Eq for Ordering {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
#[stable(feature = "rust1", since = "1.0.0")]
impl crate::marker::StructuralPartialEq for Ordering { }
#[automatically_derived]
#[stable(feature = "rust1", since = "1.0.0")]
impl crate::cmp::PartialEq for Ordering {
    #[inline]
    fn eq(&self, other: &Ordering) -> bool {
        let __self_discr = crate::intrinsics::discriminant_value(self);
        let __arg1_discr = crate::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
#[stable(feature = "rust1", since = "1.0.0")]
impl crate::hash::Hash for Ordering {
    #[inline]
    fn hash<__H: crate::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = crate::intrinsics::discriminant_value(self);
        crate::hash::Hash::hash(&__self_discr, state)
    }
}Hash)]
464#[non_exhaustive]
465#[rustc_diagnostic_item = "Ordering"]
466pub enum Ordering {
467    /// No ordering constraints, only atomic operations.
468    ///
469    /// Corresponds to [`memory_order_relaxed`] in C++20.
470    ///
471    /// [`memory_order_relaxed`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Relaxed_ordering
472    #[stable(feature = "rust1", since = "1.0.0")]
473    Relaxed,
474    /// When coupled with a store, all previous operations become ordered
475    /// before any load of this value with [`Acquire`] (or stronger) ordering.
476    /// In particular, all previous writes become visible to all threads
477    /// that perform an [`Acquire`] (or stronger) load of this value.
478    ///
479    /// Notice that using this ordering for an operation that combines loads
480    /// and stores leads to a [`Relaxed`] load operation!
481    ///
482    /// This ordering is only applicable for operations that can perform a store.
483    ///
484    /// Corresponds to [`memory_order_release`] in C++20.
485    ///
486    /// [`memory_order_release`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering
487    #[stable(feature = "rust1", since = "1.0.0")]
488    Release,
489    /// When coupled with a load, if the loaded value was written by a store operation with
490    /// [`Release`] (or stronger) ordering, then all subsequent operations
491    /// become ordered after that store. In particular, all subsequent loads will see data
492    /// written before the store.
493    ///
494    /// Notice that using this ordering for an operation that combines loads
495    /// and stores leads to a [`Relaxed`] store operation!
496    ///
497    /// This ordering is only applicable for operations that can perform a load.
498    ///
499    /// Corresponds to [`memory_order_acquire`] in C++20.
500    ///
501    /// [`memory_order_acquire`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering
502    #[stable(feature = "rust1", since = "1.0.0")]
503    Acquire,
504    /// Has the effects of both [`Acquire`] and [`Release`] together:
505    /// For loads it uses [`Acquire`] ordering. For stores it uses the [`Release`] ordering.
506    ///
507    /// Notice that in the case of `compare_and_swap`, it is possible that the operation ends up
508    /// not performing any store and hence it has just [`Acquire`] ordering. However,
509    /// `AcqRel` will never perform [`Relaxed`] accesses.
510    ///
511    /// This ordering is only applicable for operations that combine both loads and stores.
512    ///
513    /// Corresponds to [`memory_order_acq_rel`] in C++20.
514    ///
515    /// [`memory_order_acq_rel`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering
516    #[stable(feature = "rust1", since = "1.0.0")]
517    AcqRel,
518    /// Like [`Acquire`]/[`Release`]/[`AcqRel`] (for load, store, and load-with-store
519    /// operations, respectively) with the additional guarantee that all threads see all
520    /// sequentially consistent operations in the same order.
521    ///
522    /// Corresponds to [`memory_order_seq_cst`] in C++20.
523    ///
524    /// [`memory_order_seq_cst`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Sequentially-consistent_ordering
525    #[stable(feature = "rust1", since = "1.0.0")]
526    SeqCst,
527}
528
529/// An [`AtomicBool`] initialized to `false`.
530#[cfg(target_has_atomic_load_store = "8")]
531#[stable(feature = "rust1", since = "1.0.0")]
532#[deprecated(
533    since = "1.34.0",
534    note = "the `new` function is now preferred",
535    suggestion = "AtomicBool::new(false)"
536)]
537#[expect(clippy::declare_interior_mutable_const, reason = "legacy atomic initializer")]
538pub const ATOMIC_BOOL_INIT: AtomicBool = AtomicBool::new(false);
539
540#[cfg(target_has_atomic_load_store = "8")]
541impl AtomicBool {
542    /// Creates a new `AtomicBool`.
543    ///
544    /// # Examples
545    ///
546    /// ```
547    /// use std::sync::atomic::AtomicBool;
548    ///
549    /// let atomic_true = AtomicBool::new(true);
550    /// let atomic_false = AtomicBool::new(false);
551    /// ```
552    #[inline]
553    #[stable(feature = "rust1", since = "1.0.0")]
554    #[rustc_const_stable(feature = "const_atomic_new", since = "1.24.0")]
555    #[must_use]
556    pub const fn new(v: bool) -> AtomicBool {
557        // SAFETY:
558        // `Atomic<T>` is essentially a transparent wrapper around `T`.
559        unsafe { transmute(v) }
560    }
561
562    /// Creates a new `AtomicBool` from a pointer.
563    ///
564    /// # Examples
565    ///
566    /// ```
567    /// use std::sync::atomic::{self, AtomicBool};
568    ///
569    /// // Get a pointer to an allocated value
570    /// let ptr: *mut bool = Box::into_raw(Box::new(false));
571    ///
572    /// assert!(ptr.cast::<AtomicBool>().is_aligned());
573    ///
574    /// {
575    ///     // Create an atomic view of the allocated value
576    ///     let atomic = unsafe { AtomicBool::from_ptr(ptr) };
577    ///
578    ///     // Use `atomic` for atomic operations, possibly share it with other threads
579    ///     atomic.store(true, atomic::Ordering::Relaxed);
580    /// }
581    ///
582    /// // It's ok to non-atomically access the value behind `ptr`,
583    /// // since the reference to the atomic ended its lifetime in the block above
584    /// assert_eq!(unsafe { *ptr }, true);
585    ///
586    /// // Deallocate the value
587    /// unsafe { drop(Box::from_raw(ptr)) }
588    /// ```
589    ///
590    /// # Safety
591    ///
592    /// * `ptr` must be aligned to `align_of::<AtomicBool>()` (note that this is always true, since
593    ///   `align_of::<AtomicBool>() == 1`).
594    /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
595    /// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not
596    ///   allowed to mix conflicting atomic and non-atomic accesses, or atomic accesses of different
597    ///   sizes, without synchronization.
598    ///
599    /// [valid]: crate::ptr#safety
600    /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
601    #[inline]
602    #[stable(feature = "atomic_from_ptr", since = "1.75.0")]
603    #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")]
604    pub const unsafe fn from_ptr<'a>(ptr: *mut bool) -> &'a AtomicBool {
605        // SAFETY: guaranteed by the caller
606        unsafe { &*ptr.cast() }
607    }
608
609    /// Returns a mutable reference to the underlying [`bool`].
610    ///
611    /// This is safe because the mutable reference guarantees that no other threads are
612    /// concurrently accessing the atomic data.
613    ///
614    /// # Examples
615    ///
616    /// ```
617    /// use std::sync::atomic::{AtomicBool, Ordering};
618    ///
619    /// let mut some_bool = AtomicBool::new(true);
620    /// assert_eq!(*some_bool.get_mut(), true);
621    /// *some_bool.get_mut() = false;
622    /// assert_eq!(some_bool.load(Ordering::SeqCst), false);
623    /// ```
624    #[inline]
625    #[stable(feature = "atomic_access", since = "1.15.0")]
626    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
627    pub const fn get_mut(&mut self) -> &mut bool {
628        // SAFETY: the mutable reference guarantees unique ownership.
629        unsafe { &mut *self.as_ptr() }
630    }
631
632    /// Gets atomic access to a `&mut bool`.
633    ///
634    /// # Examples
635    ///
636    /// ```
637    /// use std::sync::atomic::{AtomicBool, Ordering};
638    ///
639    /// let mut some_bool = true;
640    /// let a = AtomicBool::from_mut(&mut some_bool);
641    /// a.store(false, Ordering::Relaxed);
642    /// assert_eq!(some_bool, false);
643    /// ```
644    #[inline]
645    #[cfg(target_has_atomic_primitive_alignment = "8")]
646    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
647    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
648    pub const fn from_mut(v: &mut bool) -> &mut Self {
649        // SAFETY: the mutable reference guarantees unique ownership, and
650        // alignment of both `bool` and `Self` is 1.
651        unsafe { &mut *(v as *mut bool as *mut Self) }
652    }
653
654    /// Gets non-atomic access to a `&mut [AtomicBool]` slice.
655    ///
656    /// This is safe because the mutable reference guarantees that no other threads are
657    /// concurrently accessing the atomic data.
658    ///
659    /// # Examples
660    ///
661    /// ```ignore-wasm
662    /// use std::sync::atomic::{AtomicBool, Ordering};
663    ///
664    /// let mut some_bools = [const { AtomicBool::new(false) }; 10];
665    ///
666    /// let view: &mut [bool] = AtomicBool::get_mut_slice(&mut some_bools);
667    /// assert_eq!(view, [false; 10]);
668    /// view[..5].copy_from_slice(&[true; 5]);
669    ///
670    /// std::thread::scope(|s| {
671    ///     for t in &some_bools[..5] {
672    ///         s.spawn(move || assert_eq!(t.load(Ordering::Relaxed), true));
673    ///     }
674    ///
675    ///     for f in &some_bools[5..] {
676    ///         s.spawn(move || assert_eq!(f.load(Ordering::Relaxed), false));
677    ///     }
678    /// });
679    /// ```
680    #[inline]
681    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
682    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
683    pub const fn get_mut_slice(this: &mut [Self]) -> &mut [bool] {
684        // SAFETY: the mutable reference guarantees unique ownership.
685        unsafe { &mut *(this as *mut [Self] as *mut [bool]) }
686    }
687
688    /// Gets atomic access to a `&mut [bool]` slice.
689    ///
690    /// # Examples
691    ///
692    /// ```rust,ignore-wasm
693    /// use std::sync::atomic::{AtomicBool, Ordering};
694    ///
695    /// let mut some_bools = [false; 10];
696    /// let a = &*AtomicBool::from_mut_slice(&mut some_bools);
697    /// std::thread::scope(|s| {
698    ///     for i in 0..a.len() {
699    ///         s.spawn(move || a[i].store(true, Ordering::Relaxed));
700    ///     }
701    /// });
702    /// assert_eq!(some_bools, [true; 10]);
703    /// ```
704    #[inline]
705    #[cfg(target_has_atomic_primitive_alignment = "8")]
706    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
707    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
708    pub const fn from_mut_slice(v: &mut [bool]) -> &mut [Self] {
709        // SAFETY: the mutable reference guarantees unique ownership, and
710        // alignment of both `bool` and `Self` is 1.
711        unsafe { &mut *(v as *mut [bool] as *mut [Self]) }
712    }
713
714    /// Consumes the atomic and returns the contained value.
715    ///
716    /// This is safe because passing `self` by value guarantees that no other threads are
717    /// concurrently accessing the atomic data.
718    ///
719    /// # Examples
720    ///
721    /// ```
722    /// use std::sync::atomic::AtomicBool;
723    ///
724    /// let some_bool = AtomicBool::new(true);
725    /// assert_eq!(some_bool.into_inner(), true);
726    /// ```
727    #[inline]
728    #[stable(feature = "atomic_access", since = "1.15.0")]
729    #[rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0")]
730    pub const fn into_inner(self) -> bool {
731        // SAFETY:
732        // * `Atomic<T>` is essentially a transparent wrapper around `T`.
733        // * all operations on `Atomic<bool>` ensure that `T::Storage` remains
734        //   a valid `bool`.
735        unsafe { transmute(self) }
736    }
737
738    /// Loads a value from the bool.
739    ///
740    /// `load` takes an [`Ordering`] argument which describes the memory ordering
741    /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
742    ///
743    /// # Panics
744    ///
745    /// Panics if `order` is [`Release`] or [`AcqRel`].
746    ///
747    /// # Examples
748    ///
749    /// ```
750    /// use std::sync::atomic::{AtomicBool, Ordering};
751    ///
752    /// let some_bool = AtomicBool::new(true);
753    ///
754    /// assert_eq!(some_bool.load(Ordering::Relaxed), true);
755    /// ```
756    #[inline]
757    #[stable(feature = "rust1", since = "1.0.0")]
758    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
759    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
760    pub const fn load(&self, order: Ordering) -> bool {
761        // SAFETY: any data races are prevented by atomic intrinsics and the raw
762        // pointer passed in is valid because we got it from a reference.
763        unsafe {
764            atomic_load::<_, /* VOLATILE */ false>(self.v.get().cast::<u8>(), order) != 0
765        }
766    }
767
768    /// Stores a value into the bool.
769    ///
770    /// `store` takes an [`Ordering`] argument which describes the memory ordering
771    /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
772    ///
773    /// # Panics
774    ///
775    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
776    ///
777    /// # Examples
778    ///
779    /// ```
780    /// use std::sync::atomic::{AtomicBool, Ordering};
781    ///
782    /// let some_bool = AtomicBool::new(true);
783    ///
784    /// some_bool.store(false, Ordering::Relaxed);
785    /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
786    /// ```
787    #[inline]
788    #[stable(feature = "rust1", since = "1.0.0")]
789    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
790    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
791    #[rustc_should_not_be_called_on_const_items]
792    pub const fn store(&self, val: bool, order: Ordering) {
793        // SAFETY: any data races are prevented by atomic intrinsics and the raw
794        // pointer passed in is valid because we got it from a reference.
795        unsafe {
796            atomic_store::<_, /* VOLATILE */ false>(self.v.get().cast::<u8>(), val as u8, order);
797        }
798    }
799
800    /// Stores a value into the bool, returning the previous value.
801    ///
802    /// `swap` takes an [`Ordering`] argument which describes the memory ordering
803    /// of this operation. All ordering modes are possible. Note that using
804    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
805    /// using [`Release`] makes the load part [`Relaxed`].
806    ///
807    /// **Note:** This method is only available on platforms that support atomic
808    /// operations on `u8`.
809    ///
810    /// # Examples
811    ///
812    /// ```
813    /// use std::sync::atomic::{AtomicBool, Ordering};
814    ///
815    /// let some_bool = AtomicBool::new(true);
816    ///
817    /// assert_eq!(some_bool.swap(false, Ordering::Relaxed), true);
818    /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
819    /// ```
820    #[inline]
821    #[stable(feature = "rust1", since = "1.0.0")]
822    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
823    #[cfg(target_has_atomic = "8")]
824    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
825    #[rustc_should_not_be_called_on_const_items]
826    pub const fn swap(&self, val: bool, order: Ordering) -> bool {
827        if EMULATE_ATOMIC_BOOL {
828            if val { self.fetch_or(true, order) } else { self.fetch_and(false, order) }
829        } else {
830            // SAFETY: data races are prevented by atomic intrinsics.
831            unsafe { atomic_swap(self.v.get().cast::<u8>(), val as u8, order) != 0 }
832        }
833    }
834
835    /// Stores a value into the [`bool`] if the current value is the same as the `current` value.
836    ///
837    /// The return value is always the previous value. If it is equal to `current`, then the value
838    /// was updated.
839    ///
840    /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
841    /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
842    /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
843    /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
844    /// happens, and using [`Release`] makes the load part [`Relaxed`].
845    ///
846    /// **Note:** This method is only available on platforms that support atomic
847    /// operations on `u8`.
848    ///
849    /// # Migrating to `compare_exchange` and `compare_exchange_weak`
850    ///
851    /// `compare_and_swap` is equivalent to `compare_exchange` with the following mapping for
852    /// memory orderings:
853    ///
854    /// Original | Success | Failure
855    /// -------- | ------- | -------
856    /// Relaxed  | Relaxed | Relaxed
857    /// Acquire  | Acquire | Acquire
858    /// Release  | Release | Relaxed
859    /// AcqRel   | AcqRel  | Acquire
860    /// SeqCst   | SeqCst  | SeqCst
861    ///
862    /// `compare_and_swap` and `compare_exchange` also differ in their return type. You can use
863    /// `compare_exchange(...).unwrap_or_else(|x| x)` to recover the behavior of `compare_and_swap`,
864    /// but in most cases it is more idiomatic to check whether the return value is `Ok` or `Err`
865    /// rather than to infer success vs failure based on the value that was read.
866    ///
867    /// During migration, consider whether it makes sense to use `compare_exchange_weak` instead.
868    /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds,
869    /// which allows the compiler to generate better assembly code when the compare and swap
870    /// is used in a loop.
871    ///
872    /// # Examples
873    ///
874    /// ```
875    /// use std::sync::atomic::{AtomicBool, Ordering};
876    ///
877    /// let some_bool = AtomicBool::new(true);
878    ///
879    /// assert_eq!(some_bool.compare_and_swap(true, false, Ordering::Relaxed), true);
880    /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
881    ///
882    /// assert_eq!(some_bool.compare_and_swap(true, true, Ordering::Relaxed), false);
883    /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
884    /// ```
885    #[inline]
886    #[stable(feature = "rust1", since = "1.0.0")]
887    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
888    #[deprecated(
889        since = "1.50.0",
890        note = "Use `compare_exchange` or `compare_exchange_weak` instead"
891    )]
892    #[cfg(target_has_atomic = "8")]
893    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
894    #[rustc_should_not_be_called_on_const_items]
895    pub const fn compare_and_swap(&self, current: bool, new: bool, order: Ordering) -> bool {
896        match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) {
897            Ok(x) => x,
898            Err(x) => x,
899        }
900    }
901
902    /// Stores a value into the [`bool`] if the current value is the same as the `current` value.
903    ///
904    /// The return value is a result indicating whether the new value was written and containing
905    /// the previous value. On success this value is guaranteed to be equal to `current`.
906    ///
907    /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
908    /// ordering of this operation. `success` describes the required ordering for the
909    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
910    /// `failure` describes the required ordering for the load operation that takes place when
911    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
912    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
913    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
914    ///
915    /// **Note:** This method is only available on platforms that support atomic
916    /// operations on `u8`.
917    ///
918    /// # Examples
919    ///
920    /// ```
921    /// use std::sync::atomic::{AtomicBool, Ordering};
922    ///
923    /// let some_bool = AtomicBool::new(true);
924    ///
925    /// assert_eq!(some_bool.compare_exchange(true,
926    ///                                       false,
927    ///                                       Ordering::Acquire,
928    ///                                       Ordering::Relaxed),
929    ///            Ok(true));
930    /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
931    ///
932    /// assert_eq!(some_bool.compare_exchange(true, true,
933    ///                                       Ordering::SeqCst,
934    ///                                       Ordering::Acquire),
935    ///            Err(false));
936    /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
937    /// ```
938    ///
939    /// # Considerations
940    ///
941    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
942    /// of CAS operations. In particular, a load of the value followed by a successful
943    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
944    /// changed the value in the interim. This is usually important when the *equality* check in
945    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
946    /// does not necessarily imply identity. In this case, `compare_exchange` can lead to the
947    /// [ABA problem].
948    ///
949    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
950    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
951    #[inline]
952    #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
953    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
954    #[doc(alias = "compare_and_swap")]
955    #[cfg(target_has_atomic = "8")]
956    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
957    #[rustc_should_not_be_called_on_const_items]
958    pub const fn compare_exchange(
959        &self,
960        current: bool,
961        new: bool,
962        success: Ordering,
963        failure: Ordering,
964    ) -> Result<bool, bool> {
965        if EMULATE_ATOMIC_BOOL {
966            // Pick the strongest ordering from success and failure.
967            let order = match (success, failure) {
968                (SeqCst, _) => SeqCst,
969                (_, SeqCst) => SeqCst,
970                (AcqRel, _) => AcqRel,
971                (_, AcqRel) => {
972                    {
    crate::panicking::panic_fmt(format_args!("there is no such thing as an acquire-release failure ordering"));
}panic!("there is no such thing as an acquire-release failure ordering")
973                }
974                (Release, Acquire) => AcqRel,
975                (Acquire, _) => Acquire,
976                (_, Acquire) => Acquire,
977                (Release, Relaxed) => Release,
978                (_, Release) => {
    crate::panicking::panic_fmt(format_args!("there is no such thing as a release failure ordering"));
}panic!("there is no such thing as a release failure ordering"),
979                (Relaxed, Relaxed) => Relaxed,
980            };
981            let old = if current == new {
982                // This is a no-op, but we still need to perform the operation
983                // for memory ordering reasons.
984                self.fetch_or(false, order)
985            } else {
986                // This sets the value to the new one and returns the old one.
987                self.swap(new, order)
988            };
989            if old == current { Ok(old) } else { Err(old) }
990        } else {
991            // SAFETY: data races are prevented by atomic intrinsics.
992            match unsafe {
993                atomic_compare_exchange(
994                    self.v.get().cast::<u8>(),
995                    current as u8,
996                    new as u8,
997                    success,
998                    failure,
999                )
1000            } {
1001                Ok(x) => Ok(x != 0),
1002                Err(x) => Err(x != 0),
1003            }
1004        }
1005    }
1006
1007    /// Stores a value into the [`bool`] if the current value is the same as the `current` value.
1008    ///
1009    /// Unlike [`AtomicBool::compare_exchange`], this function is allowed to spuriously fail even when the
1010    /// comparison succeeds, which can result in more efficient code on some platforms. The
1011    /// return value is a result indicating whether the new value was written and containing the
1012    /// previous value.
1013    ///
1014    /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
1015    /// ordering of this operation. `success` describes the required ordering for the
1016    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
1017    /// `failure` describes the required ordering for the load operation that takes place when
1018    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
1019    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
1020    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
1021    ///
1022    /// **Note:** This method is only available on platforms that support atomic
1023    /// operations on `u8`.
1024    ///
1025    /// # Examples
1026    ///
1027    /// ```
1028    /// use std::sync::atomic::{AtomicBool, Ordering};
1029    ///
1030    /// let val = AtomicBool::new(false);
1031    ///
1032    /// let new = true;
1033    /// let mut old = val.load(Ordering::Relaxed);
1034    /// loop {
1035    ///     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
1036    ///         Ok(_) => break,
1037    ///         Err(x) => old = x,
1038    ///     }
1039    /// }
1040    /// ```
1041    ///
1042    /// # Considerations
1043    ///
1044    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
1045    /// of CAS operations. In particular, a load of the value followed by a successful
1046    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
1047    /// changed the value in the interim. This is usually important when the *equality* check in
1048    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
1049    /// does not necessarily imply identity. In this case, `compare_exchange` can lead to the
1050    /// [ABA problem].
1051    ///
1052    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
1053    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
1054    #[inline]
1055    #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
1056    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1057    #[doc(alias = "compare_and_swap")]
1058    #[cfg(target_has_atomic = "8")]
1059    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1060    #[rustc_should_not_be_called_on_const_items]
1061    pub const fn compare_exchange_weak(
1062        &self,
1063        current: bool,
1064        new: bool,
1065        success: Ordering,
1066        failure: Ordering,
1067    ) -> Result<bool, bool> {
1068        if EMULATE_ATOMIC_BOOL {
1069            return self.compare_exchange(current, new, success, failure);
1070        }
1071
1072        // SAFETY: data races are prevented by atomic intrinsics.
1073        match unsafe {
1074            atomic_compare_exchange_weak(
1075                self.v.get().cast::<u8>(),
1076                current as u8,
1077                new as u8,
1078                success,
1079                failure,
1080            )
1081        } {
1082            Ok(x) => Ok(x != 0),
1083            Err(x) => Err(x != 0),
1084        }
1085    }
1086
1087    /// Logical "and" with a boolean value.
1088    ///
1089    /// Performs a logical "and" operation on the current value and the argument `val`, and sets
1090    /// the new value to the result.
1091    ///
1092    /// Returns the previous value.
1093    ///
1094    /// `fetch_and` takes an [`Ordering`] argument which describes the memory ordering
1095    /// of this operation. All ordering modes are possible. Note that using
1096    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
1097    /// using [`Release`] makes the load part [`Relaxed`].
1098    ///
1099    /// **Note:** This method is only available on platforms that support atomic
1100    /// operations on `u8`.
1101    ///
1102    /// # Examples
1103    ///
1104    /// ```
1105    /// use std::sync::atomic::{AtomicBool, Ordering};
1106    ///
1107    /// let foo = AtomicBool::new(true);
1108    /// assert_eq!(foo.fetch_and(false, Ordering::SeqCst), true);
1109    /// assert_eq!(foo.load(Ordering::SeqCst), false);
1110    ///
1111    /// let foo = AtomicBool::new(true);
1112    /// assert_eq!(foo.fetch_and(true, Ordering::SeqCst), true);
1113    /// assert_eq!(foo.load(Ordering::SeqCst), true);
1114    ///
1115    /// let foo = AtomicBool::new(false);
1116    /// assert_eq!(foo.fetch_and(false, Ordering::SeqCst), false);
1117    /// assert_eq!(foo.load(Ordering::SeqCst), false);
1118    /// ```
1119    #[inline]
1120    #[stable(feature = "rust1", since = "1.0.0")]
1121    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1122    #[cfg(target_has_atomic = "8")]
1123    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1124    #[rustc_should_not_be_called_on_const_items]
1125    pub const fn fetch_and(&self, val: bool, order: Ordering) -> bool {
1126        // SAFETY: data races are prevented by atomic intrinsics.
1127        unsafe { atomic_and(self.v.get().cast::<u8>(), val as u8, order) != 0 }
1128    }
1129
1130    /// Logical "nand" with a boolean value.
1131    ///
1132    /// Performs a logical "nand" operation on the current value and the argument `val`, and sets
1133    /// the new value to the result.
1134    ///
1135    /// Returns the previous value.
1136    ///
1137    /// `fetch_nand` takes an [`Ordering`] argument which describes the memory ordering
1138    /// of this operation. All ordering modes are possible. Note that using
1139    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
1140    /// using [`Release`] makes the load part [`Relaxed`].
1141    ///
1142    /// **Note:** This method is only available on platforms that support atomic
1143    /// operations on `u8`.
1144    ///
1145    /// # Examples
1146    ///
1147    /// ```
1148    /// use std::sync::atomic::{AtomicBool, Ordering};
1149    ///
1150    /// let foo = AtomicBool::new(true);
1151    /// assert_eq!(foo.fetch_nand(false, Ordering::SeqCst), true);
1152    /// assert_eq!(foo.load(Ordering::SeqCst), true);
1153    ///
1154    /// let foo = AtomicBool::new(true);
1155    /// assert_eq!(foo.fetch_nand(true, Ordering::SeqCst), true);
1156    /// assert_eq!(foo.load(Ordering::SeqCst) as usize, 0);
1157    /// assert_eq!(foo.load(Ordering::SeqCst), false);
1158    ///
1159    /// let foo = AtomicBool::new(false);
1160    /// assert_eq!(foo.fetch_nand(false, Ordering::SeqCst), false);
1161    /// assert_eq!(foo.load(Ordering::SeqCst), true);
1162    /// ```
1163    #[inline]
1164    #[stable(feature = "rust1", since = "1.0.0")]
1165    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1166    #[cfg(target_has_atomic = "8")]
1167    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1168    #[rustc_should_not_be_called_on_const_items]
1169    pub const fn fetch_nand(&self, val: bool, order: Ordering) -> bool {
1170        // We can't use atomic_nand here because it can result in a bool with
1171        // an invalid value. This happens because the atomic operation is done
1172        // with an 8-bit integer internally, which would set the upper 7 bits.
1173        // So we just use fetch_xor or swap instead.
1174        if val {
1175            // !(x & true) == !x
1176            // We must invert the bool.
1177            self.fetch_xor(true, order)
1178        } else {
1179            // !(x & false) == true
1180            // We must set the bool to true.
1181            self.swap(true, order)
1182        }
1183    }
1184
1185    /// Logical "or" with a boolean value.
1186    ///
1187    /// Performs a logical "or" operation on the current value and the argument `val`, and sets the
1188    /// new value to the result.
1189    ///
1190    /// Returns the previous value.
1191    ///
1192    /// `fetch_or` takes an [`Ordering`] argument which describes the memory ordering
1193    /// of this operation. All ordering modes are possible. Note that using
1194    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
1195    /// using [`Release`] makes the load part [`Relaxed`].
1196    ///
1197    /// **Note:** This method is only available on platforms that support atomic
1198    /// operations on `u8`.
1199    ///
1200    /// # Examples
1201    ///
1202    /// ```
1203    /// use std::sync::atomic::{AtomicBool, Ordering};
1204    ///
1205    /// let foo = AtomicBool::new(true);
1206    /// assert_eq!(foo.fetch_or(false, Ordering::SeqCst), true);
1207    /// assert_eq!(foo.load(Ordering::SeqCst), true);
1208    ///
1209    /// let foo = AtomicBool::new(false);
1210    /// assert_eq!(foo.fetch_or(true, Ordering::SeqCst), false);
1211    /// assert_eq!(foo.load(Ordering::SeqCst), true);
1212    ///
1213    /// let foo = AtomicBool::new(false);
1214    /// assert_eq!(foo.fetch_or(false, Ordering::SeqCst), false);
1215    /// assert_eq!(foo.load(Ordering::SeqCst), false);
1216    /// ```
1217    #[inline]
1218    #[stable(feature = "rust1", since = "1.0.0")]
1219    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1220    #[cfg(target_has_atomic = "8")]
1221    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1222    #[rustc_should_not_be_called_on_const_items]
1223    pub const fn fetch_or(&self, val: bool, order: Ordering) -> bool {
1224        // SAFETY: data races are prevented by atomic intrinsics.
1225        unsafe { atomic_or(self.v.get().cast::<u8>(), val as u8, order) != 0 }
1226    }
1227
1228    /// Logical "xor" with a boolean value.
1229    ///
1230    /// Performs a logical "xor" operation on the current value and the argument `val`, and sets
1231    /// the new value to the result.
1232    ///
1233    /// Returns the previous value.
1234    ///
1235    /// `fetch_xor` takes an [`Ordering`] argument which describes the memory ordering
1236    /// of this operation. All ordering modes are possible. Note that using
1237    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
1238    /// using [`Release`] makes the load part [`Relaxed`].
1239    ///
1240    /// **Note:** This method is only available on platforms that support atomic
1241    /// operations on `u8`.
1242    ///
1243    /// # Examples
1244    ///
1245    /// ```
1246    /// use std::sync::atomic::{AtomicBool, Ordering};
1247    ///
1248    /// let foo = AtomicBool::new(true);
1249    /// assert_eq!(foo.fetch_xor(false, Ordering::SeqCst), true);
1250    /// assert_eq!(foo.load(Ordering::SeqCst), true);
1251    ///
1252    /// let foo = AtomicBool::new(true);
1253    /// assert_eq!(foo.fetch_xor(true, Ordering::SeqCst), true);
1254    /// assert_eq!(foo.load(Ordering::SeqCst), false);
1255    ///
1256    /// let foo = AtomicBool::new(false);
1257    /// assert_eq!(foo.fetch_xor(false, Ordering::SeqCst), false);
1258    /// assert_eq!(foo.load(Ordering::SeqCst), false);
1259    /// ```
1260    #[inline]
1261    #[stable(feature = "rust1", since = "1.0.0")]
1262    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1263    #[cfg(target_has_atomic = "8")]
1264    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1265    #[rustc_should_not_be_called_on_const_items]
1266    pub const fn fetch_xor(&self, val: bool, order: Ordering) -> bool {
1267        // SAFETY: data races are prevented by atomic intrinsics.
1268        unsafe { atomic_xor(self.v.get().cast::<u8>(), val as u8, order) != 0 }
1269    }
1270
1271    /// Logical "not" with a boolean value.
1272    ///
1273    /// Performs a logical "not" operation on the current value, and sets
1274    /// the new value to the result.
1275    ///
1276    /// Returns the previous value.
1277    ///
1278    /// `fetch_not` takes an [`Ordering`] argument which describes the memory ordering
1279    /// of this operation. All ordering modes are possible. Note that using
1280    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
1281    /// using [`Release`] makes the load part [`Relaxed`].
1282    ///
1283    /// **Note:** This method is only available on platforms that support atomic
1284    /// operations on `u8`.
1285    ///
1286    /// # Examples
1287    ///
1288    /// ```
1289    /// use std::sync::atomic::{AtomicBool, Ordering};
1290    ///
1291    /// let foo = AtomicBool::new(true);
1292    /// assert_eq!(foo.fetch_not(Ordering::SeqCst), true);
1293    /// assert_eq!(foo.load(Ordering::SeqCst), false);
1294    ///
1295    /// let foo = AtomicBool::new(false);
1296    /// assert_eq!(foo.fetch_not(Ordering::SeqCst), false);
1297    /// assert_eq!(foo.load(Ordering::SeqCst), true);
1298    /// ```
1299    #[inline]
1300    #[stable(feature = "atomic_bool_fetch_not", since = "1.81.0")]
1301    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1302    #[cfg(target_has_atomic = "8")]
1303    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1304    #[rustc_should_not_be_called_on_const_items]
1305    pub const fn fetch_not(&self, order: Ordering) -> bool {
1306        self.fetch_xor(true, order)
1307    }
1308
1309    /// Returns a mutable pointer to the underlying [`bool`].
1310    ///
1311    /// Doing non-atomic reads and writes on the resulting boolean can be a data race.
1312    /// This method is mostly useful for FFI, where the function signature may use
1313    /// `*mut bool` instead of `&AtomicBool`.
1314    ///
1315    /// Returning an `*mut` pointer from a shared reference to this atomic is safe because the
1316    /// atomic types work with interior mutability. All modifications of an atomic change the value
1317    /// through a shared reference, and can do so safely as long as they use atomic operations. Any
1318    /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the
1319    /// requirements of the [memory model].
1320    ///
1321    /// # Examples
1322    ///
1323    /// ```ignore (extern-declaration)
1324    /// # fn main() {
1325    /// use std::sync::atomic::AtomicBool;
1326    ///
1327    /// extern "C" {
1328    ///     fn my_atomic_op(arg: *mut bool);
1329    /// }
1330    ///
1331    /// let mut atomic = AtomicBool::new(true);
1332    /// unsafe {
1333    ///     my_atomic_op(atomic.as_ptr());
1334    /// }
1335    /// # }
1336    /// ```
1337    ///
1338    /// [memory model]: self#memory-model-for-atomic-accesses
1339    #[inline]
1340    #[stable(feature = "atomic_as_ptr", since = "1.70.0")]
1341    #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")]
1342    #[rustc_never_returns_null_ptr]
1343    #[rustc_should_not_be_called_on_const_items]
1344    pub const fn as_ptr(&self) -> *mut bool {
1345        self.v.get().cast()
1346    }
1347
1348    /// An alias for [`AtomicBool::try_update`].
1349    #[inline]
1350    #[stable(feature = "atomic_fetch_update", since = "1.53.0")]
1351    #[cfg(target_has_atomic = "8")]
1352    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1353    #[rustc_should_not_be_called_on_const_items]
1354    #[deprecated(
1355        since = "1.99.0",
1356        note = "renamed to `try_update` for consistency",
1357        suggestion = "try_update"
1358    )]
1359    pub fn fetch_update<F>(
1360        &self,
1361        set_order: Ordering,
1362        fetch_order: Ordering,
1363        f: F,
1364    ) -> Result<bool, bool>
1365    where
1366        F: FnMut(bool) -> Option<bool>,
1367    {
1368        self.try_update(set_order, fetch_order, f)
1369    }
1370
1371    /// Fetches the value, and applies a function to it that returns an optional
1372    /// new value. Returns a `Result` of `Ok(previous_value)` if the function
1373    /// returned `Some(_)`, else `Err(previous_value)`.
1374    ///
1375    /// See also: [`update`](`AtomicBool::update`).
1376    ///
1377    /// Note: This may call the function multiple times if the value has been
1378    /// changed from other threads in the meantime, as long as the function
1379    /// returns `Some(_)`, but the function will have been applied only once to
1380    /// the stored value.
1381    ///
1382    /// `try_update` takes two [`Ordering`] arguments to describe the memory
1383    /// ordering of this operation. The first describes the required ordering for
1384    /// when the operation finally succeeds while the second describes the
1385    /// required ordering for loads. These correspond to the success and failure
1386    /// orderings of [`AtomicBool::compare_exchange`] respectively.
1387    ///
1388    /// Using [`Acquire`] as success ordering makes the store part of this
1389    /// operation [`Relaxed`], and using [`Release`] makes the final successful
1390    /// load [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`],
1391    /// [`Acquire`] or [`Relaxed`].
1392    ///
1393    /// **Note:** This method is only available on platforms that support atomic
1394    /// operations on `u8`.
1395    ///
1396    /// # Considerations
1397    ///
1398    /// This method is not magic; it is not provided by the hardware, and does not act like a
1399    /// critical section or mutex.
1400    ///
1401    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
1402    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem].
1403    ///
1404    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
1405    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
1406    ///
1407    /// # Examples
1408    ///
1409    /// ```rust
1410    /// use std::sync::atomic::{AtomicBool, Ordering};
1411    ///
1412    /// let x = AtomicBool::new(false);
1413    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(false));
1414    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(!x)), Ok(false));
1415    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(!x)), Ok(true));
1416    /// assert_eq!(x.load(Ordering::SeqCst), false);
1417    /// ```
1418    #[inline]
1419    #[stable(feature = "atomic_try_update", since = "1.95.0")]
1420    #[cfg(target_has_atomic = "8")]
1421    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1422    #[rustc_should_not_be_called_on_const_items]
1423    pub fn try_update(
1424        &self,
1425        set_order: Ordering,
1426        fetch_order: Ordering,
1427        mut f: impl FnMut(bool) -> Option<bool>,
1428    ) -> Result<bool, bool> {
1429        let mut prev = self.load(fetch_order);
1430        while let Some(next) = f(prev) {
1431            match self.compare_exchange_weak(prev, next, set_order, fetch_order) {
1432                x @ Ok(_) => return x,
1433                Err(next_prev) => prev = next_prev,
1434            }
1435        }
1436        Err(prev)
1437    }
1438
1439    /// Fetches the value, applies a function to it that it return a new value.
1440    /// The new value is stored and the old value is returned.
1441    ///
1442    /// See also: [`try_update`](`AtomicBool::try_update`).
1443    ///
1444    /// Note: This may call the function multiple times if the value has been changed from other threads in
1445    /// the meantime, but the function will have been applied only once to the stored value.
1446    ///
1447    /// `update` takes two [`Ordering`] arguments to describe the memory
1448    /// ordering of this operation. The first describes the required ordering for
1449    /// when the operation finally succeeds while the second describes the
1450    /// required ordering for loads. These correspond to the success and failure
1451    /// orderings of [`AtomicBool::compare_exchange`] respectively.
1452    ///
1453    /// Using [`Acquire`] as success ordering makes the store part
1454    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
1455    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
1456    ///
1457    /// **Note:** This method is only available on platforms that support atomic operations on `u8`.
1458    ///
1459    /// # Considerations
1460    ///
1461    /// This method is not magic; it is not provided by the hardware, and does not act like a
1462    /// critical section or mutex.
1463    ///
1464    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
1465    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem].
1466    ///
1467    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
1468    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
1469    ///
1470    /// # Examples
1471    ///
1472    /// ```rust
1473    ///
1474    /// use std::sync::atomic::{AtomicBool, Ordering};
1475    ///
1476    /// let x = AtomicBool::new(false);
1477    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| !x), false);
1478    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| !x), true);
1479    /// assert_eq!(x.load(Ordering::SeqCst), false);
1480    /// ```
1481    #[inline]
1482    #[stable(feature = "atomic_try_update", since = "1.95.0")]
1483    #[cfg(target_has_atomic = "8")]
1484    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1485    #[rustc_should_not_be_called_on_const_items]
1486    pub fn update(
1487        &self,
1488        set_order: Ordering,
1489        fetch_order: Ordering,
1490        mut f: impl FnMut(bool) -> bool,
1491    ) -> bool {
1492        let mut prev = self.load(fetch_order);
1493        loop {
1494            match self.compare_exchange_weak(prev, f(prev), set_order, fetch_order) {
1495                Ok(x) => break x,
1496                Err(next_prev) => prev = next_prev,
1497            }
1498        }
1499    }
1500}
1501
1502#[cfg(target_has_atomic_load_store = "ptr")]
1503impl<T> AtomicPtr<T> {
1504    /// Creates a new `AtomicPtr`.
1505    ///
1506    /// # Examples
1507    ///
1508    /// ```
1509    /// use std::sync::atomic::AtomicPtr;
1510    ///
1511    /// let ptr = &mut 5;
1512    /// let atomic_ptr = AtomicPtr::new(ptr);
1513    /// ```
1514    #[inline]
1515    #[stable(feature = "rust1", since = "1.0.0")]
1516    #[rustc_const_stable(feature = "const_atomic_new", since = "1.24.0")]
1517    pub const fn new(p: *mut T) -> AtomicPtr<T> {
1518        // SAFETY:
1519        // `Atomic<T>` is essentially a transparent wrapper around `T`.
1520        unsafe { transmute(p) }
1521    }
1522
1523    /// Creates a new `AtomicPtr` from a pointer.
1524    ///
1525    /// # Examples
1526    ///
1527    /// ```
1528    /// use std::sync::atomic::{self, AtomicPtr};
1529    ///
1530    /// // Get a pointer to an allocated value
1531    /// let ptr: *mut *mut u8 = Box::into_raw(Box::new(std::ptr::null_mut()));
1532    ///
1533    /// assert!(ptr.cast::<AtomicPtr<u8>>().is_aligned());
1534    ///
1535    /// {
1536    ///     // Create an atomic view of the allocated value
1537    ///     let atomic = unsafe { AtomicPtr::from_ptr(ptr) };
1538    ///
1539    ///     // Use `atomic` for atomic operations, possibly share it with other threads
1540    ///     atomic.store(std::ptr::NonNull::dangling().as_ptr(), atomic::Ordering::Relaxed);
1541    /// }
1542    ///
1543    /// // It's ok to non-atomically access the value behind `ptr`,
1544    /// // since the reference to the atomic ended its lifetime in the block above
1545    /// assert!(!unsafe { *ptr }.is_null());
1546    ///
1547    /// // Deallocate the value
1548    /// unsafe { drop(Box::from_raw(ptr)) }
1549    /// ```
1550    ///
1551    /// # Safety
1552    ///
1553    /// * `ptr` must be aligned to `align_of::<AtomicPtr<T>>()` (note that on some platforms this
1554    ///   can be bigger than `align_of::<*mut T>()`).
1555    /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
1556    /// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not
1557    ///   allowed to mix conflicting atomic and non-atomic accesses, or atomic accesses of different
1558    ///   sizes, without synchronization.
1559    ///
1560    /// [valid]: crate::ptr#safety
1561    /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
1562    #[inline]
1563    #[stable(feature = "atomic_from_ptr", since = "1.75.0")]
1564    #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")]
1565    pub const unsafe fn from_ptr<'a>(ptr: *mut *mut T) -> &'a AtomicPtr<T> {
1566        // SAFETY: guaranteed by the caller
1567        unsafe { &*ptr.cast() }
1568    }
1569
1570    /// Creates a new `AtomicPtr` initialized with a null pointer.
1571    ///
1572    /// # Examples
1573    ///
1574    /// ```
1575    /// #![feature(atomic_ptr_null)]
1576    /// use std::sync::atomic::{AtomicPtr, Ordering};
1577    ///
1578    /// let atomic_ptr = AtomicPtr::<()>::null();
1579    /// assert!(atomic_ptr.load(Ordering::Relaxed).is_null());
1580    /// ```
1581    #[inline]
1582    #[must_use]
1583    #[unstable(feature = "atomic_ptr_null", issue = "150733")]
1584    pub const fn null() -> AtomicPtr<T> {
1585        AtomicPtr::new(crate::ptr::null_mut())
1586    }
1587
1588    /// Returns a mutable reference to the underlying pointer.
1589    ///
1590    /// This is safe because the mutable reference guarantees that no other threads are
1591    /// concurrently accessing the atomic data.
1592    ///
1593    /// # Examples
1594    ///
1595    /// ```
1596    /// use std::sync::atomic::{AtomicPtr, Ordering};
1597    ///
1598    /// let mut data = 10;
1599    /// let mut atomic_ptr = AtomicPtr::new(&mut data);
1600    /// let mut other_data = 5;
1601    /// *atomic_ptr.get_mut() = &mut other_data;
1602    /// assert_eq!(unsafe { *atomic_ptr.load(Ordering::SeqCst) }, 5);
1603    /// ```
1604    #[inline]
1605    #[stable(feature = "atomic_access", since = "1.15.0")]
1606    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1607    pub const fn get_mut(&mut self) -> &mut *mut T {
1608        // SAFETY:
1609        // `Atomic<T>` is essentially a transparent wrapper around `T`.
1610        unsafe { &mut *self.as_ptr() }
1611    }
1612
1613    /// Gets atomic access to a pointer.
1614    ///
1615    /// **Note:** This function is only available on targets where `AtomicPtr<T>` has the same alignment as `*const T`
1616    ///
1617    /// # Examples
1618    ///
1619    /// ```
1620    /// use std::sync::atomic::{AtomicPtr, Ordering};
1621    ///
1622    /// let mut data = 123;
1623    /// let mut some_ptr = &mut data as *mut i32;
1624    /// let a = AtomicPtr::from_mut(&mut some_ptr);
1625    /// let mut other_data = 456;
1626    /// a.store(&mut other_data, Ordering::Relaxed);
1627    /// assert_eq!(unsafe { *some_ptr }, 456);
1628    /// ```
1629    #[inline]
1630    #[cfg(target_has_atomic_primitive_alignment = "ptr")]
1631    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
1632    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1633    pub const fn from_mut(v: &mut *mut T) -> &mut Self {
1634        let [] = [(); align_of::<AtomicPtr<()>>() - align_of::<*mut ()>()];
1635        // SAFETY:
1636        //  - the mutable reference guarantees unique ownership.
1637        //  - the alignment of `*mut T` and `Self` is the same on all platforms
1638        //    supported by rust, as verified above.
1639        unsafe { &mut *(v as *mut *mut T as *mut Self) }
1640    }
1641
1642    /// Gets non-atomic access to a `&mut [AtomicPtr]` slice.
1643    ///
1644    /// This is safe because the mutable reference guarantees that no other threads are
1645    /// concurrently accessing the atomic data.
1646    ///
1647    /// # Examples
1648    ///
1649    /// ```ignore-wasm
1650    /// use std::ptr::null_mut;
1651    /// use std::sync::atomic::{AtomicPtr, Ordering};
1652    ///
1653    /// let mut some_ptrs = [const { AtomicPtr::new(null_mut::<String>()) }; 10];
1654    ///
1655    /// let view: &mut [*mut String] = AtomicPtr::get_mut_slice(&mut some_ptrs);
1656    /// assert_eq!(view, [null_mut::<String>(); 10]);
1657    /// view
1658    ///     .iter_mut()
1659    ///     .enumerate()
1660    ///     .for_each(|(i, ptr)| *ptr = Box::into_raw(Box::new(format!("iteration#{i}"))));
1661    ///
1662    /// std::thread::scope(|s| {
1663    ///     for ptr in &some_ptrs {
1664    ///         s.spawn(move || {
1665    ///             let ptr = ptr.load(Ordering::Relaxed);
1666    ///             assert!(!ptr.is_null());
1667    ///
1668    ///             let name = unsafe { Box::from_raw(ptr) };
1669    ///             println!("Hello, {name}!");
1670    ///         });
1671    ///     }
1672    /// });
1673    /// ```
1674    #[inline]
1675    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
1676    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1677    pub const fn get_mut_slice(this: &mut [Self]) -> &mut [*mut T] {
1678        // SAFETY: the mutable reference guarantees unique ownership.
1679        unsafe { &mut *(this as *mut [Self] as *mut [*mut T]) }
1680    }
1681
1682    /// Gets atomic access to a slice of pointers.
1683    ///
1684    /// **Note:** This function is only available on targets where `AtomicPtr<T>` has the same alignment as `*const T`
1685    ///
1686    /// # Examples
1687    ///
1688    /// ```ignore-wasm
1689    /// use std::ptr::null_mut;
1690    /// use std::sync::atomic::{AtomicPtr, Ordering};
1691    ///
1692    /// let mut some_ptrs = [null_mut::<String>(); 10];
1693    /// let a = &*AtomicPtr::from_mut_slice(&mut some_ptrs);
1694    /// std::thread::scope(|s| {
1695    ///     for i in 0..a.len() {
1696    ///         s.spawn(move || {
1697    ///             let name = Box::new(format!("thread{i}"));
1698    ///             a[i].store(Box::into_raw(name), Ordering::Relaxed);
1699    ///         });
1700    ///     }
1701    /// });
1702    /// for p in some_ptrs {
1703    ///     assert!(!p.is_null());
1704    ///     let name = unsafe { Box::from_raw(p) };
1705    ///     println!("Hello, {name}!");
1706    /// }
1707    /// ```
1708    #[inline]
1709    #[cfg(target_has_atomic_primitive_alignment = "ptr")]
1710    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
1711    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1712    pub const fn from_mut_slice(v: &mut [*mut T]) -> &mut [Self] {
1713        // SAFETY:
1714        //  - the mutable reference guarantees unique ownership.
1715        //  - the alignment of `*mut T` and `Self` is the same on all platforms
1716        //    supported by rust, as verified above.
1717        unsafe { &mut *(v as *mut [*mut T] as *mut [Self]) }
1718    }
1719
1720    /// Consumes the atomic and returns the contained value.
1721    ///
1722    /// This is safe because passing `self` by value guarantees that no other threads are
1723    /// concurrently accessing the atomic data.
1724    ///
1725    /// # Examples
1726    ///
1727    /// ```
1728    /// use std::sync::atomic::AtomicPtr;
1729    ///
1730    /// let mut data = 5;
1731    /// let atomic_ptr = AtomicPtr::new(&mut data);
1732    /// assert_eq!(unsafe { *atomic_ptr.into_inner() }, 5);
1733    /// ```
1734    #[inline]
1735    #[stable(feature = "atomic_access", since = "1.15.0")]
1736    #[rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0")]
1737    pub const fn into_inner(self) -> *mut T {
1738        // SAFETY:
1739        // `Atomic<T>` is essentially a transparent wrapper around `T`.
1740        unsafe { transmute(self) }
1741    }
1742
1743    /// Loads a value from the pointer.
1744    ///
1745    /// `load` takes an [`Ordering`] argument which describes the memory ordering
1746    /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
1747    ///
1748    /// # Panics
1749    ///
1750    /// Panics if `order` is [`Release`] or [`AcqRel`].
1751    ///
1752    /// # Examples
1753    ///
1754    /// ```
1755    /// use std::sync::atomic::{AtomicPtr, Ordering};
1756    ///
1757    /// let ptr = &mut 5;
1758    /// let some_ptr = AtomicPtr::new(ptr);
1759    ///
1760    /// let value = some_ptr.load(Ordering::Relaxed);
1761    /// ```
1762    #[inline]
1763    #[stable(feature = "rust1", since = "1.0.0")]
1764    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1765    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1766    pub const fn load(&self, order: Ordering) -> *mut T {
1767        // SAFETY: data races are prevented by atomic intrinsics.
1768        unsafe {
1769            atomic_load::<_, /* VOLATILE */ false>(self.as_ptr(), order)
1770        }
1771    }
1772
1773    /// Stores a value into the pointer.
1774    ///
1775    /// `store` takes an [`Ordering`] argument which describes the memory ordering
1776    /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
1777    ///
1778    /// # Panics
1779    ///
1780    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
1781    ///
1782    /// # Examples
1783    ///
1784    /// ```
1785    /// use std::sync::atomic::{AtomicPtr, Ordering};
1786    ///
1787    /// let ptr = &mut 5;
1788    /// let some_ptr = AtomicPtr::new(ptr);
1789    ///
1790    /// let other_ptr = &mut 10;
1791    ///
1792    /// some_ptr.store(other_ptr, Ordering::Relaxed);
1793    /// ```
1794    #[inline]
1795    #[stable(feature = "rust1", since = "1.0.0")]
1796    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1797    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1798    #[rustc_should_not_be_called_on_const_items]
1799    pub const fn store(&self, ptr: *mut T, order: Ordering) {
1800        // SAFETY: data races are prevented by atomic intrinsics.
1801        unsafe {
1802            atomic_store::<_, /* VOLATILE */ false>(self.as_ptr(), ptr, order);
1803        }
1804    }
1805
1806    /// Stores a value into the pointer, returning the previous value.
1807    ///
1808    /// `swap` takes an [`Ordering`] argument which describes the memory ordering
1809    /// of this operation. All ordering modes are possible. Note that using
1810    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
1811    /// using [`Release`] makes the load part [`Relaxed`].
1812    ///
1813    /// **Note:** This method is only available on platforms that support atomic
1814    /// operations on pointers.
1815    ///
1816    /// # Examples
1817    ///
1818    /// ```
1819    /// use std::sync::atomic::{AtomicPtr, Ordering};
1820    ///
1821    /// let ptr = &mut 5;
1822    /// let some_ptr = AtomicPtr::new(ptr);
1823    ///
1824    /// let other_ptr = &mut 10;
1825    ///
1826    /// let value = some_ptr.swap(other_ptr, Ordering::Relaxed);
1827    /// ```
1828    #[inline]
1829    #[stable(feature = "rust1", since = "1.0.0")]
1830    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1831    #[cfg(target_has_atomic = "ptr")]
1832    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1833    #[rustc_should_not_be_called_on_const_items]
1834    pub const fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T {
1835        // SAFETY: data races are prevented by atomic intrinsics.
1836        unsafe { atomic_swap(self.as_ptr(), ptr, order) }
1837    }
1838
1839    /// Stores a value into the pointer if the current value is the same as the `current` value.
1840    ///
1841    /// The return value is always the previous value. If it is equal to `current`, then the value
1842    /// was updated.
1843    ///
1844    /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
1845    /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
1846    /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
1847    /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
1848    /// happens, and using [`Release`] makes the load part [`Relaxed`].
1849    ///
1850    /// **Note:** This method is only available on platforms that support atomic
1851    /// operations on pointers.
1852    ///
1853    /// # Migrating to `compare_exchange` and `compare_exchange_weak`
1854    ///
1855    /// `compare_and_swap` is equivalent to `compare_exchange` with the following mapping for
1856    /// memory orderings:
1857    ///
1858    /// Original | Success | Failure
1859    /// -------- | ------- | -------
1860    /// Relaxed  | Relaxed | Relaxed
1861    /// Acquire  | Acquire | Acquire
1862    /// Release  | Release | Relaxed
1863    /// AcqRel   | AcqRel  | Acquire
1864    /// SeqCst   | SeqCst  | SeqCst
1865    ///
1866    /// `compare_and_swap` and `compare_exchange` also differ in their return type. You can use
1867    /// `compare_exchange(...).unwrap_or_else(|x| x)` to recover the behavior of `compare_and_swap`,
1868    /// but in most cases it is more idiomatic to check whether the return value is `Ok` or `Err`
1869    /// rather than to infer success vs failure based on the value that was read.
1870    ///
1871    /// During migration, consider whether it makes sense to use `compare_exchange_weak` instead.
1872    /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds,
1873    /// which allows the compiler to generate better assembly code when the compare and swap
1874    /// is used in a loop.
1875    ///
1876    /// # Examples
1877    ///
1878    /// ```
1879    /// use std::sync::atomic::{AtomicPtr, Ordering};
1880    ///
1881    /// let ptr = &mut 5;
1882    /// let some_ptr = AtomicPtr::new(ptr);
1883    ///
1884    /// let other_ptr = &mut 10;
1885    ///
1886    /// let value = some_ptr.compare_and_swap(ptr, other_ptr, Ordering::Relaxed);
1887    /// ```
1888    #[inline]
1889    #[stable(feature = "rust1", since = "1.0.0")]
1890    #[deprecated(
1891        since = "1.50.0",
1892        note = "Use `compare_exchange` or `compare_exchange_weak` instead"
1893    )]
1894    #[cfg(target_has_atomic = "ptr")]
1895    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1896    #[rustc_should_not_be_called_on_const_items]
1897    pub fn compare_and_swap(&self, current: *mut T, new: *mut T, order: Ordering) -> *mut T {
1898        match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) {
1899            Ok(x) => x,
1900            Err(x) => x,
1901        }
1902    }
1903
1904    /// Stores a value into the pointer if the current value is the same as the `current` value.
1905    ///
1906    /// The return value is a result indicating whether the new value was written and containing
1907    /// the previous value. On success this value is guaranteed to be equal to `current`.
1908    ///
1909    /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
1910    /// ordering of this operation. `success` describes the required ordering for the
1911    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
1912    /// `failure` describes the required ordering for the load operation that takes place when
1913    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
1914    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
1915    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
1916    ///
1917    /// **Note:** This method is only available on platforms that support atomic
1918    /// operations on pointers.
1919    ///
1920    /// # Examples
1921    ///
1922    /// ```
1923    /// use std::sync::atomic::{AtomicPtr, Ordering};
1924    ///
1925    /// let ptr = &mut 5;
1926    /// let some_ptr = AtomicPtr::new(ptr);
1927    ///
1928    /// let other_ptr = &mut 10;
1929    ///
1930    /// let value = some_ptr.compare_exchange(ptr, other_ptr,
1931    ///                                       Ordering::SeqCst, Ordering::Relaxed);
1932    /// ```
1933    ///
1934    /// # Considerations
1935    ///
1936    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
1937    /// of CAS operations. In particular, a load of the value followed by a successful
1938    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
1939    /// changed the value in the interim. This is usually important when the *equality* check in
1940    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
1941    /// does not necessarily imply identity. This is a particularly common case for pointers, as
1942    /// a pointer holding the same address does not imply that the same object exists at that
1943    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
1944    ///
1945    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
1946    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
1947    #[inline]
1948    #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
1949    #[cfg(target_has_atomic = "ptr")]
1950    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1951    #[rustc_should_not_be_called_on_const_items]
1952    pub fn compare_exchange(
1953        &self,
1954        current: *mut T,
1955        new: *mut T,
1956        success: Ordering,
1957        failure: Ordering,
1958    ) -> Result<*mut T, *mut T> {
1959        // SAFETY: data races are prevented by atomic intrinsics.
1960        unsafe { atomic_compare_exchange(self.as_ptr(), current, new, success, failure) }
1961    }
1962
1963    /// Stores a value into the pointer if the current value is the same as the `current` value.
1964    ///
1965    /// Unlike [`AtomicPtr::compare_exchange`], this function is allowed to spuriously fail even when the
1966    /// comparison succeeds, which can result in more efficient code on some platforms. The
1967    /// return value is a result indicating whether the new value was written and containing the
1968    /// previous value.
1969    ///
1970    /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
1971    /// ordering of this operation. `success` describes the required ordering for the
1972    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
1973    /// `failure` describes the required ordering for the load operation that takes place when
1974    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
1975    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
1976    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
1977    ///
1978    /// **Note:** This method is only available on platforms that support atomic
1979    /// operations on pointers.
1980    ///
1981    /// # Examples
1982    ///
1983    /// ```
1984    /// use std::sync::atomic::{AtomicPtr, Ordering};
1985    ///
1986    /// let some_ptr = AtomicPtr::new(&mut 5);
1987    ///
1988    /// let new = &mut 10;
1989    /// let mut old = some_ptr.load(Ordering::Relaxed);
1990    /// loop {
1991    ///     match some_ptr.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
1992    ///         Ok(_) => break,
1993    ///         Err(x) => old = x,
1994    ///     }
1995    /// }
1996    /// ```
1997    ///
1998    /// # Considerations
1999    ///
2000    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
2001    /// of CAS operations. In particular, a load of the value followed by a successful
2002    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
2003    /// changed the value in the interim. This is usually important when the *equality* check in
2004    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
2005    /// does not necessarily imply identity. This is a particularly common case for pointers, as
2006    /// a pointer holding the same address does not imply that the same object exists at that
2007    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
2008    ///
2009    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
2010    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
2011    #[inline]
2012    #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
2013    #[cfg(target_has_atomic = "ptr")]
2014    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2015    #[rustc_should_not_be_called_on_const_items]
2016    pub fn compare_exchange_weak(
2017        &self,
2018        current: *mut T,
2019        new: *mut T,
2020        success: Ordering,
2021        failure: Ordering,
2022    ) -> Result<*mut T, *mut T> {
2023        // SAFETY: This intrinsic is unsafe because it operates on a raw pointer
2024        // but we know for sure that the pointer is valid (we just got it from
2025        // an `UnsafeCell` that we have by reference) and the atomic operation
2026        // itself allows us to safely mutate the `UnsafeCell` contents.
2027        unsafe { atomic_compare_exchange_weak(self.as_ptr(), current, new, success, failure) }
2028    }
2029
2030    /// An alias for [`AtomicPtr::try_update`].
2031    #[inline]
2032    #[stable(feature = "atomic_fetch_update", since = "1.53.0")]
2033    #[cfg(target_has_atomic = "ptr")]
2034    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2035    #[rustc_should_not_be_called_on_const_items]
2036    #[deprecated(
2037        since = "1.99.0",
2038        note = "renamed to `try_update` for consistency",
2039        suggestion = "try_update"
2040    )]
2041    pub fn fetch_update<F>(
2042        &self,
2043        set_order: Ordering,
2044        fetch_order: Ordering,
2045        f: F,
2046    ) -> Result<*mut T, *mut T>
2047    where
2048        F: FnMut(*mut T) -> Option<*mut T>,
2049    {
2050        self.try_update(set_order, fetch_order, f)
2051    }
2052    /// Fetches the value, and applies a function to it that returns an optional
2053    /// new value. Returns a `Result` of `Ok(previous_value)` if the function
2054    /// returned `Some(_)`, else `Err(previous_value)`.
2055    ///
2056    /// See also: [`update`](`AtomicPtr::update`).
2057    ///
2058    /// Note: This may call the function multiple times if the value has been
2059    /// changed from other threads in the meantime, as long as the function
2060    /// returns `Some(_)`, but the function will have been applied only once to
2061    /// the stored value.
2062    ///
2063    /// `try_update` takes two [`Ordering`] arguments to describe the memory
2064    /// ordering of this operation. The first describes the required ordering for
2065    /// when the operation finally succeeds while the second describes the
2066    /// required ordering for loads. These correspond to the success and failure
2067    /// orderings of [`AtomicPtr::compare_exchange`] respectively.
2068    ///
2069    /// Using [`Acquire`] as success ordering makes the store part of this
2070    /// operation [`Relaxed`], and using [`Release`] makes the final successful
2071    /// load [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`],
2072    /// [`Acquire`] or [`Relaxed`].
2073    ///
2074    /// **Note:** This method is only available on platforms that support atomic
2075    /// operations on pointers.
2076    ///
2077    /// # Considerations
2078    ///
2079    /// This method is not magic; it is not provided by the hardware, and does not act like a
2080    /// critical section or mutex.
2081    ///
2082    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
2083    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem],
2084    /// which is a particularly common pitfall for pointers!
2085    ///
2086    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
2087    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
2088    ///
2089    /// # Examples
2090    ///
2091    /// ```rust
2092    /// use std::sync::atomic::{AtomicPtr, Ordering};
2093    ///
2094    /// let ptr: *mut _ = &mut 5;
2095    /// let some_ptr = AtomicPtr::new(ptr);
2096    ///
2097    /// let new: *mut _ = &mut 10;
2098    /// assert_eq!(some_ptr.try_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(ptr));
2099    /// let result = some_ptr.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| {
2100    ///     if x == ptr {
2101    ///         Some(new)
2102    ///     } else {
2103    ///         None
2104    ///     }
2105    /// });
2106    /// assert_eq!(result, Ok(ptr));
2107    /// assert_eq!(some_ptr.load(Ordering::SeqCst), new);
2108    /// ```
2109    #[inline]
2110    #[stable(feature = "atomic_try_update", since = "1.95.0")]
2111    #[cfg(target_has_atomic = "ptr")]
2112    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2113    #[rustc_should_not_be_called_on_const_items]
2114    pub fn try_update(
2115        &self,
2116        set_order: Ordering,
2117        fetch_order: Ordering,
2118        mut f: impl FnMut(*mut T) -> Option<*mut T>,
2119    ) -> Result<*mut T, *mut T> {
2120        let mut prev = self.load(fetch_order);
2121        while let Some(next) = f(prev) {
2122            match self.compare_exchange_weak(prev, next, set_order, fetch_order) {
2123                x @ Ok(_) => return x,
2124                Err(next_prev) => prev = next_prev,
2125            }
2126        }
2127        Err(prev)
2128    }
2129
2130    /// Fetches the value, applies a function to it that it return a new value.
2131    /// The new value is stored and the old value is returned.
2132    ///
2133    /// See also: [`try_update`](`AtomicPtr::try_update`).
2134    ///
2135    /// Note: This may call the function multiple times if the value has been changed from other threads in
2136    /// the meantime, but the function will have been applied only once to the stored value.
2137    ///
2138    /// `update` takes two [`Ordering`] arguments to describe the memory
2139    /// ordering of this operation. The first describes the required ordering for
2140    /// when the operation finally succeeds while the second describes the
2141    /// required ordering for loads. These correspond to the success and failure
2142    /// orderings of [`AtomicPtr::compare_exchange`] respectively.
2143    ///
2144    /// Using [`Acquire`] as success ordering makes the store part
2145    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
2146    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
2147    ///
2148    /// **Note:** This method is only available on platforms that support atomic
2149    /// operations on pointers.
2150    ///
2151    /// # Considerations
2152    ///
2153    /// This method is not magic; it is not provided by the hardware, and does not act like a
2154    /// critical section or mutex.
2155    ///
2156    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
2157    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem],
2158    /// which is a particularly common pitfall for pointers!
2159    ///
2160    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
2161    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
2162    ///
2163    /// # Examples
2164    ///
2165    /// ```rust
2166    ///
2167    /// use std::sync::atomic::{AtomicPtr, Ordering};
2168    ///
2169    /// let ptr: *mut _ = &mut 5;
2170    /// let some_ptr = AtomicPtr::new(ptr);
2171    ///
2172    /// let new: *mut _ = &mut 10;
2173    /// let result = some_ptr.update(Ordering::SeqCst, Ordering::SeqCst, |_| new);
2174    /// assert_eq!(result, ptr);
2175    /// assert_eq!(some_ptr.load(Ordering::SeqCst), new);
2176    /// ```
2177    #[inline]
2178    #[stable(feature = "atomic_try_update", since = "1.95.0")]
2179    #[cfg(target_has_atomic = "ptr")]
2180    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2181    #[rustc_should_not_be_called_on_const_items]
2182    pub fn update(
2183        &self,
2184        set_order: Ordering,
2185        fetch_order: Ordering,
2186        mut f: impl FnMut(*mut T) -> *mut T,
2187    ) -> *mut T {
2188        let mut prev = self.load(fetch_order);
2189        loop {
2190            match self.compare_exchange_weak(prev, f(prev), set_order, fetch_order) {
2191                Ok(x) => break x,
2192                Err(next_prev) => prev = next_prev,
2193            }
2194        }
2195    }
2196
2197    /// Offsets the pointer's address by adding `val` (in units of `T`),
2198    /// returning the previous pointer.
2199    ///
2200    /// This is equivalent to using [`wrapping_add`] to atomically perform the
2201    /// equivalent of `ptr = ptr.wrapping_add(val);`.
2202    ///
2203    /// This method operates in units of `T`, which means that it cannot be used
2204    /// to offset the pointer by an amount which is not a multiple of
2205    /// `size_of::<T>()`. This can sometimes be inconvenient, as you may want to
2206    /// work with a deliberately misaligned pointer. In such cases, you may use
2207    /// the [`fetch_byte_add`](Self::fetch_byte_add) method instead.
2208    ///
2209    /// `fetch_ptr_add` takes an [`Ordering`] argument which describes the
2210    /// memory ordering of this operation. All ordering modes are possible. Note
2211    /// that using [`Acquire`] makes the store part of this operation
2212    /// [`Relaxed`], and using [`Release`] makes the load part [`Relaxed`].
2213    ///
2214    /// **Note**: This method is only available on platforms that support atomic
2215    /// operations on [`AtomicPtr`].
2216    ///
2217    /// [`wrapping_add`]: pointer::wrapping_add
2218    ///
2219    /// # Examples
2220    ///
2221    /// ```
2222    /// use core::sync::atomic::{AtomicPtr, Ordering};
2223    ///
2224    /// let atom = AtomicPtr::<i64>::new(core::ptr::null_mut());
2225    /// assert_eq!(atom.fetch_ptr_add(1, Ordering::Relaxed).addr(), 0);
2226    /// // Note: units of `size_of::<i64>()`.
2227    /// assert_eq!(atom.load(Ordering::Relaxed).addr(), 8);
2228    /// ```
2229    #[inline]
2230    #[cfg(target_has_atomic = "ptr")]
2231    #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")]
2232    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2233    #[rustc_should_not_be_called_on_const_items]
2234    pub fn fetch_ptr_add(&self, val: usize, order: Ordering) -> *mut T {
2235        self.fetch_byte_add(val.wrapping_mul(size_of::<T>()), order)
2236    }
2237
2238    /// Offsets the pointer's address by subtracting `val` (in units of `T`),
2239    /// returning the previous pointer.
2240    ///
2241    /// This is equivalent to using [`wrapping_sub`] to atomically perform the
2242    /// equivalent of `ptr = ptr.wrapping_sub(val);`.
2243    ///
2244    /// This method operates in units of `T`, which means that it cannot be used
2245    /// to offset the pointer by an amount which is not a multiple of
2246    /// `size_of::<T>()`. This can sometimes be inconvenient, as you may want to
2247    /// work with a deliberately misaligned pointer. In such cases, you may use
2248    /// the [`fetch_byte_sub`](Self::fetch_byte_sub) method instead.
2249    ///
2250    /// `fetch_ptr_sub` takes an [`Ordering`] argument which describes the memory
2251    /// ordering of this operation. All ordering modes are possible. Note that
2252    /// using [`Acquire`] makes the store part of this operation [`Relaxed`],
2253    /// and using [`Release`] makes the load part [`Relaxed`].
2254    ///
2255    /// **Note**: This method is only available on platforms that support atomic
2256    /// operations on [`AtomicPtr`].
2257    ///
2258    /// [`wrapping_sub`]: pointer::wrapping_sub
2259    ///
2260    /// # Examples
2261    ///
2262    /// ```
2263    /// use core::sync::atomic::{AtomicPtr, Ordering};
2264    ///
2265    /// let array = [1i32, 2i32];
2266    /// let atom = AtomicPtr::new(array.as_ptr().wrapping_add(1) as *mut _);
2267    ///
2268    /// assert!(core::ptr::eq(
2269    ///     atom.fetch_ptr_sub(1, Ordering::Relaxed),
2270    ///     &array[1],
2271    /// ));
2272    /// assert!(core::ptr::eq(atom.load(Ordering::Relaxed), &array[0]));
2273    /// ```
2274    #[inline]
2275    #[cfg(target_has_atomic = "ptr")]
2276    #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")]
2277    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2278    #[rustc_should_not_be_called_on_const_items]
2279    pub fn fetch_ptr_sub(&self, val: usize, order: Ordering) -> *mut T {
2280        self.fetch_byte_sub(val.wrapping_mul(size_of::<T>()), order)
2281    }
2282
2283    /// Offsets the pointer's address by adding `val` *bytes*, returning the
2284    /// previous pointer.
2285    ///
2286    /// This is equivalent to using [`wrapping_byte_add`] to atomically
2287    /// perform `ptr = ptr.wrapping_byte_add(val)`.
2288    ///
2289    /// `fetch_byte_add` takes an [`Ordering`] argument which describes the
2290    /// memory ordering of this operation. All ordering modes are possible. Note
2291    /// that using [`Acquire`] makes the store part of this operation
2292    /// [`Relaxed`], and using [`Release`] makes the load part [`Relaxed`].
2293    ///
2294    /// **Note**: This method is only available on platforms that support atomic
2295    /// operations on [`AtomicPtr`].
2296    ///
2297    /// [`wrapping_byte_add`]: pointer::wrapping_byte_add
2298    ///
2299    /// # Examples
2300    ///
2301    /// ```
2302    /// use core::sync::atomic::{AtomicPtr, Ordering};
2303    ///
2304    /// let atom = AtomicPtr::<i64>::new(core::ptr::null_mut());
2305    /// assert_eq!(atom.fetch_byte_add(1, Ordering::Relaxed).addr(), 0);
2306    /// // Note: in units of bytes, not `size_of::<i64>()`.
2307    /// assert_eq!(atom.load(Ordering::Relaxed).addr(), 1);
2308    /// ```
2309    #[inline]
2310    #[cfg(target_has_atomic = "ptr")]
2311    #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")]
2312    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2313    #[rustc_should_not_be_called_on_const_items]
2314    pub fn fetch_byte_add(&self, val: usize, order: Ordering) -> *mut T {
2315        // SAFETY: data races are prevented by atomic intrinsics.
2316        unsafe { atomic_add(self.as_ptr(), val, order).cast() }
2317    }
2318
2319    /// Offsets the pointer's address by subtracting `val` *bytes*, returning the
2320    /// previous pointer.
2321    ///
2322    /// This is equivalent to using [`wrapping_byte_sub`] to atomically
2323    /// perform `ptr = ptr.wrapping_byte_sub(val)`.
2324    ///
2325    /// `fetch_byte_sub` takes an [`Ordering`] argument which describes the
2326    /// memory ordering of this operation. All ordering modes are possible. Note
2327    /// that using [`Acquire`] makes the store part of this operation
2328    /// [`Relaxed`], and using [`Release`] makes the load part [`Relaxed`].
2329    ///
2330    /// **Note**: This method is only available on platforms that support atomic
2331    /// operations on [`AtomicPtr`].
2332    ///
2333    /// [`wrapping_byte_sub`]: pointer::wrapping_byte_sub
2334    ///
2335    /// # Examples
2336    ///
2337    /// ```
2338    /// use core::sync::atomic::{AtomicPtr, Ordering};
2339    ///
2340    /// let mut arr = [0i64, 1];
2341    /// let atom = AtomicPtr::<i64>::new(&raw mut arr[1]);
2342    /// assert_eq!(atom.fetch_byte_sub(8, Ordering::Relaxed).addr(), (&raw const arr[1]).addr());
2343    /// assert_eq!(atom.load(Ordering::Relaxed).addr(), (&raw const arr[0]).addr());
2344    /// ```
2345    #[inline]
2346    #[cfg(target_has_atomic = "ptr")]
2347    #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")]
2348    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2349    #[rustc_should_not_be_called_on_const_items]
2350    pub fn fetch_byte_sub(&self, val: usize, order: Ordering) -> *mut T {
2351        // SAFETY: data races are prevented by atomic intrinsics.
2352        unsafe { atomic_sub(self.as_ptr(), val, order).cast() }
2353    }
2354
2355    /// Performs a bitwise "or" operation on the address of the current pointer,
2356    /// and the argument `val`, and stores a pointer with provenance of the
2357    /// current pointer and the resulting address.
2358    ///
2359    /// This is equivalent to using [`map_addr`] to atomically perform
2360    /// `ptr = ptr.map_addr(|a| a | val)`. This can be used in tagged
2361    /// pointer schemes to atomically set tag bits.
2362    ///
2363    /// **Caveat**: This operation returns the previous value. To compute the
2364    /// stored value without losing provenance, you may use [`map_addr`]. For
2365    /// example: `a.fetch_or(val).map_addr(|a| a | val)`.
2366    ///
2367    /// `fetch_or` takes an [`Ordering`] argument which describes the memory
2368    /// ordering of this operation. All ordering modes are possible. Note that
2369    /// using [`Acquire`] makes the store part of this operation [`Relaxed`],
2370    /// and using [`Release`] makes the load part [`Relaxed`].
2371    ///
2372    /// **Note**: This method is only available on platforms that support atomic
2373    /// operations on [`AtomicPtr`].
2374    ///
2375    /// This API and its claimed semantics are part of the Strict Provenance
2376    /// experiment, see the [module documentation for `ptr`][crate::ptr] for
2377    /// details.
2378    ///
2379    /// [`map_addr`]: pointer::map_addr
2380    ///
2381    /// # Examples
2382    ///
2383    /// ```
2384    /// use core::sync::atomic::{AtomicPtr, Ordering};
2385    ///
2386    /// let pointer = &mut 3i64 as *mut i64;
2387    ///
2388    /// let atom = AtomicPtr::<i64>::new(pointer);
2389    /// // Tag the bottom bit of the pointer.
2390    /// assert_eq!(atom.fetch_or(1, Ordering::Relaxed).addr() & 1, 0);
2391    /// // Extract and untag.
2392    /// let tagged = atom.load(Ordering::Relaxed);
2393    /// assert_eq!(tagged.addr() & 1, 1);
2394    /// assert_eq!(tagged.map_addr(|p| p & !1), pointer);
2395    /// ```
2396    #[inline]
2397    #[cfg(target_has_atomic = "ptr")]
2398    #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")]
2399    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2400    #[rustc_should_not_be_called_on_const_items]
2401    pub fn fetch_or(&self, val: usize, order: Ordering) -> *mut T {
2402        // SAFETY: data races are prevented by atomic intrinsics.
2403        unsafe { atomic_or(self.as_ptr(), val, order).cast() }
2404    }
2405
2406    /// Performs a bitwise "and" operation on the address of the current
2407    /// pointer, and the argument `val`, and stores a pointer with provenance of
2408    /// the current pointer and the resulting address.
2409    ///
2410    /// This is equivalent to using [`map_addr`] to atomically perform
2411    /// `ptr = ptr.map_addr(|a| a & val)`. This can be used in tagged
2412    /// pointer schemes to atomically unset tag bits.
2413    ///
2414    /// **Caveat**: This operation returns the previous value. To compute the
2415    /// stored value without losing provenance, you may use [`map_addr`]. For
2416    /// example: `a.fetch_and(val).map_addr(|a| a & val)`.
2417    ///
2418    /// `fetch_and` takes an [`Ordering`] argument which describes the memory
2419    /// ordering of this operation. All ordering modes are possible. Note that
2420    /// using [`Acquire`] makes the store part of this operation [`Relaxed`],
2421    /// and using [`Release`] makes the load part [`Relaxed`].
2422    ///
2423    /// **Note**: This method is only available on platforms that support atomic
2424    /// operations on [`AtomicPtr`].
2425    ///
2426    /// This API and its claimed semantics are part of the Strict Provenance
2427    /// experiment, see the [module documentation for `ptr`][crate::ptr] for
2428    /// details.
2429    ///
2430    /// [`map_addr`]: pointer::map_addr
2431    ///
2432    /// # Examples
2433    ///
2434    /// ```
2435    /// use core::sync::atomic::{AtomicPtr, Ordering};
2436    ///
2437    /// let pointer = &mut 3i64 as *mut i64;
2438    /// // A tagged pointer
2439    /// let atom = AtomicPtr::<i64>::new(pointer.map_addr(|a| a | 1));
2440    /// assert_eq!(atom.fetch_or(1, Ordering::Relaxed).addr() & 1, 1);
2441    /// // Untag, and extract the previously tagged pointer.
2442    /// let untagged = atom.fetch_and(!1, Ordering::Relaxed)
2443    ///     .map_addr(|a| a & !1);
2444    /// assert_eq!(untagged, pointer);
2445    /// ```
2446    #[inline]
2447    #[cfg(target_has_atomic = "ptr")]
2448    #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")]
2449    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2450    #[rustc_should_not_be_called_on_const_items]
2451    pub fn fetch_and(&self, val: usize, order: Ordering) -> *mut T {
2452        // SAFETY: data races are prevented by atomic intrinsics.
2453        unsafe { atomic_and(self.as_ptr(), val, order).cast() }
2454    }
2455
2456    /// Performs a bitwise "xor" operation on the address of the current
2457    /// pointer, and the argument `val`, and stores a pointer with provenance of
2458    /// the current pointer and the resulting address.
2459    ///
2460    /// This is equivalent to using [`map_addr`] to atomically perform
2461    /// `ptr = ptr.map_addr(|a| a ^ val)`. This can be used in tagged
2462    /// pointer schemes to atomically toggle tag bits.
2463    ///
2464    /// **Caveat**: This operation returns the previous value. To compute the
2465    /// stored value without losing provenance, you may use [`map_addr`]. For
2466    /// example: `a.fetch_xor(val).map_addr(|a| a ^ val)`.
2467    ///
2468    /// `fetch_xor` takes an [`Ordering`] argument which describes the memory
2469    /// ordering of this operation. All ordering modes are possible. Note that
2470    /// using [`Acquire`] makes the store part of this operation [`Relaxed`],
2471    /// and using [`Release`] makes the load part [`Relaxed`].
2472    ///
2473    /// **Note**: This method is only available on platforms that support atomic
2474    /// operations on [`AtomicPtr`].
2475    ///
2476    /// This API and its claimed semantics are part of the Strict Provenance
2477    /// experiment, see the [module documentation for `ptr`][crate::ptr] for
2478    /// details.
2479    ///
2480    /// [`map_addr`]: pointer::map_addr
2481    ///
2482    /// # Examples
2483    ///
2484    /// ```
2485    /// use core::sync::atomic::{AtomicPtr, Ordering};
2486    ///
2487    /// let pointer = &mut 3i64 as *mut i64;
2488    /// let atom = AtomicPtr::<i64>::new(pointer);
2489    ///
2490    /// // Toggle a tag bit on the pointer.
2491    /// atom.fetch_xor(1, Ordering::Relaxed);
2492    /// assert_eq!(atom.load(Ordering::Relaxed).addr() & 1, 1);
2493    /// ```
2494    #[inline]
2495    #[cfg(target_has_atomic = "ptr")]
2496    #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")]
2497    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2498    #[rustc_should_not_be_called_on_const_items]
2499    pub fn fetch_xor(&self, val: usize, order: Ordering) -> *mut T {
2500        // SAFETY: data races are prevented by atomic intrinsics.
2501        unsafe { atomic_xor(self.as_ptr(), val, order).cast() }
2502    }
2503
2504    /// Returns a mutable pointer to the underlying pointer.
2505    ///
2506    /// Doing non-atomic reads and writes on the resulting pointer can be a data race.
2507    /// This method is mostly useful for FFI, where the function signature may use
2508    /// `*mut *mut T` instead of `&AtomicPtr<T>`.
2509    ///
2510    /// Returning an `*mut` pointer from a shared reference to this atomic is safe because the
2511    /// atomic types work with interior mutability. All modifications of an atomic change the value
2512    /// through a shared reference, and can do so safely as long as they use atomic operations. Any
2513    /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the
2514    /// requirements of the [memory model].
2515    ///
2516    /// # Examples
2517    ///
2518    /// ```ignore (extern-declaration)
2519    /// use std::sync::atomic::AtomicPtr;
2520    ///
2521    /// extern "C" {
2522    ///     fn my_atomic_op(arg: *mut *mut u32);
2523    /// }
2524    ///
2525    /// let mut value = 17;
2526    /// let atomic = AtomicPtr::new(&mut value);
2527    ///
2528    /// // SAFETY: Safe as long as `my_atomic_op` is atomic.
2529    /// unsafe {
2530    ///     my_atomic_op(atomic.as_ptr());
2531    /// }
2532    /// ```
2533    ///
2534    /// [memory model]: self#memory-model-for-atomic-accesses
2535    #[inline]
2536    #[stable(feature = "atomic_as_ptr", since = "1.70.0")]
2537    #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")]
2538    #[rustc_never_returns_null_ptr]
2539    pub const fn as_ptr(&self) -> *mut *mut T {
2540        self.v.get().cast()
2541    }
2542}
2543
2544#[cfg(target_has_atomic_load_store = "8")]
2545#[stable(feature = "atomic_bool_from", since = "1.24.0")]
2546#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
2547const impl From<bool> for AtomicBool {
2548    /// Converts a `bool` into an `AtomicBool`.
2549    ///
2550    /// # Examples
2551    ///
2552    /// ```
2553    /// use std::sync::atomic::AtomicBool;
2554    /// let atomic_bool = AtomicBool::from(true);
2555    /// assert_eq!(format!("{atomic_bool:?}"), "true")
2556    /// ```
2557    #[inline]
2558    fn from(b: bool) -> Self {
2559        Self::new(b)
2560    }
2561}
2562
2563#[cfg(target_has_atomic_load_store = "ptr")]
2564#[stable(feature = "atomic_from", since = "1.23.0")]
2565#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
2566const impl<T> From<*mut T> for AtomicPtr<T> {
2567    /// Converts a `*mut T` into an `AtomicPtr<T>`.
2568    #[inline]
2569    fn from(p: *mut T) -> Self {
2570        Self::new(p)
2571    }
2572}
2573
2574#[allow(unused_macros)] // This macro ends up being unused on some architectures.
2575macro_rules! if_8_bit {
2576    (u8, $( yes = [$($yes:tt)*], )? $( no = [$($no:tt)*], )? ) => { concat!("", $($($yes)*)?) };
2577    (i8, $( yes = [$($yes:tt)*], )? $( no = [$($no:tt)*], )? ) => { concat!("", $($($yes)*)?) };
2578    ($_:ident, $( yes = [$($yes:tt)*], )? $( no = [$($no:tt)*], )? ) => { concat!("", $($($no)*)?) };
2579}
2580
2581#[cfg(target_has_atomic_load_store)]
2582macro_rules! atomic_int {
2583    ($cfg_base:meta,
2584     $cfg_cas:meta,
2585     $cfg_align:meta,
2586     $stable:meta,
2587     $stable_cxchg:meta,
2588     $stable_debug:meta,
2589     $stable_access:meta,
2590     $stable_from:meta,
2591     $stable_nand:meta,
2592     $const_stable_new:meta,
2593     $const_stable_into_inner:meta,
2594     $s_int_type:literal,
2595     $extra_feature:expr,
2596     $min_fn:ident, $max_fn:ident,
2597     $align:expr,
2598     $int_type:ident $atomic_type:ident) => {
2599        /// An integer type which can be safely shared between threads.
2600        ///
2601        /// This type has the same
2602        #[doc = if_8_bit!(
2603            $int_type,
2604            yes = ["size, alignment, and bit validity"],
2605            no = ["size and bit validity"],
2606        )]
2607        /// as the underlying integer type, [`
2608        #[doc = $s_int_type]
2609        /// `].
2610        #[doc = if_8_bit! {
2611            $int_type,
2612            no = [
2613                "However, the alignment of this type is always equal to its ",
2614                "size, even on targets where [`", $s_int_type, "`] has a ",
2615                "lesser alignment."
2616            ],
2617        }]
2618        ///
2619        /// For more about the differences between atomic types and
2620        /// non-atomic types as well as information about the portability of
2621        /// this type, please see the [module-level documentation].
2622        ///
2623        /// **Note:** This type is only available on platforms that support
2624        /// atomic loads and stores of [`
2625        #[doc = $s_int_type]
2626        /// `].
2627        ///
2628        /// [module-level documentation]: crate::sync::atomic
2629        #[$stable]
2630        pub type $atomic_type = Atomic<$int_type>;
2631
2632        #[$stable]
2633        impl Default for $atomic_type {
2634            #[inline]
2635            fn default() -> Self {
2636                Self::new(Default::default())
2637            }
2638        }
2639
2640        #[$stable_from]
2641        #[rustc_const_unstable(feature = "const_convert", issue = "143773")]
2642        const impl From<$int_type> for $atomic_type {
2643            #[doc = concat!("Converts an `", stringify!($int_type), "` into an `", stringify!($atomic_type), "`.")]
2644            #[inline]
2645            fn from(v: $int_type) -> Self { Self::new(v) }
2646        }
2647
2648        #[$stable_debug]
2649        impl fmt::Debug for $atomic_type {
2650            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2651                fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)
2652            }
2653        }
2654
2655        impl $atomic_type {
2656            /// Creates a new atomic integer.
2657            ///
2658            /// # Examples
2659            ///
2660            #[cfg_attr($cfg_base, doc = "```")]
2661            #[cfg_attr(not($cfg_base), doc = "```compile_fail")]
2662            #[doc = concat!($extra_feature, "use std::sync::atomic::", stringify!($atomic_type), ";")]
2663            ///
2664            #[doc = concat!("let atomic_forty_two = ", stringify!($atomic_type), "::new(42);")]
2665            /// ```
2666            #[inline]
2667            #[$stable]
2668            #[$const_stable_new]
2669            #[must_use]
2670            pub const fn new(v: $int_type) -> Self {
2671                // SAFETY:
2672                // `Atomic<T>` is essentially a transparent wrapper around `T`.
2673                unsafe { transmute(v) }
2674            }
2675
2676            /// Creates a new reference to an atomic integer from a pointer.
2677            ///
2678            /// # Examples
2679            ///
2680            #[cfg_attr($cfg_base, doc = "```rust")]
2681            #[cfg_attr(not($cfg_base), doc = "```rust,compile_fail")]
2682            #[doc = concat!($extra_feature, "use std::sync::atomic::{self, ", stringify!($atomic_type), "};")]
2683            ///
2684            /// // Get a pointer to an allocated value
2685            #[doc = concat!("let ptr: *mut ", stringify!($int_type), " = Box::into_raw(Box::new(0));")]
2686            ///
2687            #[doc = concat!("assert!(ptr.cast::<", stringify!($atomic_type), ">().is_aligned());")]
2688            ///
2689            /// {
2690            ///     // Create an atomic view of the allocated value
2691            // SAFETY: this is a doc comment, tidy, it can't hurt you (also guaranteed by the construction of `ptr` and the assert above)
2692            #[doc = concat!("    let atomic = unsafe {", stringify!($atomic_type), "::from_ptr(ptr) };")]
2693            ///
2694            ///     // Use `atomic` for atomic operations, possibly share it with other threads
2695            ///     atomic.store(1, atomic::Ordering::Relaxed);
2696            /// }
2697            ///
2698            /// // It's ok to non-atomically access the value behind `ptr`,
2699            /// // since the reference to the atomic ended its lifetime in the block above
2700            /// assert_eq!(unsafe { *ptr }, 1);
2701            ///
2702            /// // Deallocate the value
2703            /// unsafe { drop(Box::from_raw(ptr)) }
2704            /// ```
2705            ///
2706            /// # Safety
2707            ///
2708            /// * `ptr` must be aligned to
2709            #[doc = concat!("  `align_of::<", stringify!($atomic_type), ">()`")]
2710            #[doc = if_8_bit!{
2711                $int_type,
2712                yes = [
2713                    "  (note that this is always true, since `align_of::<",
2714                    stringify!($atomic_type), ">() == 1`)."
2715                ],
2716                no = [
2717                    "  (note that on some platforms this can be bigger than `align_of::<",
2718                    stringify!($int_type), ">()`)."
2719                ],
2720            }]
2721            /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
2722            /// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not
2723            ///   allowed to mix conflicting atomic and non-atomic accesses, or atomic accesses of different
2724            ///   sizes, without synchronization.
2725            ///
2726            /// [valid]: crate::ptr#safety
2727            /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
2728            #[inline]
2729            #[stable(feature = "atomic_from_ptr", since = "1.75.0")]
2730            #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")]
2731            pub const unsafe fn from_ptr<'a>(ptr: *mut $int_type) -> &'a $atomic_type {
2732                // SAFETY: guaranteed by the caller
2733                unsafe { &*ptr.cast() }
2734            }
2735
2736            /// Returns a mutable reference to the underlying integer.
2737            ///
2738            /// This is safe because the mutable reference guarantees that no other threads are
2739            /// concurrently accessing the atomic data.
2740            ///
2741            /// # Examples
2742            ///
2743            #[cfg_attr($cfg_base, doc = "```")]
2744            #[cfg_attr(not($cfg_base), doc = "```compile_fail")]
2745            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2746            ///
2747            #[doc = concat!("let mut some_var = ", stringify!($atomic_type), "::new(10);")]
2748            /// assert_eq!(*some_var.get_mut(), 10);
2749            /// *some_var.get_mut() = 5;
2750            /// assert_eq!(some_var.load(Ordering::SeqCst), 5);
2751            /// ```
2752            #[inline]
2753            #[$stable_access]
2754            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
2755            pub const fn get_mut(&mut self) -> &mut $int_type {
2756                // SAFETY:
2757                // `Atomic<T>` is essentially a transparent wrapper around `T`.
2758                unsafe { &mut *self.as_ptr() }
2759            }
2760
2761            #[doc = concat!("Get atomic access to a `&mut ", stringify!($int_type), "`.")]
2762            ///
2763            #[doc = if_8_bit! {
2764                $int_type,
2765                no = [
2766                    "**Note:** This function is only available on targets where `",
2767                    stringify!($atomic_type), "` has the same alignment as `", stringify!($int_type), "`."
2768                ],
2769            }]
2770            ///
2771            /// # Examples
2772            ///
2773            #[cfg_attr($cfg_align, doc = "```rust")]
2774            #[cfg_attr(not($cfg_align), doc = "```rust,compile_fail")]
2775            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2776            ///
2777            /// let mut some_int = 123;
2778            #[doc = concat!("let a = ", stringify!($atomic_type), "::from_mut(&mut some_int);")]
2779            /// a.store(100, Ordering::Relaxed);
2780            /// assert_eq!(some_int, 100);
2781            /// ```
2782            ///
2783            #[inline]
2784            #[cfg(any($cfg_align, doc))]
2785            #[stable(feature = "atomic_from_mut", since = "1.98.0")]
2786            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
2787            pub const fn from_mut(v: &mut $int_type) -> &mut Self {
2788                let [] = [(); align_of::<Self>() - align_of::<$int_type>()];
2789                // SAFETY:
2790                //  - the mutable reference guarantees unique ownership.
2791                //  - the alignment of `$int_type` and `Self` is the
2792                //    same, as promised by $cfg_align and verified above.
2793                unsafe { &mut *(v as *mut $int_type as *mut Self) }
2794            }
2795
2796            #[doc = concat!("Get non-atomic access to a `&mut [", stringify!($atomic_type), "]` slice")]
2797            ///
2798            /// This is safe because the mutable reference guarantees that no other threads are
2799            /// concurrently accessing the atomic data.
2800            ///
2801            /// # Examples
2802            ///
2803            #[cfg_attr($cfg_base, doc = "```ignore-wasm")]
2804            #[cfg_attr(not($cfg_base), doc = "```ignore-wasm,compile_fail")]
2805            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2806            ///
2807            #[doc = concat!("let mut some_ints = [const { ", stringify!($atomic_type), "::new(0) }; 10];")]
2808            ///
2809            #[doc = concat!("let view: &mut [", stringify!($int_type), "] = ", stringify!($atomic_type), "::get_mut_slice(&mut some_ints);")]
2810            /// assert_eq!(view, [0; 10]);
2811            /// view
2812            ///     .iter_mut()
2813            ///     .enumerate()
2814            ///     .for_each(|(idx, int)| *int = idx as _);
2815            ///
2816            /// std::thread::scope(|s| {
2817            ///     some_ints
2818            ///         .iter()
2819            ///         .enumerate()
2820            ///         .for_each(|(idx, int)| {
2821            ///             s.spawn(move || assert_eq!(int.load(Ordering::Relaxed), idx as _));
2822            ///         })
2823            /// });
2824            /// ```
2825            #[inline]
2826            #[stable(feature = "atomic_from_mut", since = "1.98.0")]
2827            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
2828            pub const fn get_mut_slice(this: &mut [Self]) -> &mut [$int_type] {
2829                // SAFETY: the mutable reference guarantees unique ownership.
2830                unsafe { &mut *(this as *mut [Self] as *mut [$int_type]) }
2831            }
2832
2833            #[doc = concat!("Get atomic access to a `&mut [", stringify!($int_type), "]` slice.")]
2834            ///
2835            #[doc = if_8_bit! {
2836                $int_type,
2837                no = [
2838                    "**Note:** This function is only available on targets where `",
2839                    stringify!($atomic_type), "` has the same alignment as `", stringify!($int_type), "`."
2840                ],
2841            }]
2842            ///
2843            /// # Examples
2844            ///
2845            #[cfg_attr($cfg_align, doc = "```ignore-wasm")]
2846            #[cfg_attr(not($cfg_align), doc = "```ignore-wasm,compile_fail")]
2847            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2848            ///
2849            /// let mut some_ints = [0; 10];
2850            #[doc = concat!("let a = &*", stringify!($atomic_type), "::from_mut_slice(&mut some_ints);")]
2851            /// std::thread::scope(|s| {
2852            ///     for i in 0..a.len() {
2853            ///         s.spawn(move || a[i].store(i as _, Ordering::Relaxed));
2854            ///     }
2855            /// });
2856            /// for (i, n) in some_ints.into_iter().enumerate() {
2857            ///     assert_eq!(i, n as usize);
2858            /// }
2859            /// ```
2860            #[inline]
2861            #[cfg(any($cfg_align, doc))]
2862            #[stable(feature = "atomic_from_mut", since = "1.98.0")]
2863            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
2864            pub const fn from_mut_slice(v: &mut [$int_type]) -> &mut [Self] {
2865                let [] = [(); align_of::<Self>() - align_of::<$int_type>()];
2866                // SAFETY:
2867                //  - the mutable reference guarantees unique ownership.
2868                //  - the alignment of `$int_type` and `Self` is the
2869                //    same, as promised by $cfg_align and verified above.
2870                unsafe { &mut *(v as *mut [$int_type] as *mut [Self]) }
2871            }
2872
2873            /// Consumes the atomic and returns the contained value.
2874            ///
2875            /// This is safe because passing `self` by value guarantees that no other threads are
2876            /// concurrently accessing the atomic data.
2877            ///
2878            /// # Examples
2879            ///
2880            #[cfg_attr($cfg_base, doc = "```")]
2881            #[cfg_attr(not($cfg_base), doc = "```compile_fail")]
2882            #[doc = concat!($extra_feature, "use std::sync::atomic::", stringify!($atomic_type), ";")]
2883            ///
2884            #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
2885            /// assert_eq!(some_var.into_inner(), 5);
2886            /// ```
2887            #[inline]
2888            #[$stable_access]
2889            #[$const_stable_into_inner]
2890            pub const fn into_inner(self) -> $int_type {
2891                // SAFETY:
2892                // `Atomic<T>` is essentially a transparent wrapper around `T`.
2893                unsafe { transmute(self) }
2894            }
2895
2896            /// Loads a value from the atomic integer.
2897            ///
2898            /// `load` takes an [`Ordering`] argument which describes the memory ordering of this operation.
2899            /// Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
2900            ///
2901            /// # Panics
2902            ///
2903            /// Panics if `order` is [`Release`] or [`AcqRel`].
2904            ///
2905            /// # Examples
2906            ///
2907            #[cfg_attr($cfg_base, doc = "```")]
2908            #[cfg_attr(not($cfg_base), doc = "```compile_fail")]
2909            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2910            ///
2911            #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
2912            ///
2913            /// assert_eq!(some_var.load(Ordering::Relaxed), 5);
2914            /// ```
2915            #[inline]
2916            #[$stable]
2917            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
2918            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2919            pub const fn load(&self, order: Ordering) -> $int_type {
2920                // SAFETY: data races are prevented by atomic intrinsics.
2921                unsafe { atomic_load::<_, /* VOLATILE */ false>(self.as_ptr(), order) }
2922            }
2923
2924            /// Stores a value into the atomic integer.
2925            ///
2926            /// `store` takes an [`Ordering`] argument which describes the memory ordering of this operation.
2927            ///  Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
2928            ///
2929            /// # Panics
2930            ///
2931            /// Panics if `order` is [`Acquire`] or [`AcqRel`].
2932            ///
2933            /// # Examples
2934            ///
2935            #[cfg_attr($cfg_base, doc = "```")]
2936            #[cfg_attr(not($cfg_base), doc = "```compile_fail")]
2937            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2938            ///
2939            #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
2940            ///
2941            /// some_var.store(10, Ordering::Relaxed);
2942            /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
2943            /// ```
2944            #[inline]
2945            #[$stable]
2946            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
2947            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2948            #[rustc_should_not_be_called_on_const_items]
2949            pub const fn store(&self, val: $int_type, order: Ordering) {
2950                // SAFETY: data races are prevented by atomic intrinsics.
2951                unsafe { atomic_store::<_, /* VOLATILE */ false>(self.as_ptr(), val, order); }
2952            }
2953
2954            /// Stores a value into the atomic integer, returning the previous value.
2955            ///
2956            /// `swap` takes an [`Ordering`] argument which describes the memory ordering
2957            /// of this operation. All ordering modes are possible. Note that using
2958            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
2959            /// using [`Release`] makes the load part [`Relaxed`].
2960            ///
2961            /// **Note**: This method is only available on platforms that support atomic operations on
2962            #[doc = concat!("[`", $s_int_type, "`].")]
2963            ///
2964            /// # Examples
2965            ///
2966            #[cfg_attr($cfg_cas, doc = "```")]
2967            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
2968            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2969            ///
2970            #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
2971            ///
2972            /// assert_eq!(some_var.swap(10, Ordering::Relaxed), 5);
2973            /// ```
2974            #[inline]
2975            #[$stable]
2976            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
2977            #[cfg(any($cfg_cas, doc))]
2978            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2979            #[rustc_should_not_be_called_on_const_items]
2980            pub const fn swap(&self, val: $int_type, order: Ordering) -> $int_type {
2981                // SAFETY: data races are prevented by atomic intrinsics.
2982                unsafe { atomic_swap(self.as_ptr(), val, order) }
2983            }
2984
2985            /// Stores a value into the atomic integer if the current value is the same as
2986            /// the `current` value.
2987            ///
2988            /// The return value is always the previous value. If it is equal to `current`, then the
2989            /// value was updated.
2990            ///
2991            /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
2992            /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
2993            /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
2994            /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
2995            /// happens, and using [`Release`] makes the load part [`Relaxed`].
2996            ///
2997            /// **Note**: This method is only available on platforms that support atomic operations on
2998            #[doc = concat!("[`", $s_int_type, "`].")]
2999            ///
3000            /// # Migrating to `compare_exchange` and `compare_exchange_weak`
3001            ///
3002            /// `compare_and_swap` is equivalent to `compare_exchange` with the following mapping for
3003            /// memory orderings:
3004            ///
3005            /// Original | Success | Failure
3006            /// -------- | ------- | -------
3007            /// Relaxed  | Relaxed | Relaxed
3008            /// Acquire  | Acquire | Acquire
3009            /// Release  | Release | Relaxed
3010            /// AcqRel   | AcqRel  | Acquire
3011            /// SeqCst   | SeqCst  | SeqCst
3012            ///
3013            /// `compare_and_swap` and `compare_exchange` also differ in their return type. You can use
3014            /// `compare_exchange(...).unwrap_or_else(|x| x)` to recover the behavior of `compare_and_swap`,
3015            /// but in most cases it is more idiomatic to check whether the return value is `Ok` or `Err`
3016            /// rather than to infer success vs failure based on the value that was read.
3017            ///
3018            /// During migration, consider whether it makes sense to use `compare_exchange_weak` instead.
3019            /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds,
3020            /// which allows the compiler to generate better assembly code when the compare and swap
3021            /// is used in a loop.
3022            ///
3023            /// # Examples
3024            ///
3025            #[cfg_attr($cfg_cas, doc = "```")]
3026            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3027            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3028            ///
3029            #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
3030            ///
3031            /// assert_eq!(some_var.compare_and_swap(5, 10, Ordering::Relaxed), 5);
3032            /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
3033            ///
3034            /// assert_eq!(some_var.compare_and_swap(6, 12, Ordering::Relaxed), 10);
3035            /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
3036            /// ```
3037            #[inline]
3038            #[$stable]
3039            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3040            #[deprecated(
3041                since = "1.50.0",
3042                note = "Use `compare_exchange` or `compare_exchange_weak` instead")
3043            ]
3044            #[cfg(any($cfg_cas, doc))]
3045            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3046            #[rustc_should_not_be_called_on_const_items]
3047            pub const fn compare_and_swap(&self,
3048                                    current: $int_type,
3049                                    new: $int_type,
3050                                    order: Ordering) -> $int_type {
3051                match self.compare_exchange(current,
3052                                            new,
3053                                            order,
3054                                            strongest_failure_ordering(order)) {
3055                    Ok(x) => x,
3056                    Err(x) => x,
3057                }
3058            }
3059
3060            /// Stores a value into the atomic integer if the current value is the same as
3061            /// the `current` value.
3062            ///
3063            /// The return value is a result indicating whether the new value was written and
3064            /// containing the previous value. On success this value is guaranteed to be equal to
3065            /// `current`.
3066            ///
3067            /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
3068            /// ordering of this operation. `success` describes the required ordering for the
3069            /// read-modify-write operation that takes place if the comparison with `current` succeeds.
3070            /// `failure` describes the required ordering for the load operation that takes place when
3071            /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
3072            /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
3073            /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
3074            ///
3075            /// **Note**: This method is only available on platforms that support atomic operations on
3076            #[doc = concat!("[`", $s_int_type, "`].")]
3077            ///
3078            /// # Examples
3079            ///
3080            #[cfg_attr($cfg_cas, doc = "```")]
3081            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3082            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3083            ///
3084            #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
3085            ///
3086            /// assert_eq!(some_var.compare_exchange(5, 10,
3087            ///                                      Ordering::Acquire,
3088            ///                                      Ordering::Relaxed),
3089            ///            Ok(5));
3090            /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
3091            ///
3092            /// assert_eq!(some_var.compare_exchange(6, 12,
3093            ///                                      Ordering::SeqCst,
3094            ///                                      Ordering::Acquire),
3095            ///            Err(10));
3096            /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
3097            /// ```
3098            ///
3099            /// # Considerations
3100            ///
3101            /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
3102            /// of CAS operations. In particular, a load of the value followed by a successful
3103            /// `compare_exchange` with the previous load *does not ensure* that other threads have not
3104            /// changed the value in the interim! This is usually important when the *equality* check in
3105            /// the `compare_exchange` is being used to check the *identity* of a value, but equality
3106            /// does not necessarily imply identity. This is a particularly common case for pointers, as
3107            /// a pointer holding the same address does not imply that the same object exists at that
3108            /// address! In this case, `compare_exchange` can lead to the [ABA problem].
3109            ///
3110            /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
3111            /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
3112            #[inline]
3113            #[$stable_cxchg]
3114            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3115            #[cfg(any($cfg_cas, doc))]
3116            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3117            #[rustc_should_not_be_called_on_const_items]
3118            pub const fn compare_exchange(&self,
3119                                    current: $int_type,
3120                                    new: $int_type,
3121                                    success: Ordering,
3122                                    failure: Ordering) -> Result<$int_type, $int_type> {
3123                // SAFETY: data races are prevented by atomic intrinsics.
3124                unsafe { atomic_compare_exchange(self.as_ptr(), current, new, success, failure) }
3125            }
3126
3127            /// Stores a value into the atomic integer if the current value is the same as
3128            /// the `current` value.
3129            ///
3130            #[doc = concat!("Unlike [`", stringify!($atomic_type), "::compare_exchange`],")]
3131            /// this function is allowed to spuriously fail even
3132            /// when the comparison succeeds, which can result in more efficient code on some
3133            /// platforms. The return value is a result indicating whether the new value was
3134            /// written and containing the previous value.
3135            ///
3136            /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
3137            /// ordering of this operation. `success` describes the required ordering for the
3138            /// read-modify-write operation that takes place if the comparison with `current` succeeds.
3139            /// `failure` describes the required ordering for the load operation that takes place when
3140            /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
3141            /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
3142            /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
3143            ///
3144            /// **Note**: This method is only available on platforms that support atomic operations on
3145            #[doc = concat!("[`", $s_int_type, "`].")]
3146            ///
3147            /// # Examples
3148            ///
3149            #[cfg_attr($cfg_cas, doc = "```")]
3150            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3151            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3152            ///
3153            #[doc = concat!("let val = ", stringify!($atomic_type), "::new(4);")]
3154            ///
3155            /// let mut old = val.load(Ordering::Relaxed);
3156            /// loop {
3157            ///     let new = old * 2;
3158            ///     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
3159            ///         Ok(_) => break,
3160            ///         Err(x) => old = x,
3161            ///     }
3162            /// }
3163            /// ```
3164            ///
3165            /// # Considerations
3166            ///
3167            /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
3168            /// of CAS operations. In particular, a load of the value followed by a successful
3169            /// `compare_exchange` with the previous load *does not ensure* that other threads have not
3170            /// changed the value in the interim. This is usually important when the *equality* check in
3171            /// the `compare_exchange` is being used to check the *identity* of a value, but equality
3172            /// does not necessarily imply identity. This is a particularly common case for pointers, as
3173            /// a pointer holding the same address does not imply that the same object exists at that
3174            /// address! In this case, `compare_exchange` can lead to the [ABA problem].
3175            ///
3176            /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
3177            /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
3178            #[inline]
3179            #[$stable_cxchg]
3180            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3181            #[cfg(any($cfg_cas, doc))]
3182            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3183            #[rustc_should_not_be_called_on_const_items]
3184            pub const fn compare_exchange_weak(&self,
3185                                         current: $int_type,
3186                                         new: $int_type,
3187                                         success: Ordering,
3188                                         failure: Ordering) -> Result<$int_type, $int_type> {
3189                // SAFETY: data races are prevented by atomic intrinsics.
3190                unsafe {
3191                    atomic_compare_exchange_weak(self.as_ptr(), current, new, success, failure)
3192                }
3193            }
3194
3195            /// Adds to the current value, returning the previous value.
3196            ///
3197            /// This operation wraps around on overflow.
3198            ///
3199            /// `fetch_add` takes an [`Ordering`] argument which describes the memory ordering
3200            /// of this operation. All ordering modes are possible. Note that using
3201            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3202            /// using [`Release`] makes the load part [`Relaxed`].
3203            ///
3204            /// **Note**: This method is only available on platforms that support atomic operations on
3205            #[doc = concat!("[`", $s_int_type, "`].")]
3206            ///
3207            /// # Examples
3208            ///
3209            #[cfg_attr($cfg_cas, doc = "```")]
3210            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3211            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3212            ///
3213            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0);")]
3214            /// assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0);
3215            /// assert_eq!(foo.load(Ordering::SeqCst), 10);
3216            /// ```
3217            #[inline]
3218            #[$stable]
3219            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3220            #[cfg(any($cfg_cas, doc))]
3221            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3222            #[rustc_should_not_be_called_on_const_items]
3223            pub const fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type {
3224                // SAFETY: data races are prevented by atomic intrinsics.
3225                unsafe { atomic_add(self.as_ptr(), val, order) }
3226            }
3227
3228            /// Subtracts from the current value, returning the previous value.
3229            ///
3230            /// This operation wraps around on overflow.
3231            ///
3232            /// `fetch_sub` takes an [`Ordering`] argument which describes the memory ordering
3233            /// of this operation. All ordering modes are possible. Note that using
3234            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3235            /// using [`Release`] makes the load part [`Relaxed`].
3236            ///
3237            /// **Note**: This method is only available on platforms that support atomic operations on
3238            #[doc = concat!("[`", $s_int_type, "`].")]
3239            ///
3240            /// # Examples
3241            ///
3242            #[cfg_attr($cfg_cas, doc = "```")]
3243            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3244            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3245            ///
3246            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(20);")]
3247            /// assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 20);
3248            /// assert_eq!(foo.load(Ordering::SeqCst), 10);
3249            /// ```
3250            #[inline]
3251            #[$stable]
3252            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3253            #[cfg(any($cfg_cas, doc))]
3254            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3255            #[rustc_should_not_be_called_on_const_items]
3256            pub const fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type {
3257                // SAFETY: data races are prevented by atomic intrinsics.
3258                unsafe { atomic_sub(self.as_ptr(), val, order) }
3259            }
3260
3261            /// Bitwise "and" with the current value.
3262            ///
3263            /// Performs a bitwise "and" operation on the current value and the argument `val`, and
3264            /// sets the new value to the result.
3265            ///
3266            /// Returns the previous value.
3267            ///
3268            /// `fetch_and` takes an [`Ordering`] argument which describes the memory ordering
3269            /// of this operation. All ordering modes are possible. Note that using
3270            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3271            /// using [`Release`] makes the load part [`Relaxed`].
3272            ///
3273            /// **Note**: This method is only available on platforms that support atomic operations on
3274            #[doc = concat!("[`", $s_int_type, "`].")]
3275            ///
3276            /// # Examples
3277            ///
3278            #[cfg_attr($cfg_cas, doc = "```")]
3279            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3280            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3281            ///
3282            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0b101101);")]
3283            /// assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101);
3284            /// assert_eq!(foo.load(Ordering::SeqCst), 0b100001);
3285            /// ```
3286            #[inline]
3287            #[$stable]
3288            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3289            #[cfg(any($cfg_cas, doc))]
3290            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3291            #[rustc_should_not_be_called_on_const_items]
3292            pub const fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type {
3293                // SAFETY: data races are prevented by atomic intrinsics.
3294                unsafe { atomic_and(self.as_ptr(), val, order) }
3295            }
3296
3297            /// Bitwise "nand" with the current value.
3298            ///
3299            /// Performs a bitwise "nand" operation on the current value and the argument `val`, and
3300            /// sets the new value to the result.
3301            ///
3302            /// Returns the previous value.
3303            ///
3304            /// `fetch_nand` takes an [`Ordering`] argument which describes the memory ordering
3305            /// of this operation. All ordering modes are possible. Note that using
3306            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3307            /// using [`Release`] makes the load part [`Relaxed`].
3308            ///
3309            /// **Note**: This method is only available on platforms that support atomic operations on
3310            #[doc = concat!("[`", $s_int_type, "`].")]
3311            ///
3312            /// # Examples
3313            ///
3314            #[cfg_attr($cfg_cas, doc = "```")]
3315            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3316            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3317            ///
3318            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0x13);")]
3319            /// assert_eq!(foo.fetch_nand(0x31, Ordering::SeqCst), 0x13);
3320            /// assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31));
3321            /// ```
3322            #[inline]
3323            #[$stable_nand]
3324            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3325            #[cfg(any($cfg_cas, doc))]
3326            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3327            #[rustc_should_not_be_called_on_const_items]
3328            pub const fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type {
3329                // SAFETY: data races are prevented by atomic intrinsics.
3330                unsafe { atomic_nand(self.as_ptr(), val, order) }
3331            }
3332
3333            /// Bitwise "or" with the current value.
3334            ///
3335            /// Performs a bitwise "or" operation on the current value and the argument `val`, and
3336            /// sets the new value to the result.
3337            ///
3338            /// Returns the previous value.
3339            ///
3340            /// `fetch_or` takes an [`Ordering`] argument which describes the memory ordering
3341            /// of this operation. All ordering modes are possible. Note that using
3342            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3343            /// using [`Release`] makes the load part [`Relaxed`].
3344            ///
3345            /// **Note**: This method is only available on platforms that support atomic operations on
3346            #[doc = concat!("[`", $s_int_type, "`].")]
3347            ///
3348            /// # Examples
3349            ///
3350            #[cfg_attr($cfg_cas, doc = "```")]
3351            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3352            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3353            ///
3354            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0b101101);")]
3355            /// assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101);
3356            /// assert_eq!(foo.load(Ordering::SeqCst), 0b111111);
3357            /// ```
3358            #[inline]
3359            #[$stable]
3360            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3361            #[cfg(any($cfg_cas, doc))]
3362            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3363            #[rustc_should_not_be_called_on_const_items]
3364            pub const fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type {
3365                // SAFETY: data races are prevented by atomic intrinsics.
3366                unsafe { atomic_or(self.as_ptr(), val, order) }
3367            }
3368
3369            /// Bitwise "xor" with the current value.
3370            ///
3371            /// Performs a bitwise "xor" operation on the current value and the argument `val`, and
3372            /// sets the new value to the result.
3373            ///
3374            /// Returns the previous value.
3375            ///
3376            /// `fetch_xor` takes an [`Ordering`] argument which describes the memory ordering
3377            /// of this operation. All ordering modes are possible. Note that using
3378            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3379            /// using [`Release`] makes the load part [`Relaxed`].
3380            ///
3381            /// **Note**: This method is only available on platforms that support atomic operations on
3382            #[doc = concat!("[`", $s_int_type, "`].")]
3383            ///
3384            /// # Examples
3385            ///
3386            #[cfg_attr($cfg_cas, doc = "```")]
3387            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3388            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3389            ///
3390            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0b101101);")]
3391            /// assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101);
3392            /// assert_eq!(foo.load(Ordering::SeqCst), 0b011110);
3393            /// ```
3394            #[inline]
3395            #[$stable]
3396            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3397            #[cfg(any($cfg_cas, doc))]
3398            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3399            #[rustc_should_not_be_called_on_const_items]
3400            pub const fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type {
3401                // SAFETY: data races are prevented by atomic intrinsics.
3402                unsafe { atomic_xor(self.as_ptr(), val, order) }
3403            }
3404
3405            /// An alias for
3406            #[doc = concat!("[`", stringify!($atomic_type), "::try_update`]")]
3407            /// .
3408            #[inline]
3409            #[stable(feature = "no_more_cas", since = "1.45.0")]
3410            #[cfg(any($cfg_cas, doc))]
3411            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3412            #[rustc_should_not_be_called_on_const_items]
3413            #[deprecated(
3414                since = "1.99.0",
3415                note = "renamed to `try_update` for consistency",
3416                suggestion = "try_update"
3417            )]
3418            pub fn fetch_update<F>(&self,
3419                                   set_order: Ordering,
3420                                   fetch_order: Ordering,
3421                                   f: F) -> Result<$int_type, $int_type>
3422            where F: FnMut($int_type) -> Option<$int_type> {
3423                self.try_update(set_order, fetch_order, f)
3424            }
3425
3426            /// Fetches the value, and applies a function to it that returns an optional
3427            /// new value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else
3428            /// `Err(previous_value)`.
3429            ///
3430            #[doc = concat!("See also: [`update`](`", stringify!($atomic_type), "::update`).")]
3431            ///
3432            /// Note: This may call the function multiple times if the value has been changed from other threads in
3433            /// the meantime, as long as the function returns `Some(_)`, but the function will have been applied
3434            /// only once to the stored value.
3435            ///
3436            /// `try_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
3437            /// The first describes the required ordering for when the operation finally succeeds while the second
3438            /// describes the required ordering for loads. These correspond to the success and failure orderings of
3439            #[doc = concat!("[`", stringify!($atomic_type), "::compare_exchange`]")]
3440            /// respectively.
3441            ///
3442            /// Using [`Acquire`] as success ordering makes the store part
3443            /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
3444            /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
3445            ///
3446            /// **Note**: This method is only available on platforms that support atomic operations on
3447            #[doc = concat!("[`", $s_int_type, "`].")]
3448            ///
3449            /// # Considerations
3450            ///
3451            /// This method is not magic; it is not provided by the hardware, and does not act like a
3452            /// critical section or mutex.
3453            ///
3454            /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
3455            /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
3456            /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
3457            /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
3458            ///
3459            /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
3460            /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
3461            ///
3462            /// # Examples
3463            ///
3464            #[cfg_attr($cfg_cas, doc = "```rust")]
3465            #[cfg_attr(not($cfg_cas), doc = "```rust,compile_fail")]
3466            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3467            ///
3468            #[doc = concat!("let x = ", stringify!($atomic_type), "::new(7);")]
3469            /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(7));
3470            /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(7));
3471            /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(8));
3472            /// assert_eq!(x.load(Ordering::SeqCst), 9);
3473            /// ```
3474            #[inline]
3475            #[stable(feature = "atomic_try_update", since = "1.95.0")]
3476            #[cfg(any($cfg_cas, doc))]
3477            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3478            #[rustc_should_not_be_called_on_const_items]
3479            pub fn try_update(
3480                &self,
3481                set_order: Ordering,
3482                fetch_order: Ordering,
3483                mut f: impl FnMut($int_type) -> Option<$int_type>,
3484            ) -> Result<$int_type, $int_type> {
3485                let mut prev = self.load(fetch_order);
3486                while let Some(next) = f(prev) {
3487                    match self.compare_exchange_weak(prev, next, set_order, fetch_order) {
3488                        x @ Ok(_) => return x,
3489                        Err(next_prev) => prev = next_prev
3490                    }
3491                }
3492                Err(prev)
3493            }
3494
3495            /// Fetches the value, applies a function to it that it return a new value.
3496            /// The new value is stored and the old value is returned.
3497            ///
3498            #[doc = concat!("See also: [`try_update`](`", stringify!($atomic_type), "::try_update`).")]
3499            ///
3500            /// Note: This may call the function multiple times if the value has been changed from other threads in
3501            /// the meantime, but the function will have been applied only once to the stored value.
3502            ///
3503            /// `update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
3504            /// The first describes the required ordering for when the operation finally succeeds while the second
3505            /// describes the required ordering for loads. These correspond to the success and failure orderings of
3506            #[doc = concat!("[`", stringify!($atomic_type), "::compare_exchange`]")]
3507            /// respectively.
3508            ///
3509            /// Using [`Acquire`] as success ordering makes the store part
3510            /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
3511            /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
3512            ///
3513            /// **Note**: This method is only available on platforms that support atomic operations on
3514            #[doc = concat!("[`", $s_int_type, "`].")]
3515            ///
3516            /// # Considerations
3517            ///
3518            /// [CAS operation]: https://en.wikipedia.org/wiki/Compare-and-swap
3519            /// This method is not magic; it is not provided by the hardware, and does not act like a
3520            /// critical section or mutex.
3521            ///
3522            /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
3523            /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
3524            /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
3525            /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
3526            ///
3527            /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
3528            /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
3529            ///
3530            /// # Examples
3531            ///
3532            #[cfg_attr($cfg_cas, doc = "```rust")]
3533            #[cfg_attr(not($cfg_cas), doc = "```rust,compile_fail")]
3534            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3535            ///
3536            #[doc = concat!("let x = ", stringify!($atomic_type), "::new(7);")]
3537            /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 7);
3538            /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 8);
3539            /// assert_eq!(x.load(Ordering::SeqCst), 9);
3540            /// ```
3541            #[inline]
3542            #[stable(feature = "atomic_try_update", since = "1.95.0")]
3543            #[cfg(any($cfg_cas, doc))]
3544            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3545            #[rustc_should_not_be_called_on_const_items]
3546            pub fn update(
3547                &self,
3548                set_order: Ordering,
3549                fetch_order: Ordering,
3550                mut f: impl FnMut($int_type) -> $int_type,
3551            ) -> $int_type {
3552                let mut prev = self.load(fetch_order);
3553                loop {
3554                    match self.compare_exchange_weak(prev, f(prev), set_order, fetch_order) {
3555                        Ok(x) => break x,
3556                        Err(next_prev) => prev = next_prev,
3557                    }
3558                }
3559            }
3560
3561            /// Maximum with the current value.
3562            ///
3563            /// Finds the maximum of the current value and the argument `val`, and
3564            /// sets the new value to the result.
3565            ///
3566            /// Returns the previous value.
3567            ///
3568            /// `fetch_max` takes an [`Ordering`] argument which describes the memory ordering
3569            /// of this operation. All ordering modes are possible. Note that using
3570            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3571            /// using [`Release`] makes the load part [`Relaxed`].
3572            ///
3573            /// **Note**: This method is only available on platforms that support atomic operations on
3574            #[doc = concat!("[`", $s_int_type, "`].")]
3575            ///
3576            /// # Examples
3577            ///
3578            #[cfg_attr($cfg_cas, doc = "```")]
3579            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3580            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3581            ///
3582            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(23);")]
3583            /// assert_eq!(foo.fetch_max(42, Ordering::SeqCst), 23);
3584            /// assert_eq!(foo.load(Ordering::SeqCst), 42);
3585            /// ```
3586            ///
3587            /// If you want to obtain the maximum value in one step, you can use the following:
3588            ///
3589            #[cfg_attr($cfg_cas, doc = "```")]
3590            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3591            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3592            ///
3593            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(23);")]
3594            /// let bar = 42;
3595            /// let max_foo = foo.fetch_max(bar, Ordering::SeqCst).max(bar);
3596            /// assert!(max_foo == 42);
3597            /// ```
3598            #[inline]
3599            #[stable(feature = "atomic_min_max", since = "1.45.0")]
3600            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3601            #[cfg(any($cfg_cas, doc))]
3602            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3603            #[rustc_should_not_be_called_on_const_items]
3604            pub const fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type {
3605                // SAFETY: data races are prevented by atomic intrinsics.
3606                unsafe { $max_fn(self.as_ptr(), val, order) }
3607            }
3608
3609            /// Minimum with the current value.
3610            ///
3611            /// Finds the minimum of the current value and the argument `val`, and
3612            /// sets the new value to the result.
3613            ///
3614            /// Returns the previous value.
3615            ///
3616            /// `fetch_min` takes an [`Ordering`] argument which describes the memory ordering
3617            /// of this operation. All ordering modes are possible. Note that using
3618            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3619            /// using [`Release`] makes the load part [`Relaxed`].
3620            ///
3621            /// **Note**: This method is only available on platforms that support atomic operations on
3622            #[doc = concat!("[`", $s_int_type, "`].")]
3623            ///
3624            /// # Examples
3625            ///
3626            #[cfg_attr($cfg_cas, doc = "```")]
3627            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3628            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3629            ///
3630            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(23);")]
3631            /// assert_eq!(foo.fetch_min(42, Ordering::Relaxed), 23);
3632            /// assert_eq!(foo.load(Ordering::Relaxed), 23);
3633            /// assert_eq!(foo.fetch_min(22, Ordering::Relaxed), 23);
3634            /// assert_eq!(foo.load(Ordering::Relaxed), 22);
3635            /// ```
3636            ///
3637            /// If you want to obtain the minimum value in one step, you can use the following:
3638            ///
3639            #[cfg_attr($cfg_cas, doc = "```")]
3640            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3641            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3642            ///
3643            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(23);")]
3644            /// let bar = 12;
3645            /// let min_foo = foo.fetch_min(bar, Ordering::SeqCst).min(bar);
3646            /// assert_eq!(min_foo, 12);
3647            /// ```
3648            #[inline]
3649            #[stable(feature = "atomic_min_max", since = "1.45.0")]
3650            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3651            #[cfg(any($cfg_cas, doc))]
3652            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3653            #[rustc_should_not_be_called_on_const_items]
3654            pub const fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type {
3655                // SAFETY: data races are prevented by atomic intrinsics.
3656                unsafe { $min_fn(self.as_ptr(), val, order) }
3657            }
3658
3659            /// Returns a mutable pointer to the underlying integer.
3660            ///
3661            /// Doing non-atomic reads and writes on the resulting integer can be a data race.
3662            /// This method is mostly useful for FFI, where the function signature may use
3663            #[doc = concat!("`*mut ", stringify!($int_type), "` instead of `&", stringify!($atomic_type), "`.")]
3664            ///
3665            /// Returning an `*mut` pointer from a shared reference to this atomic is safe because the
3666            /// atomic types work with interior mutability. All modifications of an atomic change the value
3667            /// through a shared reference, and can do so safely as long as they use atomic operations. Any
3668            /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the
3669            /// requirements of the [memory model].
3670            ///
3671            /// # Examples
3672            ///
3673            /// ```ignore (extern-declaration)
3674            /// # fn main() {
3675            #[doc = concat!($extra_feature, "use std::sync::atomic::", stringify!($atomic_type), ";")]
3676            ///
3677            /// extern "C" {
3678            #[doc = concat!("    fn my_atomic_op(arg: *mut ", stringify!($int_type), ");")]
3679            /// }
3680            ///
3681            #[doc = concat!("let atomic = ", stringify!($atomic_type), "::new(1);")]
3682            ///
3683            /// // SAFETY: Safe as long as `my_atomic_op` is atomic.
3684            /// unsafe {
3685            ///     my_atomic_op(atomic.as_ptr());
3686            /// }
3687            /// # }
3688            /// ```
3689            ///
3690            /// [memory model]: self#memory-model-for-atomic-accesses
3691            #[inline]
3692            #[stable(feature = "atomic_as_ptr", since = "1.70.0")]
3693            #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")]
3694            #[rustc_never_returns_null_ptr]
3695            pub const fn as_ptr(&self) -> *mut $int_type {
3696                self.v.get().cast()
3697            }
3698        }
3699    }
3700}
3701
3702#[cfg(target_has_atomic_load_store = "8")]
3703/// An integer type which can be safely shared between threads.
///
/// This type has the same
#[doc = "size, alignment, and bit validity"]
/// as the underlying integer type, [`
#[doc = "i8"]
/// `].
#[doc = ""]
///
/// For more about the differences between atomic types and
/// non-atomic types as well as information about the portability of
/// this type, please see the [module-level documentation].
///
/// **Note:** This type is only available on platforms that support
/// atomic loads and stores of [`
#[doc = "i8"]
/// `].
///
/// [module-level documentation]: crate::sync::atomic
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
pub type AtomicI8 = Atomic<i8>;
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
impl Default for AtomicI8 {
    #[inline]
    fn default() -> Self { Self::new(Default::default()) }
}
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
const impl From<i8> for AtomicI8 {
    #[doc = "Converts an `i8` into an `AtomicI8`."]
    #[inline]
    fn from(v: i8) -> Self { Self::new(v) }
}
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
impl fmt::Debug for AtomicI8 {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)
    }
}
impl AtomicI8 {
    /// Creates a new atomic integer.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::AtomicI8;"]
    ///
    #[doc = "let atomic_forty_two = AtomicI8::new(42);"]
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0")]
    #[must_use]
    pub const fn new(v: i8) -> Self { unsafe { transmute(v) } }
    /// Creates a new reference to an atomic integer from a pointer.
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{self, AtomicI8};"]
    ///
    /// // Get a pointer to an allocated value
    #[doc = "let ptr: *mut i8 = Box::into_raw(Box::new(0));"]
    ///
    #[doc = "assert!(ptr.cast::<AtomicI8>().is_aligned());"]
    ///
    /// {
    ///     // Create an atomic view of the allocated value
    #[doc = "    let atomic = unsafe {AtomicI8::from_ptr(ptr) };"]
    ///
    ///     // Use `atomic` for atomic operations, possibly share it with other threads
    ///     atomic.store(1, atomic::Ordering::Relaxed);
    /// }
    ///
    /// // It's ok to non-atomically access the value behind `ptr`,
    /// // since the reference to the atomic ended its lifetime in the block above
    /// assert_eq!(unsafe { *ptr }, 1);
    ///
    /// // Deallocate the value
    /// unsafe { drop(Box::from_raw(ptr)) }
    /// ```
    ///
    /// # Safety
    ///
    /// * `ptr` must be aligned to
    #[doc = "  `align_of::<AtomicI8>()`"]
    #[doc =
    "  (note that this is always true, since `align_of::<AtomicI8>() == 1`)."]
    /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
    /// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not
    ///   allowed to mix conflicting atomic and non-atomic accesses, or atomic accesses of different
    ///   sizes, without synchronization.
    ///
    /// [valid]: crate::ptr#safety
    /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
    #[inline]
    #[stable(feature = "atomic_from_ptr", since = "1.75.0")]
    #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")]
    pub const unsafe fn from_ptr<'a>(ptr: *mut i8) -> &'a AtomicI8 {
        unsafe { &*ptr.cast() }
    }
    /// Returns a mutable reference to the underlying integer.
    ///
    /// This is safe because the mutable reference guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI8, Ordering};"]
    ///
    #[doc = "let mut some_var = AtomicI8::new(10);"]
    /// assert_eq!(*some_var.get_mut(), 10);
    /// *some_var.get_mut() = 5;
    /// assert_eq!(some_var.load(Ordering::SeqCst), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn get_mut(&mut self) -> &mut i8 {
        unsafe { &mut *self.as_ptr() }
    }
    #[doc = "Get atomic access to a `&mut i8`."]
    ///
    #[doc = ""]
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicI8, Ordering};"]
    ///
    /// let mut some_int = 123;
    #[doc = "let a = AtomicI8::from_mut(&mut some_int);"]
    /// a.store(100, Ordering::Relaxed);
    /// assert_eq!(some_int, 100);
    /// ```
    ///
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn from_mut(v: &mut i8) -> &mut Self {
        let [] = [(); align_of::<Self>() - align_of::<i8>()];
        unsafe { &mut *(v as *mut i8 as *mut Self) }
    }
    #[doc = "Get non-atomic access to a `&mut [AtomicI8]` slice"]
    ///
    /// This is safe because the mutable reference guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```ignore-wasm"]
    #[doc = "use std::sync::atomic::{AtomicI8, Ordering};"]
    ///
    #[doc = "let mut some_ints = [const { AtomicI8::new(0) }; 10];"]
    ///
    #[doc = "let view: &mut [i8] = AtomicI8::get_mut_slice(&mut some_ints);"]
    /// assert_eq!(view, [0; 10]);
    /// view
    ///     .iter_mut()
    ///     .enumerate()
    ///     .for_each(|(idx, int)| *int = idx as _);
    ///
    /// std::thread::scope(|s| {
    ///     some_ints
    ///         .iter()
    ///         .enumerate()
    ///         .for_each(|(idx, int)| {
    ///             s.spawn(move || assert_eq!(int.load(Ordering::Relaxed), idx as _));
    ///         })
    /// });
    /// ```
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn get_mut_slice(this: &mut [Self]) -> &mut [i8] {
        unsafe { &mut *(this as *mut [Self] as *mut [i8]) }
    }
    #[doc = "Get atomic access to a `&mut [i8]` slice."]
    ///
    #[doc = ""]
    ///
    /// # Examples
    ///
    #[doc = "```ignore-wasm"]
    #[doc = "use std::sync::atomic::{AtomicI8, Ordering};"]
    ///
    /// let mut some_ints = [0; 10];
    #[doc = "let a = &*AtomicI8::from_mut_slice(&mut some_ints);"]
    /// std::thread::scope(|s| {
    ///     for i in 0..a.len() {
    ///         s.spawn(move || a[i].store(i as _, Ordering::Relaxed));
    ///     }
    /// });
    /// for (i, n) in some_ints.into_iter().enumerate() {
    ///     assert_eq!(i, n as usize);
    /// }
    /// ```
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn from_mut_slice(v: &mut [i8]) -> &mut [Self] {
        let [] = [(); align_of::<Self>() - align_of::<i8>()];
        unsafe { &mut *(v as *mut [i8] as *mut [Self]) }
    }
    /// Consumes the atomic and returns the contained value.
    ///
    /// This is safe because passing `self` by value guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::AtomicI8;"]
    ///
    #[doc = "let some_var = AtomicI8::new(5);"]
    /// assert_eq!(some_var.into_inner(), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_stable(feature = "const_atomic_into_inner", since =
    "1.79.0")]
    pub const fn into_inner(self) -> i8 { unsafe { transmute(self) } }
    /// Loads a value from the atomic integer.
    ///
    /// `load` takes an [`Ordering`] argument which describes the memory ordering of this operation.
    /// Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Release`] or [`AcqRel`].
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI8, Ordering};"]
    ///
    #[doc = "let some_var = AtomicI8::new(5);"]
    ///
    /// assert_eq!(some_var.load(Ordering::Relaxed), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn load(&self, order: Ordering) -> i8 {
        unsafe { atomic_load::<_, false>(self.as_ptr(), order) }
    }
    /// Stores a value into the atomic integer.
    ///
    /// `store` takes an [`Ordering`] argument which describes the memory ordering of this operation.
    ///  Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI8, Ordering};"]
    ///
    #[doc = "let some_var = AtomicI8::new(5);"]
    ///
    /// some_var.store(10, Ordering::Relaxed);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn store(&self, val: i8, order: Ordering) {
        unsafe { atomic_store::<_, false>(self.as_ptr(), val, order); }
    }
    /// Stores a value into the atomic integer, returning the previous value.
    ///
    /// `swap` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i8`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI8, Ordering};"]
    ///
    #[doc = "let some_var = AtomicI8::new(5);"]
    ///
    /// assert_eq!(some_var.swap(10, Ordering::Relaxed), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn swap(&self, val: i8, order: Ordering) -> i8 {
        unsafe { atomic_swap(self.as_ptr(), val, order) }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    /// The return value is always the previous value. If it is equal to `current`, then the
    /// value was updated.
    ///
    /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
    /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
    /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
    /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
    /// happens, and using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i8`]."]
    ///
    /// # Migrating to `compare_exchange` and `compare_exchange_weak`
    ///
    /// `compare_and_swap` is equivalent to `compare_exchange` with the following mapping for
    /// memory orderings:
    ///
    /// Original | Success | Failure
    /// -------- | ------- | -------
    /// Relaxed  | Relaxed | Relaxed
    /// Acquire  | Acquire | Acquire
    /// Release  | Release | Relaxed
    /// AcqRel   | AcqRel  | Acquire
    /// SeqCst   | SeqCst  | SeqCst
    ///
    /// `compare_and_swap` and `compare_exchange` also differ in their return type. You can use
    /// `compare_exchange(...).unwrap_or_else(|x| x)` to recover the behavior of `compare_and_swap`,
    /// but in most cases it is more idiomatic to check whether the return value is `Ok` or `Err`
    /// rather than to infer success vs failure based on the value that was read.
    ///
    /// During migration, consider whether it makes sense to use `compare_exchange_weak` instead.
    /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds,
    /// which allows the compiler to generate better assembly code when the compare and swap
    /// is used in a loop.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI8, Ordering};"]
    ///
    #[doc = "let some_var = AtomicI8::new(5);"]
    ///
    /// assert_eq!(some_var.compare_and_swap(5, 10, Ordering::Relaxed), 5);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    ///
    /// assert_eq!(some_var.compare_and_swap(6, 12, Ordering::Relaxed), 10);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[deprecated(since = "1.50.0", note =
    "Use `compare_exchange` or `compare_exchange_weak` instead")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_and_swap(&self, current: i8, new: i8,
        order: Ordering) -> i8 {
        match self.compare_exchange(current, new, order,
                strongest_failure_ordering(order)) {
            Ok(x) => x,
            Err(x) => x,
        }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    /// The return value is a result indicating whether the new value was written and
    /// containing the previous value. On success this value is guaranteed to be equal to
    /// `current`.
    ///
    /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
    /// ordering of this operation. `success` describes the required ordering for the
    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
    /// `failure` describes the required ordering for the load operation that takes place when
    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i8`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI8, Ordering};"]
    ///
    #[doc = "let some_var = AtomicI8::new(5);"]
    ///
    /// assert_eq!(some_var.compare_exchange(5, 10,
    ///                                      Ordering::Acquire,
    ///                                      Ordering::Relaxed),
    ///            Ok(5));
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    ///
    /// assert_eq!(some_var.compare_exchange(6, 12,
    ///                                      Ordering::SeqCst,
    ///                                      Ordering::Acquire),
    ///            Err(10));
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    ///
    /// # Considerations
    ///
    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
    /// of CAS operations. In particular, a load of the value followed by a successful
    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
    /// changed the value in the interim! This is usually important when the *equality* check in
    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
    /// does not necessarily imply identity. This is a particularly common case for pointers, as
    /// a pointer holding the same address does not imply that the same object exists at that
    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_exchange(&self, current: i8, new: i8,
        success: Ordering, failure: Ordering) -> Result<i8, i8> {
        unsafe {
            atomic_compare_exchange(self.as_ptr(), current, new, success,
                failure)
        }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    #[doc = "Unlike [`AtomicI8::compare_exchange`],"]
    /// this function is allowed to spuriously fail even
    /// when the comparison succeeds, which can result in more efficient code on some
    /// platforms. The return value is a result indicating whether the new value was
    /// written and containing the previous value.
    ///
    /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
    /// ordering of this operation. `success` describes the required ordering for the
    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
    /// `failure` describes the required ordering for the load operation that takes place when
    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i8`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI8, Ordering};"]
    ///
    #[doc = "let val = AtomicI8::new(4);"]
    ///
    /// let mut old = val.load(Ordering::Relaxed);
    /// loop {
    ///     let new = old * 2;
    ///     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
    ///         Ok(_) => break,
    ///         Err(x) => old = x,
    ///     }
    /// }
    /// ```
    ///
    /// # Considerations
    ///
    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
    /// of CAS operations. In particular, a load of the value followed by a successful
    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
    /// changed the value in the interim. This is usually important when the *equality* check in
    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
    /// does not necessarily imply identity. This is a particularly common case for pointers, as
    /// a pointer holding the same address does not imply that the same object exists at that
    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_exchange_weak(&self, current: i8, new: i8,
        success: Ordering, failure: Ordering) -> Result<i8, i8> {
        unsafe {
            atomic_compare_exchange_weak(self.as_ptr(), current, new, success,
                failure)
        }
    }
    /// Adds to the current value, returning the previous value.
    ///
    /// This operation wraps around on overflow.
    ///
    /// `fetch_add` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i8`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI8, Ordering};"]
    ///
    #[doc = "let foo = AtomicI8::new(0);"]
    /// assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0);
    /// assert_eq!(foo.load(Ordering::SeqCst), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_add(&self, val: i8, order: Ordering) -> i8 {
        unsafe { atomic_add(self.as_ptr(), val, order) }
    }
    /// Subtracts from the current value, returning the previous value.
    ///
    /// This operation wraps around on overflow.
    ///
    /// `fetch_sub` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i8`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI8, Ordering};"]
    ///
    #[doc = "let foo = AtomicI8::new(20);"]
    /// assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 20);
    /// assert_eq!(foo.load(Ordering::SeqCst), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_sub(&self, val: i8, order: Ordering) -> i8 {
        unsafe { atomic_sub(self.as_ptr(), val, order) }
    }
    /// Bitwise "and" with the current value.
    ///
    /// Performs a bitwise "and" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_and` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i8`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI8, Ordering};"]
    ///
    #[doc = "let foo = AtomicI8::new(0b101101);"]
    /// assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b100001);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_and(&self, val: i8, order: Ordering) -> i8 {
        unsafe { atomic_and(self.as_ptr(), val, order) }
    }
    /// Bitwise "nand" with the current value.
    ///
    /// Performs a bitwise "nand" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_nand` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i8`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI8, Ordering};"]
    ///
    #[doc = "let foo = AtomicI8::new(0x13);"]
    /// assert_eq!(foo.fetch_nand(0x31, Ordering::SeqCst), 0x13);
    /// assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31));
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_nand(&self, val: i8, order: Ordering) -> i8 {
        unsafe { atomic_nand(self.as_ptr(), val, order) }
    }
    /// Bitwise "or" with the current value.
    ///
    /// Performs a bitwise "or" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_or` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i8`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI8, Ordering};"]
    ///
    #[doc = "let foo = AtomicI8::new(0b101101);"]
    /// assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b111111);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_or(&self, val: i8, order: Ordering) -> i8 {
        unsafe { atomic_or(self.as_ptr(), val, order) }
    }
    /// Bitwise "xor" with the current value.
    ///
    /// Performs a bitwise "xor" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_xor` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i8`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI8, Ordering};"]
    ///
    #[doc = "let foo = AtomicI8::new(0b101101);"]
    /// assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b011110);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_xor(&self, val: i8, order: Ordering) -> i8 {
        unsafe { atomic_xor(self.as_ptr(), val, order) }
    }
    /// An alias for
    #[doc = "[`AtomicI8::try_update`]"]
    /// .
    #[inline]
    #[stable(feature = "no_more_cas", since = "1.45.0")]
    #[rustc_should_not_be_called_on_const_items]
    #[deprecated(since = "1.99.0", note =
    "renamed to `try_update` for consistency", suggestion = "try_update")]
    pub fn fetch_update<F>(&self, set_order: Ordering, fetch_order: Ordering,
        f: F) -> Result<i8, i8> where F: FnMut(i8) -> Option<i8> {
        self.try_update(set_order, fetch_order, f)
    }
    /// Fetches the value, and applies a function to it that returns an optional
    /// new value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else
    /// `Err(previous_value)`.
    ///
    #[doc = "See also: [`update`](`AtomicI8::update`)."]
    ///
    /// Note: This may call the function multiple times if the value has been changed from other threads in
    /// the meantime, as long as the function returns `Some(_)`, but the function will have been applied
    /// only once to the stored value.
    ///
    /// `try_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
    /// The first describes the required ordering for when the operation finally succeeds while the second
    /// describes the required ordering for loads. These correspond to the success and failure orderings of
    #[doc = "[`AtomicI8::compare_exchange`]"]
    /// respectively.
    ///
    /// Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i8`]."]
    ///
    /// # Considerations
    ///
    /// This method is not magic; it is not provided by the hardware, and does not act like a
    /// critical section or mutex.
    ///
    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
    /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
    /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicI8, Ordering};"]
    ///
    #[doc = "let x = AtomicI8::new(7);"]
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(7));
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(7));
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(8));
    /// assert_eq!(x.load(Ordering::SeqCst), 9);
    /// ```
    #[inline]
    #[stable(feature = "atomic_try_update", since = "1.95.0")]
    #[rustc_should_not_be_called_on_const_items]
    pub fn try_update(&self, set_order: Ordering, fetch_order: Ordering,
        mut f: impl FnMut(i8) -> Option<i8>) -> Result<i8, i8> {
        let mut prev = self.load(fetch_order);
        while let Some(next) = f(prev) {
            match self.compare_exchange_weak(prev, next, set_order,
                    fetch_order) {
                x @ Ok(_) => return x,
                Err(next_prev) => prev = next_prev,
            }
        }
        Err(prev)
    }
    /// Fetches the value, applies a function to it that it return a new value.
    /// The new value is stored and the old value is returned.
    ///
    #[doc = "See also: [`try_update`](`AtomicI8::try_update`)."]
    ///
    /// Note: This may call the function multiple times if the value has been changed from other threads in
    /// the meantime, but the function will have been applied only once to the stored value.
    ///
    /// `update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
    /// The first describes the required ordering for when the operation finally succeeds while the second
    /// describes the required ordering for loads. These correspond to the success and failure orderings of
    #[doc = "[`AtomicI8::compare_exchange`]"]
    /// respectively.
    ///
    /// Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i8`]."]
    ///
    /// # Considerations
    ///
    /// [CAS operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    /// This method is not magic; it is not provided by the hardware, and does not act like a
    /// critical section or mutex.
    ///
    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
    /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
    /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicI8, Ordering};"]
    ///
    #[doc = "let x = AtomicI8::new(7);"]
    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 7);
    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 8);
    /// assert_eq!(x.load(Ordering::SeqCst), 9);
    /// ```
    #[inline]
    #[stable(feature = "atomic_try_update", since = "1.95.0")]
    #[rustc_should_not_be_called_on_const_items]
    pub fn update(&self, set_order: Ordering, fetch_order: Ordering,
        mut f: impl FnMut(i8) -> i8) -> i8 {
        let mut prev = self.load(fetch_order);
        loop {
            match self.compare_exchange_weak(prev, f(prev), set_order,
                    fetch_order) {
                Ok(x) => break x,
                Err(next_prev) => prev = next_prev,
            }
        }
    }
    /// Maximum with the current value.
    ///
    /// Finds the maximum of the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_max` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i8`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI8, Ordering};"]
    ///
    #[doc = "let foo = AtomicI8::new(23);"]
    /// assert_eq!(foo.fetch_max(42, Ordering::SeqCst), 23);
    /// assert_eq!(foo.load(Ordering::SeqCst), 42);
    /// ```
    ///
    /// If you want to obtain the maximum value in one step, you can use the following:
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI8, Ordering};"]
    ///
    #[doc = "let foo = AtomicI8::new(23);"]
    /// let bar = 42;
    /// let max_foo = foo.fetch_max(bar, Ordering::SeqCst).max(bar);
    /// assert!(max_foo == 42);
    /// ```
    #[inline]
    #[stable(feature = "atomic_min_max", since = "1.45.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_max(&self, val: i8, order: Ordering) -> i8 {
        unsafe { atomic_max(self.as_ptr(), val, order) }
    }
    /// Minimum with the current value.
    ///
    /// Finds the minimum of the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_min` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i8`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI8, Ordering};"]
    ///
    #[doc = "let foo = AtomicI8::new(23);"]
    /// assert_eq!(foo.fetch_min(42, Ordering::Relaxed), 23);
    /// assert_eq!(foo.load(Ordering::Relaxed), 23);
    /// assert_eq!(foo.fetch_min(22, Ordering::Relaxed), 23);
    /// assert_eq!(foo.load(Ordering::Relaxed), 22);
    /// ```
    ///
    /// If you want to obtain the minimum value in one step, you can use the following:
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI8, Ordering};"]
    ///
    #[doc = "let foo = AtomicI8::new(23);"]
    /// let bar = 12;
    /// let min_foo = foo.fetch_min(bar, Ordering::SeqCst).min(bar);
    /// assert_eq!(min_foo, 12);
    /// ```
    #[inline]
    #[stable(feature = "atomic_min_max", since = "1.45.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_min(&self, val: i8, order: Ordering) -> i8 {
        unsafe { atomic_min(self.as_ptr(), val, order) }
    }
    /// Returns a mutable pointer to the underlying integer.
    ///
    /// Doing non-atomic reads and writes on the resulting integer can be a data race.
    /// This method is mostly useful for FFI, where the function signature may use
    #[doc = "`*mut i8` instead of `&AtomicI8`."]
    ///
    /// Returning an `*mut` pointer from a shared reference to this atomic is safe because the
    /// atomic types work with interior mutability. All modifications of an atomic change the value
    /// through a shared reference, and can do so safely as long as they use atomic operations. Any
    /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the
    /// requirements of the [memory model].
    ///
    /// # Examples
    ///
    /// ```ignore (extern-declaration)
    /// # fn main() {
    #[doc = "use std::sync::atomic::AtomicI8;"]
    ///
    /// extern "C" {
    #[doc = "    fn my_atomic_op(arg: *mut i8);"]
    /// }
    ///
    #[doc = "let atomic = AtomicI8::new(1);"]
    ///
    /// // SAFETY: Safe as long as `my_atomic_op` is atomic.
    /// unsafe {
    ///     my_atomic_op(atomic.as_ptr());
    /// }
    /// # }
    /// ```
    ///
    /// [memory model]: self#memory-model-for-atomic-accesses
    #[inline]
    #[stable(feature = "atomic_as_ptr", since = "1.70.0")]
    #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")]
    #[rustc_never_returns_null_ptr]
    pub const fn as_ptr(&self) -> *mut i8 { self.v.get().cast() }
}atomic_int! {
3704    target_has_atomic_load_store = "8",
3705    target_has_atomic = "8",
3706    target_has_atomic_primitive_alignment = "8",
3707    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3708    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3709    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3710    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3711    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3712    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3713    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
3714    rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
3715    "i8",
3716    "",
3717    atomic_min, atomic_max,
3718    1,
3719    i8 AtomicI8
3720}
3721#[cfg(target_has_atomic_load_store = "8")]
3722/// An integer type which can be safely shared between threads.
///
/// This type has the same
#[doc = "size, alignment, and bit validity"]
/// as the underlying integer type, [`
#[doc = "u8"]
/// `].
#[doc = ""]
///
/// For more about the differences between atomic types and
/// non-atomic types as well as information about the portability of
/// this type, please see the [module-level documentation].
///
/// **Note:** This type is only available on platforms that support
/// atomic loads and stores of [`
#[doc = "u8"]
/// `].
///
/// [module-level documentation]: crate::sync::atomic
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
pub type AtomicU8 = Atomic<u8>;
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
impl Default for AtomicU8 {
    #[inline]
    fn default() -> Self { Self::new(Default::default()) }
}
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
const impl From<u8> for AtomicU8 {
    #[doc = "Converts an `u8` into an `AtomicU8`."]
    #[inline]
    fn from(v: u8) -> Self { Self::new(v) }
}
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
impl fmt::Debug for AtomicU8 {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)
    }
}
impl AtomicU8 {
    /// Creates a new atomic integer.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::AtomicU8;"]
    ///
    #[doc = "let atomic_forty_two = AtomicU8::new(42);"]
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0")]
    #[must_use]
    pub const fn new(v: u8) -> Self { unsafe { transmute(v) } }
    /// Creates a new reference to an atomic integer from a pointer.
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{self, AtomicU8};"]
    ///
    /// // Get a pointer to an allocated value
    #[doc = "let ptr: *mut u8 = Box::into_raw(Box::new(0));"]
    ///
    #[doc = "assert!(ptr.cast::<AtomicU8>().is_aligned());"]
    ///
    /// {
    ///     // Create an atomic view of the allocated value
    #[doc = "    let atomic = unsafe {AtomicU8::from_ptr(ptr) };"]
    ///
    ///     // Use `atomic` for atomic operations, possibly share it with other threads
    ///     atomic.store(1, atomic::Ordering::Relaxed);
    /// }
    ///
    /// // It's ok to non-atomically access the value behind `ptr`,
    /// // since the reference to the atomic ended its lifetime in the block above
    /// assert_eq!(unsafe { *ptr }, 1);
    ///
    /// // Deallocate the value
    /// unsafe { drop(Box::from_raw(ptr)) }
    /// ```
    ///
    /// # Safety
    ///
    /// * `ptr` must be aligned to
    #[doc = "  `align_of::<AtomicU8>()`"]
    #[doc =
    "  (note that this is always true, since `align_of::<AtomicU8>() == 1`)."]
    /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
    /// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not
    ///   allowed to mix conflicting atomic and non-atomic accesses, or atomic accesses of different
    ///   sizes, without synchronization.
    ///
    /// [valid]: crate::ptr#safety
    /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
    #[inline]
    #[stable(feature = "atomic_from_ptr", since = "1.75.0")]
    #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")]
    pub const unsafe fn from_ptr<'a>(ptr: *mut u8) -> &'a AtomicU8 {
        unsafe { &*ptr.cast() }
    }
    /// Returns a mutable reference to the underlying integer.
    ///
    /// This is safe because the mutable reference guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU8, Ordering};"]
    ///
    #[doc = "let mut some_var = AtomicU8::new(10);"]
    /// assert_eq!(*some_var.get_mut(), 10);
    /// *some_var.get_mut() = 5;
    /// assert_eq!(some_var.load(Ordering::SeqCst), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn get_mut(&mut self) -> &mut u8 {
        unsafe { &mut *self.as_ptr() }
    }
    #[doc = "Get atomic access to a `&mut u8`."]
    ///
    #[doc = ""]
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicU8, Ordering};"]
    ///
    /// let mut some_int = 123;
    #[doc = "let a = AtomicU8::from_mut(&mut some_int);"]
    /// a.store(100, Ordering::Relaxed);
    /// assert_eq!(some_int, 100);
    /// ```
    ///
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn from_mut(v: &mut u8) -> &mut Self {
        let [] = [(); align_of::<Self>() - align_of::<u8>()];
        unsafe { &mut *(v as *mut u8 as *mut Self) }
    }
    #[doc = "Get non-atomic access to a `&mut [AtomicU8]` slice"]
    ///
    /// This is safe because the mutable reference guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```ignore-wasm"]
    #[doc = "use std::sync::atomic::{AtomicU8, Ordering};"]
    ///
    #[doc = "let mut some_ints = [const { AtomicU8::new(0) }; 10];"]
    ///
    #[doc = "let view: &mut [u8] = AtomicU8::get_mut_slice(&mut some_ints);"]
    /// assert_eq!(view, [0; 10]);
    /// view
    ///     .iter_mut()
    ///     .enumerate()
    ///     .for_each(|(idx, int)| *int = idx as _);
    ///
    /// std::thread::scope(|s| {
    ///     some_ints
    ///         .iter()
    ///         .enumerate()
    ///         .for_each(|(idx, int)| {
    ///             s.spawn(move || assert_eq!(int.load(Ordering::Relaxed), idx as _));
    ///         })
    /// });
    /// ```
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn get_mut_slice(this: &mut [Self]) -> &mut [u8] {
        unsafe { &mut *(this as *mut [Self] as *mut [u8]) }
    }
    #[doc = "Get atomic access to a `&mut [u8]` slice."]
    ///
    #[doc = ""]
    ///
    /// # Examples
    ///
    #[doc = "```ignore-wasm"]
    #[doc = "use std::sync::atomic::{AtomicU8, Ordering};"]
    ///
    /// let mut some_ints = [0; 10];
    #[doc = "let a = &*AtomicU8::from_mut_slice(&mut some_ints);"]
    /// std::thread::scope(|s| {
    ///     for i in 0..a.len() {
    ///         s.spawn(move || a[i].store(i as _, Ordering::Relaxed));
    ///     }
    /// });
    /// for (i, n) in some_ints.into_iter().enumerate() {
    ///     assert_eq!(i, n as usize);
    /// }
    /// ```
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn from_mut_slice(v: &mut [u8]) -> &mut [Self] {
        let [] = [(); align_of::<Self>() - align_of::<u8>()];
        unsafe { &mut *(v as *mut [u8] as *mut [Self]) }
    }
    /// Consumes the atomic and returns the contained value.
    ///
    /// This is safe because passing `self` by value guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::AtomicU8;"]
    ///
    #[doc = "let some_var = AtomicU8::new(5);"]
    /// assert_eq!(some_var.into_inner(), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_stable(feature = "const_atomic_into_inner", since =
    "1.79.0")]
    pub const fn into_inner(self) -> u8 { unsafe { transmute(self) } }
    /// Loads a value from the atomic integer.
    ///
    /// `load` takes an [`Ordering`] argument which describes the memory ordering of this operation.
    /// Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Release`] or [`AcqRel`].
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU8, Ordering};"]
    ///
    #[doc = "let some_var = AtomicU8::new(5);"]
    ///
    /// assert_eq!(some_var.load(Ordering::Relaxed), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn load(&self, order: Ordering) -> u8 {
        unsafe { atomic_load::<_, false>(self.as_ptr(), order) }
    }
    /// Stores a value into the atomic integer.
    ///
    /// `store` takes an [`Ordering`] argument which describes the memory ordering of this operation.
    ///  Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU8, Ordering};"]
    ///
    #[doc = "let some_var = AtomicU8::new(5);"]
    ///
    /// some_var.store(10, Ordering::Relaxed);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn store(&self, val: u8, order: Ordering) {
        unsafe { atomic_store::<_, false>(self.as_ptr(), val, order); }
    }
    /// Stores a value into the atomic integer, returning the previous value.
    ///
    /// `swap` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u8`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU8, Ordering};"]
    ///
    #[doc = "let some_var = AtomicU8::new(5);"]
    ///
    /// assert_eq!(some_var.swap(10, Ordering::Relaxed), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn swap(&self, val: u8, order: Ordering) -> u8 {
        unsafe { atomic_swap(self.as_ptr(), val, order) }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    /// The return value is always the previous value. If it is equal to `current`, then the
    /// value was updated.
    ///
    /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
    /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
    /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
    /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
    /// happens, and using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u8`]."]
    ///
    /// # Migrating to `compare_exchange` and `compare_exchange_weak`
    ///
    /// `compare_and_swap` is equivalent to `compare_exchange` with the following mapping for
    /// memory orderings:
    ///
    /// Original | Success | Failure
    /// -------- | ------- | -------
    /// Relaxed  | Relaxed | Relaxed
    /// Acquire  | Acquire | Acquire
    /// Release  | Release | Relaxed
    /// AcqRel   | AcqRel  | Acquire
    /// SeqCst   | SeqCst  | SeqCst
    ///
    /// `compare_and_swap` and `compare_exchange` also differ in their return type. You can use
    /// `compare_exchange(...).unwrap_or_else(|x| x)` to recover the behavior of `compare_and_swap`,
    /// but in most cases it is more idiomatic to check whether the return value is `Ok` or `Err`
    /// rather than to infer success vs failure based on the value that was read.
    ///
    /// During migration, consider whether it makes sense to use `compare_exchange_weak` instead.
    /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds,
    /// which allows the compiler to generate better assembly code when the compare and swap
    /// is used in a loop.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU8, Ordering};"]
    ///
    #[doc = "let some_var = AtomicU8::new(5);"]
    ///
    /// assert_eq!(some_var.compare_and_swap(5, 10, Ordering::Relaxed), 5);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    ///
    /// assert_eq!(some_var.compare_and_swap(6, 12, Ordering::Relaxed), 10);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[deprecated(since = "1.50.0", note =
    "Use `compare_exchange` or `compare_exchange_weak` instead")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_and_swap(&self, current: u8, new: u8,
        order: Ordering) -> u8 {
        match self.compare_exchange(current, new, order,
                strongest_failure_ordering(order)) {
            Ok(x) => x,
            Err(x) => x,
        }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    /// The return value is a result indicating whether the new value was written and
    /// containing the previous value. On success this value is guaranteed to be equal to
    /// `current`.
    ///
    /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
    /// ordering of this operation. `success` describes the required ordering for the
    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
    /// `failure` describes the required ordering for the load operation that takes place when
    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u8`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU8, Ordering};"]
    ///
    #[doc = "let some_var = AtomicU8::new(5);"]
    ///
    /// assert_eq!(some_var.compare_exchange(5, 10,
    ///                                      Ordering::Acquire,
    ///                                      Ordering::Relaxed),
    ///            Ok(5));
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    ///
    /// assert_eq!(some_var.compare_exchange(6, 12,
    ///                                      Ordering::SeqCst,
    ///                                      Ordering::Acquire),
    ///            Err(10));
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    ///
    /// # Considerations
    ///
    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
    /// of CAS operations. In particular, a load of the value followed by a successful
    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
    /// changed the value in the interim! This is usually important when the *equality* check in
    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
    /// does not necessarily imply identity. This is a particularly common case for pointers, as
    /// a pointer holding the same address does not imply that the same object exists at that
    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_exchange(&self, current: u8, new: u8,
        success: Ordering, failure: Ordering) -> Result<u8, u8> {
        unsafe {
            atomic_compare_exchange(self.as_ptr(), current, new, success,
                failure)
        }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    #[doc = "Unlike [`AtomicU8::compare_exchange`],"]
    /// this function is allowed to spuriously fail even
    /// when the comparison succeeds, which can result in more efficient code on some
    /// platforms. The return value is a result indicating whether the new value was
    /// written and containing the previous value.
    ///
    /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
    /// ordering of this operation. `success` describes the required ordering for the
    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
    /// `failure` describes the required ordering for the load operation that takes place when
    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u8`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU8, Ordering};"]
    ///
    #[doc = "let val = AtomicU8::new(4);"]
    ///
    /// let mut old = val.load(Ordering::Relaxed);
    /// loop {
    ///     let new = old * 2;
    ///     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
    ///         Ok(_) => break,
    ///         Err(x) => old = x,
    ///     }
    /// }
    /// ```
    ///
    /// # Considerations
    ///
    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
    /// of CAS operations. In particular, a load of the value followed by a successful
    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
    /// changed the value in the interim. This is usually important when the *equality* check in
    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
    /// does not necessarily imply identity. This is a particularly common case for pointers, as
    /// a pointer holding the same address does not imply that the same object exists at that
    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_exchange_weak(&self, current: u8, new: u8,
        success: Ordering, failure: Ordering) -> Result<u8, u8> {
        unsafe {
            atomic_compare_exchange_weak(self.as_ptr(), current, new, success,
                failure)
        }
    }
    /// Adds to the current value, returning the previous value.
    ///
    /// This operation wraps around on overflow.
    ///
    /// `fetch_add` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u8`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU8, Ordering};"]
    ///
    #[doc = "let foo = AtomicU8::new(0);"]
    /// assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0);
    /// assert_eq!(foo.load(Ordering::SeqCst), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_add(&self, val: u8, order: Ordering) -> u8 {
        unsafe { atomic_add(self.as_ptr(), val, order) }
    }
    /// Subtracts from the current value, returning the previous value.
    ///
    /// This operation wraps around on overflow.
    ///
    /// `fetch_sub` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u8`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU8, Ordering};"]
    ///
    #[doc = "let foo = AtomicU8::new(20);"]
    /// assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 20);
    /// assert_eq!(foo.load(Ordering::SeqCst), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_sub(&self, val: u8, order: Ordering) -> u8 {
        unsafe { atomic_sub(self.as_ptr(), val, order) }
    }
    /// Bitwise "and" with the current value.
    ///
    /// Performs a bitwise "and" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_and` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u8`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU8, Ordering};"]
    ///
    #[doc = "let foo = AtomicU8::new(0b101101);"]
    /// assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b100001);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_and(&self, val: u8, order: Ordering) -> u8 {
        unsafe { atomic_and(self.as_ptr(), val, order) }
    }
    /// Bitwise "nand" with the current value.
    ///
    /// Performs a bitwise "nand" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_nand` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u8`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU8, Ordering};"]
    ///
    #[doc = "let foo = AtomicU8::new(0x13);"]
    /// assert_eq!(foo.fetch_nand(0x31, Ordering::SeqCst), 0x13);
    /// assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31));
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_nand(&self, val: u8, order: Ordering) -> u8 {
        unsafe { atomic_nand(self.as_ptr(), val, order) }
    }
    /// Bitwise "or" with the current value.
    ///
    /// Performs a bitwise "or" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_or` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u8`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU8, Ordering};"]
    ///
    #[doc = "let foo = AtomicU8::new(0b101101);"]
    /// assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b111111);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_or(&self, val: u8, order: Ordering) -> u8 {
        unsafe { atomic_or(self.as_ptr(), val, order) }
    }
    /// Bitwise "xor" with the current value.
    ///
    /// Performs a bitwise "xor" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_xor` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u8`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU8, Ordering};"]
    ///
    #[doc = "let foo = AtomicU8::new(0b101101);"]
    /// assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b011110);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_xor(&self, val: u8, order: Ordering) -> u8 {
        unsafe { atomic_xor(self.as_ptr(), val, order) }
    }
    /// An alias for
    #[doc = "[`AtomicU8::try_update`]"]
    /// .
    #[inline]
    #[stable(feature = "no_more_cas", since = "1.45.0")]
    #[rustc_should_not_be_called_on_const_items]
    #[deprecated(since = "1.99.0", note =
    "renamed to `try_update` for consistency", suggestion = "try_update")]
    pub fn fetch_update<F>(&self, set_order: Ordering, fetch_order: Ordering,
        f: F) -> Result<u8, u8> where F: FnMut(u8) -> Option<u8> {
        self.try_update(set_order, fetch_order, f)
    }
    /// Fetches the value, and applies a function to it that returns an optional
    /// new value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else
    /// `Err(previous_value)`.
    ///
    #[doc = "See also: [`update`](`AtomicU8::update`)."]
    ///
    /// Note: This may call the function multiple times if the value has been changed from other threads in
    /// the meantime, as long as the function returns `Some(_)`, but the function will have been applied
    /// only once to the stored value.
    ///
    /// `try_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
    /// The first describes the required ordering for when the operation finally succeeds while the second
    /// describes the required ordering for loads. These correspond to the success and failure orderings of
    #[doc = "[`AtomicU8::compare_exchange`]"]
    /// respectively.
    ///
    /// Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u8`]."]
    ///
    /// # Considerations
    ///
    /// This method is not magic; it is not provided by the hardware, and does not act like a
    /// critical section or mutex.
    ///
    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
    /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
    /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicU8, Ordering};"]
    ///
    #[doc = "let x = AtomicU8::new(7);"]
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(7));
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(7));
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(8));
    /// assert_eq!(x.load(Ordering::SeqCst), 9);
    /// ```
    #[inline]
    #[stable(feature = "atomic_try_update", since = "1.95.0")]
    #[rustc_should_not_be_called_on_const_items]
    pub fn try_update(&self, set_order: Ordering, fetch_order: Ordering,
        mut f: impl FnMut(u8) -> Option<u8>) -> Result<u8, u8> {
        let mut prev = self.load(fetch_order);
        while let Some(next) = f(prev) {
            match self.compare_exchange_weak(prev, next, set_order,
                    fetch_order) {
                x @ Ok(_) => return x,
                Err(next_prev) => prev = next_prev,
            }
        }
        Err(prev)
    }
    /// Fetches the value, applies a function to it that it return a new value.
    /// The new value is stored and the old value is returned.
    ///
    #[doc = "See also: [`try_update`](`AtomicU8::try_update`)."]
    ///
    /// Note: This may call the function multiple times if the value has been changed from other threads in
    /// the meantime, but the function will have been applied only once to the stored value.
    ///
    /// `update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
    /// The first describes the required ordering for when the operation finally succeeds while the second
    /// describes the required ordering for loads. These correspond to the success and failure orderings of
    #[doc = "[`AtomicU8::compare_exchange`]"]
    /// respectively.
    ///
    /// Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u8`]."]
    ///
    /// # Considerations
    ///
    /// [CAS operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    /// This method is not magic; it is not provided by the hardware, and does not act like a
    /// critical section or mutex.
    ///
    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
    /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
    /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicU8, Ordering};"]
    ///
    #[doc = "let x = AtomicU8::new(7);"]
    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 7);
    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 8);
    /// assert_eq!(x.load(Ordering::SeqCst), 9);
    /// ```
    #[inline]
    #[stable(feature = "atomic_try_update", since = "1.95.0")]
    #[rustc_should_not_be_called_on_const_items]
    pub fn update(&self, set_order: Ordering, fetch_order: Ordering,
        mut f: impl FnMut(u8) -> u8) -> u8 {
        let mut prev = self.load(fetch_order);
        loop {
            match self.compare_exchange_weak(prev, f(prev), set_order,
                    fetch_order) {
                Ok(x) => break x,
                Err(next_prev) => prev = next_prev,
            }
        }
    }
    /// Maximum with the current value.
    ///
    /// Finds the maximum of the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_max` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u8`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU8, Ordering};"]
    ///
    #[doc = "let foo = AtomicU8::new(23);"]
    /// assert_eq!(foo.fetch_max(42, Ordering::SeqCst), 23);
    /// assert_eq!(foo.load(Ordering::SeqCst), 42);
    /// ```
    ///
    /// If you want to obtain the maximum value in one step, you can use the following:
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU8, Ordering};"]
    ///
    #[doc = "let foo = AtomicU8::new(23);"]
    /// let bar = 42;
    /// let max_foo = foo.fetch_max(bar, Ordering::SeqCst).max(bar);
    /// assert!(max_foo == 42);
    /// ```
    #[inline]
    #[stable(feature = "atomic_min_max", since = "1.45.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_max(&self, val: u8, order: Ordering) -> u8 {
        unsafe { atomic_umax(self.as_ptr(), val, order) }
    }
    /// Minimum with the current value.
    ///
    /// Finds the minimum of the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_min` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u8`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU8, Ordering};"]
    ///
    #[doc = "let foo = AtomicU8::new(23);"]
    /// assert_eq!(foo.fetch_min(42, Ordering::Relaxed), 23);
    /// assert_eq!(foo.load(Ordering::Relaxed), 23);
    /// assert_eq!(foo.fetch_min(22, Ordering::Relaxed), 23);
    /// assert_eq!(foo.load(Ordering::Relaxed), 22);
    /// ```
    ///
    /// If you want to obtain the minimum value in one step, you can use the following:
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU8, Ordering};"]
    ///
    #[doc = "let foo = AtomicU8::new(23);"]
    /// let bar = 12;
    /// let min_foo = foo.fetch_min(bar, Ordering::SeqCst).min(bar);
    /// assert_eq!(min_foo, 12);
    /// ```
    #[inline]
    #[stable(feature = "atomic_min_max", since = "1.45.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_min(&self, val: u8, order: Ordering) -> u8 {
        unsafe { atomic_umin(self.as_ptr(), val, order) }
    }
    /// Returns a mutable pointer to the underlying integer.
    ///
    /// Doing non-atomic reads and writes on the resulting integer can be a data race.
    /// This method is mostly useful for FFI, where the function signature may use
    #[doc = "`*mut u8` instead of `&AtomicU8`."]
    ///
    /// Returning an `*mut` pointer from a shared reference to this atomic is safe because the
    /// atomic types work with interior mutability. All modifications of an atomic change the value
    /// through a shared reference, and can do so safely as long as they use atomic operations. Any
    /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the
    /// requirements of the [memory model].
    ///
    /// # Examples
    ///
    /// ```ignore (extern-declaration)
    /// # fn main() {
    #[doc = "use std::sync::atomic::AtomicU8;"]
    ///
    /// extern "C" {
    #[doc = "    fn my_atomic_op(arg: *mut u8);"]
    /// }
    ///
    #[doc = "let atomic = AtomicU8::new(1);"]
    ///
    /// // SAFETY: Safe as long as `my_atomic_op` is atomic.
    /// unsafe {
    ///     my_atomic_op(atomic.as_ptr());
    /// }
    /// # }
    /// ```
    ///
    /// [memory model]: self#memory-model-for-atomic-accesses
    #[inline]
    #[stable(feature = "atomic_as_ptr", since = "1.70.0")]
    #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")]
    #[rustc_never_returns_null_ptr]
    pub const fn as_ptr(&self) -> *mut u8 { self.v.get().cast() }
}atomic_int! {
3723    target_has_atomic_load_store = "8",
3724    target_has_atomic = "8",
3725    target_has_atomic_primitive_alignment = "8",
3726    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3727    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3728    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3729    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3730    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3731    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3732    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
3733    rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
3734    "u8",
3735    "",
3736    atomic_umin, atomic_umax,
3737    1,
3738    u8 AtomicU8
3739}
3740#[cfg(target_has_atomic_load_store = "16")]
3741/// An integer type which can be safely shared between threads.
///
/// This type has the same
#[doc = "size and bit validity"]
/// as the underlying integer type, [`
#[doc = "i16"]
/// `].
#[doc =
"However, the alignment of this type is always equal to its size, even on targets where [`i16`] has a lesser alignment."]
///
/// For more about the differences between atomic types and
/// non-atomic types as well as information about the portability of
/// this type, please see the [module-level documentation].
///
/// **Note:** This type is only available on platforms that support
/// atomic loads and stores of [`
#[doc = "i16"]
/// `].
///
/// [module-level documentation]: crate::sync::atomic
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
pub type AtomicI16 = Atomic<i16>;
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
impl Default for AtomicI16 {
    #[inline]
    fn default() -> Self { Self::new(Default::default()) }
}
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
const impl From<i16> for AtomicI16 {
    #[doc = "Converts an `i16` into an `AtomicI16`."]
    #[inline]
    fn from(v: i16) -> Self { Self::new(v) }
}
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
impl fmt::Debug for AtomicI16 {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)
    }
}
impl AtomicI16 {
    /// Creates a new atomic integer.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::AtomicI16;"]
    ///
    #[doc = "let atomic_forty_two = AtomicI16::new(42);"]
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0")]
    #[must_use]
    pub const fn new(v: i16) -> Self { unsafe { transmute(v) } }
    /// Creates a new reference to an atomic integer from a pointer.
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{self, AtomicI16};"]
    ///
    /// // Get a pointer to an allocated value
    #[doc = "let ptr: *mut i16 = Box::into_raw(Box::new(0));"]
    ///
    #[doc = "assert!(ptr.cast::<AtomicI16>().is_aligned());"]
    ///
    /// {
    ///     // Create an atomic view of the allocated value
    #[doc = "    let atomic = unsafe {AtomicI16::from_ptr(ptr) };"]
    ///
    ///     // Use `atomic` for atomic operations, possibly share it with other threads
    ///     atomic.store(1, atomic::Ordering::Relaxed);
    /// }
    ///
    /// // It's ok to non-atomically access the value behind `ptr`,
    /// // since the reference to the atomic ended its lifetime in the block above
    /// assert_eq!(unsafe { *ptr }, 1);
    ///
    /// // Deallocate the value
    /// unsafe { drop(Box::from_raw(ptr)) }
    /// ```
    ///
    /// # Safety
    ///
    /// * `ptr` must be aligned to
    #[doc = "  `align_of::<AtomicI16>()`"]
    #[doc =
    "  (note that on some platforms this can be bigger than `align_of::<i16>()`)."]
    /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
    /// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not
    ///   allowed to mix conflicting atomic and non-atomic accesses, or atomic accesses of different
    ///   sizes, without synchronization.
    ///
    /// [valid]: crate::ptr#safety
    /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
    #[inline]
    #[stable(feature = "atomic_from_ptr", since = "1.75.0")]
    #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")]
    pub const unsafe fn from_ptr<'a>(ptr: *mut i16) -> &'a AtomicI16 {
        unsafe { &*ptr.cast() }
    }
    /// Returns a mutable reference to the underlying integer.
    ///
    /// This is safe because the mutable reference guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI16, Ordering};"]
    ///
    #[doc = "let mut some_var = AtomicI16::new(10);"]
    /// assert_eq!(*some_var.get_mut(), 10);
    /// *some_var.get_mut() = 5;
    /// assert_eq!(some_var.load(Ordering::SeqCst), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn get_mut(&mut self) -> &mut i16 {
        unsafe { &mut *self.as_ptr() }
    }
    #[doc = "Get atomic access to a `&mut i16`."]
    ///
    #[doc =
    "**Note:** This function is only available on targets where `AtomicI16` has the same alignment as `i16`."]
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicI16, Ordering};"]
    ///
    /// let mut some_int = 123;
    #[doc = "let a = AtomicI16::from_mut(&mut some_int);"]
    /// a.store(100, Ordering::Relaxed);
    /// assert_eq!(some_int, 100);
    /// ```
    ///
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn from_mut(v: &mut i16) -> &mut Self {
        let [] = [(); align_of::<Self>() - align_of::<i16>()];
        unsafe { &mut *(v as *mut i16 as *mut Self) }
    }
    #[doc = "Get non-atomic access to a `&mut [AtomicI16]` slice"]
    ///
    /// This is safe because the mutable reference guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```ignore-wasm"]
    #[doc = "use std::sync::atomic::{AtomicI16, Ordering};"]
    ///
    #[doc = "let mut some_ints = [const { AtomicI16::new(0) }; 10];"]
    ///
    #[doc =
    "let view: &mut [i16] = AtomicI16::get_mut_slice(&mut some_ints);"]
    /// assert_eq!(view, [0; 10]);
    /// view
    ///     .iter_mut()
    ///     .enumerate()
    ///     .for_each(|(idx, int)| *int = idx as _);
    ///
    /// std::thread::scope(|s| {
    ///     some_ints
    ///         .iter()
    ///         .enumerate()
    ///         .for_each(|(idx, int)| {
    ///             s.spawn(move || assert_eq!(int.load(Ordering::Relaxed), idx as _));
    ///         })
    /// });
    /// ```
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn get_mut_slice(this: &mut [Self]) -> &mut [i16] {
        unsafe { &mut *(this as *mut [Self] as *mut [i16]) }
    }
    #[doc = "Get atomic access to a `&mut [i16]` slice."]
    ///
    #[doc =
    "**Note:** This function is only available on targets where `AtomicI16` has the same alignment as `i16`."]
    ///
    /// # Examples
    ///
    #[doc = "```ignore-wasm"]
    #[doc = "use std::sync::atomic::{AtomicI16, Ordering};"]
    ///
    /// let mut some_ints = [0; 10];
    #[doc = "let a = &*AtomicI16::from_mut_slice(&mut some_ints);"]
    /// std::thread::scope(|s| {
    ///     for i in 0..a.len() {
    ///         s.spawn(move || a[i].store(i as _, Ordering::Relaxed));
    ///     }
    /// });
    /// for (i, n) in some_ints.into_iter().enumerate() {
    ///     assert_eq!(i, n as usize);
    /// }
    /// ```
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn from_mut_slice(v: &mut [i16]) -> &mut [Self] {
        let [] = [(); align_of::<Self>() - align_of::<i16>()];
        unsafe { &mut *(v as *mut [i16] as *mut [Self]) }
    }
    /// Consumes the atomic and returns the contained value.
    ///
    /// This is safe because passing `self` by value guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::AtomicI16;"]
    ///
    #[doc = "let some_var = AtomicI16::new(5);"]
    /// assert_eq!(some_var.into_inner(), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_stable(feature = "const_atomic_into_inner", since =
    "1.79.0")]
    pub const fn into_inner(self) -> i16 { unsafe { transmute(self) } }
    /// Loads a value from the atomic integer.
    ///
    /// `load` takes an [`Ordering`] argument which describes the memory ordering of this operation.
    /// Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Release`] or [`AcqRel`].
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI16, Ordering};"]
    ///
    #[doc = "let some_var = AtomicI16::new(5);"]
    ///
    /// assert_eq!(some_var.load(Ordering::Relaxed), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn load(&self, order: Ordering) -> i16 {
        unsafe { atomic_load::<_, false>(self.as_ptr(), order) }
    }
    /// Stores a value into the atomic integer.
    ///
    /// `store` takes an [`Ordering`] argument which describes the memory ordering of this operation.
    ///  Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI16, Ordering};"]
    ///
    #[doc = "let some_var = AtomicI16::new(5);"]
    ///
    /// some_var.store(10, Ordering::Relaxed);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn store(&self, val: i16, order: Ordering) {
        unsafe { atomic_store::<_, false>(self.as_ptr(), val, order); }
    }
    /// Stores a value into the atomic integer, returning the previous value.
    ///
    /// `swap` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i16`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI16, Ordering};"]
    ///
    #[doc = "let some_var = AtomicI16::new(5);"]
    ///
    /// assert_eq!(some_var.swap(10, Ordering::Relaxed), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn swap(&self, val: i16, order: Ordering) -> i16 {
        unsafe { atomic_swap(self.as_ptr(), val, order) }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    /// The return value is always the previous value. If it is equal to `current`, then the
    /// value was updated.
    ///
    /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
    /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
    /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
    /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
    /// happens, and using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i16`]."]
    ///
    /// # Migrating to `compare_exchange` and `compare_exchange_weak`
    ///
    /// `compare_and_swap` is equivalent to `compare_exchange` with the following mapping for
    /// memory orderings:
    ///
    /// Original | Success | Failure
    /// -------- | ------- | -------
    /// Relaxed  | Relaxed | Relaxed
    /// Acquire  | Acquire | Acquire
    /// Release  | Release | Relaxed
    /// AcqRel   | AcqRel  | Acquire
    /// SeqCst   | SeqCst  | SeqCst
    ///
    /// `compare_and_swap` and `compare_exchange` also differ in their return type. You can use
    /// `compare_exchange(...).unwrap_or_else(|x| x)` to recover the behavior of `compare_and_swap`,
    /// but in most cases it is more idiomatic to check whether the return value is `Ok` or `Err`
    /// rather than to infer success vs failure based on the value that was read.
    ///
    /// During migration, consider whether it makes sense to use `compare_exchange_weak` instead.
    /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds,
    /// which allows the compiler to generate better assembly code when the compare and swap
    /// is used in a loop.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI16, Ordering};"]
    ///
    #[doc = "let some_var = AtomicI16::new(5);"]
    ///
    /// assert_eq!(some_var.compare_and_swap(5, 10, Ordering::Relaxed), 5);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    ///
    /// assert_eq!(some_var.compare_and_swap(6, 12, Ordering::Relaxed), 10);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[deprecated(since = "1.50.0", note =
    "Use `compare_exchange` or `compare_exchange_weak` instead")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_and_swap(&self, current: i16, new: i16,
        order: Ordering) -> i16 {
        match self.compare_exchange(current, new, order,
                strongest_failure_ordering(order)) {
            Ok(x) => x,
            Err(x) => x,
        }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    /// The return value is a result indicating whether the new value was written and
    /// containing the previous value. On success this value is guaranteed to be equal to
    /// `current`.
    ///
    /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
    /// ordering of this operation. `success` describes the required ordering for the
    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
    /// `failure` describes the required ordering for the load operation that takes place when
    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i16`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI16, Ordering};"]
    ///
    #[doc = "let some_var = AtomicI16::new(5);"]
    ///
    /// assert_eq!(some_var.compare_exchange(5, 10,
    ///                                      Ordering::Acquire,
    ///                                      Ordering::Relaxed),
    ///            Ok(5));
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    ///
    /// assert_eq!(some_var.compare_exchange(6, 12,
    ///                                      Ordering::SeqCst,
    ///                                      Ordering::Acquire),
    ///            Err(10));
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    ///
    /// # Considerations
    ///
    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
    /// of CAS operations. In particular, a load of the value followed by a successful
    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
    /// changed the value in the interim! This is usually important when the *equality* check in
    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
    /// does not necessarily imply identity. This is a particularly common case for pointers, as
    /// a pointer holding the same address does not imply that the same object exists at that
    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_exchange(&self, current: i16, new: i16,
        success: Ordering, failure: Ordering) -> Result<i16, i16> {
        unsafe {
            atomic_compare_exchange(self.as_ptr(), current, new, success,
                failure)
        }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    #[doc = "Unlike [`AtomicI16::compare_exchange`],"]
    /// this function is allowed to spuriously fail even
    /// when the comparison succeeds, which can result in more efficient code on some
    /// platforms. The return value is a result indicating whether the new value was
    /// written and containing the previous value.
    ///
    /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
    /// ordering of this operation. `success` describes the required ordering for the
    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
    /// `failure` describes the required ordering for the load operation that takes place when
    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i16`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI16, Ordering};"]
    ///
    #[doc = "let val = AtomicI16::new(4);"]
    ///
    /// let mut old = val.load(Ordering::Relaxed);
    /// loop {
    ///     let new = old * 2;
    ///     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
    ///         Ok(_) => break,
    ///         Err(x) => old = x,
    ///     }
    /// }
    /// ```
    ///
    /// # Considerations
    ///
    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
    /// of CAS operations. In particular, a load of the value followed by a successful
    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
    /// changed the value in the interim. This is usually important when the *equality* check in
    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
    /// does not necessarily imply identity. This is a particularly common case for pointers, as
    /// a pointer holding the same address does not imply that the same object exists at that
    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_exchange_weak(&self, current: i16, new: i16,
        success: Ordering, failure: Ordering) -> Result<i16, i16> {
        unsafe {
            atomic_compare_exchange_weak(self.as_ptr(), current, new, success,
                failure)
        }
    }
    /// Adds to the current value, returning the previous value.
    ///
    /// This operation wraps around on overflow.
    ///
    /// `fetch_add` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i16`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI16, Ordering};"]
    ///
    #[doc = "let foo = AtomicI16::new(0);"]
    /// assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0);
    /// assert_eq!(foo.load(Ordering::SeqCst), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_add(&self, val: i16, order: Ordering) -> i16 {
        unsafe { atomic_add(self.as_ptr(), val, order) }
    }
    /// Subtracts from the current value, returning the previous value.
    ///
    /// This operation wraps around on overflow.
    ///
    /// `fetch_sub` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i16`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI16, Ordering};"]
    ///
    #[doc = "let foo = AtomicI16::new(20);"]
    /// assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 20);
    /// assert_eq!(foo.load(Ordering::SeqCst), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_sub(&self, val: i16, order: Ordering) -> i16 {
        unsafe { atomic_sub(self.as_ptr(), val, order) }
    }
    /// Bitwise "and" with the current value.
    ///
    /// Performs a bitwise "and" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_and` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i16`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI16, Ordering};"]
    ///
    #[doc = "let foo = AtomicI16::new(0b101101);"]
    /// assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b100001);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_and(&self, val: i16, order: Ordering) -> i16 {
        unsafe { atomic_and(self.as_ptr(), val, order) }
    }
    /// Bitwise "nand" with the current value.
    ///
    /// Performs a bitwise "nand" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_nand` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i16`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI16, Ordering};"]
    ///
    #[doc = "let foo = AtomicI16::new(0x13);"]
    /// assert_eq!(foo.fetch_nand(0x31, Ordering::SeqCst), 0x13);
    /// assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31));
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_nand(&self, val: i16, order: Ordering) -> i16 {
        unsafe { atomic_nand(self.as_ptr(), val, order) }
    }
    /// Bitwise "or" with the current value.
    ///
    /// Performs a bitwise "or" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_or` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i16`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI16, Ordering};"]
    ///
    #[doc = "let foo = AtomicI16::new(0b101101);"]
    /// assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b111111);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_or(&self, val: i16, order: Ordering) -> i16 {
        unsafe { atomic_or(self.as_ptr(), val, order) }
    }
    /// Bitwise "xor" with the current value.
    ///
    /// Performs a bitwise "xor" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_xor` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i16`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI16, Ordering};"]
    ///
    #[doc = "let foo = AtomicI16::new(0b101101);"]
    /// assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b011110);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_xor(&self, val: i16, order: Ordering) -> i16 {
        unsafe { atomic_xor(self.as_ptr(), val, order) }
    }
    /// An alias for
    #[doc = "[`AtomicI16::try_update`]"]
    /// .
    #[inline]
    #[stable(feature = "no_more_cas", since = "1.45.0")]
    #[rustc_should_not_be_called_on_const_items]
    #[deprecated(since = "1.99.0", note =
    "renamed to `try_update` for consistency", suggestion = "try_update")]
    pub fn fetch_update<F>(&self, set_order: Ordering, fetch_order: Ordering,
        f: F) -> Result<i16, i16> where F: FnMut(i16) -> Option<i16> {
        self.try_update(set_order, fetch_order, f)
    }
    /// Fetches the value, and applies a function to it that returns an optional
    /// new value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else
    /// `Err(previous_value)`.
    ///
    #[doc = "See also: [`update`](`AtomicI16::update`)."]
    ///
    /// Note: This may call the function multiple times if the value has been changed from other threads in
    /// the meantime, as long as the function returns `Some(_)`, but the function will have been applied
    /// only once to the stored value.
    ///
    /// `try_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
    /// The first describes the required ordering for when the operation finally succeeds while the second
    /// describes the required ordering for loads. These correspond to the success and failure orderings of
    #[doc = "[`AtomicI16::compare_exchange`]"]
    /// respectively.
    ///
    /// Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i16`]."]
    ///
    /// # Considerations
    ///
    /// This method is not magic; it is not provided by the hardware, and does not act like a
    /// critical section or mutex.
    ///
    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
    /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
    /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicI16, Ordering};"]
    ///
    #[doc = "let x = AtomicI16::new(7);"]
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(7));
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(7));
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(8));
    /// assert_eq!(x.load(Ordering::SeqCst), 9);
    /// ```
    #[inline]
    #[stable(feature = "atomic_try_update", since = "1.95.0")]
    #[rustc_should_not_be_called_on_const_items]
    pub fn try_update(&self, set_order: Ordering, fetch_order: Ordering,
        mut f: impl FnMut(i16) -> Option<i16>) -> Result<i16, i16> {
        let mut prev = self.load(fetch_order);
        while let Some(next) = f(prev) {
            match self.compare_exchange_weak(prev, next, set_order,
                    fetch_order) {
                x @ Ok(_) => return x,
                Err(next_prev) => prev = next_prev,
            }
        }
        Err(prev)
    }
    /// Fetches the value, applies a function to it that it return a new value.
    /// The new value is stored and the old value is returned.
    ///
    #[doc = "See also: [`try_update`](`AtomicI16::try_update`)."]
    ///
    /// Note: This may call the function multiple times if the value has been changed from other threads in
    /// the meantime, but the function will have been applied only once to the stored value.
    ///
    /// `update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
    /// The first describes the required ordering for when the operation finally succeeds while the second
    /// describes the required ordering for loads. These correspond to the success and failure orderings of
    #[doc = "[`AtomicI16::compare_exchange`]"]
    /// respectively.
    ///
    /// Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i16`]."]
    ///
    /// # Considerations
    ///
    /// [CAS operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    /// This method is not magic; it is not provided by the hardware, and does not act like a
    /// critical section or mutex.
    ///
    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
    /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
    /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicI16, Ordering};"]
    ///
    #[doc = "let x = AtomicI16::new(7);"]
    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 7);
    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 8);
    /// assert_eq!(x.load(Ordering::SeqCst), 9);
    /// ```
    #[inline]
    #[stable(feature = "atomic_try_update", since = "1.95.0")]
    #[rustc_should_not_be_called_on_const_items]
    pub fn update(&self, set_order: Ordering, fetch_order: Ordering,
        mut f: impl FnMut(i16) -> i16) -> i16 {
        let mut prev = self.load(fetch_order);
        loop {
            match self.compare_exchange_weak(prev, f(prev), set_order,
                    fetch_order) {
                Ok(x) => break x,
                Err(next_prev) => prev = next_prev,
            }
        }
    }
    /// Maximum with the current value.
    ///
    /// Finds the maximum of the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_max` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i16`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI16, Ordering};"]
    ///
    #[doc = "let foo = AtomicI16::new(23);"]
    /// assert_eq!(foo.fetch_max(42, Ordering::SeqCst), 23);
    /// assert_eq!(foo.load(Ordering::SeqCst), 42);
    /// ```
    ///
    /// If you want to obtain the maximum value in one step, you can use the following:
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI16, Ordering};"]
    ///
    #[doc = "let foo = AtomicI16::new(23);"]
    /// let bar = 42;
    /// let max_foo = foo.fetch_max(bar, Ordering::SeqCst).max(bar);
    /// assert!(max_foo == 42);
    /// ```
    #[inline]
    #[stable(feature = "atomic_min_max", since = "1.45.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_max(&self, val: i16, order: Ordering) -> i16 {
        unsafe { atomic_max(self.as_ptr(), val, order) }
    }
    /// Minimum with the current value.
    ///
    /// Finds the minimum of the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_min` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i16`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI16, Ordering};"]
    ///
    #[doc = "let foo = AtomicI16::new(23);"]
    /// assert_eq!(foo.fetch_min(42, Ordering::Relaxed), 23);
    /// assert_eq!(foo.load(Ordering::Relaxed), 23);
    /// assert_eq!(foo.fetch_min(22, Ordering::Relaxed), 23);
    /// assert_eq!(foo.load(Ordering::Relaxed), 22);
    /// ```
    ///
    /// If you want to obtain the minimum value in one step, you can use the following:
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI16, Ordering};"]
    ///
    #[doc = "let foo = AtomicI16::new(23);"]
    /// let bar = 12;
    /// let min_foo = foo.fetch_min(bar, Ordering::SeqCst).min(bar);
    /// assert_eq!(min_foo, 12);
    /// ```
    #[inline]
    #[stable(feature = "atomic_min_max", since = "1.45.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_min(&self, val: i16, order: Ordering) -> i16 {
        unsafe { atomic_min(self.as_ptr(), val, order) }
    }
    /// Returns a mutable pointer to the underlying integer.
    ///
    /// Doing non-atomic reads and writes on the resulting integer can be a data race.
    /// This method is mostly useful for FFI, where the function signature may use
    #[doc = "`*mut i16` instead of `&AtomicI16`."]
    ///
    /// Returning an `*mut` pointer from a shared reference to this atomic is safe because the
    /// atomic types work with interior mutability. All modifications of an atomic change the value
    /// through a shared reference, and can do so safely as long as they use atomic operations. Any
    /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the
    /// requirements of the [memory model].
    ///
    /// # Examples
    ///
    /// ```ignore (extern-declaration)
    /// # fn main() {
    #[doc = "use std::sync::atomic::AtomicI16;"]
    ///
    /// extern "C" {
    #[doc = "    fn my_atomic_op(arg: *mut i16);"]
    /// }
    ///
    #[doc = "let atomic = AtomicI16::new(1);"]
    ///
    /// // SAFETY: Safe as long as `my_atomic_op` is atomic.
    /// unsafe {
    ///     my_atomic_op(atomic.as_ptr());
    /// }
    /// # }
    /// ```
    ///
    /// [memory model]: self#memory-model-for-atomic-accesses
    #[inline]
    #[stable(feature = "atomic_as_ptr", since = "1.70.0")]
    #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")]
    #[rustc_never_returns_null_ptr]
    pub const fn as_ptr(&self) -> *mut i16 { self.v.get().cast() }
}atomic_int! {
3742    target_has_atomic_load_store = "16",
3743    target_has_atomic = "16",
3744    target_has_atomic_primitive_alignment = "16",
3745    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3746    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3747    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3748    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3749    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3750    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3751    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
3752    rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
3753    "i16",
3754    "",
3755    atomic_min, atomic_max,
3756    2,
3757    i16 AtomicI16
3758}
3759#[cfg(target_has_atomic_load_store = "16")]
3760/// An integer type which can be safely shared between threads.
///
/// This type has the same
#[doc = "size and bit validity"]
/// as the underlying integer type, [`
#[doc = "u16"]
/// `].
#[doc =
"However, the alignment of this type is always equal to its size, even on targets where [`u16`] has a lesser alignment."]
///
/// For more about the differences between atomic types and
/// non-atomic types as well as information about the portability of
/// this type, please see the [module-level documentation].
///
/// **Note:** This type is only available on platforms that support
/// atomic loads and stores of [`
#[doc = "u16"]
/// `].
///
/// [module-level documentation]: crate::sync::atomic
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
pub type AtomicU16 = Atomic<u16>;
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
impl Default for AtomicU16 {
    #[inline]
    fn default() -> Self { Self::new(Default::default()) }
}
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
const impl From<u16> for AtomicU16 {
    #[doc = "Converts an `u16` into an `AtomicU16`."]
    #[inline]
    fn from(v: u16) -> Self { Self::new(v) }
}
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
impl fmt::Debug for AtomicU16 {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)
    }
}
impl AtomicU16 {
    /// Creates a new atomic integer.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::AtomicU16;"]
    ///
    #[doc = "let atomic_forty_two = AtomicU16::new(42);"]
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0")]
    #[must_use]
    pub const fn new(v: u16) -> Self { unsafe { transmute(v) } }
    /// Creates a new reference to an atomic integer from a pointer.
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{self, AtomicU16};"]
    ///
    /// // Get a pointer to an allocated value
    #[doc = "let ptr: *mut u16 = Box::into_raw(Box::new(0));"]
    ///
    #[doc = "assert!(ptr.cast::<AtomicU16>().is_aligned());"]
    ///
    /// {
    ///     // Create an atomic view of the allocated value
    #[doc = "    let atomic = unsafe {AtomicU16::from_ptr(ptr) };"]
    ///
    ///     // Use `atomic` for atomic operations, possibly share it with other threads
    ///     atomic.store(1, atomic::Ordering::Relaxed);
    /// }
    ///
    /// // It's ok to non-atomically access the value behind `ptr`,
    /// // since the reference to the atomic ended its lifetime in the block above
    /// assert_eq!(unsafe { *ptr }, 1);
    ///
    /// // Deallocate the value
    /// unsafe { drop(Box::from_raw(ptr)) }
    /// ```
    ///
    /// # Safety
    ///
    /// * `ptr` must be aligned to
    #[doc = "  `align_of::<AtomicU16>()`"]
    #[doc =
    "  (note that on some platforms this can be bigger than `align_of::<u16>()`)."]
    /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
    /// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not
    ///   allowed to mix conflicting atomic and non-atomic accesses, or atomic accesses of different
    ///   sizes, without synchronization.
    ///
    /// [valid]: crate::ptr#safety
    /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
    #[inline]
    #[stable(feature = "atomic_from_ptr", since = "1.75.0")]
    #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")]
    pub const unsafe fn from_ptr<'a>(ptr: *mut u16) -> &'a AtomicU16 {
        unsafe { &*ptr.cast() }
    }
    /// Returns a mutable reference to the underlying integer.
    ///
    /// This is safe because the mutable reference guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU16, Ordering};"]
    ///
    #[doc = "let mut some_var = AtomicU16::new(10);"]
    /// assert_eq!(*some_var.get_mut(), 10);
    /// *some_var.get_mut() = 5;
    /// assert_eq!(some_var.load(Ordering::SeqCst), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn get_mut(&mut self) -> &mut u16 {
        unsafe { &mut *self.as_ptr() }
    }
    #[doc = "Get atomic access to a `&mut u16`."]
    ///
    #[doc =
    "**Note:** This function is only available on targets where `AtomicU16` has the same alignment as `u16`."]
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicU16, Ordering};"]
    ///
    /// let mut some_int = 123;
    #[doc = "let a = AtomicU16::from_mut(&mut some_int);"]
    /// a.store(100, Ordering::Relaxed);
    /// assert_eq!(some_int, 100);
    /// ```
    ///
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn from_mut(v: &mut u16) -> &mut Self {
        let [] = [(); align_of::<Self>() - align_of::<u16>()];
        unsafe { &mut *(v as *mut u16 as *mut Self) }
    }
    #[doc = "Get non-atomic access to a `&mut [AtomicU16]` slice"]
    ///
    /// This is safe because the mutable reference guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```ignore-wasm"]
    #[doc = "use std::sync::atomic::{AtomicU16, Ordering};"]
    ///
    #[doc = "let mut some_ints = [const { AtomicU16::new(0) }; 10];"]
    ///
    #[doc =
    "let view: &mut [u16] = AtomicU16::get_mut_slice(&mut some_ints);"]
    /// assert_eq!(view, [0; 10]);
    /// view
    ///     .iter_mut()
    ///     .enumerate()
    ///     .for_each(|(idx, int)| *int = idx as _);
    ///
    /// std::thread::scope(|s| {
    ///     some_ints
    ///         .iter()
    ///         .enumerate()
    ///         .for_each(|(idx, int)| {
    ///             s.spawn(move || assert_eq!(int.load(Ordering::Relaxed), idx as _));
    ///         })
    /// });
    /// ```
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn get_mut_slice(this: &mut [Self]) -> &mut [u16] {
        unsafe { &mut *(this as *mut [Self] as *mut [u16]) }
    }
    #[doc = "Get atomic access to a `&mut [u16]` slice."]
    ///
    #[doc =
    "**Note:** This function is only available on targets where `AtomicU16` has the same alignment as `u16`."]
    ///
    /// # Examples
    ///
    #[doc = "```ignore-wasm"]
    #[doc = "use std::sync::atomic::{AtomicU16, Ordering};"]
    ///
    /// let mut some_ints = [0; 10];
    #[doc = "let a = &*AtomicU16::from_mut_slice(&mut some_ints);"]
    /// std::thread::scope(|s| {
    ///     for i in 0..a.len() {
    ///         s.spawn(move || a[i].store(i as _, Ordering::Relaxed));
    ///     }
    /// });
    /// for (i, n) in some_ints.into_iter().enumerate() {
    ///     assert_eq!(i, n as usize);
    /// }
    /// ```
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn from_mut_slice(v: &mut [u16]) -> &mut [Self] {
        let [] = [(); align_of::<Self>() - align_of::<u16>()];
        unsafe { &mut *(v as *mut [u16] as *mut [Self]) }
    }
    /// Consumes the atomic and returns the contained value.
    ///
    /// This is safe because passing `self` by value guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::AtomicU16;"]
    ///
    #[doc = "let some_var = AtomicU16::new(5);"]
    /// assert_eq!(some_var.into_inner(), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_stable(feature = "const_atomic_into_inner", since =
    "1.79.0")]
    pub const fn into_inner(self) -> u16 { unsafe { transmute(self) } }
    /// Loads a value from the atomic integer.
    ///
    /// `load` takes an [`Ordering`] argument which describes the memory ordering of this operation.
    /// Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Release`] or [`AcqRel`].
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU16, Ordering};"]
    ///
    #[doc = "let some_var = AtomicU16::new(5);"]
    ///
    /// assert_eq!(some_var.load(Ordering::Relaxed), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn load(&self, order: Ordering) -> u16 {
        unsafe { atomic_load::<_, false>(self.as_ptr(), order) }
    }
    /// Stores a value into the atomic integer.
    ///
    /// `store` takes an [`Ordering`] argument which describes the memory ordering of this operation.
    ///  Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU16, Ordering};"]
    ///
    #[doc = "let some_var = AtomicU16::new(5);"]
    ///
    /// some_var.store(10, Ordering::Relaxed);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn store(&self, val: u16, order: Ordering) {
        unsafe { atomic_store::<_, false>(self.as_ptr(), val, order); }
    }
    /// Stores a value into the atomic integer, returning the previous value.
    ///
    /// `swap` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u16`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU16, Ordering};"]
    ///
    #[doc = "let some_var = AtomicU16::new(5);"]
    ///
    /// assert_eq!(some_var.swap(10, Ordering::Relaxed), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn swap(&self, val: u16, order: Ordering) -> u16 {
        unsafe { atomic_swap(self.as_ptr(), val, order) }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    /// The return value is always the previous value. If it is equal to `current`, then the
    /// value was updated.
    ///
    /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
    /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
    /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
    /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
    /// happens, and using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u16`]."]
    ///
    /// # Migrating to `compare_exchange` and `compare_exchange_weak`
    ///
    /// `compare_and_swap` is equivalent to `compare_exchange` with the following mapping for
    /// memory orderings:
    ///
    /// Original | Success | Failure
    /// -------- | ------- | -------
    /// Relaxed  | Relaxed | Relaxed
    /// Acquire  | Acquire | Acquire
    /// Release  | Release | Relaxed
    /// AcqRel   | AcqRel  | Acquire
    /// SeqCst   | SeqCst  | SeqCst
    ///
    /// `compare_and_swap` and `compare_exchange` also differ in their return type. You can use
    /// `compare_exchange(...).unwrap_or_else(|x| x)` to recover the behavior of `compare_and_swap`,
    /// but in most cases it is more idiomatic to check whether the return value is `Ok` or `Err`
    /// rather than to infer success vs failure based on the value that was read.
    ///
    /// During migration, consider whether it makes sense to use `compare_exchange_weak` instead.
    /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds,
    /// which allows the compiler to generate better assembly code when the compare and swap
    /// is used in a loop.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU16, Ordering};"]
    ///
    #[doc = "let some_var = AtomicU16::new(5);"]
    ///
    /// assert_eq!(some_var.compare_and_swap(5, 10, Ordering::Relaxed), 5);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    ///
    /// assert_eq!(some_var.compare_and_swap(6, 12, Ordering::Relaxed), 10);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[deprecated(since = "1.50.0", note =
    "Use `compare_exchange` or `compare_exchange_weak` instead")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_and_swap(&self, current: u16, new: u16,
        order: Ordering) -> u16 {
        match self.compare_exchange(current, new, order,
                strongest_failure_ordering(order)) {
            Ok(x) => x,
            Err(x) => x,
        }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    /// The return value is a result indicating whether the new value was written and
    /// containing the previous value. On success this value is guaranteed to be equal to
    /// `current`.
    ///
    /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
    /// ordering of this operation. `success` describes the required ordering for the
    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
    /// `failure` describes the required ordering for the load operation that takes place when
    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u16`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU16, Ordering};"]
    ///
    #[doc = "let some_var = AtomicU16::new(5);"]
    ///
    /// assert_eq!(some_var.compare_exchange(5, 10,
    ///                                      Ordering::Acquire,
    ///                                      Ordering::Relaxed),
    ///            Ok(5));
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    ///
    /// assert_eq!(some_var.compare_exchange(6, 12,
    ///                                      Ordering::SeqCst,
    ///                                      Ordering::Acquire),
    ///            Err(10));
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    ///
    /// # Considerations
    ///
    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
    /// of CAS operations. In particular, a load of the value followed by a successful
    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
    /// changed the value in the interim! This is usually important when the *equality* check in
    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
    /// does not necessarily imply identity. This is a particularly common case for pointers, as
    /// a pointer holding the same address does not imply that the same object exists at that
    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_exchange(&self, current: u16, new: u16,
        success: Ordering, failure: Ordering) -> Result<u16, u16> {
        unsafe {
            atomic_compare_exchange(self.as_ptr(), current, new, success,
                failure)
        }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    #[doc = "Unlike [`AtomicU16::compare_exchange`],"]
    /// this function is allowed to spuriously fail even
    /// when the comparison succeeds, which can result in more efficient code on some
    /// platforms. The return value is a result indicating whether the new value was
    /// written and containing the previous value.
    ///
    /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
    /// ordering of this operation. `success` describes the required ordering for the
    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
    /// `failure` describes the required ordering for the load operation that takes place when
    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u16`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU16, Ordering};"]
    ///
    #[doc = "let val = AtomicU16::new(4);"]
    ///
    /// let mut old = val.load(Ordering::Relaxed);
    /// loop {
    ///     let new = old * 2;
    ///     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
    ///         Ok(_) => break,
    ///         Err(x) => old = x,
    ///     }
    /// }
    /// ```
    ///
    /// # Considerations
    ///
    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
    /// of CAS operations. In particular, a load of the value followed by a successful
    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
    /// changed the value in the interim. This is usually important when the *equality* check in
    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
    /// does not necessarily imply identity. This is a particularly common case for pointers, as
    /// a pointer holding the same address does not imply that the same object exists at that
    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_exchange_weak(&self, current: u16, new: u16,
        success: Ordering, failure: Ordering) -> Result<u16, u16> {
        unsafe {
            atomic_compare_exchange_weak(self.as_ptr(), current, new, success,
                failure)
        }
    }
    /// Adds to the current value, returning the previous value.
    ///
    /// This operation wraps around on overflow.
    ///
    /// `fetch_add` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u16`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU16, Ordering};"]
    ///
    #[doc = "let foo = AtomicU16::new(0);"]
    /// assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0);
    /// assert_eq!(foo.load(Ordering::SeqCst), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_add(&self, val: u16, order: Ordering) -> u16 {
        unsafe { atomic_add(self.as_ptr(), val, order) }
    }
    /// Subtracts from the current value, returning the previous value.
    ///
    /// This operation wraps around on overflow.
    ///
    /// `fetch_sub` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u16`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU16, Ordering};"]
    ///
    #[doc = "let foo = AtomicU16::new(20);"]
    /// assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 20);
    /// assert_eq!(foo.load(Ordering::SeqCst), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_sub(&self, val: u16, order: Ordering) -> u16 {
        unsafe { atomic_sub(self.as_ptr(), val, order) }
    }
    /// Bitwise "and" with the current value.
    ///
    /// Performs a bitwise "and" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_and` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u16`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU16, Ordering};"]
    ///
    #[doc = "let foo = AtomicU16::new(0b101101);"]
    /// assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b100001);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_and(&self, val: u16, order: Ordering) -> u16 {
        unsafe { atomic_and(self.as_ptr(), val, order) }
    }
    /// Bitwise "nand" with the current value.
    ///
    /// Performs a bitwise "nand" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_nand` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u16`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU16, Ordering};"]
    ///
    #[doc = "let foo = AtomicU16::new(0x13);"]
    /// assert_eq!(foo.fetch_nand(0x31, Ordering::SeqCst), 0x13);
    /// assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31));
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_nand(&self, val: u16, order: Ordering) -> u16 {
        unsafe { atomic_nand(self.as_ptr(), val, order) }
    }
    /// Bitwise "or" with the current value.
    ///
    /// Performs a bitwise "or" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_or` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u16`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU16, Ordering};"]
    ///
    #[doc = "let foo = AtomicU16::new(0b101101);"]
    /// assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b111111);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_or(&self, val: u16, order: Ordering) -> u16 {
        unsafe { atomic_or(self.as_ptr(), val, order) }
    }
    /// Bitwise "xor" with the current value.
    ///
    /// Performs a bitwise "xor" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_xor` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u16`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU16, Ordering};"]
    ///
    #[doc = "let foo = AtomicU16::new(0b101101);"]
    /// assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b011110);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_xor(&self, val: u16, order: Ordering) -> u16 {
        unsafe { atomic_xor(self.as_ptr(), val, order) }
    }
    /// An alias for
    #[doc = "[`AtomicU16::try_update`]"]
    /// .
    #[inline]
    #[stable(feature = "no_more_cas", since = "1.45.0")]
    #[rustc_should_not_be_called_on_const_items]
    #[deprecated(since = "1.99.0", note =
    "renamed to `try_update` for consistency", suggestion = "try_update")]
    pub fn fetch_update<F>(&self, set_order: Ordering, fetch_order: Ordering,
        f: F) -> Result<u16, u16> where F: FnMut(u16) -> Option<u16> {
        self.try_update(set_order, fetch_order, f)
    }
    /// Fetches the value, and applies a function to it that returns an optional
    /// new value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else
    /// `Err(previous_value)`.
    ///
    #[doc = "See also: [`update`](`AtomicU16::update`)."]
    ///
    /// Note: This may call the function multiple times if the value has been changed from other threads in
    /// the meantime, as long as the function returns `Some(_)`, but the function will have been applied
    /// only once to the stored value.
    ///
    /// `try_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
    /// The first describes the required ordering for when the operation finally succeeds while the second
    /// describes the required ordering for loads. These correspond to the success and failure orderings of
    #[doc = "[`AtomicU16::compare_exchange`]"]
    /// respectively.
    ///
    /// Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u16`]."]
    ///
    /// # Considerations
    ///
    /// This method is not magic; it is not provided by the hardware, and does not act like a
    /// critical section or mutex.
    ///
    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
    /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
    /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicU16, Ordering};"]
    ///
    #[doc = "let x = AtomicU16::new(7);"]
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(7));
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(7));
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(8));
    /// assert_eq!(x.load(Ordering::SeqCst), 9);
    /// ```
    #[inline]
    #[stable(feature = "atomic_try_update", since = "1.95.0")]
    #[rustc_should_not_be_called_on_const_items]
    pub fn try_update(&self, set_order: Ordering, fetch_order: Ordering,
        mut f: impl FnMut(u16) -> Option<u16>) -> Result<u16, u16> {
        let mut prev = self.load(fetch_order);
        while let Some(next) = f(prev) {
            match self.compare_exchange_weak(prev, next, set_order,
                    fetch_order) {
                x @ Ok(_) => return x,
                Err(next_prev) => prev = next_prev,
            }
        }
        Err(prev)
    }
    /// Fetches the value, applies a function to it that it return a new value.
    /// The new value is stored and the old value is returned.
    ///
    #[doc = "See also: [`try_update`](`AtomicU16::try_update`)."]
    ///
    /// Note: This may call the function multiple times if the value has been changed from other threads in
    /// the meantime, but the function will have been applied only once to the stored value.
    ///
    /// `update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
    /// The first describes the required ordering for when the operation finally succeeds while the second
    /// describes the required ordering for loads. These correspond to the success and failure orderings of
    #[doc = "[`AtomicU16::compare_exchange`]"]
    /// respectively.
    ///
    /// Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u16`]."]
    ///
    /// # Considerations
    ///
    /// [CAS operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    /// This method is not magic; it is not provided by the hardware, and does not act like a
    /// critical section or mutex.
    ///
    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
    /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
    /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicU16, Ordering};"]
    ///
    #[doc = "let x = AtomicU16::new(7);"]
    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 7);
    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 8);
    /// assert_eq!(x.load(Ordering::SeqCst), 9);
    /// ```
    #[inline]
    #[stable(feature = "atomic_try_update", since = "1.95.0")]
    #[rustc_should_not_be_called_on_const_items]
    pub fn update(&self, set_order: Ordering, fetch_order: Ordering,
        mut f: impl FnMut(u16) -> u16) -> u16 {
        let mut prev = self.load(fetch_order);
        loop {
            match self.compare_exchange_weak(prev, f(prev), set_order,
                    fetch_order) {
                Ok(x) => break x,
                Err(next_prev) => prev = next_prev,
            }
        }
    }
    /// Maximum with the current value.
    ///
    /// Finds the maximum of the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_max` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u16`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU16, Ordering};"]
    ///
    #[doc = "let foo = AtomicU16::new(23);"]
    /// assert_eq!(foo.fetch_max(42, Ordering::SeqCst), 23);
    /// assert_eq!(foo.load(Ordering::SeqCst), 42);
    /// ```
    ///
    /// If you want to obtain the maximum value in one step, you can use the following:
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU16, Ordering};"]
    ///
    #[doc = "let foo = AtomicU16::new(23);"]
    /// let bar = 42;
    /// let max_foo = foo.fetch_max(bar, Ordering::SeqCst).max(bar);
    /// assert!(max_foo == 42);
    /// ```
    #[inline]
    #[stable(feature = "atomic_min_max", since = "1.45.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_max(&self, val: u16, order: Ordering) -> u16 {
        unsafe { atomic_umax(self.as_ptr(), val, order) }
    }
    /// Minimum with the current value.
    ///
    /// Finds the minimum of the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_min` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u16`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU16, Ordering};"]
    ///
    #[doc = "let foo = AtomicU16::new(23);"]
    /// assert_eq!(foo.fetch_min(42, Ordering::Relaxed), 23);
    /// assert_eq!(foo.load(Ordering::Relaxed), 23);
    /// assert_eq!(foo.fetch_min(22, Ordering::Relaxed), 23);
    /// assert_eq!(foo.load(Ordering::Relaxed), 22);
    /// ```
    ///
    /// If you want to obtain the minimum value in one step, you can use the following:
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU16, Ordering};"]
    ///
    #[doc = "let foo = AtomicU16::new(23);"]
    /// let bar = 12;
    /// let min_foo = foo.fetch_min(bar, Ordering::SeqCst).min(bar);
    /// assert_eq!(min_foo, 12);
    /// ```
    #[inline]
    #[stable(feature = "atomic_min_max", since = "1.45.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_min(&self, val: u16, order: Ordering) -> u16 {
        unsafe { atomic_umin(self.as_ptr(), val, order) }
    }
    /// Returns a mutable pointer to the underlying integer.
    ///
    /// Doing non-atomic reads and writes on the resulting integer can be a data race.
    /// This method is mostly useful for FFI, where the function signature may use
    #[doc = "`*mut u16` instead of `&AtomicU16`."]
    ///
    /// Returning an `*mut` pointer from a shared reference to this atomic is safe because the
    /// atomic types work with interior mutability. All modifications of an atomic change the value
    /// through a shared reference, and can do so safely as long as they use atomic operations. Any
    /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the
    /// requirements of the [memory model].
    ///
    /// # Examples
    ///
    /// ```ignore (extern-declaration)
    /// # fn main() {
    #[doc = "use std::sync::atomic::AtomicU16;"]
    ///
    /// extern "C" {
    #[doc = "    fn my_atomic_op(arg: *mut u16);"]
    /// }
    ///
    #[doc = "let atomic = AtomicU16::new(1);"]
    ///
    /// // SAFETY: Safe as long as `my_atomic_op` is atomic.
    /// unsafe {
    ///     my_atomic_op(atomic.as_ptr());
    /// }
    /// # }
    /// ```
    ///
    /// [memory model]: self#memory-model-for-atomic-accesses
    #[inline]
    #[stable(feature = "atomic_as_ptr", since = "1.70.0")]
    #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")]
    #[rustc_never_returns_null_ptr]
    pub const fn as_ptr(&self) -> *mut u16 { self.v.get().cast() }
}atomic_int! {
3761    target_has_atomic_load_store = "16",
3762    target_has_atomic = "16",
3763    target_has_atomic_primitive_alignment = "16",
3764    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3765    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3766    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3767    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3768    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3769    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3770    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
3771    rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
3772    "u16",
3773    "",
3774    atomic_umin, atomic_umax,
3775    2,
3776    u16 AtomicU16
3777}
3778#[cfg(target_has_atomic_load_store = "32")]
3779/// An integer type which can be safely shared between threads.
///
/// This type has the same
#[doc = "size and bit validity"]
/// as the underlying integer type, [`
#[doc = "i32"]
/// `].
#[doc =
"However, the alignment of this type is always equal to its size, even on targets where [`i32`] has a lesser alignment."]
///
/// For more about the differences between atomic types and
/// non-atomic types as well as information about the portability of
/// this type, please see the [module-level documentation].
///
/// **Note:** This type is only available on platforms that support
/// atomic loads and stores of [`
#[doc = "i32"]
/// `].
///
/// [module-level documentation]: crate::sync::atomic
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
pub type AtomicI32 = Atomic<i32>;
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
impl Default for AtomicI32 {
    #[inline]
    fn default() -> Self { Self::new(Default::default()) }
}
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
const impl From<i32> for AtomicI32 {
    #[doc = "Converts an `i32` into an `AtomicI32`."]
    #[inline]
    fn from(v: i32) -> Self { Self::new(v) }
}
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
impl fmt::Debug for AtomicI32 {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)
    }
}
impl AtomicI32 {
    /// Creates a new atomic integer.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::AtomicI32;"]
    ///
    #[doc = "let atomic_forty_two = AtomicI32::new(42);"]
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0")]
    #[must_use]
    pub const fn new(v: i32) -> Self { unsafe { transmute(v) } }
    /// Creates a new reference to an atomic integer from a pointer.
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{self, AtomicI32};"]
    ///
    /// // Get a pointer to an allocated value
    #[doc = "let ptr: *mut i32 = Box::into_raw(Box::new(0));"]
    ///
    #[doc = "assert!(ptr.cast::<AtomicI32>().is_aligned());"]
    ///
    /// {
    ///     // Create an atomic view of the allocated value
    #[doc = "    let atomic = unsafe {AtomicI32::from_ptr(ptr) };"]
    ///
    ///     // Use `atomic` for atomic operations, possibly share it with other threads
    ///     atomic.store(1, atomic::Ordering::Relaxed);
    /// }
    ///
    /// // It's ok to non-atomically access the value behind `ptr`,
    /// // since the reference to the atomic ended its lifetime in the block above
    /// assert_eq!(unsafe { *ptr }, 1);
    ///
    /// // Deallocate the value
    /// unsafe { drop(Box::from_raw(ptr)) }
    /// ```
    ///
    /// # Safety
    ///
    /// * `ptr` must be aligned to
    #[doc = "  `align_of::<AtomicI32>()`"]
    #[doc =
    "  (note that on some platforms this can be bigger than `align_of::<i32>()`)."]
    /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
    /// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not
    ///   allowed to mix conflicting atomic and non-atomic accesses, or atomic accesses of different
    ///   sizes, without synchronization.
    ///
    /// [valid]: crate::ptr#safety
    /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
    #[inline]
    #[stable(feature = "atomic_from_ptr", since = "1.75.0")]
    #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")]
    pub const unsafe fn from_ptr<'a>(ptr: *mut i32) -> &'a AtomicI32 {
        unsafe { &*ptr.cast() }
    }
    /// Returns a mutable reference to the underlying integer.
    ///
    /// This is safe because the mutable reference guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI32, Ordering};"]
    ///
    #[doc = "let mut some_var = AtomicI32::new(10);"]
    /// assert_eq!(*some_var.get_mut(), 10);
    /// *some_var.get_mut() = 5;
    /// assert_eq!(some_var.load(Ordering::SeqCst), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn get_mut(&mut self) -> &mut i32 {
        unsafe { &mut *self.as_ptr() }
    }
    #[doc = "Get atomic access to a `&mut i32`."]
    ///
    #[doc =
    "**Note:** This function is only available on targets where `AtomicI32` has the same alignment as `i32`."]
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicI32, Ordering};"]
    ///
    /// let mut some_int = 123;
    #[doc = "let a = AtomicI32::from_mut(&mut some_int);"]
    /// a.store(100, Ordering::Relaxed);
    /// assert_eq!(some_int, 100);
    /// ```
    ///
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn from_mut(v: &mut i32) -> &mut Self {
        let [] = [(); align_of::<Self>() - align_of::<i32>()];
        unsafe { &mut *(v as *mut i32 as *mut Self) }
    }
    #[doc = "Get non-atomic access to a `&mut [AtomicI32]` slice"]
    ///
    /// This is safe because the mutable reference guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```ignore-wasm"]
    #[doc = "use std::sync::atomic::{AtomicI32, Ordering};"]
    ///
    #[doc = "let mut some_ints = [const { AtomicI32::new(0) }; 10];"]
    ///
    #[doc =
    "let view: &mut [i32] = AtomicI32::get_mut_slice(&mut some_ints);"]
    /// assert_eq!(view, [0; 10]);
    /// view
    ///     .iter_mut()
    ///     .enumerate()
    ///     .for_each(|(idx, int)| *int = idx as _);
    ///
    /// std::thread::scope(|s| {
    ///     some_ints
    ///         .iter()
    ///         .enumerate()
    ///         .for_each(|(idx, int)| {
    ///             s.spawn(move || assert_eq!(int.load(Ordering::Relaxed), idx as _));
    ///         })
    /// });
    /// ```
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn get_mut_slice(this: &mut [Self]) -> &mut [i32] {
        unsafe { &mut *(this as *mut [Self] as *mut [i32]) }
    }
    #[doc = "Get atomic access to a `&mut [i32]` slice."]
    ///
    #[doc =
    "**Note:** This function is only available on targets where `AtomicI32` has the same alignment as `i32`."]
    ///
    /// # Examples
    ///
    #[doc = "```ignore-wasm"]
    #[doc = "use std::sync::atomic::{AtomicI32, Ordering};"]
    ///
    /// let mut some_ints = [0; 10];
    #[doc = "let a = &*AtomicI32::from_mut_slice(&mut some_ints);"]
    /// std::thread::scope(|s| {
    ///     for i in 0..a.len() {
    ///         s.spawn(move || a[i].store(i as _, Ordering::Relaxed));
    ///     }
    /// });
    /// for (i, n) in some_ints.into_iter().enumerate() {
    ///     assert_eq!(i, n as usize);
    /// }
    /// ```
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn from_mut_slice(v: &mut [i32]) -> &mut [Self] {
        let [] = [(); align_of::<Self>() - align_of::<i32>()];
        unsafe { &mut *(v as *mut [i32] as *mut [Self]) }
    }
    /// Consumes the atomic and returns the contained value.
    ///
    /// This is safe because passing `self` by value guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::AtomicI32;"]
    ///
    #[doc = "let some_var = AtomicI32::new(5);"]
    /// assert_eq!(some_var.into_inner(), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_stable(feature = "const_atomic_into_inner", since =
    "1.79.0")]
    pub const fn into_inner(self) -> i32 { unsafe { transmute(self) } }
    /// Loads a value from the atomic integer.
    ///
    /// `load` takes an [`Ordering`] argument which describes the memory ordering of this operation.
    /// Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Release`] or [`AcqRel`].
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI32, Ordering};"]
    ///
    #[doc = "let some_var = AtomicI32::new(5);"]
    ///
    /// assert_eq!(some_var.load(Ordering::Relaxed), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn load(&self, order: Ordering) -> i32 {
        unsafe { atomic_load::<_, false>(self.as_ptr(), order) }
    }
    /// Stores a value into the atomic integer.
    ///
    /// `store` takes an [`Ordering`] argument which describes the memory ordering of this operation.
    ///  Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI32, Ordering};"]
    ///
    #[doc = "let some_var = AtomicI32::new(5);"]
    ///
    /// some_var.store(10, Ordering::Relaxed);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn store(&self, val: i32, order: Ordering) {
        unsafe { atomic_store::<_, false>(self.as_ptr(), val, order); }
    }
    /// Stores a value into the atomic integer, returning the previous value.
    ///
    /// `swap` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i32`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI32, Ordering};"]
    ///
    #[doc = "let some_var = AtomicI32::new(5);"]
    ///
    /// assert_eq!(some_var.swap(10, Ordering::Relaxed), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn swap(&self, val: i32, order: Ordering) -> i32 {
        unsafe { atomic_swap(self.as_ptr(), val, order) }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    /// The return value is always the previous value. If it is equal to `current`, then the
    /// value was updated.
    ///
    /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
    /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
    /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
    /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
    /// happens, and using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i32`]."]
    ///
    /// # Migrating to `compare_exchange` and `compare_exchange_weak`
    ///
    /// `compare_and_swap` is equivalent to `compare_exchange` with the following mapping for
    /// memory orderings:
    ///
    /// Original | Success | Failure
    /// -------- | ------- | -------
    /// Relaxed  | Relaxed | Relaxed
    /// Acquire  | Acquire | Acquire
    /// Release  | Release | Relaxed
    /// AcqRel   | AcqRel  | Acquire
    /// SeqCst   | SeqCst  | SeqCst
    ///
    /// `compare_and_swap` and `compare_exchange` also differ in their return type. You can use
    /// `compare_exchange(...).unwrap_or_else(|x| x)` to recover the behavior of `compare_and_swap`,
    /// but in most cases it is more idiomatic to check whether the return value is `Ok` or `Err`
    /// rather than to infer success vs failure based on the value that was read.
    ///
    /// During migration, consider whether it makes sense to use `compare_exchange_weak` instead.
    /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds,
    /// which allows the compiler to generate better assembly code when the compare and swap
    /// is used in a loop.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI32, Ordering};"]
    ///
    #[doc = "let some_var = AtomicI32::new(5);"]
    ///
    /// assert_eq!(some_var.compare_and_swap(5, 10, Ordering::Relaxed), 5);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    ///
    /// assert_eq!(some_var.compare_and_swap(6, 12, Ordering::Relaxed), 10);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[deprecated(since = "1.50.0", note =
    "Use `compare_exchange` or `compare_exchange_weak` instead")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_and_swap(&self, current: i32, new: i32,
        order: Ordering) -> i32 {
        match self.compare_exchange(current, new, order,
                strongest_failure_ordering(order)) {
            Ok(x) => x,
            Err(x) => x,
        }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    /// The return value is a result indicating whether the new value was written and
    /// containing the previous value. On success this value is guaranteed to be equal to
    /// `current`.
    ///
    /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
    /// ordering of this operation. `success` describes the required ordering for the
    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
    /// `failure` describes the required ordering for the load operation that takes place when
    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i32`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI32, Ordering};"]
    ///
    #[doc = "let some_var = AtomicI32::new(5);"]
    ///
    /// assert_eq!(some_var.compare_exchange(5, 10,
    ///                                      Ordering::Acquire,
    ///                                      Ordering::Relaxed),
    ///            Ok(5));
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    ///
    /// assert_eq!(some_var.compare_exchange(6, 12,
    ///                                      Ordering::SeqCst,
    ///                                      Ordering::Acquire),
    ///            Err(10));
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    ///
    /// # Considerations
    ///
    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
    /// of CAS operations. In particular, a load of the value followed by a successful
    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
    /// changed the value in the interim! This is usually important when the *equality* check in
    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
    /// does not necessarily imply identity. This is a particularly common case for pointers, as
    /// a pointer holding the same address does not imply that the same object exists at that
    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_exchange(&self, current: i32, new: i32,
        success: Ordering, failure: Ordering) -> Result<i32, i32> {
        unsafe {
            atomic_compare_exchange(self.as_ptr(), current, new, success,
                failure)
        }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    #[doc = "Unlike [`AtomicI32::compare_exchange`],"]
    /// this function is allowed to spuriously fail even
    /// when the comparison succeeds, which can result in more efficient code on some
    /// platforms. The return value is a result indicating whether the new value was
    /// written and containing the previous value.
    ///
    /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
    /// ordering of this operation. `success` describes the required ordering for the
    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
    /// `failure` describes the required ordering for the load operation that takes place when
    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i32`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI32, Ordering};"]
    ///
    #[doc = "let val = AtomicI32::new(4);"]
    ///
    /// let mut old = val.load(Ordering::Relaxed);
    /// loop {
    ///     let new = old * 2;
    ///     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
    ///         Ok(_) => break,
    ///         Err(x) => old = x,
    ///     }
    /// }
    /// ```
    ///
    /// # Considerations
    ///
    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
    /// of CAS operations. In particular, a load of the value followed by a successful
    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
    /// changed the value in the interim. This is usually important when the *equality* check in
    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
    /// does not necessarily imply identity. This is a particularly common case for pointers, as
    /// a pointer holding the same address does not imply that the same object exists at that
    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_exchange_weak(&self, current: i32, new: i32,
        success: Ordering, failure: Ordering) -> Result<i32, i32> {
        unsafe {
            atomic_compare_exchange_weak(self.as_ptr(), current, new, success,
                failure)
        }
    }
    /// Adds to the current value, returning the previous value.
    ///
    /// This operation wraps around on overflow.
    ///
    /// `fetch_add` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i32`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI32, Ordering};"]
    ///
    #[doc = "let foo = AtomicI32::new(0);"]
    /// assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0);
    /// assert_eq!(foo.load(Ordering::SeqCst), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_add(&self, val: i32, order: Ordering) -> i32 {
        unsafe { atomic_add(self.as_ptr(), val, order) }
    }
    /// Subtracts from the current value, returning the previous value.
    ///
    /// This operation wraps around on overflow.
    ///
    /// `fetch_sub` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i32`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI32, Ordering};"]
    ///
    #[doc = "let foo = AtomicI32::new(20);"]
    /// assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 20);
    /// assert_eq!(foo.load(Ordering::SeqCst), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_sub(&self, val: i32, order: Ordering) -> i32 {
        unsafe { atomic_sub(self.as_ptr(), val, order) }
    }
    /// Bitwise "and" with the current value.
    ///
    /// Performs a bitwise "and" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_and` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i32`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI32, Ordering};"]
    ///
    #[doc = "let foo = AtomicI32::new(0b101101);"]
    /// assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b100001);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_and(&self, val: i32, order: Ordering) -> i32 {
        unsafe { atomic_and(self.as_ptr(), val, order) }
    }
    /// Bitwise "nand" with the current value.
    ///
    /// Performs a bitwise "nand" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_nand` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i32`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI32, Ordering};"]
    ///
    #[doc = "let foo = AtomicI32::new(0x13);"]
    /// assert_eq!(foo.fetch_nand(0x31, Ordering::SeqCst), 0x13);
    /// assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31));
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_nand(&self, val: i32, order: Ordering) -> i32 {
        unsafe { atomic_nand(self.as_ptr(), val, order) }
    }
    /// Bitwise "or" with the current value.
    ///
    /// Performs a bitwise "or" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_or` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i32`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI32, Ordering};"]
    ///
    #[doc = "let foo = AtomicI32::new(0b101101);"]
    /// assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b111111);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_or(&self, val: i32, order: Ordering) -> i32 {
        unsafe { atomic_or(self.as_ptr(), val, order) }
    }
    /// Bitwise "xor" with the current value.
    ///
    /// Performs a bitwise "xor" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_xor` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i32`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI32, Ordering};"]
    ///
    #[doc = "let foo = AtomicI32::new(0b101101);"]
    /// assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b011110);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_xor(&self, val: i32, order: Ordering) -> i32 {
        unsafe { atomic_xor(self.as_ptr(), val, order) }
    }
    /// An alias for
    #[doc = "[`AtomicI32::try_update`]"]
    /// .
    #[inline]
    #[stable(feature = "no_more_cas", since = "1.45.0")]
    #[rustc_should_not_be_called_on_const_items]
    #[deprecated(since = "1.99.0", note =
    "renamed to `try_update` for consistency", suggestion = "try_update")]
    pub fn fetch_update<F>(&self, set_order: Ordering, fetch_order: Ordering,
        f: F) -> Result<i32, i32> where F: FnMut(i32) -> Option<i32> {
        self.try_update(set_order, fetch_order, f)
    }
    /// Fetches the value, and applies a function to it that returns an optional
    /// new value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else
    /// `Err(previous_value)`.
    ///
    #[doc = "See also: [`update`](`AtomicI32::update`)."]
    ///
    /// Note: This may call the function multiple times if the value has been changed from other threads in
    /// the meantime, as long as the function returns `Some(_)`, but the function will have been applied
    /// only once to the stored value.
    ///
    /// `try_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
    /// The first describes the required ordering for when the operation finally succeeds while the second
    /// describes the required ordering for loads. These correspond to the success and failure orderings of
    #[doc = "[`AtomicI32::compare_exchange`]"]
    /// respectively.
    ///
    /// Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i32`]."]
    ///
    /// # Considerations
    ///
    /// This method is not magic; it is not provided by the hardware, and does not act like a
    /// critical section or mutex.
    ///
    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
    /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
    /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicI32, Ordering};"]
    ///
    #[doc = "let x = AtomicI32::new(7);"]
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(7));
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(7));
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(8));
    /// assert_eq!(x.load(Ordering::SeqCst), 9);
    /// ```
    #[inline]
    #[stable(feature = "atomic_try_update", since = "1.95.0")]
    #[rustc_should_not_be_called_on_const_items]
    pub fn try_update(&self, set_order: Ordering, fetch_order: Ordering,
        mut f: impl FnMut(i32) -> Option<i32>) -> Result<i32, i32> {
        let mut prev = self.load(fetch_order);
        while let Some(next) = f(prev) {
            match self.compare_exchange_weak(prev, next, set_order,
                    fetch_order) {
                x @ Ok(_) => return x,
                Err(next_prev) => prev = next_prev,
            }
        }
        Err(prev)
    }
    /// Fetches the value, applies a function to it that it return a new value.
    /// The new value is stored and the old value is returned.
    ///
    #[doc = "See also: [`try_update`](`AtomicI32::try_update`)."]
    ///
    /// Note: This may call the function multiple times if the value has been changed from other threads in
    /// the meantime, but the function will have been applied only once to the stored value.
    ///
    /// `update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
    /// The first describes the required ordering for when the operation finally succeeds while the second
    /// describes the required ordering for loads. These correspond to the success and failure orderings of
    #[doc = "[`AtomicI32::compare_exchange`]"]
    /// respectively.
    ///
    /// Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i32`]."]
    ///
    /// # Considerations
    ///
    /// [CAS operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    /// This method is not magic; it is not provided by the hardware, and does not act like a
    /// critical section or mutex.
    ///
    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
    /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
    /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicI32, Ordering};"]
    ///
    #[doc = "let x = AtomicI32::new(7);"]
    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 7);
    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 8);
    /// assert_eq!(x.load(Ordering::SeqCst), 9);
    /// ```
    #[inline]
    #[stable(feature = "atomic_try_update", since = "1.95.0")]
    #[rustc_should_not_be_called_on_const_items]
    pub fn update(&self, set_order: Ordering, fetch_order: Ordering,
        mut f: impl FnMut(i32) -> i32) -> i32 {
        let mut prev = self.load(fetch_order);
        loop {
            match self.compare_exchange_weak(prev, f(prev), set_order,
                    fetch_order) {
                Ok(x) => break x,
                Err(next_prev) => prev = next_prev,
            }
        }
    }
    /// Maximum with the current value.
    ///
    /// Finds the maximum of the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_max` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i32`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI32, Ordering};"]
    ///
    #[doc = "let foo = AtomicI32::new(23);"]
    /// assert_eq!(foo.fetch_max(42, Ordering::SeqCst), 23);
    /// assert_eq!(foo.load(Ordering::SeqCst), 42);
    /// ```
    ///
    /// If you want to obtain the maximum value in one step, you can use the following:
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI32, Ordering};"]
    ///
    #[doc = "let foo = AtomicI32::new(23);"]
    /// let bar = 42;
    /// let max_foo = foo.fetch_max(bar, Ordering::SeqCst).max(bar);
    /// assert!(max_foo == 42);
    /// ```
    #[inline]
    #[stable(feature = "atomic_min_max", since = "1.45.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_max(&self, val: i32, order: Ordering) -> i32 {
        unsafe { atomic_max(self.as_ptr(), val, order) }
    }
    /// Minimum with the current value.
    ///
    /// Finds the minimum of the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_min` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i32`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI32, Ordering};"]
    ///
    #[doc = "let foo = AtomicI32::new(23);"]
    /// assert_eq!(foo.fetch_min(42, Ordering::Relaxed), 23);
    /// assert_eq!(foo.load(Ordering::Relaxed), 23);
    /// assert_eq!(foo.fetch_min(22, Ordering::Relaxed), 23);
    /// assert_eq!(foo.load(Ordering::Relaxed), 22);
    /// ```
    ///
    /// If you want to obtain the minimum value in one step, you can use the following:
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI32, Ordering};"]
    ///
    #[doc = "let foo = AtomicI32::new(23);"]
    /// let bar = 12;
    /// let min_foo = foo.fetch_min(bar, Ordering::SeqCst).min(bar);
    /// assert_eq!(min_foo, 12);
    /// ```
    #[inline]
    #[stable(feature = "atomic_min_max", since = "1.45.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_min(&self, val: i32, order: Ordering) -> i32 {
        unsafe { atomic_min(self.as_ptr(), val, order) }
    }
    /// Returns a mutable pointer to the underlying integer.
    ///
    /// Doing non-atomic reads and writes on the resulting integer can be a data race.
    /// This method is mostly useful for FFI, where the function signature may use
    #[doc = "`*mut i32` instead of `&AtomicI32`."]
    ///
    /// Returning an `*mut` pointer from a shared reference to this atomic is safe because the
    /// atomic types work with interior mutability. All modifications of an atomic change the value
    /// through a shared reference, and can do so safely as long as they use atomic operations. Any
    /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the
    /// requirements of the [memory model].
    ///
    /// # Examples
    ///
    /// ```ignore (extern-declaration)
    /// # fn main() {
    #[doc = "use std::sync::atomic::AtomicI32;"]
    ///
    /// extern "C" {
    #[doc = "    fn my_atomic_op(arg: *mut i32);"]
    /// }
    ///
    #[doc = "let atomic = AtomicI32::new(1);"]
    ///
    /// // SAFETY: Safe as long as `my_atomic_op` is atomic.
    /// unsafe {
    ///     my_atomic_op(atomic.as_ptr());
    /// }
    /// # }
    /// ```
    ///
    /// [memory model]: self#memory-model-for-atomic-accesses
    #[inline]
    #[stable(feature = "atomic_as_ptr", since = "1.70.0")]
    #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")]
    #[rustc_never_returns_null_ptr]
    pub const fn as_ptr(&self) -> *mut i32 { self.v.get().cast() }
}atomic_int! {
3780    target_has_atomic_load_store = "32",
3781    target_has_atomic = "32",
3782    target_has_atomic_primitive_alignment = "32",
3783    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3784    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3785    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3786    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3787    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3788    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3789    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
3790    rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
3791    "i32",
3792    "",
3793    atomic_min, atomic_max,
3794    4,
3795    i32 AtomicI32
3796}
3797#[cfg(target_has_atomic_load_store = "32")]
3798/// An integer type which can be safely shared between threads.
///
/// This type has the same
#[doc = "size and bit validity"]
/// as the underlying integer type, [`
#[doc = "u32"]
/// `].
#[doc =
"However, the alignment of this type is always equal to its size, even on targets where [`u32`] has a lesser alignment."]
///
/// For more about the differences between atomic types and
/// non-atomic types as well as information about the portability of
/// this type, please see the [module-level documentation].
///
/// **Note:** This type is only available on platforms that support
/// atomic loads and stores of [`
#[doc = "u32"]
/// `].
///
/// [module-level documentation]: crate::sync::atomic
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
pub type AtomicU32 = Atomic<u32>;
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
impl Default for AtomicU32 {
    #[inline]
    fn default() -> Self { Self::new(Default::default()) }
}
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
const impl From<u32> for AtomicU32 {
    #[doc = "Converts an `u32` into an `AtomicU32`."]
    #[inline]
    fn from(v: u32) -> Self { Self::new(v) }
}
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
impl fmt::Debug for AtomicU32 {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)
    }
}
impl AtomicU32 {
    /// Creates a new atomic integer.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::AtomicU32;"]
    ///
    #[doc = "let atomic_forty_two = AtomicU32::new(42);"]
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0")]
    #[must_use]
    pub const fn new(v: u32) -> Self { unsafe { transmute(v) } }
    /// Creates a new reference to an atomic integer from a pointer.
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{self, AtomicU32};"]
    ///
    /// // Get a pointer to an allocated value
    #[doc = "let ptr: *mut u32 = Box::into_raw(Box::new(0));"]
    ///
    #[doc = "assert!(ptr.cast::<AtomicU32>().is_aligned());"]
    ///
    /// {
    ///     // Create an atomic view of the allocated value
    #[doc = "    let atomic = unsafe {AtomicU32::from_ptr(ptr) };"]
    ///
    ///     // Use `atomic` for atomic operations, possibly share it with other threads
    ///     atomic.store(1, atomic::Ordering::Relaxed);
    /// }
    ///
    /// // It's ok to non-atomically access the value behind `ptr`,
    /// // since the reference to the atomic ended its lifetime in the block above
    /// assert_eq!(unsafe { *ptr }, 1);
    ///
    /// // Deallocate the value
    /// unsafe { drop(Box::from_raw(ptr)) }
    /// ```
    ///
    /// # Safety
    ///
    /// * `ptr` must be aligned to
    #[doc = "  `align_of::<AtomicU32>()`"]
    #[doc =
    "  (note that on some platforms this can be bigger than `align_of::<u32>()`)."]
    /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
    /// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not
    ///   allowed to mix conflicting atomic and non-atomic accesses, or atomic accesses of different
    ///   sizes, without synchronization.
    ///
    /// [valid]: crate::ptr#safety
    /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
    #[inline]
    #[stable(feature = "atomic_from_ptr", since = "1.75.0")]
    #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")]
    pub const unsafe fn from_ptr<'a>(ptr: *mut u32) -> &'a AtomicU32 {
        unsafe { &*ptr.cast() }
    }
    /// Returns a mutable reference to the underlying integer.
    ///
    /// This is safe because the mutable reference guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU32, Ordering};"]
    ///
    #[doc = "let mut some_var = AtomicU32::new(10);"]
    /// assert_eq!(*some_var.get_mut(), 10);
    /// *some_var.get_mut() = 5;
    /// assert_eq!(some_var.load(Ordering::SeqCst), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn get_mut(&mut self) -> &mut u32 {
        unsafe { &mut *self.as_ptr() }
    }
    #[doc = "Get atomic access to a `&mut u32`."]
    ///
    #[doc =
    "**Note:** This function is only available on targets where `AtomicU32` has the same alignment as `u32`."]
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicU32, Ordering};"]
    ///
    /// let mut some_int = 123;
    #[doc = "let a = AtomicU32::from_mut(&mut some_int);"]
    /// a.store(100, Ordering::Relaxed);
    /// assert_eq!(some_int, 100);
    /// ```
    ///
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn from_mut(v: &mut u32) -> &mut Self {
        let [] = [(); align_of::<Self>() - align_of::<u32>()];
        unsafe { &mut *(v as *mut u32 as *mut Self) }
    }
    #[doc = "Get non-atomic access to a `&mut [AtomicU32]` slice"]
    ///
    /// This is safe because the mutable reference guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```ignore-wasm"]
    #[doc = "use std::sync::atomic::{AtomicU32, Ordering};"]
    ///
    #[doc = "let mut some_ints = [const { AtomicU32::new(0) }; 10];"]
    ///
    #[doc =
    "let view: &mut [u32] = AtomicU32::get_mut_slice(&mut some_ints);"]
    /// assert_eq!(view, [0; 10]);
    /// view
    ///     .iter_mut()
    ///     .enumerate()
    ///     .for_each(|(idx, int)| *int = idx as _);
    ///
    /// std::thread::scope(|s| {
    ///     some_ints
    ///         .iter()
    ///         .enumerate()
    ///         .for_each(|(idx, int)| {
    ///             s.spawn(move || assert_eq!(int.load(Ordering::Relaxed), idx as _));
    ///         })
    /// });
    /// ```
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn get_mut_slice(this: &mut [Self]) -> &mut [u32] {
        unsafe { &mut *(this as *mut [Self] as *mut [u32]) }
    }
    #[doc = "Get atomic access to a `&mut [u32]` slice."]
    ///
    #[doc =
    "**Note:** This function is only available on targets where `AtomicU32` has the same alignment as `u32`."]
    ///
    /// # Examples
    ///
    #[doc = "```ignore-wasm"]
    #[doc = "use std::sync::atomic::{AtomicU32, Ordering};"]
    ///
    /// let mut some_ints = [0; 10];
    #[doc = "let a = &*AtomicU32::from_mut_slice(&mut some_ints);"]
    /// std::thread::scope(|s| {
    ///     for i in 0..a.len() {
    ///         s.spawn(move || a[i].store(i as _, Ordering::Relaxed));
    ///     }
    /// });
    /// for (i, n) in some_ints.into_iter().enumerate() {
    ///     assert_eq!(i, n as usize);
    /// }
    /// ```
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn from_mut_slice(v: &mut [u32]) -> &mut [Self] {
        let [] = [(); align_of::<Self>() - align_of::<u32>()];
        unsafe { &mut *(v as *mut [u32] as *mut [Self]) }
    }
    /// Consumes the atomic and returns the contained value.
    ///
    /// This is safe because passing `self` by value guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::AtomicU32;"]
    ///
    #[doc = "let some_var = AtomicU32::new(5);"]
    /// assert_eq!(some_var.into_inner(), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_stable(feature = "const_atomic_into_inner", since =
    "1.79.0")]
    pub const fn into_inner(self) -> u32 { unsafe { transmute(self) } }
    /// Loads a value from the atomic integer.
    ///
    /// `load` takes an [`Ordering`] argument which describes the memory ordering of this operation.
    /// Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Release`] or [`AcqRel`].
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU32, Ordering};"]
    ///
    #[doc = "let some_var = AtomicU32::new(5);"]
    ///
    /// assert_eq!(some_var.load(Ordering::Relaxed), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn load(&self, order: Ordering) -> u32 {
        unsafe { atomic_load::<_, false>(self.as_ptr(), order) }
    }
    /// Stores a value into the atomic integer.
    ///
    /// `store` takes an [`Ordering`] argument which describes the memory ordering of this operation.
    ///  Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU32, Ordering};"]
    ///
    #[doc = "let some_var = AtomicU32::new(5);"]
    ///
    /// some_var.store(10, Ordering::Relaxed);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn store(&self, val: u32, order: Ordering) {
        unsafe { atomic_store::<_, false>(self.as_ptr(), val, order); }
    }
    /// Stores a value into the atomic integer, returning the previous value.
    ///
    /// `swap` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u32`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU32, Ordering};"]
    ///
    #[doc = "let some_var = AtomicU32::new(5);"]
    ///
    /// assert_eq!(some_var.swap(10, Ordering::Relaxed), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn swap(&self, val: u32, order: Ordering) -> u32 {
        unsafe { atomic_swap(self.as_ptr(), val, order) }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    /// The return value is always the previous value. If it is equal to `current`, then the
    /// value was updated.
    ///
    /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
    /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
    /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
    /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
    /// happens, and using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u32`]."]
    ///
    /// # Migrating to `compare_exchange` and `compare_exchange_weak`
    ///
    /// `compare_and_swap` is equivalent to `compare_exchange` with the following mapping for
    /// memory orderings:
    ///
    /// Original | Success | Failure
    /// -------- | ------- | -------
    /// Relaxed  | Relaxed | Relaxed
    /// Acquire  | Acquire | Acquire
    /// Release  | Release | Relaxed
    /// AcqRel   | AcqRel  | Acquire
    /// SeqCst   | SeqCst  | SeqCst
    ///
    /// `compare_and_swap` and `compare_exchange` also differ in their return type. You can use
    /// `compare_exchange(...).unwrap_or_else(|x| x)` to recover the behavior of `compare_and_swap`,
    /// but in most cases it is more idiomatic to check whether the return value is `Ok` or `Err`
    /// rather than to infer success vs failure based on the value that was read.
    ///
    /// During migration, consider whether it makes sense to use `compare_exchange_weak` instead.
    /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds,
    /// which allows the compiler to generate better assembly code when the compare and swap
    /// is used in a loop.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU32, Ordering};"]
    ///
    #[doc = "let some_var = AtomicU32::new(5);"]
    ///
    /// assert_eq!(some_var.compare_and_swap(5, 10, Ordering::Relaxed), 5);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    ///
    /// assert_eq!(some_var.compare_and_swap(6, 12, Ordering::Relaxed), 10);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[deprecated(since = "1.50.0", note =
    "Use `compare_exchange` or `compare_exchange_weak` instead")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_and_swap(&self, current: u32, new: u32,
        order: Ordering) -> u32 {
        match self.compare_exchange(current, new, order,
                strongest_failure_ordering(order)) {
            Ok(x) => x,
            Err(x) => x,
        }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    /// The return value is a result indicating whether the new value was written and
    /// containing the previous value. On success this value is guaranteed to be equal to
    /// `current`.
    ///
    /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
    /// ordering of this operation. `success` describes the required ordering for the
    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
    /// `failure` describes the required ordering for the load operation that takes place when
    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u32`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU32, Ordering};"]
    ///
    #[doc = "let some_var = AtomicU32::new(5);"]
    ///
    /// assert_eq!(some_var.compare_exchange(5, 10,
    ///                                      Ordering::Acquire,
    ///                                      Ordering::Relaxed),
    ///            Ok(5));
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    ///
    /// assert_eq!(some_var.compare_exchange(6, 12,
    ///                                      Ordering::SeqCst,
    ///                                      Ordering::Acquire),
    ///            Err(10));
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    ///
    /// # Considerations
    ///
    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
    /// of CAS operations. In particular, a load of the value followed by a successful
    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
    /// changed the value in the interim! This is usually important when the *equality* check in
    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
    /// does not necessarily imply identity. This is a particularly common case for pointers, as
    /// a pointer holding the same address does not imply that the same object exists at that
    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_exchange(&self, current: u32, new: u32,
        success: Ordering, failure: Ordering) -> Result<u32, u32> {
        unsafe {
            atomic_compare_exchange(self.as_ptr(), current, new, success,
                failure)
        }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    #[doc = "Unlike [`AtomicU32::compare_exchange`],"]
    /// this function is allowed to spuriously fail even
    /// when the comparison succeeds, which can result in more efficient code on some
    /// platforms. The return value is a result indicating whether the new value was
    /// written and containing the previous value.
    ///
    /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
    /// ordering of this operation. `success` describes the required ordering for the
    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
    /// `failure` describes the required ordering for the load operation that takes place when
    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u32`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU32, Ordering};"]
    ///
    #[doc = "let val = AtomicU32::new(4);"]
    ///
    /// let mut old = val.load(Ordering::Relaxed);
    /// loop {
    ///     let new = old * 2;
    ///     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
    ///         Ok(_) => break,
    ///         Err(x) => old = x,
    ///     }
    /// }
    /// ```
    ///
    /// # Considerations
    ///
    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
    /// of CAS operations. In particular, a load of the value followed by a successful
    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
    /// changed the value in the interim. This is usually important when the *equality* check in
    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
    /// does not necessarily imply identity. This is a particularly common case for pointers, as
    /// a pointer holding the same address does not imply that the same object exists at that
    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_exchange_weak(&self, current: u32, new: u32,
        success: Ordering, failure: Ordering) -> Result<u32, u32> {
        unsafe {
            atomic_compare_exchange_weak(self.as_ptr(), current, new, success,
                failure)
        }
    }
    /// Adds to the current value, returning the previous value.
    ///
    /// This operation wraps around on overflow.
    ///
    /// `fetch_add` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u32`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU32, Ordering};"]
    ///
    #[doc = "let foo = AtomicU32::new(0);"]
    /// assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0);
    /// assert_eq!(foo.load(Ordering::SeqCst), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_add(&self, val: u32, order: Ordering) -> u32 {
        unsafe { atomic_add(self.as_ptr(), val, order) }
    }
    /// Subtracts from the current value, returning the previous value.
    ///
    /// This operation wraps around on overflow.
    ///
    /// `fetch_sub` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u32`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU32, Ordering};"]
    ///
    #[doc = "let foo = AtomicU32::new(20);"]
    /// assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 20);
    /// assert_eq!(foo.load(Ordering::SeqCst), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_sub(&self, val: u32, order: Ordering) -> u32 {
        unsafe { atomic_sub(self.as_ptr(), val, order) }
    }
    /// Bitwise "and" with the current value.
    ///
    /// Performs a bitwise "and" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_and` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u32`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU32, Ordering};"]
    ///
    #[doc = "let foo = AtomicU32::new(0b101101);"]
    /// assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b100001);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_and(&self, val: u32, order: Ordering) -> u32 {
        unsafe { atomic_and(self.as_ptr(), val, order) }
    }
    /// Bitwise "nand" with the current value.
    ///
    /// Performs a bitwise "nand" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_nand` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u32`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU32, Ordering};"]
    ///
    #[doc = "let foo = AtomicU32::new(0x13);"]
    /// assert_eq!(foo.fetch_nand(0x31, Ordering::SeqCst), 0x13);
    /// assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31));
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_nand(&self, val: u32, order: Ordering) -> u32 {
        unsafe { atomic_nand(self.as_ptr(), val, order) }
    }
    /// Bitwise "or" with the current value.
    ///
    /// Performs a bitwise "or" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_or` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u32`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU32, Ordering};"]
    ///
    #[doc = "let foo = AtomicU32::new(0b101101);"]
    /// assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b111111);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_or(&self, val: u32, order: Ordering) -> u32 {
        unsafe { atomic_or(self.as_ptr(), val, order) }
    }
    /// Bitwise "xor" with the current value.
    ///
    /// Performs a bitwise "xor" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_xor` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u32`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU32, Ordering};"]
    ///
    #[doc = "let foo = AtomicU32::new(0b101101);"]
    /// assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b011110);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_xor(&self, val: u32, order: Ordering) -> u32 {
        unsafe { atomic_xor(self.as_ptr(), val, order) }
    }
    /// An alias for
    #[doc = "[`AtomicU32::try_update`]"]
    /// .
    #[inline]
    #[stable(feature = "no_more_cas", since = "1.45.0")]
    #[rustc_should_not_be_called_on_const_items]
    #[deprecated(since = "1.99.0", note =
    "renamed to `try_update` for consistency", suggestion = "try_update")]
    pub fn fetch_update<F>(&self, set_order: Ordering, fetch_order: Ordering,
        f: F) -> Result<u32, u32> where F: FnMut(u32) -> Option<u32> {
        self.try_update(set_order, fetch_order, f)
    }
    /// Fetches the value, and applies a function to it that returns an optional
    /// new value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else
    /// `Err(previous_value)`.
    ///
    #[doc = "See also: [`update`](`AtomicU32::update`)."]
    ///
    /// Note: This may call the function multiple times if the value has been changed from other threads in
    /// the meantime, as long as the function returns `Some(_)`, but the function will have been applied
    /// only once to the stored value.
    ///
    /// `try_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
    /// The first describes the required ordering for when the operation finally succeeds while the second
    /// describes the required ordering for loads. These correspond to the success and failure orderings of
    #[doc = "[`AtomicU32::compare_exchange`]"]
    /// respectively.
    ///
    /// Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u32`]."]
    ///
    /// # Considerations
    ///
    /// This method is not magic; it is not provided by the hardware, and does not act like a
    /// critical section or mutex.
    ///
    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
    /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
    /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicU32, Ordering};"]
    ///
    #[doc = "let x = AtomicU32::new(7);"]
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(7));
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(7));
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(8));
    /// assert_eq!(x.load(Ordering::SeqCst), 9);
    /// ```
    #[inline]
    #[stable(feature = "atomic_try_update", since = "1.95.0")]
    #[rustc_should_not_be_called_on_const_items]
    pub fn try_update(&self, set_order: Ordering, fetch_order: Ordering,
        mut f: impl FnMut(u32) -> Option<u32>) -> Result<u32, u32> {
        let mut prev = self.load(fetch_order);
        while let Some(next) = f(prev) {
            match self.compare_exchange_weak(prev, next, set_order,
                    fetch_order) {
                x @ Ok(_) => return x,
                Err(next_prev) => prev = next_prev,
            }
        }
        Err(prev)
    }
    /// Fetches the value, applies a function to it that it return a new value.
    /// The new value is stored and the old value is returned.
    ///
    #[doc = "See also: [`try_update`](`AtomicU32::try_update`)."]
    ///
    /// Note: This may call the function multiple times if the value has been changed from other threads in
    /// the meantime, but the function will have been applied only once to the stored value.
    ///
    /// `update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
    /// The first describes the required ordering for when the operation finally succeeds while the second
    /// describes the required ordering for loads. These correspond to the success and failure orderings of
    #[doc = "[`AtomicU32::compare_exchange`]"]
    /// respectively.
    ///
    /// Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u32`]."]
    ///
    /// # Considerations
    ///
    /// [CAS operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    /// This method is not magic; it is not provided by the hardware, and does not act like a
    /// critical section or mutex.
    ///
    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
    /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
    /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicU32, Ordering};"]
    ///
    #[doc = "let x = AtomicU32::new(7);"]
    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 7);
    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 8);
    /// assert_eq!(x.load(Ordering::SeqCst), 9);
    /// ```
    #[inline]
    #[stable(feature = "atomic_try_update", since = "1.95.0")]
    #[rustc_should_not_be_called_on_const_items]
    pub fn update(&self, set_order: Ordering, fetch_order: Ordering,
        mut f: impl FnMut(u32) -> u32) -> u32 {
        let mut prev = self.load(fetch_order);
        loop {
            match self.compare_exchange_weak(prev, f(prev), set_order,
                    fetch_order) {
                Ok(x) => break x,
                Err(next_prev) => prev = next_prev,
            }
        }
    }
    /// Maximum with the current value.
    ///
    /// Finds the maximum of the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_max` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u32`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU32, Ordering};"]
    ///
    #[doc = "let foo = AtomicU32::new(23);"]
    /// assert_eq!(foo.fetch_max(42, Ordering::SeqCst), 23);
    /// assert_eq!(foo.load(Ordering::SeqCst), 42);
    /// ```
    ///
    /// If you want to obtain the maximum value in one step, you can use the following:
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU32, Ordering};"]
    ///
    #[doc = "let foo = AtomicU32::new(23);"]
    /// let bar = 42;
    /// let max_foo = foo.fetch_max(bar, Ordering::SeqCst).max(bar);
    /// assert!(max_foo == 42);
    /// ```
    #[inline]
    #[stable(feature = "atomic_min_max", since = "1.45.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_max(&self, val: u32, order: Ordering) -> u32 {
        unsafe { atomic_umax(self.as_ptr(), val, order) }
    }
    /// Minimum with the current value.
    ///
    /// Finds the minimum of the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_min` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u32`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU32, Ordering};"]
    ///
    #[doc = "let foo = AtomicU32::new(23);"]
    /// assert_eq!(foo.fetch_min(42, Ordering::Relaxed), 23);
    /// assert_eq!(foo.load(Ordering::Relaxed), 23);
    /// assert_eq!(foo.fetch_min(22, Ordering::Relaxed), 23);
    /// assert_eq!(foo.load(Ordering::Relaxed), 22);
    /// ```
    ///
    /// If you want to obtain the minimum value in one step, you can use the following:
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU32, Ordering};"]
    ///
    #[doc = "let foo = AtomicU32::new(23);"]
    /// let bar = 12;
    /// let min_foo = foo.fetch_min(bar, Ordering::SeqCst).min(bar);
    /// assert_eq!(min_foo, 12);
    /// ```
    #[inline]
    #[stable(feature = "atomic_min_max", since = "1.45.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_min(&self, val: u32, order: Ordering) -> u32 {
        unsafe { atomic_umin(self.as_ptr(), val, order) }
    }
    /// Returns a mutable pointer to the underlying integer.
    ///
    /// Doing non-atomic reads and writes on the resulting integer can be a data race.
    /// This method is mostly useful for FFI, where the function signature may use
    #[doc = "`*mut u32` instead of `&AtomicU32`."]
    ///
    /// Returning an `*mut` pointer from a shared reference to this atomic is safe because the
    /// atomic types work with interior mutability. All modifications of an atomic change the value
    /// through a shared reference, and can do so safely as long as they use atomic operations. Any
    /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the
    /// requirements of the [memory model].
    ///
    /// # Examples
    ///
    /// ```ignore (extern-declaration)
    /// # fn main() {
    #[doc = "use std::sync::atomic::AtomicU32;"]
    ///
    /// extern "C" {
    #[doc = "    fn my_atomic_op(arg: *mut u32);"]
    /// }
    ///
    #[doc = "let atomic = AtomicU32::new(1);"]
    ///
    /// // SAFETY: Safe as long as `my_atomic_op` is atomic.
    /// unsafe {
    ///     my_atomic_op(atomic.as_ptr());
    /// }
    /// # }
    /// ```
    ///
    /// [memory model]: self#memory-model-for-atomic-accesses
    #[inline]
    #[stable(feature = "atomic_as_ptr", since = "1.70.0")]
    #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")]
    #[rustc_never_returns_null_ptr]
    pub const fn as_ptr(&self) -> *mut u32 { self.v.get().cast() }
}atomic_int! {
3799    target_has_atomic_load_store = "32",
3800    target_has_atomic = "32",
3801    target_has_atomic_primitive_alignment = "32",
3802    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3803    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3804    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3805    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3806    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3807    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3808    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
3809    rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
3810    "u32",
3811    "",
3812    atomic_umin, atomic_umax,
3813    4,
3814    u32 AtomicU32
3815}
3816#[cfg(target_has_atomic_load_store = "64")]
3817/// An integer type which can be safely shared between threads.
///
/// This type has the same
#[doc = "size and bit validity"]
/// as the underlying integer type, [`
#[doc = "i64"]
/// `].
#[doc =
"However, the alignment of this type is always equal to its size, even on targets where [`i64`] has a lesser alignment."]
///
/// For more about the differences between atomic types and
/// non-atomic types as well as information about the portability of
/// this type, please see the [module-level documentation].
///
/// **Note:** This type is only available on platforms that support
/// atomic loads and stores of [`
#[doc = "i64"]
/// `].
///
/// [module-level documentation]: crate::sync::atomic
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
pub type AtomicI64 = Atomic<i64>;
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
impl Default for AtomicI64 {
    #[inline]
    fn default() -> Self { Self::new(Default::default()) }
}
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
const impl From<i64> for AtomicI64 {
    #[doc = "Converts an `i64` into an `AtomicI64`."]
    #[inline]
    fn from(v: i64) -> Self { Self::new(v) }
}
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
impl fmt::Debug for AtomicI64 {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)
    }
}
impl AtomicI64 {
    /// Creates a new atomic integer.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::AtomicI64;"]
    ///
    #[doc = "let atomic_forty_two = AtomicI64::new(42);"]
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0")]
    #[must_use]
    pub const fn new(v: i64) -> Self { unsafe { transmute(v) } }
    /// Creates a new reference to an atomic integer from a pointer.
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{self, AtomicI64};"]
    ///
    /// // Get a pointer to an allocated value
    #[doc = "let ptr: *mut i64 = Box::into_raw(Box::new(0));"]
    ///
    #[doc = "assert!(ptr.cast::<AtomicI64>().is_aligned());"]
    ///
    /// {
    ///     // Create an atomic view of the allocated value
    #[doc = "    let atomic = unsafe {AtomicI64::from_ptr(ptr) };"]
    ///
    ///     // Use `atomic` for atomic operations, possibly share it with other threads
    ///     atomic.store(1, atomic::Ordering::Relaxed);
    /// }
    ///
    /// // It's ok to non-atomically access the value behind `ptr`,
    /// // since the reference to the atomic ended its lifetime in the block above
    /// assert_eq!(unsafe { *ptr }, 1);
    ///
    /// // Deallocate the value
    /// unsafe { drop(Box::from_raw(ptr)) }
    /// ```
    ///
    /// # Safety
    ///
    /// * `ptr` must be aligned to
    #[doc = "  `align_of::<AtomicI64>()`"]
    #[doc =
    "  (note that on some platforms this can be bigger than `align_of::<i64>()`)."]
    /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
    /// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not
    ///   allowed to mix conflicting atomic and non-atomic accesses, or atomic accesses of different
    ///   sizes, without synchronization.
    ///
    /// [valid]: crate::ptr#safety
    /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
    #[inline]
    #[stable(feature = "atomic_from_ptr", since = "1.75.0")]
    #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")]
    pub const unsafe fn from_ptr<'a>(ptr: *mut i64) -> &'a AtomicI64 {
        unsafe { &*ptr.cast() }
    }
    /// Returns a mutable reference to the underlying integer.
    ///
    /// This is safe because the mutable reference guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI64, Ordering};"]
    ///
    #[doc = "let mut some_var = AtomicI64::new(10);"]
    /// assert_eq!(*some_var.get_mut(), 10);
    /// *some_var.get_mut() = 5;
    /// assert_eq!(some_var.load(Ordering::SeqCst), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn get_mut(&mut self) -> &mut i64 {
        unsafe { &mut *self.as_ptr() }
    }
    #[doc = "Get atomic access to a `&mut i64`."]
    ///
    #[doc =
    "**Note:** This function is only available on targets where `AtomicI64` has the same alignment as `i64`."]
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicI64, Ordering};"]
    ///
    /// let mut some_int = 123;
    #[doc = "let a = AtomicI64::from_mut(&mut some_int);"]
    /// a.store(100, Ordering::Relaxed);
    /// assert_eq!(some_int, 100);
    /// ```
    ///
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn from_mut(v: &mut i64) -> &mut Self {
        let [] = [(); align_of::<Self>() - align_of::<i64>()];
        unsafe { &mut *(v as *mut i64 as *mut Self) }
    }
    #[doc = "Get non-atomic access to a `&mut [AtomicI64]` slice"]
    ///
    /// This is safe because the mutable reference guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```ignore-wasm"]
    #[doc = "use std::sync::atomic::{AtomicI64, Ordering};"]
    ///
    #[doc = "let mut some_ints = [const { AtomicI64::new(0) }; 10];"]
    ///
    #[doc =
    "let view: &mut [i64] = AtomicI64::get_mut_slice(&mut some_ints);"]
    /// assert_eq!(view, [0; 10]);
    /// view
    ///     .iter_mut()
    ///     .enumerate()
    ///     .for_each(|(idx, int)| *int = idx as _);
    ///
    /// std::thread::scope(|s| {
    ///     some_ints
    ///         .iter()
    ///         .enumerate()
    ///         .for_each(|(idx, int)| {
    ///             s.spawn(move || assert_eq!(int.load(Ordering::Relaxed), idx as _));
    ///         })
    /// });
    /// ```
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn get_mut_slice(this: &mut [Self]) -> &mut [i64] {
        unsafe { &mut *(this as *mut [Self] as *mut [i64]) }
    }
    #[doc = "Get atomic access to a `&mut [i64]` slice."]
    ///
    #[doc =
    "**Note:** This function is only available on targets where `AtomicI64` has the same alignment as `i64`."]
    ///
    /// # Examples
    ///
    #[doc = "```ignore-wasm"]
    #[doc = "use std::sync::atomic::{AtomicI64, Ordering};"]
    ///
    /// let mut some_ints = [0; 10];
    #[doc = "let a = &*AtomicI64::from_mut_slice(&mut some_ints);"]
    /// std::thread::scope(|s| {
    ///     for i in 0..a.len() {
    ///         s.spawn(move || a[i].store(i as _, Ordering::Relaxed));
    ///     }
    /// });
    /// for (i, n) in some_ints.into_iter().enumerate() {
    ///     assert_eq!(i, n as usize);
    /// }
    /// ```
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn from_mut_slice(v: &mut [i64]) -> &mut [Self] {
        let [] = [(); align_of::<Self>() - align_of::<i64>()];
        unsafe { &mut *(v as *mut [i64] as *mut [Self]) }
    }
    /// Consumes the atomic and returns the contained value.
    ///
    /// This is safe because passing `self` by value guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::AtomicI64;"]
    ///
    #[doc = "let some_var = AtomicI64::new(5);"]
    /// assert_eq!(some_var.into_inner(), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_stable(feature = "const_atomic_into_inner", since =
    "1.79.0")]
    pub const fn into_inner(self) -> i64 { unsafe { transmute(self) } }
    /// Loads a value from the atomic integer.
    ///
    /// `load` takes an [`Ordering`] argument which describes the memory ordering of this operation.
    /// Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Release`] or [`AcqRel`].
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI64, Ordering};"]
    ///
    #[doc = "let some_var = AtomicI64::new(5);"]
    ///
    /// assert_eq!(some_var.load(Ordering::Relaxed), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn load(&self, order: Ordering) -> i64 {
        unsafe { atomic_load::<_, false>(self.as_ptr(), order) }
    }
    /// Stores a value into the atomic integer.
    ///
    /// `store` takes an [`Ordering`] argument which describes the memory ordering of this operation.
    ///  Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI64, Ordering};"]
    ///
    #[doc = "let some_var = AtomicI64::new(5);"]
    ///
    /// some_var.store(10, Ordering::Relaxed);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn store(&self, val: i64, order: Ordering) {
        unsafe { atomic_store::<_, false>(self.as_ptr(), val, order); }
    }
    /// Stores a value into the atomic integer, returning the previous value.
    ///
    /// `swap` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i64`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI64, Ordering};"]
    ///
    #[doc = "let some_var = AtomicI64::new(5);"]
    ///
    /// assert_eq!(some_var.swap(10, Ordering::Relaxed), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn swap(&self, val: i64, order: Ordering) -> i64 {
        unsafe { atomic_swap(self.as_ptr(), val, order) }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    /// The return value is always the previous value. If it is equal to `current`, then the
    /// value was updated.
    ///
    /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
    /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
    /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
    /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
    /// happens, and using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i64`]."]
    ///
    /// # Migrating to `compare_exchange` and `compare_exchange_weak`
    ///
    /// `compare_and_swap` is equivalent to `compare_exchange` with the following mapping for
    /// memory orderings:
    ///
    /// Original | Success | Failure
    /// -------- | ------- | -------
    /// Relaxed  | Relaxed | Relaxed
    /// Acquire  | Acquire | Acquire
    /// Release  | Release | Relaxed
    /// AcqRel   | AcqRel  | Acquire
    /// SeqCst   | SeqCst  | SeqCst
    ///
    /// `compare_and_swap` and `compare_exchange` also differ in their return type. You can use
    /// `compare_exchange(...).unwrap_or_else(|x| x)` to recover the behavior of `compare_and_swap`,
    /// but in most cases it is more idiomatic to check whether the return value is `Ok` or `Err`
    /// rather than to infer success vs failure based on the value that was read.
    ///
    /// During migration, consider whether it makes sense to use `compare_exchange_weak` instead.
    /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds,
    /// which allows the compiler to generate better assembly code when the compare and swap
    /// is used in a loop.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI64, Ordering};"]
    ///
    #[doc = "let some_var = AtomicI64::new(5);"]
    ///
    /// assert_eq!(some_var.compare_and_swap(5, 10, Ordering::Relaxed), 5);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    ///
    /// assert_eq!(some_var.compare_and_swap(6, 12, Ordering::Relaxed), 10);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[deprecated(since = "1.50.0", note =
    "Use `compare_exchange` or `compare_exchange_weak` instead")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_and_swap(&self, current: i64, new: i64,
        order: Ordering) -> i64 {
        match self.compare_exchange(current, new, order,
                strongest_failure_ordering(order)) {
            Ok(x) => x,
            Err(x) => x,
        }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    /// The return value is a result indicating whether the new value was written and
    /// containing the previous value. On success this value is guaranteed to be equal to
    /// `current`.
    ///
    /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
    /// ordering of this operation. `success` describes the required ordering for the
    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
    /// `failure` describes the required ordering for the load operation that takes place when
    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i64`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI64, Ordering};"]
    ///
    #[doc = "let some_var = AtomicI64::new(5);"]
    ///
    /// assert_eq!(some_var.compare_exchange(5, 10,
    ///                                      Ordering::Acquire,
    ///                                      Ordering::Relaxed),
    ///            Ok(5));
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    ///
    /// assert_eq!(some_var.compare_exchange(6, 12,
    ///                                      Ordering::SeqCst,
    ///                                      Ordering::Acquire),
    ///            Err(10));
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    ///
    /// # Considerations
    ///
    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
    /// of CAS operations. In particular, a load of the value followed by a successful
    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
    /// changed the value in the interim! This is usually important when the *equality* check in
    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
    /// does not necessarily imply identity. This is a particularly common case for pointers, as
    /// a pointer holding the same address does not imply that the same object exists at that
    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_exchange(&self, current: i64, new: i64,
        success: Ordering, failure: Ordering) -> Result<i64, i64> {
        unsafe {
            atomic_compare_exchange(self.as_ptr(), current, new, success,
                failure)
        }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    #[doc = "Unlike [`AtomicI64::compare_exchange`],"]
    /// this function is allowed to spuriously fail even
    /// when the comparison succeeds, which can result in more efficient code on some
    /// platforms. The return value is a result indicating whether the new value was
    /// written and containing the previous value.
    ///
    /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
    /// ordering of this operation. `success` describes the required ordering for the
    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
    /// `failure` describes the required ordering for the load operation that takes place when
    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i64`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI64, Ordering};"]
    ///
    #[doc = "let val = AtomicI64::new(4);"]
    ///
    /// let mut old = val.load(Ordering::Relaxed);
    /// loop {
    ///     let new = old * 2;
    ///     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
    ///         Ok(_) => break,
    ///         Err(x) => old = x,
    ///     }
    /// }
    /// ```
    ///
    /// # Considerations
    ///
    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
    /// of CAS operations. In particular, a load of the value followed by a successful
    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
    /// changed the value in the interim. This is usually important when the *equality* check in
    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
    /// does not necessarily imply identity. This is a particularly common case for pointers, as
    /// a pointer holding the same address does not imply that the same object exists at that
    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_exchange_weak(&self, current: i64, new: i64,
        success: Ordering, failure: Ordering) -> Result<i64, i64> {
        unsafe {
            atomic_compare_exchange_weak(self.as_ptr(), current, new, success,
                failure)
        }
    }
    /// Adds to the current value, returning the previous value.
    ///
    /// This operation wraps around on overflow.
    ///
    /// `fetch_add` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i64`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI64, Ordering};"]
    ///
    #[doc = "let foo = AtomicI64::new(0);"]
    /// assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0);
    /// assert_eq!(foo.load(Ordering::SeqCst), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_add(&self, val: i64, order: Ordering) -> i64 {
        unsafe { atomic_add(self.as_ptr(), val, order) }
    }
    /// Subtracts from the current value, returning the previous value.
    ///
    /// This operation wraps around on overflow.
    ///
    /// `fetch_sub` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i64`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI64, Ordering};"]
    ///
    #[doc = "let foo = AtomicI64::new(20);"]
    /// assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 20);
    /// assert_eq!(foo.load(Ordering::SeqCst), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_sub(&self, val: i64, order: Ordering) -> i64 {
        unsafe { atomic_sub(self.as_ptr(), val, order) }
    }
    /// Bitwise "and" with the current value.
    ///
    /// Performs a bitwise "and" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_and` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i64`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI64, Ordering};"]
    ///
    #[doc = "let foo = AtomicI64::new(0b101101);"]
    /// assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b100001);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_and(&self, val: i64, order: Ordering) -> i64 {
        unsafe { atomic_and(self.as_ptr(), val, order) }
    }
    /// Bitwise "nand" with the current value.
    ///
    /// Performs a bitwise "nand" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_nand` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i64`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI64, Ordering};"]
    ///
    #[doc = "let foo = AtomicI64::new(0x13);"]
    /// assert_eq!(foo.fetch_nand(0x31, Ordering::SeqCst), 0x13);
    /// assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31));
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_nand(&self, val: i64, order: Ordering) -> i64 {
        unsafe { atomic_nand(self.as_ptr(), val, order) }
    }
    /// Bitwise "or" with the current value.
    ///
    /// Performs a bitwise "or" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_or` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i64`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI64, Ordering};"]
    ///
    #[doc = "let foo = AtomicI64::new(0b101101);"]
    /// assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b111111);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_or(&self, val: i64, order: Ordering) -> i64 {
        unsafe { atomic_or(self.as_ptr(), val, order) }
    }
    /// Bitwise "xor" with the current value.
    ///
    /// Performs a bitwise "xor" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_xor` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i64`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI64, Ordering};"]
    ///
    #[doc = "let foo = AtomicI64::new(0b101101);"]
    /// assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b011110);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_xor(&self, val: i64, order: Ordering) -> i64 {
        unsafe { atomic_xor(self.as_ptr(), val, order) }
    }
    /// An alias for
    #[doc = "[`AtomicI64::try_update`]"]
    /// .
    #[inline]
    #[stable(feature = "no_more_cas", since = "1.45.0")]
    #[rustc_should_not_be_called_on_const_items]
    #[deprecated(since = "1.99.0", note =
    "renamed to `try_update` for consistency", suggestion = "try_update")]
    pub fn fetch_update<F>(&self, set_order: Ordering, fetch_order: Ordering,
        f: F) -> Result<i64, i64> where F: FnMut(i64) -> Option<i64> {
        self.try_update(set_order, fetch_order, f)
    }
    /// Fetches the value, and applies a function to it that returns an optional
    /// new value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else
    /// `Err(previous_value)`.
    ///
    #[doc = "See also: [`update`](`AtomicI64::update`)."]
    ///
    /// Note: This may call the function multiple times if the value has been changed from other threads in
    /// the meantime, as long as the function returns `Some(_)`, but the function will have been applied
    /// only once to the stored value.
    ///
    /// `try_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
    /// The first describes the required ordering for when the operation finally succeeds while the second
    /// describes the required ordering for loads. These correspond to the success and failure orderings of
    #[doc = "[`AtomicI64::compare_exchange`]"]
    /// respectively.
    ///
    /// Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i64`]."]
    ///
    /// # Considerations
    ///
    /// This method is not magic; it is not provided by the hardware, and does not act like a
    /// critical section or mutex.
    ///
    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
    /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
    /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicI64, Ordering};"]
    ///
    #[doc = "let x = AtomicI64::new(7);"]
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(7));
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(7));
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(8));
    /// assert_eq!(x.load(Ordering::SeqCst), 9);
    /// ```
    #[inline]
    #[stable(feature = "atomic_try_update", since = "1.95.0")]
    #[rustc_should_not_be_called_on_const_items]
    pub fn try_update(&self, set_order: Ordering, fetch_order: Ordering,
        mut f: impl FnMut(i64) -> Option<i64>) -> Result<i64, i64> {
        let mut prev = self.load(fetch_order);
        while let Some(next) = f(prev) {
            match self.compare_exchange_weak(prev, next, set_order,
                    fetch_order) {
                x @ Ok(_) => return x,
                Err(next_prev) => prev = next_prev,
            }
        }
        Err(prev)
    }
    /// Fetches the value, applies a function to it that it return a new value.
    /// The new value is stored and the old value is returned.
    ///
    #[doc = "See also: [`try_update`](`AtomicI64::try_update`)."]
    ///
    /// Note: This may call the function multiple times if the value has been changed from other threads in
    /// the meantime, but the function will have been applied only once to the stored value.
    ///
    /// `update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
    /// The first describes the required ordering for when the operation finally succeeds while the second
    /// describes the required ordering for loads. These correspond to the success and failure orderings of
    #[doc = "[`AtomicI64::compare_exchange`]"]
    /// respectively.
    ///
    /// Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i64`]."]
    ///
    /// # Considerations
    ///
    /// [CAS operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    /// This method is not magic; it is not provided by the hardware, and does not act like a
    /// critical section or mutex.
    ///
    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
    /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
    /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicI64, Ordering};"]
    ///
    #[doc = "let x = AtomicI64::new(7);"]
    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 7);
    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 8);
    /// assert_eq!(x.load(Ordering::SeqCst), 9);
    /// ```
    #[inline]
    #[stable(feature = "atomic_try_update", since = "1.95.0")]
    #[rustc_should_not_be_called_on_const_items]
    pub fn update(&self, set_order: Ordering, fetch_order: Ordering,
        mut f: impl FnMut(i64) -> i64) -> i64 {
        let mut prev = self.load(fetch_order);
        loop {
            match self.compare_exchange_weak(prev, f(prev), set_order,
                    fetch_order) {
                Ok(x) => break x,
                Err(next_prev) => prev = next_prev,
            }
        }
    }
    /// Maximum with the current value.
    ///
    /// Finds the maximum of the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_max` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i64`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI64, Ordering};"]
    ///
    #[doc = "let foo = AtomicI64::new(23);"]
    /// assert_eq!(foo.fetch_max(42, Ordering::SeqCst), 23);
    /// assert_eq!(foo.load(Ordering::SeqCst), 42);
    /// ```
    ///
    /// If you want to obtain the maximum value in one step, you can use the following:
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI64, Ordering};"]
    ///
    #[doc = "let foo = AtomicI64::new(23);"]
    /// let bar = 42;
    /// let max_foo = foo.fetch_max(bar, Ordering::SeqCst).max(bar);
    /// assert!(max_foo == 42);
    /// ```
    #[inline]
    #[stable(feature = "atomic_min_max", since = "1.45.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_max(&self, val: i64, order: Ordering) -> i64 {
        unsafe { atomic_max(self.as_ptr(), val, order) }
    }
    /// Minimum with the current value.
    ///
    /// Finds the minimum of the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_min` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`i64`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI64, Ordering};"]
    ///
    #[doc = "let foo = AtomicI64::new(23);"]
    /// assert_eq!(foo.fetch_min(42, Ordering::Relaxed), 23);
    /// assert_eq!(foo.load(Ordering::Relaxed), 23);
    /// assert_eq!(foo.fetch_min(22, Ordering::Relaxed), 23);
    /// assert_eq!(foo.load(Ordering::Relaxed), 22);
    /// ```
    ///
    /// If you want to obtain the minimum value in one step, you can use the following:
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicI64, Ordering};"]
    ///
    #[doc = "let foo = AtomicI64::new(23);"]
    /// let bar = 12;
    /// let min_foo = foo.fetch_min(bar, Ordering::SeqCst).min(bar);
    /// assert_eq!(min_foo, 12);
    /// ```
    #[inline]
    #[stable(feature = "atomic_min_max", since = "1.45.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_min(&self, val: i64, order: Ordering) -> i64 {
        unsafe { atomic_min(self.as_ptr(), val, order) }
    }
    /// Returns a mutable pointer to the underlying integer.
    ///
    /// Doing non-atomic reads and writes on the resulting integer can be a data race.
    /// This method is mostly useful for FFI, where the function signature may use
    #[doc = "`*mut i64` instead of `&AtomicI64`."]
    ///
    /// Returning an `*mut` pointer from a shared reference to this atomic is safe because the
    /// atomic types work with interior mutability. All modifications of an atomic change the value
    /// through a shared reference, and can do so safely as long as they use atomic operations. Any
    /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the
    /// requirements of the [memory model].
    ///
    /// # Examples
    ///
    /// ```ignore (extern-declaration)
    /// # fn main() {
    #[doc = "use std::sync::atomic::AtomicI64;"]
    ///
    /// extern "C" {
    #[doc = "    fn my_atomic_op(arg: *mut i64);"]
    /// }
    ///
    #[doc = "let atomic = AtomicI64::new(1);"]
    ///
    /// // SAFETY: Safe as long as `my_atomic_op` is atomic.
    /// unsafe {
    ///     my_atomic_op(atomic.as_ptr());
    /// }
    /// # }
    /// ```
    ///
    /// [memory model]: self#memory-model-for-atomic-accesses
    #[inline]
    #[stable(feature = "atomic_as_ptr", since = "1.70.0")]
    #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")]
    #[rustc_never_returns_null_ptr]
    pub const fn as_ptr(&self) -> *mut i64 { self.v.get().cast() }
}atomic_int! {
3818    target_has_atomic_load_store = "64",
3819    target_has_atomic = "64",
3820    target_has_atomic_primitive_alignment = "64",
3821    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3822    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3823    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3824    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3825    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3826    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3827    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
3828    rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
3829    "i64",
3830    "",
3831    atomic_min, atomic_max,
3832    8,
3833    i64 AtomicI64
3834}
3835#[cfg(target_has_atomic_load_store = "64")]
3836/// An integer type which can be safely shared between threads.
///
/// This type has the same
#[doc = "size and bit validity"]
/// as the underlying integer type, [`
#[doc = "u64"]
/// `].
#[doc =
"However, the alignment of this type is always equal to its size, even on targets where [`u64`] has a lesser alignment."]
///
/// For more about the differences between atomic types and
/// non-atomic types as well as information about the portability of
/// this type, please see the [module-level documentation].
///
/// **Note:** This type is only available on platforms that support
/// atomic loads and stores of [`
#[doc = "u64"]
/// `].
///
/// [module-level documentation]: crate::sync::atomic
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
pub type AtomicU64 = Atomic<u64>;
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
impl Default for AtomicU64 {
    #[inline]
    fn default() -> Self { Self::new(Default::default()) }
}
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
const impl From<u64> for AtomicU64 {
    #[doc = "Converts an `u64` into an `AtomicU64`."]
    #[inline]
    fn from(v: u64) -> Self { Self::new(v) }
}
#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
impl fmt::Debug for AtomicU64 {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)
    }
}
impl AtomicU64 {
    /// Creates a new atomic integer.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::AtomicU64;"]
    ///
    #[doc = "let atomic_forty_two = AtomicU64::new(42);"]
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0")]
    #[must_use]
    pub const fn new(v: u64) -> Self { unsafe { transmute(v) } }
    /// Creates a new reference to an atomic integer from a pointer.
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{self, AtomicU64};"]
    ///
    /// // Get a pointer to an allocated value
    #[doc = "let ptr: *mut u64 = Box::into_raw(Box::new(0));"]
    ///
    #[doc = "assert!(ptr.cast::<AtomicU64>().is_aligned());"]
    ///
    /// {
    ///     // Create an atomic view of the allocated value
    #[doc = "    let atomic = unsafe {AtomicU64::from_ptr(ptr) };"]
    ///
    ///     // Use `atomic` for atomic operations, possibly share it with other threads
    ///     atomic.store(1, atomic::Ordering::Relaxed);
    /// }
    ///
    /// // It's ok to non-atomically access the value behind `ptr`,
    /// // since the reference to the atomic ended its lifetime in the block above
    /// assert_eq!(unsafe { *ptr }, 1);
    ///
    /// // Deallocate the value
    /// unsafe { drop(Box::from_raw(ptr)) }
    /// ```
    ///
    /// # Safety
    ///
    /// * `ptr` must be aligned to
    #[doc = "  `align_of::<AtomicU64>()`"]
    #[doc =
    "  (note that on some platforms this can be bigger than `align_of::<u64>()`)."]
    /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
    /// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not
    ///   allowed to mix conflicting atomic and non-atomic accesses, or atomic accesses of different
    ///   sizes, without synchronization.
    ///
    /// [valid]: crate::ptr#safety
    /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
    #[inline]
    #[stable(feature = "atomic_from_ptr", since = "1.75.0")]
    #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")]
    pub const unsafe fn from_ptr<'a>(ptr: *mut u64) -> &'a AtomicU64 {
        unsafe { &*ptr.cast() }
    }
    /// Returns a mutable reference to the underlying integer.
    ///
    /// This is safe because the mutable reference guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU64, Ordering};"]
    ///
    #[doc = "let mut some_var = AtomicU64::new(10);"]
    /// assert_eq!(*some_var.get_mut(), 10);
    /// *some_var.get_mut() = 5;
    /// assert_eq!(some_var.load(Ordering::SeqCst), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn get_mut(&mut self) -> &mut u64 {
        unsafe { &mut *self.as_ptr() }
    }
    #[doc = "Get atomic access to a `&mut u64`."]
    ///
    #[doc =
    "**Note:** This function is only available on targets where `AtomicU64` has the same alignment as `u64`."]
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicU64, Ordering};"]
    ///
    /// let mut some_int = 123;
    #[doc = "let a = AtomicU64::from_mut(&mut some_int);"]
    /// a.store(100, Ordering::Relaxed);
    /// assert_eq!(some_int, 100);
    /// ```
    ///
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn from_mut(v: &mut u64) -> &mut Self {
        let [] = [(); align_of::<Self>() - align_of::<u64>()];
        unsafe { &mut *(v as *mut u64 as *mut Self) }
    }
    #[doc = "Get non-atomic access to a `&mut [AtomicU64]` slice"]
    ///
    /// This is safe because the mutable reference guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```ignore-wasm"]
    #[doc = "use std::sync::atomic::{AtomicU64, Ordering};"]
    ///
    #[doc = "let mut some_ints = [const { AtomicU64::new(0) }; 10];"]
    ///
    #[doc =
    "let view: &mut [u64] = AtomicU64::get_mut_slice(&mut some_ints);"]
    /// assert_eq!(view, [0; 10]);
    /// view
    ///     .iter_mut()
    ///     .enumerate()
    ///     .for_each(|(idx, int)| *int = idx as _);
    ///
    /// std::thread::scope(|s| {
    ///     some_ints
    ///         .iter()
    ///         .enumerate()
    ///         .for_each(|(idx, int)| {
    ///             s.spawn(move || assert_eq!(int.load(Ordering::Relaxed), idx as _));
    ///         })
    /// });
    /// ```
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn get_mut_slice(this: &mut [Self]) -> &mut [u64] {
        unsafe { &mut *(this as *mut [Self] as *mut [u64]) }
    }
    #[doc = "Get atomic access to a `&mut [u64]` slice."]
    ///
    #[doc =
    "**Note:** This function is only available on targets where `AtomicU64` has the same alignment as `u64`."]
    ///
    /// # Examples
    ///
    #[doc = "```ignore-wasm"]
    #[doc = "use std::sync::atomic::{AtomicU64, Ordering};"]
    ///
    /// let mut some_ints = [0; 10];
    #[doc = "let a = &*AtomicU64::from_mut_slice(&mut some_ints);"]
    /// std::thread::scope(|s| {
    ///     for i in 0..a.len() {
    ///         s.spawn(move || a[i].store(i as _, Ordering::Relaxed));
    ///     }
    /// });
    /// for (i, n) in some_ints.into_iter().enumerate() {
    ///     assert_eq!(i, n as usize);
    /// }
    /// ```
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn from_mut_slice(v: &mut [u64]) -> &mut [Self] {
        let [] = [(); align_of::<Self>() - align_of::<u64>()];
        unsafe { &mut *(v as *mut [u64] as *mut [Self]) }
    }
    /// Consumes the atomic and returns the contained value.
    ///
    /// This is safe because passing `self` by value guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::AtomicU64;"]
    ///
    #[doc = "let some_var = AtomicU64::new(5);"]
    /// assert_eq!(some_var.into_inner(), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_stable(feature = "const_atomic_into_inner", since =
    "1.79.0")]
    pub const fn into_inner(self) -> u64 { unsafe { transmute(self) } }
    /// Loads a value from the atomic integer.
    ///
    /// `load` takes an [`Ordering`] argument which describes the memory ordering of this operation.
    /// Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Release`] or [`AcqRel`].
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU64, Ordering};"]
    ///
    #[doc = "let some_var = AtomicU64::new(5);"]
    ///
    /// assert_eq!(some_var.load(Ordering::Relaxed), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn load(&self, order: Ordering) -> u64 {
        unsafe { atomic_load::<_, false>(self.as_ptr(), order) }
    }
    /// Stores a value into the atomic integer.
    ///
    /// `store` takes an [`Ordering`] argument which describes the memory ordering of this operation.
    ///  Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU64, Ordering};"]
    ///
    #[doc = "let some_var = AtomicU64::new(5);"]
    ///
    /// some_var.store(10, Ordering::Relaxed);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn store(&self, val: u64, order: Ordering) {
        unsafe { atomic_store::<_, false>(self.as_ptr(), val, order); }
    }
    /// Stores a value into the atomic integer, returning the previous value.
    ///
    /// `swap` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u64`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU64, Ordering};"]
    ///
    #[doc = "let some_var = AtomicU64::new(5);"]
    ///
    /// assert_eq!(some_var.swap(10, Ordering::Relaxed), 5);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn swap(&self, val: u64, order: Ordering) -> u64 {
        unsafe { atomic_swap(self.as_ptr(), val, order) }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    /// The return value is always the previous value. If it is equal to `current`, then the
    /// value was updated.
    ///
    /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
    /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
    /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
    /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
    /// happens, and using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u64`]."]
    ///
    /// # Migrating to `compare_exchange` and `compare_exchange_weak`
    ///
    /// `compare_and_swap` is equivalent to `compare_exchange` with the following mapping for
    /// memory orderings:
    ///
    /// Original | Success | Failure
    /// -------- | ------- | -------
    /// Relaxed  | Relaxed | Relaxed
    /// Acquire  | Acquire | Acquire
    /// Release  | Release | Relaxed
    /// AcqRel   | AcqRel  | Acquire
    /// SeqCst   | SeqCst  | SeqCst
    ///
    /// `compare_and_swap` and `compare_exchange` also differ in their return type. You can use
    /// `compare_exchange(...).unwrap_or_else(|x| x)` to recover the behavior of `compare_and_swap`,
    /// but in most cases it is more idiomatic to check whether the return value is `Ok` or `Err`
    /// rather than to infer success vs failure based on the value that was read.
    ///
    /// During migration, consider whether it makes sense to use `compare_exchange_weak` instead.
    /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds,
    /// which allows the compiler to generate better assembly code when the compare and swap
    /// is used in a loop.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU64, Ordering};"]
    ///
    #[doc = "let some_var = AtomicU64::new(5);"]
    ///
    /// assert_eq!(some_var.compare_and_swap(5, 10, Ordering::Relaxed), 5);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    ///
    /// assert_eq!(some_var.compare_and_swap(6, 12, Ordering::Relaxed), 10);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[deprecated(since = "1.50.0", note =
    "Use `compare_exchange` or `compare_exchange_weak` instead")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_and_swap(&self, current: u64, new: u64,
        order: Ordering) -> u64 {
        match self.compare_exchange(current, new, order,
                strongest_failure_ordering(order)) {
            Ok(x) => x,
            Err(x) => x,
        }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    /// The return value is a result indicating whether the new value was written and
    /// containing the previous value. On success this value is guaranteed to be equal to
    /// `current`.
    ///
    /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
    /// ordering of this operation. `success` describes the required ordering for the
    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
    /// `failure` describes the required ordering for the load operation that takes place when
    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u64`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU64, Ordering};"]
    ///
    #[doc = "let some_var = AtomicU64::new(5);"]
    ///
    /// assert_eq!(some_var.compare_exchange(5, 10,
    ///                                      Ordering::Acquire,
    ///                                      Ordering::Relaxed),
    ///            Ok(5));
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    ///
    /// assert_eq!(some_var.compare_exchange(6, 12,
    ///                                      Ordering::SeqCst,
    ///                                      Ordering::Acquire),
    ///            Err(10));
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    ///
    /// # Considerations
    ///
    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
    /// of CAS operations. In particular, a load of the value followed by a successful
    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
    /// changed the value in the interim! This is usually important when the *equality* check in
    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
    /// does not necessarily imply identity. This is a particularly common case for pointers, as
    /// a pointer holding the same address does not imply that the same object exists at that
    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_exchange(&self, current: u64, new: u64,
        success: Ordering, failure: Ordering) -> Result<u64, u64> {
        unsafe {
            atomic_compare_exchange(self.as_ptr(), current, new, success,
                failure)
        }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    #[doc = "Unlike [`AtomicU64::compare_exchange`],"]
    /// this function is allowed to spuriously fail even
    /// when the comparison succeeds, which can result in more efficient code on some
    /// platforms. The return value is a result indicating whether the new value was
    /// written and containing the previous value.
    ///
    /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
    /// ordering of this operation. `success` describes the required ordering for the
    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
    /// `failure` describes the required ordering for the load operation that takes place when
    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u64`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU64, Ordering};"]
    ///
    #[doc = "let val = AtomicU64::new(4);"]
    ///
    /// let mut old = val.load(Ordering::Relaxed);
    /// loop {
    ///     let new = old * 2;
    ///     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
    ///         Ok(_) => break,
    ///         Err(x) => old = x,
    ///     }
    /// }
    /// ```
    ///
    /// # Considerations
    ///
    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
    /// of CAS operations. In particular, a load of the value followed by a successful
    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
    /// changed the value in the interim. This is usually important when the *equality* check in
    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
    /// does not necessarily imply identity. This is a particularly common case for pointers, as
    /// a pointer holding the same address does not imply that the same object exists at that
    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_exchange_weak(&self, current: u64, new: u64,
        success: Ordering, failure: Ordering) -> Result<u64, u64> {
        unsafe {
            atomic_compare_exchange_weak(self.as_ptr(), current, new, success,
                failure)
        }
    }
    /// Adds to the current value, returning the previous value.
    ///
    /// This operation wraps around on overflow.
    ///
    /// `fetch_add` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u64`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU64, Ordering};"]
    ///
    #[doc = "let foo = AtomicU64::new(0);"]
    /// assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0);
    /// assert_eq!(foo.load(Ordering::SeqCst), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_add(&self, val: u64, order: Ordering) -> u64 {
        unsafe { atomic_add(self.as_ptr(), val, order) }
    }
    /// Subtracts from the current value, returning the previous value.
    ///
    /// This operation wraps around on overflow.
    ///
    /// `fetch_sub` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u64`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU64, Ordering};"]
    ///
    #[doc = "let foo = AtomicU64::new(20);"]
    /// assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 20);
    /// assert_eq!(foo.load(Ordering::SeqCst), 10);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_sub(&self, val: u64, order: Ordering) -> u64 {
        unsafe { atomic_sub(self.as_ptr(), val, order) }
    }
    /// Bitwise "and" with the current value.
    ///
    /// Performs a bitwise "and" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_and` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u64`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU64, Ordering};"]
    ///
    #[doc = "let foo = AtomicU64::new(0b101101);"]
    /// assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b100001);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_and(&self, val: u64, order: Ordering) -> u64 {
        unsafe { atomic_and(self.as_ptr(), val, order) }
    }
    /// Bitwise "nand" with the current value.
    ///
    /// Performs a bitwise "nand" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_nand` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u64`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU64, Ordering};"]
    ///
    #[doc = "let foo = AtomicU64::new(0x13);"]
    /// assert_eq!(foo.fetch_nand(0x31, Ordering::SeqCst), 0x13);
    /// assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31));
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_nand(&self, val: u64, order: Ordering) -> u64 {
        unsafe { atomic_nand(self.as_ptr(), val, order) }
    }
    /// Bitwise "or" with the current value.
    ///
    /// Performs a bitwise "or" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_or` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u64`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU64, Ordering};"]
    ///
    #[doc = "let foo = AtomicU64::new(0b101101);"]
    /// assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b111111);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_or(&self, val: u64, order: Ordering) -> u64 {
        unsafe { atomic_or(self.as_ptr(), val, order) }
    }
    /// Bitwise "xor" with the current value.
    ///
    /// Performs a bitwise "xor" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_xor` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u64`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU64, Ordering};"]
    ///
    #[doc = "let foo = AtomicU64::new(0b101101);"]
    /// assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b011110);
    /// ```
    #[inline]
    #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_xor(&self, val: u64, order: Ordering) -> u64 {
        unsafe { atomic_xor(self.as_ptr(), val, order) }
    }
    /// An alias for
    #[doc = "[`AtomicU64::try_update`]"]
    /// .
    #[inline]
    #[stable(feature = "no_more_cas", since = "1.45.0")]
    #[rustc_should_not_be_called_on_const_items]
    #[deprecated(since = "1.99.0", note =
    "renamed to `try_update` for consistency", suggestion = "try_update")]
    pub fn fetch_update<F>(&self, set_order: Ordering, fetch_order: Ordering,
        f: F) -> Result<u64, u64> where F: FnMut(u64) -> Option<u64> {
        self.try_update(set_order, fetch_order, f)
    }
    /// Fetches the value, and applies a function to it that returns an optional
    /// new value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else
    /// `Err(previous_value)`.
    ///
    #[doc = "See also: [`update`](`AtomicU64::update`)."]
    ///
    /// Note: This may call the function multiple times if the value has been changed from other threads in
    /// the meantime, as long as the function returns `Some(_)`, but the function will have been applied
    /// only once to the stored value.
    ///
    /// `try_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
    /// The first describes the required ordering for when the operation finally succeeds while the second
    /// describes the required ordering for loads. These correspond to the success and failure orderings of
    #[doc = "[`AtomicU64::compare_exchange`]"]
    /// respectively.
    ///
    /// Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u64`]."]
    ///
    /// # Considerations
    ///
    /// This method is not magic; it is not provided by the hardware, and does not act like a
    /// critical section or mutex.
    ///
    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
    /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
    /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicU64, Ordering};"]
    ///
    #[doc = "let x = AtomicU64::new(7);"]
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(7));
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(7));
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(8));
    /// assert_eq!(x.load(Ordering::SeqCst), 9);
    /// ```
    #[inline]
    #[stable(feature = "atomic_try_update", since = "1.95.0")]
    #[rustc_should_not_be_called_on_const_items]
    pub fn try_update(&self, set_order: Ordering, fetch_order: Ordering,
        mut f: impl FnMut(u64) -> Option<u64>) -> Result<u64, u64> {
        let mut prev = self.load(fetch_order);
        while let Some(next) = f(prev) {
            match self.compare_exchange_weak(prev, next, set_order,
                    fetch_order) {
                x @ Ok(_) => return x,
                Err(next_prev) => prev = next_prev,
            }
        }
        Err(prev)
    }
    /// Fetches the value, applies a function to it that it return a new value.
    /// The new value is stored and the old value is returned.
    ///
    #[doc = "See also: [`try_update`](`AtomicU64::try_update`)."]
    ///
    /// Note: This may call the function multiple times if the value has been changed from other threads in
    /// the meantime, but the function will have been applied only once to the stored value.
    ///
    /// `update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
    /// The first describes the required ordering for when the operation finally succeeds while the second
    /// describes the required ordering for loads. These correspond to the success and failure orderings of
    #[doc = "[`AtomicU64::compare_exchange`]"]
    /// respectively.
    ///
    /// Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u64`]."]
    ///
    /// # Considerations
    ///
    /// [CAS operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    /// This method is not magic; it is not provided by the hardware, and does not act like a
    /// critical section or mutex.
    ///
    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
    /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
    /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicU64, Ordering};"]
    ///
    #[doc = "let x = AtomicU64::new(7);"]
    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 7);
    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 8);
    /// assert_eq!(x.load(Ordering::SeqCst), 9);
    /// ```
    #[inline]
    #[stable(feature = "atomic_try_update", since = "1.95.0")]
    #[rustc_should_not_be_called_on_const_items]
    pub fn update(&self, set_order: Ordering, fetch_order: Ordering,
        mut f: impl FnMut(u64) -> u64) -> u64 {
        let mut prev = self.load(fetch_order);
        loop {
            match self.compare_exchange_weak(prev, f(prev), set_order,
                    fetch_order) {
                Ok(x) => break x,
                Err(next_prev) => prev = next_prev,
            }
        }
    }
    /// Maximum with the current value.
    ///
    /// Finds the maximum of the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_max` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u64`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU64, Ordering};"]
    ///
    #[doc = "let foo = AtomicU64::new(23);"]
    /// assert_eq!(foo.fetch_max(42, Ordering::SeqCst), 23);
    /// assert_eq!(foo.load(Ordering::SeqCst), 42);
    /// ```
    ///
    /// If you want to obtain the maximum value in one step, you can use the following:
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU64, Ordering};"]
    ///
    #[doc = "let foo = AtomicU64::new(23);"]
    /// let bar = 42;
    /// let max_foo = foo.fetch_max(bar, Ordering::SeqCst).max(bar);
    /// assert!(max_foo == 42);
    /// ```
    #[inline]
    #[stable(feature = "atomic_min_max", since = "1.45.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_max(&self, val: u64, order: Ordering) -> u64 {
        unsafe { atomic_umax(self.as_ptr(), val, order) }
    }
    /// Minimum with the current value.
    ///
    /// Finds the minimum of the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_min` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`u64`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU64, Ordering};"]
    ///
    #[doc = "let foo = AtomicU64::new(23);"]
    /// assert_eq!(foo.fetch_min(42, Ordering::Relaxed), 23);
    /// assert_eq!(foo.load(Ordering::Relaxed), 23);
    /// assert_eq!(foo.fetch_min(22, Ordering::Relaxed), 23);
    /// assert_eq!(foo.load(Ordering::Relaxed), 22);
    /// ```
    ///
    /// If you want to obtain the minimum value in one step, you can use the following:
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicU64, Ordering};"]
    ///
    #[doc = "let foo = AtomicU64::new(23);"]
    /// let bar = 12;
    /// let min_foo = foo.fetch_min(bar, Ordering::SeqCst).min(bar);
    /// assert_eq!(min_foo, 12);
    /// ```
    #[inline]
    #[stable(feature = "atomic_min_max", since = "1.45.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_min(&self, val: u64, order: Ordering) -> u64 {
        unsafe { atomic_umin(self.as_ptr(), val, order) }
    }
    /// Returns a mutable pointer to the underlying integer.
    ///
    /// Doing non-atomic reads and writes on the resulting integer can be a data race.
    /// This method is mostly useful for FFI, where the function signature may use
    #[doc = "`*mut u64` instead of `&AtomicU64`."]
    ///
    /// Returning an `*mut` pointer from a shared reference to this atomic is safe because the
    /// atomic types work with interior mutability. All modifications of an atomic change the value
    /// through a shared reference, and can do so safely as long as they use atomic operations. Any
    /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the
    /// requirements of the [memory model].
    ///
    /// # Examples
    ///
    /// ```ignore (extern-declaration)
    /// # fn main() {
    #[doc = "use std::sync::atomic::AtomicU64;"]
    ///
    /// extern "C" {
    #[doc = "    fn my_atomic_op(arg: *mut u64);"]
    /// }
    ///
    #[doc = "let atomic = AtomicU64::new(1);"]
    ///
    /// // SAFETY: Safe as long as `my_atomic_op` is atomic.
    /// unsafe {
    ///     my_atomic_op(atomic.as_ptr());
    /// }
    /// # }
    /// ```
    ///
    /// [memory model]: self#memory-model-for-atomic-accesses
    #[inline]
    #[stable(feature = "atomic_as_ptr", since = "1.70.0")]
    #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")]
    #[rustc_never_returns_null_ptr]
    pub const fn as_ptr(&self) -> *mut u64 { self.v.get().cast() }
}atomic_int! {
3837    target_has_atomic_load_store = "64",
3838    target_has_atomic = "64",
3839    target_has_atomic_primitive_alignment = "64",
3840    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3841    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3842    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3843    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3844    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3845    stable(feature = "integer_atomics_stable", since = "1.34.0"),
3846    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
3847    rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
3848    "u64",
3849    "",
3850    atomic_umin, atomic_umax,
3851    8,
3852    u64 AtomicU64
3853}
3854#[cfg(any(target_has_atomic_load_store = "128", doc))]
3855atomic_int! {
3856    target_has_atomic_load_store = "128",
3857    target_has_atomic = "128",
3858    target_has_atomic_primitive_alignment = "128",
3859    unstable(feature = "integer_atomics", issue = "99069"),
3860    unstable(feature = "integer_atomics", issue = "99069"),
3861    unstable(feature = "integer_atomics", issue = "99069"),
3862    unstable(feature = "integer_atomics", issue = "99069"),
3863    unstable(feature = "integer_atomics", issue = "99069"),
3864    unstable(feature = "integer_atomics", issue = "99069"),
3865    rustc_const_unstable(feature = "integer_atomics", issue = "99069"),
3866    rustc_const_unstable(feature = "integer_atomics", issue = "99069"),
3867    "i128",
3868    "#![feature(integer_atomics)]\n\n",
3869    atomic_min, atomic_max,
3870    16,
3871    i128 AtomicI128
3872}
3873#[cfg(any(target_has_atomic_load_store = "128", doc))]
3874atomic_int! {
3875    target_has_atomic_load_store = "128",
3876    target_has_atomic = "128",
3877    target_has_atomic_primitive_alignment = "128",
3878    unstable(feature = "integer_atomics", issue = "99069"),
3879    unstable(feature = "integer_atomics", issue = "99069"),
3880    unstable(feature = "integer_atomics", issue = "99069"),
3881    unstable(feature = "integer_atomics", issue = "99069"),
3882    unstable(feature = "integer_atomics", issue = "99069"),
3883    unstable(feature = "integer_atomics", issue = "99069"),
3884    rustc_const_unstable(feature = "integer_atomics", issue = "99069"),
3885    rustc_const_unstable(feature = "integer_atomics", issue = "99069"),
3886    "u128",
3887    "#![feature(integer_atomics)]\n\n",
3888    atomic_umin, atomic_umax,
3889    16,
3890    u128 AtomicU128
3891}
3892
3893#[cfg(target_has_atomic_load_store = "ptr")]
3894macro_rules! atomic_int_ptr_sized {
3895    ( $($target_pointer_width:literal $align:literal)* ) => { $(
3896        #[cfg(target_pointer_width = $target_pointer_width)]
3897        atomic_int! {
3898            target_has_atomic_load_store = "ptr",
3899            target_has_atomic = "ptr",
3900            target_has_atomic_primitive_alignment = "ptr",
3901            stable(feature = "rust1", since = "1.0.0"),
3902            stable(feature = "extended_compare_and_swap", since = "1.10.0"),
3903            stable(feature = "atomic_debug", since = "1.3.0"),
3904            stable(feature = "atomic_access", since = "1.15.0"),
3905            stable(feature = "atomic_from", since = "1.23.0"),
3906            stable(feature = "atomic_nand", since = "1.27.0"),
3907            rustc_const_stable(feature = "const_ptr_sized_atomics", since = "1.24.0"),
3908            rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
3909            "isize",
3910            "",
3911            atomic_min, atomic_max,
3912            $align,
3913            isize AtomicIsize
3914        }
3915        #[cfg(target_pointer_width = $target_pointer_width)]
3916        atomic_int! {
3917            target_has_atomic_load_store = "ptr",
3918            target_has_atomic = "ptr",
3919            target_has_atomic_primitive_alignment = "ptr",
3920            stable(feature = "rust1", since = "1.0.0"),
3921            stable(feature = "extended_compare_and_swap", since = "1.10.0"),
3922            stable(feature = "atomic_debug", since = "1.3.0"),
3923            stable(feature = "atomic_access", since = "1.15.0"),
3924            stable(feature = "atomic_from", since = "1.23.0"),
3925            stable(feature = "atomic_nand", since = "1.27.0"),
3926            rustc_const_stable(feature = "const_ptr_sized_atomics", since = "1.24.0"),
3927            rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
3928            "usize",
3929            "",
3930            atomic_umin, atomic_umax,
3931            $align,
3932            usize AtomicUsize
3933        }
3934
3935        /// An [`AtomicIsize`] initialized to `0`.
3936        #[cfg(target_pointer_width = $target_pointer_width)]
3937        #[stable(feature = "rust1", since = "1.0.0")]
3938        #[deprecated(
3939            since = "1.34.0",
3940            note = "the `new` function is now preferred",
3941            suggestion = "AtomicIsize::new(0)",
3942        )]
3943        #[expect(clippy::declare_interior_mutable_const, reason = "legacy atomic initializer")]
3944        pub const ATOMIC_ISIZE_INIT: AtomicIsize = AtomicIsize::new(0);
3945
3946        /// An [`AtomicUsize`] initialized to `0`.
3947        #[cfg(target_pointer_width = $target_pointer_width)]
3948        #[stable(feature = "rust1", since = "1.0.0")]
3949        #[deprecated(
3950            since = "1.34.0",
3951            note = "the `new` function is now preferred",
3952            suggestion = "AtomicUsize::new(0)",
3953        )]
3954        #[expect(clippy::declare_interior_mutable_const, reason = "legacy atomic initializer")]
3955        pub const ATOMIC_USIZE_INIT: AtomicUsize = AtomicUsize::new(0);
3956    )* };
3957}
3958
3959#[cfg(target_has_atomic_load_store = "ptr")]
3960/// An integer type which can be safely shared between threads.
///
/// This type has the same
#[doc = "size and bit validity"]
/// as the underlying integer type, [`
#[doc = "isize"]
/// `].
#[doc =
"However, the alignment of this type is always equal to its size, even on targets where [`isize`] has a lesser alignment."]
///
/// For more about the differences between atomic types and
/// non-atomic types as well as information about the portability of
/// this type, please see the [module-level documentation].
///
/// **Note:** This type is only available on platforms that support
/// atomic loads and stores of [`
#[doc = "isize"]
/// `].
///
/// [module-level documentation]: crate::sync::atomic
#[stable(feature = "rust1", since = "1.0.0")]
pub type AtomicIsize = Atomic<isize>;
#[stable(feature = "rust1", since = "1.0.0")]
impl Default for AtomicIsize {
    #[inline]
    fn default() -> Self { Self::new(Default::default()) }
}
#[stable(feature = "atomic_from", since = "1.23.0")]
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
const impl From<isize> for AtomicIsize {
    #[doc = "Converts an `isize` into an `AtomicIsize`."]
    #[inline]
    fn from(v: isize) -> Self { Self::new(v) }
}
#[stable(feature = "atomic_debug", since = "1.3.0")]
impl fmt::Debug for AtomicIsize {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)
    }
}
impl AtomicIsize {
    /// Creates a new atomic integer.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::AtomicIsize;"]
    ///
    #[doc = "let atomic_forty_two = AtomicIsize::new(42);"]
    /// ```
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[rustc_const_stable(feature = "const_ptr_sized_atomics", since =
    "1.24.0")]
    #[must_use]
    pub const fn new(v: isize) -> Self { unsafe { transmute(v) } }
    /// Creates a new reference to an atomic integer from a pointer.
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{self, AtomicIsize};"]
    ///
    /// // Get a pointer to an allocated value
    #[doc = "let ptr: *mut isize = Box::into_raw(Box::new(0));"]
    ///
    #[doc = "assert!(ptr.cast::<AtomicIsize>().is_aligned());"]
    ///
    /// {
    ///     // Create an atomic view of the allocated value
    #[doc = "    let atomic = unsafe {AtomicIsize::from_ptr(ptr) };"]
    ///
    ///     // Use `atomic` for atomic operations, possibly share it with other threads
    ///     atomic.store(1, atomic::Ordering::Relaxed);
    /// }
    ///
    /// // It's ok to non-atomically access the value behind `ptr`,
    /// // since the reference to the atomic ended its lifetime in the block above
    /// assert_eq!(unsafe { *ptr }, 1);
    ///
    /// // Deallocate the value
    /// unsafe { drop(Box::from_raw(ptr)) }
    /// ```
    ///
    /// # Safety
    ///
    /// * `ptr` must be aligned to
    #[doc = "  `align_of::<AtomicIsize>()`"]
    #[doc =
    "  (note that on some platforms this can be bigger than `align_of::<isize>()`)."]
    /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
    /// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not
    ///   allowed to mix conflicting atomic and non-atomic accesses, or atomic accesses of different
    ///   sizes, without synchronization.
    ///
    /// [valid]: crate::ptr#safety
    /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
    #[inline]
    #[stable(feature = "atomic_from_ptr", since = "1.75.0")]
    #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")]
    pub const unsafe fn from_ptr<'a>(ptr: *mut isize) -> &'a AtomicIsize {
        unsafe { &*ptr.cast() }
    }
    /// Returns a mutable reference to the underlying integer.
    ///
    /// This is safe because the mutable reference guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicIsize, Ordering};"]
    ///
    #[doc = "let mut some_var = AtomicIsize::new(10);"]
    /// assert_eq!(*some_var.get_mut(), 10);
    /// *some_var.get_mut() = 5;
    /// assert_eq!(some_var.load(Ordering::SeqCst), 5);
    /// ```
    #[inline]
    #[stable(feature = "atomic_access", since = "1.15.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn get_mut(&mut self) -> &mut isize {
        unsafe { &mut *self.as_ptr() }
    }
    #[doc = "Get atomic access to a `&mut isize`."]
    ///
    #[doc =
    "**Note:** This function is only available on targets where `AtomicIsize` has the same alignment as `isize`."]
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicIsize, Ordering};"]
    ///
    /// let mut some_int = 123;
    #[doc = "let a = AtomicIsize::from_mut(&mut some_int);"]
    /// a.store(100, Ordering::Relaxed);
    /// assert_eq!(some_int, 100);
    /// ```
    ///
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn from_mut(v: &mut isize) -> &mut Self {
        let [] = [(); align_of::<Self>() - align_of::<isize>()];
        unsafe { &mut *(v as *mut isize as *mut Self) }
    }
    #[doc = "Get non-atomic access to a `&mut [AtomicIsize]` slice"]
    ///
    /// This is safe because the mutable reference guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```ignore-wasm"]
    #[doc = "use std::sync::atomic::{AtomicIsize, Ordering};"]
    ///
    #[doc = "let mut some_ints = [const { AtomicIsize::new(0) }; 10];"]
    ///
    #[doc =
    "let view: &mut [isize] = AtomicIsize::get_mut_slice(&mut some_ints);"]
    /// assert_eq!(view, [0; 10]);
    /// view
    ///     .iter_mut()
    ///     .enumerate()
    ///     .for_each(|(idx, int)| *int = idx as _);
    ///
    /// std::thread::scope(|s| {
    ///     some_ints
    ///         .iter()
    ///         .enumerate()
    ///         .for_each(|(idx, int)| {
    ///             s.spawn(move || assert_eq!(int.load(Ordering::Relaxed), idx as _));
    ///         })
    /// });
    /// ```
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn get_mut_slice(this: &mut [Self]) -> &mut [isize] {
        unsafe { &mut *(this as *mut [Self] as *mut [isize]) }
    }
    #[doc = "Get atomic access to a `&mut [isize]` slice."]
    ///
    #[doc =
    "**Note:** This function is only available on targets where `AtomicIsize` has the same alignment as `isize`."]
    ///
    /// # Examples
    ///
    #[doc = "```ignore-wasm"]
    #[doc = "use std::sync::atomic::{AtomicIsize, Ordering};"]
    ///
    /// let mut some_ints = [0; 10];
    #[doc = "let a = &*AtomicIsize::from_mut_slice(&mut some_ints);"]
    /// std::thread::scope(|s| {
    ///     for i in 0..a.len() {
    ///         s.spawn(move || a[i].store(i as _, Ordering::Relaxed));
    ///     }
    /// });
    /// for (i, n) in some_ints.into_iter().enumerate() {
    ///     assert_eq!(i, n as usize);
    /// }
    /// ```
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn from_mut_slice(v: &mut [isize]) -> &mut [Self] {
        let [] = [(); align_of::<Self>() - align_of::<isize>()];
        unsafe { &mut *(v as *mut [isize] as *mut [Self]) }
    }
    /// Consumes the atomic and returns the contained value.
    ///
    /// This is safe because passing `self` by value guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::AtomicIsize;"]
    ///
    #[doc = "let some_var = AtomicIsize::new(5);"]
    /// assert_eq!(some_var.into_inner(), 5);
    /// ```
    #[inline]
    #[stable(feature = "atomic_access", since = "1.15.0")]
    #[rustc_const_stable(feature = "const_atomic_into_inner", since =
    "1.79.0")]
    pub const fn into_inner(self) -> isize { unsafe { transmute(self) } }
    /// Loads a value from the atomic integer.
    ///
    /// `load` takes an [`Ordering`] argument which describes the memory ordering of this operation.
    /// Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Release`] or [`AcqRel`].
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicIsize, Ordering};"]
    ///
    #[doc = "let some_var = AtomicIsize::new(5);"]
    ///
    /// assert_eq!(some_var.load(Ordering::Relaxed), 5);
    /// ```
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn load(&self, order: Ordering) -> isize {
        unsafe { atomic_load::<_, false>(self.as_ptr(), order) }
    }
    /// Stores a value into the atomic integer.
    ///
    /// `store` takes an [`Ordering`] argument which describes the memory ordering of this operation.
    ///  Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicIsize, Ordering};"]
    ///
    #[doc = "let some_var = AtomicIsize::new(5);"]
    ///
    /// some_var.store(10, Ordering::Relaxed);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn store(&self, val: isize, order: Ordering) {
        unsafe { atomic_store::<_, false>(self.as_ptr(), val, order); }
    }
    /// Stores a value into the atomic integer, returning the previous value.
    ///
    /// `swap` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`isize`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicIsize, Ordering};"]
    ///
    #[doc = "let some_var = AtomicIsize::new(5);"]
    ///
    /// assert_eq!(some_var.swap(10, Ordering::Relaxed), 5);
    /// ```
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn swap(&self, val: isize, order: Ordering) -> isize {
        unsafe { atomic_swap(self.as_ptr(), val, order) }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    /// The return value is always the previous value. If it is equal to `current`, then the
    /// value was updated.
    ///
    /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
    /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
    /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
    /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
    /// happens, and using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`isize`]."]
    ///
    /// # Migrating to `compare_exchange` and `compare_exchange_weak`
    ///
    /// `compare_and_swap` is equivalent to `compare_exchange` with the following mapping for
    /// memory orderings:
    ///
    /// Original | Success | Failure
    /// -------- | ------- | -------
    /// Relaxed  | Relaxed | Relaxed
    /// Acquire  | Acquire | Acquire
    /// Release  | Release | Relaxed
    /// AcqRel   | AcqRel  | Acquire
    /// SeqCst   | SeqCst  | SeqCst
    ///
    /// `compare_and_swap` and `compare_exchange` also differ in their return type. You can use
    /// `compare_exchange(...).unwrap_or_else(|x| x)` to recover the behavior of `compare_and_swap`,
    /// but in most cases it is more idiomatic to check whether the return value is `Ok` or `Err`
    /// rather than to infer success vs failure based on the value that was read.
    ///
    /// During migration, consider whether it makes sense to use `compare_exchange_weak` instead.
    /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds,
    /// which allows the compiler to generate better assembly code when the compare and swap
    /// is used in a loop.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicIsize, Ordering};"]
    ///
    #[doc = "let some_var = AtomicIsize::new(5);"]
    ///
    /// assert_eq!(some_var.compare_and_swap(5, 10, Ordering::Relaxed), 5);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    ///
    /// assert_eq!(some_var.compare_and_swap(6, 12, Ordering::Relaxed), 10);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[deprecated(since = "1.50.0", note =
    "Use `compare_exchange` or `compare_exchange_weak` instead")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_and_swap(&self, current: isize, new: isize,
        order: Ordering) -> isize {
        match self.compare_exchange(current, new, order,
                strongest_failure_ordering(order)) {
            Ok(x) => x,
            Err(x) => x,
        }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    /// The return value is a result indicating whether the new value was written and
    /// containing the previous value. On success this value is guaranteed to be equal to
    /// `current`.
    ///
    /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
    /// ordering of this operation. `success` describes the required ordering for the
    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
    /// `failure` describes the required ordering for the load operation that takes place when
    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`isize`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicIsize, Ordering};"]
    ///
    #[doc = "let some_var = AtomicIsize::new(5);"]
    ///
    /// assert_eq!(some_var.compare_exchange(5, 10,
    ///                                      Ordering::Acquire,
    ///                                      Ordering::Relaxed),
    ///            Ok(5));
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    ///
    /// assert_eq!(some_var.compare_exchange(6, 12,
    ///                                      Ordering::SeqCst,
    ///                                      Ordering::Acquire),
    ///            Err(10));
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    ///
    /// # Considerations
    ///
    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
    /// of CAS operations. In particular, a load of the value followed by a successful
    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
    /// changed the value in the interim! This is usually important when the *equality* check in
    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
    /// does not necessarily imply identity. This is a particularly common case for pointers, as
    /// a pointer holding the same address does not imply that the same object exists at that
    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    #[inline]
    #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_exchange(&self, current: isize, new: isize,
        success: Ordering, failure: Ordering) -> Result<isize, isize> {
        unsafe {
            atomic_compare_exchange(self.as_ptr(), current, new, success,
                failure)
        }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    #[doc = "Unlike [`AtomicIsize::compare_exchange`],"]
    /// this function is allowed to spuriously fail even
    /// when the comparison succeeds, which can result in more efficient code on some
    /// platforms. The return value is a result indicating whether the new value was
    /// written and containing the previous value.
    ///
    /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
    /// ordering of this operation. `success` describes the required ordering for the
    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
    /// `failure` describes the required ordering for the load operation that takes place when
    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`isize`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicIsize, Ordering};"]
    ///
    #[doc = "let val = AtomicIsize::new(4);"]
    ///
    /// let mut old = val.load(Ordering::Relaxed);
    /// loop {
    ///     let new = old * 2;
    ///     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
    ///         Ok(_) => break,
    ///         Err(x) => old = x,
    ///     }
    /// }
    /// ```
    ///
    /// # Considerations
    ///
    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
    /// of CAS operations. In particular, a load of the value followed by a successful
    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
    /// changed the value in the interim. This is usually important when the *equality* check in
    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
    /// does not necessarily imply identity. This is a particularly common case for pointers, as
    /// a pointer holding the same address does not imply that the same object exists at that
    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    #[inline]
    #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_exchange_weak(&self, current: isize, new: isize,
        success: Ordering, failure: Ordering) -> Result<isize, isize> {
        unsafe {
            atomic_compare_exchange_weak(self.as_ptr(), current, new, success,
                failure)
        }
    }
    /// Adds to the current value, returning the previous value.
    ///
    /// This operation wraps around on overflow.
    ///
    /// `fetch_add` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`isize`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicIsize, Ordering};"]
    ///
    #[doc = "let foo = AtomicIsize::new(0);"]
    /// assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0);
    /// assert_eq!(foo.load(Ordering::SeqCst), 10);
    /// ```
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_add(&self, val: isize, order: Ordering) -> isize {
        unsafe { atomic_add(self.as_ptr(), val, order) }
    }
    /// Subtracts from the current value, returning the previous value.
    ///
    /// This operation wraps around on overflow.
    ///
    /// `fetch_sub` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`isize`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicIsize, Ordering};"]
    ///
    #[doc = "let foo = AtomicIsize::new(20);"]
    /// assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 20);
    /// assert_eq!(foo.load(Ordering::SeqCst), 10);
    /// ```
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_sub(&self, val: isize, order: Ordering) -> isize {
        unsafe { atomic_sub(self.as_ptr(), val, order) }
    }
    /// Bitwise "and" with the current value.
    ///
    /// Performs a bitwise "and" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_and` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`isize`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicIsize, Ordering};"]
    ///
    #[doc = "let foo = AtomicIsize::new(0b101101);"]
    /// assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b100001);
    /// ```
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_and(&self, val: isize, order: Ordering) -> isize {
        unsafe { atomic_and(self.as_ptr(), val, order) }
    }
    /// Bitwise "nand" with the current value.
    ///
    /// Performs a bitwise "nand" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_nand` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`isize`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicIsize, Ordering};"]
    ///
    #[doc = "let foo = AtomicIsize::new(0x13);"]
    /// assert_eq!(foo.fetch_nand(0x31, Ordering::SeqCst), 0x13);
    /// assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31));
    /// ```
    #[inline]
    #[stable(feature = "atomic_nand", since = "1.27.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_nand(&self, val: isize, order: Ordering) -> isize {
        unsafe { atomic_nand(self.as_ptr(), val, order) }
    }
    /// Bitwise "or" with the current value.
    ///
    /// Performs a bitwise "or" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_or` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`isize`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicIsize, Ordering};"]
    ///
    #[doc = "let foo = AtomicIsize::new(0b101101);"]
    /// assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b111111);
    /// ```
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_or(&self, val: isize, order: Ordering) -> isize {
        unsafe { atomic_or(self.as_ptr(), val, order) }
    }
    /// Bitwise "xor" with the current value.
    ///
    /// Performs a bitwise "xor" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_xor` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`isize`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicIsize, Ordering};"]
    ///
    #[doc = "let foo = AtomicIsize::new(0b101101);"]
    /// assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b011110);
    /// ```
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_xor(&self, val: isize, order: Ordering) -> isize {
        unsafe { atomic_xor(self.as_ptr(), val, order) }
    }
    /// An alias for
    #[doc = "[`AtomicIsize::try_update`]"]
    /// .
    #[inline]
    #[stable(feature = "no_more_cas", since = "1.45.0")]
    #[rustc_should_not_be_called_on_const_items]
    #[deprecated(since = "1.99.0", note =
    "renamed to `try_update` for consistency", suggestion = "try_update")]
    pub fn fetch_update<F>(&self, set_order: Ordering, fetch_order: Ordering,
        f: F) -> Result<isize, isize> where F: FnMut(isize) -> Option<isize> {
        self.try_update(set_order, fetch_order, f)
    }
    /// Fetches the value, and applies a function to it that returns an optional
    /// new value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else
    /// `Err(previous_value)`.
    ///
    #[doc = "See also: [`update`](`AtomicIsize::update`)."]
    ///
    /// Note: This may call the function multiple times if the value has been changed from other threads in
    /// the meantime, as long as the function returns `Some(_)`, but the function will have been applied
    /// only once to the stored value.
    ///
    /// `try_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
    /// The first describes the required ordering for when the operation finally succeeds while the second
    /// describes the required ordering for loads. These correspond to the success and failure orderings of
    #[doc = "[`AtomicIsize::compare_exchange`]"]
    /// respectively.
    ///
    /// Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`isize`]."]
    ///
    /// # Considerations
    ///
    /// This method is not magic; it is not provided by the hardware, and does not act like a
    /// critical section or mutex.
    ///
    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
    /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
    /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicIsize, Ordering};"]
    ///
    #[doc = "let x = AtomicIsize::new(7);"]
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(7));
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(7));
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(8));
    /// assert_eq!(x.load(Ordering::SeqCst), 9);
    /// ```
    #[inline]
    #[stable(feature = "atomic_try_update", since = "1.95.0")]
    #[rustc_should_not_be_called_on_const_items]
    pub fn try_update(&self, set_order: Ordering, fetch_order: Ordering,
        mut f: impl FnMut(isize) -> Option<isize>) -> Result<isize, isize> {
        let mut prev = self.load(fetch_order);
        while let Some(next) = f(prev) {
            match self.compare_exchange_weak(prev, next, set_order,
                    fetch_order) {
                x @ Ok(_) => return x,
                Err(next_prev) => prev = next_prev,
            }
        }
        Err(prev)
    }
    /// Fetches the value, applies a function to it that it return a new value.
    /// The new value is stored and the old value is returned.
    ///
    #[doc = "See also: [`try_update`](`AtomicIsize::try_update`)."]
    ///
    /// Note: This may call the function multiple times if the value has been changed from other threads in
    /// the meantime, but the function will have been applied only once to the stored value.
    ///
    /// `update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
    /// The first describes the required ordering for when the operation finally succeeds while the second
    /// describes the required ordering for loads. These correspond to the success and failure orderings of
    #[doc = "[`AtomicIsize::compare_exchange`]"]
    /// respectively.
    ///
    /// Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`isize`]."]
    ///
    /// # Considerations
    ///
    /// [CAS operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    /// This method is not magic; it is not provided by the hardware, and does not act like a
    /// critical section or mutex.
    ///
    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
    /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
    /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicIsize, Ordering};"]
    ///
    #[doc = "let x = AtomicIsize::new(7);"]
    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 7);
    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 8);
    /// assert_eq!(x.load(Ordering::SeqCst), 9);
    /// ```
    #[inline]
    #[stable(feature = "atomic_try_update", since = "1.95.0")]
    #[rustc_should_not_be_called_on_const_items]
    pub fn update(&self, set_order: Ordering, fetch_order: Ordering,
        mut f: impl FnMut(isize) -> isize) -> isize {
        let mut prev = self.load(fetch_order);
        loop {
            match self.compare_exchange_weak(prev, f(prev), set_order,
                    fetch_order) {
                Ok(x) => break x,
                Err(next_prev) => prev = next_prev,
            }
        }
    }
    /// Maximum with the current value.
    ///
    /// Finds the maximum of the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_max` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`isize`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicIsize, Ordering};"]
    ///
    #[doc = "let foo = AtomicIsize::new(23);"]
    /// assert_eq!(foo.fetch_max(42, Ordering::SeqCst), 23);
    /// assert_eq!(foo.load(Ordering::SeqCst), 42);
    /// ```
    ///
    /// If you want to obtain the maximum value in one step, you can use the following:
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicIsize, Ordering};"]
    ///
    #[doc = "let foo = AtomicIsize::new(23);"]
    /// let bar = 42;
    /// let max_foo = foo.fetch_max(bar, Ordering::SeqCst).max(bar);
    /// assert!(max_foo == 42);
    /// ```
    #[inline]
    #[stable(feature = "atomic_min_max", since = "1.45.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_max(&self, val: isize, order: Ordering) -> isize {
        unsafe { atomic_max(self.as_ptr(), val, order) }
    }
    /// Minimum with the current value.
    ///
    /// Finds the minimum of the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_min` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`isize`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicIsize, Ordering};"]
    ///
    #[doc = "let foo = AtomicIsize::new(23);"]
    /// assert_eq!(foo.fetch_min(42, Ordering::Relaxed), 23);
    /// assert_eq!(foo.load(Ordering::Relaxed), 23);
    /// assert_eq!(foo.fetch_min(22, Ordering::Relaxed), 23);
    /// assert_eq!(foo.load(Ordering::Relaxed), 22);
    /// ```
    ///
    /// If you want to obtain the minimum value in one step, you can use the following:
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicIsize, Ordering};"]
    ///
    #[doc = "let foo = AtomicIsize::new(23);"]
    /// let bar = 12;
    /// let min_foo = foo.fetch_min(bar, Ordering::SeqCst).min(bar);
    /// assert_eq!(min_foo, 12);
    /// ```
    #[inline]
    #[stable(feature = "atomic_min_max", since = "1.45.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_min(&self, val: isize, order: Ordering) -> isize {
        unsafe { atomic_min(self.as_ptr(), val, order) }
    }
    /// Returns a mutable pointer to the underlying integer.
    ///
    /// Doing non-atomic reads and writes on the resulting integer can be a data race.
    /// This method is mostly useful for FFI, where the function signature may use
    #[doc = "`*mut isize` instead of `&AtomicIsize`."]
    ///
    /// Returning an `*mut` pointer from a shared reference to this atomic is safe because the
    /// atomic types work with interior mutability. All modifications of an atomic change the value
    /// through a shared reference, and can do so safely as long as they use atomic operations. Any
    /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the
    /// requirements of the [memory model].
    ///
    /// # Examples
    ///
    /// ```ignore (extern-declaration)
    /// # fn main() {
    #[doc = "use std::sync::atomic::AtomicIsize;"]
    ///
    /// extern "C" {
    #[doc = "    fn my_atomic_op(arg: *mut isize);"]
    /// }
    ///
    #[doc = "let atomic = AtomicIsize::new(1);"]
    ///
    /// // SAFETY: Safe as long as `my_atomic_op` is atomic.
    /// unsafe {
    ///     my_atomic_op(atomic.as_ptr());
    /// }
    /// # }
    /// ```
    ///
    /// [memory model]: self#memory-model-for-atomic-accesses
    #[inline]
    #[stable(feature = "atomic_as_ptr", since = "1.70.0")]
    #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")]
    #[rustc_never_returns_null_ptr]
    pub const fn as_ptr(&self) -> *mut isize { self.v.get().cast() }
}
/// An integer type which can be safely shared between threads.
///
/// This type has the same
#[doc = "size and bit validity"]
/// as the underlying integer type, [`
#[doc = "usize"]
/// `].
#[doc =
"However, the alignment of this type is always equal to its size, even on targets where [`usize`] has a lesser alignment."]
///
/// For more about the differences between atomic types and
/// non-atomic types as well as information about the portability of
/// this type, please see the [module-level documentation].
///
/// **Note:** This type is only available on platforms that support
/// atomic loads and stores of [`
#[doc = "usize"]
/// `].
///
/// [module-level documentation]: crate::sync::atomic
#[stable(feature = "rust1", since = "1.0.0")]
pub type AtomicUsize = Atomic<usize>;
#[stable(feature = "rust1", since = "1.0.0")]
impl Default for AtomicUsize {
    #[inline]
    fn default() -> Self { Self::new(Default::default()) }
}
#[stable(feature = "atomic_from", since = "1.23.0")]
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
const impl From<usize> for AtomicUsize {
    #[doc = "Converts an `usize` into an `AtomicUsize`."]
    #[inline]
    fn from(v: usize) -> Self { Self::new(v) }
}
#[stable(feature = "atomic_debug", since = "1.3.0")]
impl fmt::Debug for AtomicUsize {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)
    }
}
impl AtomicUsize {
    /// Creates a new atomic integer.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::AtomicUsize;"]
    ///
    #[doc = "let atomic_forty_two = AtomicUsize::new(42);"]
    /// ```
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[rustc_const_stable(feature = "const_ptr_sized_atomics", since =
    "1.24.0")]
    #[must_use]
    pub const fn new(v: usize) -> Self { unsafe { transmute(v) } }
    /// Creates a new reference to an atomic integer from a pointer.
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{self, AtomicUsize};"]
    ///
    /// // Get a pointer to an allocated value
    #[doc = "let ptr: *mut usize = Box::into_raw(Box::new(0));"]
    ///
    #[doc = "assert!(ptr.cast::<AtomicUsize>().is_aligned());"]
    ///
    /// {
    ///     // Create an atomic view of the allocated value
    #[doc = "    let atomic = unsafe {AtomicUsize::from_ptr(ptr) };"]
    ///
    ///     // Use `atomic` for atomic operations, possibly share it with other threads
    ///     atomic.store(1, atomic::Ordering::Relaxed);
    /// }
    ///
    /// // It's ok to non-atomically access the value behind `ptr`,
    /// // since the reference to the atomic ended its lifetime in the block above
    /// assert_eq!(unsafe { *ptr }, 1);
    ///
    /// // Deallocate the value
    /// unsafe { drop(Box::from_raw(ptr)) }
    /// ```
    ///
    /// # Safety
    ///
    /// * `ptr` must be aligned to
    #[doc = "  `align_of::<AtomicUsize>()`"]
    #[doc =
    "  (note that on some platforms this can be bigger than `align_of::<usize>()`)."]
    /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
    /// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not
    ///   allowed to mix conflicting atomic and non-atomic accesses, or atomic accesses of different
    ///   sizes, without synchronization.
    ///
    /// [valid]: crate::ptr#safety
    /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
    #[inline]
    #[stable(feature = "atomic_from_ptr", since = "1.75.0")]
    #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")]
    pub const unsafe fn from_ptr<'a>(ptr: *mut usize) -> &'a AtomicUsize {
        unsafe { &*ptr.cast() }
    }
    /// Returns a mutable reference to the underlying integer.
    ///
    /// This is safe because the mutable reference guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicUsize, Ordering};"]
    ///
    #[doc = "let mut some_var = AtomicUsize::new(10);"]
    /// assert_eq!(*some_var.get_mut(), 10);
    /// *some_var.get_mut() = 5;
    /// assert_eq!(some_var.load(Ordering::SeqCst), 5);
    /// ```
    #[inline]
    #[stable(feature = "atomic_access", since = "1.15.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn get_mut(&mut self) -> &mut usize {
        unsafe { &mut *self.as_ptr() }
    }
    #[doc = "Get atomic access to a `&mut usize`."]
    ///
    #[doc =
    "**Note:** This function is only available on targets where `AtomicUsize` has the same alignment as `usize`."]
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicUsize, Ordering};"]
    ///
    /// let mut some_int = 123;
    #[doc = "let a = AtomicUsize::from_mut(&mut some_int);"]
    /// a.store(100, Ordering::Relaxed);
    /// assert_eq!(some_int, 100);
    /// ```
    ///
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn from_mut(v: &mut usize) -> &mut Self {
        let [] = [(); align_of::<Self>() - align_of::<usize>()];
        unsafe { &mut *(v as *mut usize as *mut Self) }
    }
    #[doc = "Get non-atomic access to a `&mut [AtomicUsize]` slice"]
    ///
    /// This is safe because the mutable reference guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```ignore-wasm"]
    #[doc = "use std::sync::atomic::{AtomicUsize, Ordering};"]
    ///
    #[doc = "let mut some_ints = [const { AtomicUsize::new(0) }; 10];"]
    ///
    #[doc =
    "let view: &mut [usize] = AtomicUsize::get_mut_slice(&mut some_ints);"]
    /// assert_eq!(view, [0; 10]);
    /// view
    ///     .iter_mut()
    ///     .enumerate()
    ///     .for_each(|(idx, int)| *int = idx as _);
    ///
    /// std::thread::scope(|s| {
    ///     some_ints
    ///         .iter()
    ///         .enumerate()
    ///         .for_each(|(idx, int)| {
    ///             s.spawn(move || assert_eq!(int.load(Ordering::Relaxed), idx as _));
    ///         })
    /// });
    /// ```
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn get_mut_slice(this: &mut [Self]) -> &mut [usize] {
        unsafe { &mut *(this as *mut [Self] as *mut [usize]) }
    }
    #[doc = "Get atomic access to a `&mut [usize]` slice."]
    ///
    #[doc =
    "**Note:** This function is only available on targets where `AtomicUsize` has the same alignment as `usize`."]
    ///
    /// # Examples
    ///
    #[doc = "```ignore-wasm"]
    #[doc = "use std::sync::atomic::{AtomicUsize, Ordering};"]
    ///
    /// let mut some_ints = [0; 10];
    #[doc = "let a = &*AtomicUsize::from_mut_slice(&mut some_ints);"]
    /// std::thread::scope(|s| {
    ///     for i in 0..a.len() {
    ///         s.spawn(move || a[i].store(i as _, Ordering::Relaxed));
    ///     }
    /// });
    /// for (i, n) in some_ints.into_iter().enumerate() {
    ///     assert_eq!(i, n as usize);
    /// }
    /// ```
    #[inline]
    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn from_mut_slice(v: &mut [usize]) -> &mut [Self] {
        let [] = [(); align_of::<Self>() - align_of::<usize>()];
        unsafe { &mut *(v as *mut [usize] as *mut [Self]) }
    }
    /// Consumes the atomic and returns the contained value.
    ///
    /// This is safe because passing `self` by value guarantees that no other threads are
    /// concurrently accessing the atomic data.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::AtomicUsize;"]
    ///
    #[doc = "let some_var = AtomicUsize::new(5);"]
    /// assert_eq!(some_var.into_inner(), 5);
    /// ```
    #[inline]
    #[stable(feature = "atomic_access", since = "1.15.0")]
    #[rustc_const_stable(feature = "const_atomic_into_inner", since =
    "1.79.0")]
    pub const fn into_inner(self) -> usize { unsafe { transmute(self) } }
    /// Loads a value from the atomic integer.
    ///
    /// `load` takes an [`Ordering`] argument which describes the memory ordering of this operation.
    /// Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Release`] or [`AcqRel`].
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicUsize, Ordering};"]
    ///
    #[doc = "let some_var = AtomicUsize::new(5);"]
    ///
    /// assert_eq!(some_var.load(Ordering::Relaxed), 5);
    /// ```
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    pub const fn load(&self, order: Ordering) -> usize {
        unsafe { atomic_load::<_, false>(self.as_ptr(), order) }
    }
    /// Stores a value into the atomic integer.
    ///
    /// `store` takes an [`Ordering`] argument which describes the memory ordering of this operation.
    ///  Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicUsize, Ordering};"]
    ///
    #[doc = "let some_var = AtomicUsize::new(5);"]
    ///
    /// some_var.store(10, Ordering::Relaxed);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn store(&self, val: usize, order: Ordering) {
        unsafe { atomic_store::<_, false>(self.as_ptr(), val, order); }
    }
    /// Stores a value into the atomic integer, returning the previous value.
    ///
    /// `swap` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`usize`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicUsize, Ordering};"]
    ///
    #[doc = "let some_var = AtomicUsize::new(5);"]
    ///
    /// assert_eq!(some_var.swap(10, Ordering::Relaxed), 5);
    /// ```
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn swap(&self, val: usize, order: Ordering) -> usize {
        unsafe { atomic_swap(self.as_ptr(), val, order) }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    /// The return value is always the previous value. If it is equal to `current`, then the
    /// value was updated.
    ///
    /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
    /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
    /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
    /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
    /// happens, and using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`usize`]."]
    ///
    /// # Migrating to `compare_exchange` and `compare_exchange_weak`
    ///
    /// `compare_and_swap` is equivalent to `compare_exchange` with the following mapping for
    /// memory orderings:
    ///
    /// Original | Success | Failure
    /// -------- | ------- | -------
    /// Relaxed  | Relaxed | Relaxed
    /// Acquire  | Acquire | Acquire
    /// Release  | Release | Relaxed
    /// AcqRel   | AcqRel  | Acquire
    /// SeqCst   | SeqCst  | SeqCst
    ///
    /// `compare_and_swap` and `compare_exchange` also differ in their return type. You can use
    /// `compare_exchange(...).unwrap_or_else(|x| x)` to recover the behavior of `compare_and_swap`,
    /// but in most cases it is more idiomatic to check whether the return value is `Ok` or `Err`
    /// rather than to infer success vs failure based on the value that was read.
    ///
    /// During migration, consider whether it makes sense to use `compare_exchange_weak` instead.
    /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds,
    /// which allows the compiler to generate better assembly code when the compare and swap
    /// is used in a loop.
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicUsize, Ordering};"]
    ///
    #[doc = "let some_var = AtomicUsize::new(5);"]
    ///
    /// assert_eq!(some_var.compare_and_swap(5, 10, Ordering::Relaxed), 5);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    ///
    /// assert_eq!(some_var.compare_and_swap(6, 12, Ordering::Relaxed), 10);
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[deprecated(since = "1.50.0", note =
    "Use `compare_exchange` or `compare_exchange_weak` instead")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_and_swap(&self, current: usize, new: usize,
        order: Ordering) -> usize {
        match self.compare_exchange(current, new, order,
                strongest_failure_ordering(order)) {
            Ok(x) => x,
            Err(x) => x,
        }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    /// The return value is a result indicating whether the new value was written and
    /// containing the previous value. On success this value is guaranteed to be equal to
    /// `current`.
    ///
    /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
    /// ordering of this operation. `success` describes the required ordering for the
    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
    /// `failure` describes the required ordering for the load operation that takes place when
    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`usize`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicUsize, Ordering};"]
    ///
    #[doc = "let some_var = AtomicUsize::new(5);"]
    ///
    /// assert_eq!(some_var.compare_exchange(5, 10,
    ///                                      Ordering::Acquire,
    ///                                      Ordering::Relaxed),
    ///            Ok(5));
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    ///
    /// assert_eq!(some_var.compare_exchange(6, 12,
    ///                                      Ordering::SeqCst,
    ///                                      Ordering::Acquire),
    ///            Err(10));
    /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
    /// ```
    ///
    /// # Considerations
    ///
    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
    /// of CAS operations. In particular, a load of the value followed by a successful
    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
    /// changed the value in the interim! This is usually important when the *equality* check in
    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
    /// does not necessarily imply identity. This is a particularly common case for pointers, as
    /// a pointer holding the same address does not imply that the same object exists at that
    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    #[inline]
    #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_exchange(&self, current: usize, new: usize,
        success: Ordering, failure: Ordering) -> Result<usize, usize> {
        unsafe {
            atomic_compare_exchange(self.as_ptr(), current, new, success,
                failure)
        }
    }
    /// Stores a value into the atomic integer if the current value is the same as
    /// the `current` value.
    ///
    #[doc = "Unlike [`AtomicUsize::compare_exchange`],"]
    /// this function is allowed to spuriously fail even
    /// when the comparison succeeds, which can result in more efficient code on some
    /// platforms. The return value is a result indicating whether the new value was
    /// written and containing the previous value.
    ///
    /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
    /// ordering of this operation. `success` describes the required ordering for the
    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
    /// `failure` describes the required ordering for the load operation that takes place when
    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`usize`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicUsize, Ordering};"]
    ///
    #[doc = "let val = AtomicUsize::new(4);"]
    ///
    /// let mut old = val.load(Ordering::Relaxed);
    /// loop {
    ///     let new = old * 2;
    ///     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
    ///         Ok(_) => break,
    ///         Err(x) => old = x,
    ///     }
    /// }
    /// ```
    ///
    /// # Considerations
    ///
    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
    /// of CAS operations. In particular, a load of the value followed by a successful
    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
    /// changed the value in the interim. This is usually important when the *equality* check in
    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
    /// does not necessarily imply identity. This is a particularly common case for pointers, as
    /// a pointer holding the same address does not imply that the same object exists at that
    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    #[inline]
    #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn compare_exchange_weak(&self, current: usize, new: usize,
        success: Ordering, failure: Ordering) -> Result<usize, usize> {
        unsafe {
            atomic_compare_exchange_weak(self.as_ptr(), current, new, success,
                failure)
        }
    }
    /// Adds to the current value, returning the previous value.
    ///
    /// This operation wraps around on overflow.
    ///
    /// `fetch_add` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`usize`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicUsize, Ordering};"]
    ///
    #[doc = "let foo = AtomicUsize::new(0);"]
    /// assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0);
    /// assert_eq!(foo.load(Ordering::SeqCst), 10);
    /// ```
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_add(&self, val: usize, order: Ordering) -> usize {
        unsafe { atomic_add(self.as_ptr(), val, order) }
    }
    /// Subtracts from the current value, returning the previous value.
    ///
    /// This operation wraps around on overflow.
    ///
    /// `fetch_sub` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`usize`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicUsize, Ordering};"]
    ///
    #[doc = "let foo = AtomicUsize::new(20);"]
    /// assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 20);
    /// assert_eq!(foo.load(Ordering::SeqCst), 10);
    /// ```
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_sub(&self, val: usize, order: Ordering) -> usize {
        unsafe { atomic_sub(self.as_ptr(), val, order) }
    }
    /// Bitwise "and" with the current value.
    ///
    /// Performs a bitwise "and" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_and` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`usize`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicUsize, Ordering};"]
    ///
    #[doc = "let foo = AtomicUsize::new(0b101101);"]
    /// assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b100001);
    /// ```
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_and(&self, val: usize, order: Ordering) -> usize {
        unsafe { atomic_and(self.as_ptr(), val, order) }
    }
    /// Bitwise "nand" with the current value.
    ///
    /// Performs a bitwise "nand" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_nand` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`usize`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicUsize, Ordering};"]
    ///
    #[doc = "let foo = AtomicUsize::new(0x13);"]
    /// assert_eq!(foo.fetch_nand(0x31, Ordering::SeqCst), 0x13);
    /// assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31));
    /// ```
    #[inline]
    #[stable(feature = "atomic_nand", since = "1.27.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_nand(&self, val: usize, order: Ordering) -> usize {
        unsafe { atomic_nand(self.as_ptr(), val, order) }
    }
    /// Bitwise "or" with the current value.
    ///
    /// Performs a bitwise "or" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_or` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`usize`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicUsize, Ordering};"]
    ///
    #[doc = "let foo = AtomicUsize::new(0b101101);"]
    /// assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b111111);
    /// ```
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_or(&self, val: usize, order: Ordering) -> usize {
        unsafe { atomic_or(self.as_ptr(), val, order) }
    }
    /// Bitwise "xor" with the current value.
    ///
    /// Performs a bitwise "xor" operation on the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_xor` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`usize`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicUsize, Ordering};"]
    ///
    #[doc = "let foo = AtomicUsize::new(0b101101);"]
    /// assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101);
    /// assert_eq!(foo.load(Ordering::SeqCst), 0b011110);
    /// ```
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_xor(&self, val: usize, order: Ordering) -> usize {
        unsafe { atomic_xor(self.as_ptr(), val, order) }
    }
    /// An alias for
    #[doc = "[`AtomicUsize::try_update`]"]
    /// .
    #[inline]
    #[stable(feature = "no_more_cas", since = "1.45.0")]
    #[rustc_should_not_be_called_on_const_items]
    #[deprecated(since = "1.99.0", note =
    "renamed to `try_update` for consistency", suggestion = "try_update")]
    pub fn fetch_update<F>(&self, set_order: Ordering, fetch_order: Ordering,
        f: F) -> Result<usize, usize> where F: FnMut(usize) -> Option<usize> {
        self.try_update(set_order, fetch_order, f)
    }
    /// Fetches the value, and applies a function to it that returns an optional
    /// new value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else
    /// `Err(previous_value)`.
    ///
    #[doc = "See also: [`update`](`AtomicUsize::update`)."]
    ///
    /// Note: This may call the function multiple times if the value has been changed from other threads in
    /// the meantime, as long as the function returns `Some(_)`, but the function will have been applied
    /// only once to the stored value.
    ///
    /// `try_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
    /// The first describes the required ordering for when the operation finally succeeds while the second
    /// describes the required ordering for loads. These correspond to the success and failure orderings of
    #[doc = "[`AtomicUsize::compare_exchange`]"]
    /// respectively.
    ///
    /// Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`usize`]."]
    ///
    /// # Considerations
    ///
    /// This method is not magic; it is not provided by the hardware, and does not act like a
    /// critical section or mutex.
    ///
    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
    /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
    /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicUsize, Ordering};"]
    ///
    #[doc = "let x = AtomicUsize::new(7);"]
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(7));
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(7));
    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(8));
    /// assert_eq!(x.load(Ordering::SeqCst), 9);
    /// ```
    #[inline]
    #[stable(feature = "atomic_try_update", since = "1.95.0")]
    #[rustc_should_not_be_called_on_const_items]
    pub fn try_update(&self, set_order: Ordering, fetch_order: Ordering,
        mut f: impl FnMut(usize) -> Option<usize>) -> Result<usize, usize> {
        let mut prev = self.load(fetch_order);
        while let Some(next) = f(prev) {
            match self.compare_exchange_weak(prev, next, set_order,
                    fetch_order) {
                x @ Ok(_) => return x,
                Err(next_prev) => prev = next_prev,
            }
        }
        Err(prev)
    }
    /// Fetches the value, applies a function to it that it return a new value.
    /// The new value is stored and the old value is returned.
    ///
    #[doc = "See also: [`try_update`](`AtomicUsize::try_update`)."]
    ///
    /// Note: This may call the function multiple times if the value has been changed from other threads in
    /// the meantime, but the function will have been applied only once to the stored value.
    ///
    /// `update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
    /// The first describes the required ordering for when the operation finally succeeds while the second
    /// describes the required ordering for loads. These correspond to the success and failure orderings of
    #[doc = "[`AtomicUsize::compare_exchange`]"]
    /// respectively.
    ///
    /// Using [`Acquire`] as success ordering makes the store part
    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`usize`]."]
    ///
    /// # Considerations
    ///
    /// [CAS operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    /// This method is not magic; it is not provided by the hardware, and does not act like a
    /// critical section or mutex.
    ///
    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
    /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
    /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
    ///
    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
    ///
    /// # Examples
    ///
    #[doc = "```rust"]
    #[doc = "use std::sync::atomic::{AtomicUsize, Ordering};"]
    ///
    #[doc = "let x = AtomicUsize::new(7);"]
    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 7);
    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 8);
    /// assert_eq!(x.load(Ordering::SeqCst), 9);
    /// ```
    #[inline]
    #[stable(feature = "atomic_try_update", since = "1.95.0")]
    #[rustc_should_not_be_called_on_const_items]
    pub fn update(&self, set_order: Ordering, fetch_order: Ordering,
        mut f: impl FnMut(usize) -> usize) -> usize {
        let mut prev = self.load(fetch_order);
        loop {
            match self.compare_exchange_weak(prev, f(prev), set_order,
                    fetch_order) {
                Ok(x) => break x,
                Err(next_prev) => prev = next_prev,
            }
        }
    }
    /// Maximum with the current value.
    ///
    /// Finds the maximum of the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_max` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`usize`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicUsize, Ordering};"]
    ///
    #[doc = "let foo = AtomicUsize::new(23);"]
    /// assert_eq!(foo.fetch_max(42, Ordering::SeqCst), 23);
    /// assert_eq!(foo.load(Ordering::SeqCst), 42);
    /// ```
    ///
    /// If you want to obtain the maximum value in one step, you can use the following:
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicUsize, Ordering};"]
    ///
    #[doc = "let foo = AtomicUsize::new(23);"]
    /// let bar = 42;
    /// let max_foo = foo.fetch_max(bar, Ordering::SeqCst).max(bar);
    /// assert!(max_foo == 42);
    /// ```
    #[inline]
    #[stable(feature = "atomic_min_max", since = "1.45.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_max(&self, val: usize, order: Ordering) -> usize {
        unsafe { atomic_umax(self.as_ptr(), val, order) }
    }
    /// Minimum with the current value.
    ///
    /// Finds the minimum of the current value and the argument `val`, and
    /// sets the new value to the result.
    ///
    /// Returns the previous value.
    ///
    /// `fetch_min` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. All ordering modes are possible. Note that using
    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
    /// using [`Release`] makes the load part [`Relaxed`].
    ///
    /// **Note**: This method is only available on platforms that support atomic operations on
    #[doc = "[`usize`]."]
    ///
    /// # Examples
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicUsize, Ordering};"]
    ///
    #[doc = "let foo = AtomicUsize::new(23);"]
    /// assert_eq!(foo.fetch_min(42, Ordering::Relaxed), 23);
    /// assert_eq!(foo.load(Ordering::Relaxed), 23);
    /// assert_eq!(foo.fetch_min(22, Ordering::Relaxed), 23);
    /// assert_eq!(foo.load(Ordering::Relaxed), 22);
    /// ```
    ///
    /// If you want to obtain the minimum value in one step, you can use the following:
    ///
    #[doc = "```"]
    #[doc = "use std::sync::atomic::{AtomicUsize, Ordering};"]
    ///
    #[doc = "let foo = AtomicUsize::new(23);"]
    /// let bar = 12;
    /// let min_foo = foo.fetch_min(bar, Ordering::SeqCst).min(bar);
    /// assert_eq!(min_foo, 12);
    /// ```
    #[inline]
    #[stable(feature = "atomic_min_max", since = "1.45.0")]
    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
    #[rustc_should_not_be_called_on_const_items]
    pub const fn fetch_min(&self, val: usize, order: Ordering) -> usize {
        unsafe { atomic_umin(self.as_ptr(), val, order) }
    }
    /// Returns a mutable pointer to the underlying integer.
    ///
    /// Doing non-atomic reads and writes on the resulting integer can be a data race.
    /// This method is mostly useful for FFI, where the function signature may use
    #[doc = "`*mut usize` instead of `&AtomicUsize`."]
    ///
    /// Returning an `*mut` pointer from a shared reference to this atomic is safe because the
    /// atomic types work with interior mutability. All modifications of an atomic change the value
    /// through a shared reference, and can do so safely as long as they use atomic operations. Any
    /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the
    /// requirements of the [memory model].
    ///
    /// # Examples
    ///
    /// ```ignore (extern-declaration)
    /// # fn main() {
    #[doc = "use std::sync::atomic::AtomicUsize;"]
    ///
    /// extern "C" {
    #[doc = "    fn my_atomic_op(arg: *mut usize);"]
    /// }
    ///
    #[doc = "let atomic = AtomicUsize::new(1);"]
    ///
    /// // SAFETY: Safe as long as `my_atomic_op` is atomic.
    /// unsafe {
    ///     my_atomic_op(atomic.as_ptr());
    /// }
    /// # }
    /// ```
    ///
    /// [memory model]: self#memory-model-for-atomic-accesses
    #[inline]
    #[stable(feature = "atomic_as_ptr", since = "1.70.0")]
    #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")]
    #[rustc_never_returns_null_ptr]
    pub const fn as_ptr(&self) -> *mut usize { self.v.get().cast() }
}
/// An [`AtomicIsize`] initialized to `0`.
#[stable(feature = "rust1", since = "1.0.0")]
#[deprecated(since = "1.34.0", note = "the `new` function is now preferred",
suggestion = "AtomicIsize::new(0)",)]
#[expect(clippy :: declare_interior_mutable_const, reason =
"legacy atomic initializer")]
pub const ATOMIC_ISIZE_INIT: AtomicIsize = AtomicIsize::new(0);
/// An [`AtomicUsize`] initialized to `0`.
#[stable(feature = "rust1", since = "1.0.0")]
#[deprecated(since = "1.34.0", note = "the `new` function is now preferred",
suggestion = "AtomicUsize::new(0)",)]
#[expect(clippy :: declare_interior_mutable_const, reason =
"legacy atomic initializer")]
pub const ATOMIC_USIZE_INIT: AtomicUsize = AtomicUsize::new(0);atomic_int_ptr_sized! {
3961    "16" 2
3962    "32" 4
3963    "64" 8
3964}
3965
3966#[inline]
3967#[cfg(target_has_atomic)]
3968const fn strongest_failure_ordering(order: Ordering) -> Ordering {
3969    match order {
3970        Release => Relaxed,
3971        Relaxed => Relaxed,
3972        SeqCst => SeqCst,
3973        Acquire => Acquire,
3974        AcqRel => Acquire,
3975    }
3976}
3977
3978#[inline]
3979#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3980#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3981const unsafe fn atomic_store<T: Copy, const VOLATILE: bool>(dst: *mut T, val: T, order: Ordering) {
3982    // SAFETY: the caller must uphold the safety contract for `atomic_store`.
3983    unsafe {
3984        match order {
3985            Relaxed => intrinsics::atomic_store::<T, { AO::Relaxed }, VOLATILE>(dst, val),
3986            Release => intrinsics::atomic_store::<T, { AO::Release }, VOLATILE>(dst, val),
3987            SeqCst => intrinsics::atomic_store::<T, { AO::SeqCst }, VOLATILE>(dst, val),
3988            Acquire => {
    crate::panicking::panic_fmt(format_args!("there is no such thing as an acquire store"));
}panic!("there is no such thing as an acquire store"),
3989            AcqRel => {
    crate::panicking::panic_fmt(format_args!("there is no such thing as an acquire-release store"));
}panic!("there is no such thing as an acquire-release store"),
3990        }
3991    }
3992}
3993
3994#[inline]
3995#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3996#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3997const unsafe fn atomic_load<T: Copy, const VOLATILE: bool>(dst: *const T, order: Ordering) -> T {
3998    // SAFETY: the caller must uphold the safety contract for `atomic_load`.
3999    unsafe {
4000        match order {
4001            Relaxed => intrinsics::atomic_load::<T, { AO::Relaxed }, VOLATILE>(dst),
4002            Acquire => intrinsics::atomic_load::<T, { AO::Acquire }, VOLATILE>(dst),
4003            SeqCst => intrinsics::atomic_load::<T, { AO::SeqCst }, VOLATILE>(dst),
4004            Release => {
    crate::panicking::panic_fmt(format_args!("there is no such thing as a release load"));
}panic!("there is no such thing as a release load"),
4005            AcqRel => {
    crate::panicking::panic_fmt(format_args!("there is no such thing as an acquire-release load"));
}panic!("there is no such thing as an acquire-release load"),
4006        }
4007    }
4008}
4009
4010#[inline]
4011#[cfg(target_has_atomic)]
4012#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4013#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4014const unsafe fn atomic_swap<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
4015    // SAFETY: the caller must uphold the safety contract for `atomic_swap`.
4016    unsafe {
4017        match order {
4018            Relaxed => intrinsics::atomic_xchg::<T, { AO::Relaxed }>(dst, val),
4019            Acquire => intrinsics::atomic_xchg::<T, { AO::Acquire }>(dst, val),
4020            Release => intrinsics::atomic_xchg::<T, { AO::Release }>(dst, val),
4021            AcqRel => intrinsics::atomic_xchg::<T, { AO::AcqRel }>(dst, val),
4022            SeqCst => intrinsics::atomic_xchg::<T, { AO::SeqCst }>(dst, val),
4023        }
4024    }
4025}
4026
4027/// Returns the previous value (like __sync_fetch_and_add).
4028#[inline]
4029#[cfg(target_has_atomic)]
4030#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4031#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4032const unsafe fn atomic_add<T: Copy, U: Copy>(dst: *mut T, val: U, order: Ordering) -> T {
4033    // SAFETY: the caller must uphold the safety contract for `atomic_add`.
4034    unsafe {
4035        match order {
4036            Relaxed => intrinsics::atomic_xadd::<T, U, { AO::Relaxed }>(dst, val),
4037            Acquire => intrinsics::atomic_xadd::<T, U, { AO::Acquire }>(dst, val),
4038            Release => intrinsics::atomic_xadd::<T, U, { AO::Release }>(dst, val),
4039            AcqRel => intrinsics::atomic_xadd::<T, U, { AO::AcqRel }>(dst, val),
4040            SeqCst => intrinsics::atomic_xadd::<T, U, { AO::SeqCst }>(dst, val),
4041        }
4042    }
4043}
4044
4045/// Returns the previous value (like __sync_fetch_and_sub).
4046#[inline]
4047#[cfg(target_has_atomic)]
4048#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4049#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4050const unsafe fn atomic_sub<T: Copy, U: Copy>(dst: *mut T, val: U, order: Ordering) -> T {
4051    // SAFETY: the caller must uphold the safety contract for `atomic_sub`.
4052    unsafe {
4053        match order {
4054            Relaxed => intrinsics::atomic_xsub::<T, U, { AO::Relaxed }>(dst, val),
4055            Acquire => intrinsics::atomic_xsub::<T, U, { AO::Acquire }>(dst, val),
4056            Release => intrinsics::atomic_xsub::<T, U, { AO::Release }>(dst, val),
4057            AcqRel => intrinsics::atomic_xsub::<T, U, { AO::AcqRel }>(dst, val),
4058            SeqCst => intrinsics::atomic_xsub::<T, U, { AO::SeqCst }>(dst, val),
4059        }
4060    }
4061}
4062
4063/// Publicly exposed for stdarch; nobody else should use this.
4064#[inline]
4065#[cfg(target_has_atomic)]
4066#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4067#[unstable(feature = "core_intrinsics", issue = "none")]
4068#[doc(hidden)]
4069#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4070pub const unsafe fn atomic_compare_exchange<T: Copy>(
4071    dst: *mut T,
4072    old: T,
4073    new: T,
4074    success: Ordering,
4075    failure: Ordering,
4076) -> Result<T, T> {
4077    // SAFETY: the caller must uphold the safety contract for `atomic_compare_exchange`.
4078    let (val, ok) = unsafe {
4079        match (success, failure) {
4080            (Relaxed, Relaxed) => {
4081                intrinsics::atomic_cxchg::<T, { AO::Relaxed }, { AO::Relaxed }>(dst, old, new)
4082            }
4083            (Relaxed, Acquire) => {
4084                intrinsics::atomic_cxchg::<T, { AO::Relaxed }, { AO::Acquire }>(dst, old, new)
4085            }
4086            (Relaxed, SeqCst) => {
4087                intrinsics::atomic_cxchg::<T, { AO::Relaxed }, { AO::SeqCst }>(dst, old, new)
4088            }
4089            (Acquire, Relaxed) => {
4090                intrinsics::atomic_cxchg::<T, { AO::Acquire }, { AO::Relaxed }>(dst, old, new)
4091            }
4092            (Acquire, Acquire) => {
4093                intrinsics::atomic_cxchg::<T, { AO::Acquire }, { AO::Acquire }>(dst, old, new)
4094            }
4095            (Acquire, SeqCst) => {
4096                intrinsics::atomic_cxchg::<T, { AO::Acquire }, { AO::SeqCst }>(dst, old, new)
4097            }
4098            (Release, Relaxed) => {
4099                intrinsics::atomic_cxchg::<T, { AO::Release }, { AO::Relaxed }>(dst, old, new)
4100            }
4101            (Release, Acquire) => {
4102                intrinsics::atomic_cxchg::<T, { AO::Release }, { AO::Acquire }>(dst, old, new)
4103            }
4104            (Release, SeqCst) => {
4105                intrinsics::atomic_cxchg::<T, { AO::Release }, { AO::SeqCst }>(dst, old, new)
4106            }
4107            (AcqRel, Relaxed) => {
4108                intrinsics::atomic_cxchg::<T, { AO::AcqRel }, { AO::Relaxed }>(dst, old, new)
4109            }
4110            (AcqRel, Acquire) => {
4111                intrinsics::atomic_cxchg::<T, { AO::AcqRel }, { AO::Acquire }>(dst, old, new)
4112            }
4113            (AcqRel, SeqCst) => {
4114                intrinsics::atomic_cxchg::<T, { AO::AcqRel }, { AO::SeqCst }>(dst, old, new)
4115            }
4116            (SeqCst, Relaxed) => {
4117                intrinsics::atomic_cxchg::<T, { AO::SeqCst }, { AO::Relaxed }>(dst, old, new)
4118            }
4119            (SeqCst, Acquire) => {
4120                intrinsics::atomic_cxchg::<T, { AO::SeqCst }, { AO::Acquire }>(dst, old, new)
4121            }
4122            (SeqCst, SeqCst) => {
4123                intrinsics::atomic_cxchg::<T, { AO::SeqCst }, { AO::SeqCst }>(dst, old, new)
4124            }
4125            (_, AcqRel) => {
    crate::panicking::panic_fmt(format_args!("there is no such thing as an acquire-release failure ordering"));
}panic!("there is no such thing as an acquire-release failure ordering"),
4126            (_, Release) => {
    crate::panicking::panic_fmt(format_args!("there is no such thing as a release failure ordering"));
}panic!("there is no such thing as a release failure ordering"),
4127        }
4128    };
4129    if ok { Ok(val) } else { Err(val) }
4130}
4131
4132#[inline]
4133#[cfg(target_has_atomic)]
4134#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4135#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4136const unsafe fn atomic_compare_exchange_weak<T: Copy>(
4137    dst: *mut T,
4138    old: T,
4139    new: T,
4140    success: Ordering,
4141    failure: Ordering,
4142) -> Result<T, T> {
4143    // SAFETY: the caller must uphold the safety contract for `atomic_compare_exchange_weak`.
4144    let (val, ok) = unsafe {
4145        match (success, failure) {
4146            (Relaxed, Relaxed) => {
4147                intrinsics::atomic_cxchgweak::<T, { AO::Relaxed }, { AO::Relaxed }>(dst, old, new)
4148            }
4149            (Relaxed, Acquire) => {
4150                intrinsics::atomic_cxchgweak::<T, { AO::Relaxed }, { AO::Acquire }>(dst, old, new)
4151            }
4152            (Relaxed, SeqCst) => {
4153                intrinsics::atomic_cxchgweak::<T, { AO::Relaxed }, { AO::SeqCst }>(dst, old, new)
4154            }
4155            (Acquire, Relaxed) => {
4156                intrinsics::atomic_cxchgweak::<T, { AO::Acquire }, { AO::Relaxed }>(dst, old, new)
4157            }
4158            (Acquire, Acquire) => {
4159                intrinsics::atomic_cxchgweak::<T, { AO::Acquire }, { AO::Acquire }>(dst, old, new)
4160            }
4161            (Acquire, SeqCst) => {
4162                intrinsics::atomic_cxchgweak::<T, { AO::Acquire }, { AO::SeqCst }>(dst, old, new)
4163            }
4164            (Release, Relaxed) => {
4165                intrinsics::atomic_cxchgweak::<T, { AO::Release }, { AO::Relaxed }>(dst, old, new)
4166            }
4167            (Release, Acquire) => {
4168                intrinsics::atomic_cxchgweak::<T, { AO::Release }, { AO::Acquire }>(dst, old, new)
4169            }
4170            (Release, SeqCst) => {
4171                intrinsics::atomic_cxchgweak::<T, { AO::Release }, { AO::SeqCst }>(dst, old, new)
4172            }
4173            (AcqRel, Relaxed) => {
4174                intrinsics::atomic_cxchgweak::<T, { AO::AcqRel }, { AO::Relaxed }>(dst, old, new)
4175            }
4176            (AcqRel, Acquire) => {
4177                intrinsics::atomic_cxchgweak::<T, { AO::AcqRel }, { AO::Acquire }>(dst, old, new)
4178            }
4179            (AcqRel, SeqCst) => {
4180                intrinsics::atomic_cxchgweak::<T, { AO::AcqRel }, { AO::SeqCst }>(dst, old, new)
4181            }
4182            (SeqCst, Relaxed) => {
4183                intrinsics::atomic_cxchgweak::<T, { AO::SeqCst }, { AO::Relaxed }>(dst, old, new)
4184            }
4185            (SeqCst, Acquire) => {
4186                intrinsics::atomic_cxchgweak::<T, { AO::SeqCst }, { AO::Acquire }>(dst, old, new)
4187            }
4188            (SeqCst, SeqCst) => {
4189                intrinsics::atomic_cxchgweak::<T, { AO::SeqCst }, { AO::SeqCst }>(dst, old, new)
4190            }
4191            (_, AcqRel) => {
    crate::panicking::panic_fmt(format_args!("there is no such thing as an acquire-release failure ordering"));
}panic!("there is no such thing as an acquire-release failure ordering"),
4192            (_, Release) => {
    crate::panicking::panic_fmt(format_args!("there is no such thing as a release failure ordering"));
}panic!("there is no such thing as a release failure ordering"),
4193        }
4194    };
4195    if ok { Ok(val) } else { Err(val) }
4196}
4197
4198#[inline]
4199#[cfg(target_has_atomic)]
4200#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4201#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4202const unsafe fn atomic_and<T: Copy, U: Copy>(dst: *mut T, val: U, order: Ordering) -> T {
4203    // SAFETY: the caller must uphold the safety contract for `atomic_and`
4204    unsafe {
4205        match order {
4206            Relaxed => intrinsics::atomic_and::<T, U, { AO::Relaxed }>(dst, val),
4207            Acquire => intrinsics::atomic_and::<T, U, { AO::Acquire }>(dst, val),
4208            Release => intrinsics::atomic_and::<T, U, { AO::Release }>(dst, val),
4209            AcqRel => intrinsics::atomic_and::<T, U, { AO::AcqRel }>(dst, val),
4210            SeqCst => intrinsics::atomic_and::<T, U, { AO::SeqCst }>(dst, val),
4211        }
4212    }
4213}
4214
4215#[inline]
4216#[cfg(target_has_atomic)]
4217#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4218#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4219const unsafe fn atomic_nand<T: Copy, U: Copy>(dst: *mut T, val: U, order: Ordering) -> T {
4220    // SAFETY: the caller must uphold the safety contract for `atomic_nand`
4221    unsafe {
4222        match order {
4223            Relaxed => intrinsics::atomic_nand::<T, U, { AO::Relaxed }>(dst, val),
4224            Acquire => intrinsics::atomic_nand::<T, U, { AO::Acquire }>(dst, val),
4225            Release => intrinsics::atomic_nand::<T, U, { AO::Release }>(dst, val),
4226            AcqRel => intrinsics::atomic_nand::<T, U, { AO::AcqRel }>(dst, val),
4227            SeqCst => intrinsics::atomic_nand::<T, U, { AO::SeqCst }>(dst, val),
4228        }
4229    }
4230}
4231
4232#[inline]
4233#[cfg(target_has_atomic)]
4234#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4235#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4236const unsafe fn atomic_or<T: Copy, U: Copy>(dst: *mut T, val: U, order: Ordering) -> T {
4237    // SAFETY: the caller must uphold the safety contract for `atomic_or`
4238    unsafe {
4239        match order {
4240            SeqCst => intrinsics::atomic_or::<T, U, { AO::SeqCst }>(dst, val),
4241            Acquire => intrinsics::atomic_or::<T, U, { AO::Acquire }>(dst, val),
4242            Release => intrinsics::atomic_or::<T, U, { AO::Release }>(dst, val),
4243            AcqRel => intrinsics::atomic_or::<T, U, { AO::AcqRel }>(dst, val),
4244            Relaxed => intrinsics::atomic_or::<T, U, { AO::Relaxed }>(dst, val),
4245        }
4246    }
4247}
4248
4249#[inline]
4250#[cfg(target_has_atomic)]
4251#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4252#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4253const unsafe fn atomic_xor<T: Copy, U: Copy>(dst: *mut T, val: U, order: Ordering) -> T {
4254    // SAFETY: the caller must uphold the safety contract for `atomic_xor`
4255    unsafe {
4256        match order {
4257            SeqCst => intrinsics::atomic_xor::<T, U, { AO::SeqCst }>(dst, val),
4258            Acquire => intrinsics::atomic_xor::<T, U, { AO::Acquire }>(dst, val),
4259            Release => intrinsics::atomic_xor::<T, U, { AO::Release }>(dst, val),
4260            AcqRel => intrinsics::atomic_xor::<T, U, { AO::AcqRel }>(dst, val),
4261            Relaxed => intrinsics::atomic_xor::<T, U, { AO::Relaxed }>(dst, val),
4262        }
4263    }
4264}
4265
4266/// Updates `*dst` to the max value of `val` and the old value (signed comparison)
4267#[inline]
4268#[cfg(target_has_atomic)]
4269#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4270#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4271const unsafe fn atomic_max<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
4272    // SAFETY: the caller must uphold the safety contract for `atomic_max`
4273    unsafe {
4274        match order {
4275            Relaxed => intrinsics::atomic_max::<T, { AO::Relaxed }>(dst, val),
4276            Acquire => intrinsics::atomic_max::<T, { AO::Acquire }>(dst, val),
4277            Release => intrinsics::atomic_max::<T, { AO::Release }>(dst, val),
4278            AcqRel => intrinsics::atomic_max::<T, { AO::AcqRel }>(dst, val),
4279            SeqCst => intrinsics::atomic_max::<T, { AO::SeqCst }>(dst, val),
4280        }
4281    }
4282}
4283
4284/// Updates `*dst` to the min value of `val` and the old value (signed comparison)
4285#[inline]
4286#[cfg(target_has_atomic)]
4287#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4288#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4289const unsafe fn atomic_min<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
4290    // SAFETY: the caller must uphold the safety contract for `atomic_min`
4291    unsafe {
4292        match order {
4293            Relaxed => intrinsics::atomic_min::<T, { AO::Relaxed }>(dst, val),
4294            Acquire => intrinsics::atomic_min::<T, { AO::Acquire }>(dst, val),
4295            Release => intrinsics::atomic_min::<T, { AO::Release }>(dst, val),
4296            AcqRel => intrinsics::atomic_min::<T, { AO::AcqRel }>(dst, val),
4297            SeqCst => intrinsics::atomic_min::<T, { AO::SeqCst }>(dst, val),
4298        }
4299    }
4300}
4301
4302/// Updates `*dst` to the max value of `val` and the old value (unsigned comparison)
4303#[inline]
4304#[cfg(target_has_atomic)]
4305#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4306#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4307const unsafe fn atomic_umax<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
4308    // SAFETY: the caller must uphold the safety contract for `atomic_umax`
4309    unsafe {
4310        match order {
4311            Relaxed => intrinsics::atomic_umax::<T, { AO::Relaxed }>(dst, val),
4312            Acquire => intrinsics::atomic_umax::<T, { AO::Acquire }>(dst, val),
4313            Release => intrinsics::atomic_umax::<T, { AO::Release }>(dst, val),
4314            AcqRel => intrinsics::atomic_umax::<T, { AO::AcqRel }>(dst, val),
4315            SeqCst => intrinsics::atomic_umax::<T, { AO::SeqCst }>(dst, val),
4316        }
4317    }
4318}
4319
4320/// Updates `*dst` to the min value of `val` and the old value (unsigned comparison)
4321#[inline]
4322#[cfg(target_has_atomic)]
4323#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4324#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4325const unsafe fn atomic_umin<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
4326    // SAFETY: the caller must uphold the safety contract for `atomic_umin`
4327    unsafe {
4328        match order {
4329            Relaxed => intrinsics::atomic_umin::<T, { AO::Relaxed }>(dst, val),
4330            Acquire => intrinsics::atomic_umin::<T, { AO::Acquire }>(dst, val),
4331            Release => intrinsics::atomic_umin::<T, { AO::Release }>(dst, val),
4332            AcqRel => intrinsics::atomic_umin::<T, { AO::AcqRel }>(dst, val),
4333            SeqCst => intrinsics::atomic_umin::<T, { AO::SeqCst }>(dst, val),
4334        }
4335    }
4336}
4337
4338/// An atomic fence.
4339///
4340/// Fences create synchronization between themselves and atomic operations or fences in other
4341/// threads. It can be helpful to think of a fence as preventing the compiler and CPU from
4342/// reordering certain types of memory operations around it, but that is a simplified model which
4343/// fails to capture some of the nuances.
4344///
4345/// There are 3 different ways to use an atomic fence:
4346///
4347/// - atomic - fence synchronization: an atomic operation with (at least) [`Release`] ordering
4348///   semantics synchronizes with a fence with (at least) [`Acquire`] ordering semantics.
4349/// - fence - atomic synchronization: a fence with (at least) [`Release`] ordering semantics
4350///   synchronizes with an atomic operation with (at least) [`Acquire`] ordering semantics.
4351/// - fence - fence synchronization: a fence with (at least) [`Release`] ordering semantics
4352///   synchronizes with a fence with (at least) [`Acquire`] ordering semantics.
4353///
4354/// These 3 ways complement the regular, fence-less, atomic - atomic synchronization.
4355///
4356/// ## Atomic - Fence
4357///
4358/// An atomic operation on one thread will synchronize with a fence on another thread when:
4359///
4360/// -   on thread 1:
4361///     -   an atomic operation 'X' with (at least) [`Release`] ordering semantics on some atomic
4362///         object 'm',
4363///
4364/// -   is paired on thread 2 with:
4365///     -   an atomic read 'Y' with any order on 'm',
4366///     -   followed by a fence 'B' with (at least) [`Acquire`] ordering semantics.
4367///
4368/// This provides a happens-before dependence between X and B.
4369///
4370/// ```text
4371///     Thread 1                                          Thread 2
4372///
4373/// m.store(3, Release); X ---------
4374///                                |
4375///                                |
4376///                                -------------> Y  if m.load(Relaxed) == 3 {
4377///                                               B      fence(Acquire);
4378///                                                      ...
4379///                                                  }
4380/// ```
4381///
4382/// ## Fence - Atomic
4383///
4384/// A fence on one thread will synchronize with an atomic operation on another thread when:
4385///
4386/// -   on thread:
4387///     -   a fence 'A' with (at least) [`Release`] ordering semantics,
4388///     -   followed by an atomic write 'X' with any ordering on some atomic object 'm',
4389///
4390/// -   is paired on thread 2 with:
4391///     -   an atomic operation 'Y' with (at least) [`Acquire`] ordering semantics.
4392///
4393/// This provides a happens-before dependence between A and Y.
4394///
4395/// ```text
4396///     Thread 1                                          Thread 2
4397///
4398/// fence(Release);      A
4399/// m.store(3, Relaxed); X ---------
4400///                                |
4401///                                |
4402///                                -------------> Y  if m.load(Acquire) == 3 {
4403///                                                      ...
4404///                                                  }
4405/// ```
4406///
4407/// ## Fence - Fence
4408///
4409/// A fence on one thread will synchronize with a fence on another thread when:
4410///
4411/// -   on thread 1:
4412///     -   a fence 'A' which has (at least) [`Release`] ordering semantics,
4413///     -   followed by an atomic write 'X' with any ordering on some atomic object 'm',
4414///
4415/// -   is paired on thread 2 with:
4416///     -   an atomic read 'Y' with any ordering on 'm',
4417///     -   followed by a fence 'B' with (at least) [`Acquire`] ordering semantics.
4418///
4419/// This provides a happens-before dependence between A and B.
4420///
4421/// ```text
4422///     Thread 1                                          Thread 2
4423///
4424/// fence(Release);      A --------------
4425/// m.store(3, Relaxed); X ---------    |
4426///                                |    |
4427///                                |    |
4428///                                -------------> Y  if m.load(Relaxed) == 3 {
4429///                                     |-------> B      fence(Acquire);
4430///                                                      ...
4431///                                                  }
4432/// ```
4433///
4434/// ## Mandatory Atomic
4435///
4436/// Note that in the examples above, it is crucial that the access to `m` are atomic. Fences cannot
4437/// be used to establish synchronization between non-atomic accesses in different threads. However,
4438/// thanks to the happens-before relationship, any non-atomic access that happen-before the atomic
4439/// operation or fence with (at least) [`Release`] ordering semantics are now also properly
4440/// synchronized with any non-atomic accesses that happen-after the atomic operation or fence with
4441/// (at least) [`Acquire`] ordering semantics.
4442///
4443/// ## Memory Ordering
4444///
4445/// A fence which has [`SeqCst`] ordering, in addition to having both [`Acquire`] and [`Release`]
4446/// semantics, participates in the global program order of the other [`SeqCst`] operations and/or
4447/// fences.
4448///
4449/// Accepts [`Acquire`], [`Release`], [`AcqRel`] and [`SeqCst`] orderings.
4450///
4451/// # Panics
4452///
4453/// Panics if `order` is [`Relaxed`].
4454///
4455/// # Examples
4456///
4457/// ```
4458/// use std::sync::atomic::AtomicBool;
4459/// use std::sync::atomic::fence;
4460/// use std::sync::atomic::Ordering;
4461///
4462/// // A mutual exclusion primitive based on spinlock.
4463/// pub struct Mutex {
4464///     flag: AtomicBool,
4465/// }
4466///
4467/// impl Mutex {
4468///     pub fn new() -> Mutex {
4469///         Mutex {
4470///             flag: AtomicBool::new(false),
4471///         }
4472///     }
4473///
4474///     pub fn lock(&self) {
4475///         // Wait until the old value is `false`.
4476///         while self
4477///             .flag
4478///             .compare_exchange_weak(false, true, Ordering::Relaxed, Ordering::Relaxed)
4479///             .is_err()
4480///         {}
4481///         // This fence synchronizes-with store in `unlock`.
4482///         fence(Ordering::Acquire);
4483///     }
4484///
4485///     pub fn unlock(&self) {
4486///         self.flag.store(false, Ordering::Release);
4487///     }
4488/// }
4489/// ```
4490#[inline]
4491#[stable(feature = "rust1", since = "1.0.0")]
4492#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4493#[rustc_diagnostic_item = "fence"]
4494#[doc(alias = "atomic_thread_fence")]
4495#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4496pub const fn fence(order: Ordering) {
4497    // SAFETY: using an atomic fence is safe.
4498    unsafe {
4499        match order {
4500            Acquire => intrinsics::atomic_fence::<{ AO::Acquire }>(),
4501            Release => intrinsics::atomic_fence::<{ AO::Release }>(),
4502            AcqRel => intrinsics::atomic_fence::<{ AO::AcqRel }>(),
4503            SeqCst => intrinsics::atomic_fence::<{ AO::SeqCst }>(),
4504            Relaxed => {
    crate::panicking::panic_fmt(format_args!("there is no such thing as a relaxed fence"));
}panic!("there is no such thing as a relaxed fence"),
4505        }
4506    }
4507}
4508
4509/// An atomic fence for synchronization within a single thread.
4510///
4511/// Like [`fence`], this function establishes synchronization with other atomic operations and
4512/// fences. However, unlike [`fence`], `compiler_fence` only establishes synchronization with
4513/// operations *in the same thread*. This may at first sound rather useless, since code within a
4514/// thread is typically already totally ordered and does not need any further synchronization.
4515/// However, there are cases where code can run on the same thread without being synchronized:
4516/// - The most common case is that of a *signal handler*: a signal handler runs in the same thread
4517///   as the code it interrupted, but it is not synchronized with that code. `compiler_fence`
4518///   can be used to establish synchronization between a thread and its signal handler, the same way
4519///   that `fence` can be used to establish synchronization across threads.
4520/// - Similar situations can arise in embedded programming with interrupt handlers, or in custom
4521///   implementations of preemptive green threads. In general, `compiler_fence` can establish
4522///   synchronization with code that is guaranteed to run on the same hardware CPU.
4523///
4524/// See [`fence`] for how a fence can be used to achieve synchronization. Note that just like
4525/// [`fence`], synchronization still requires atomic operations to be used in both threads -- it is
4526/// not possible to perform synchronization entirely with fences and non-atomic operations.
4527///
4528/// `compiler_fence` does not emit any machine code. However, note that `compiler_fence` is also
4529/// *not* a "compiler barrier". It can be helpful to think of a `compiler_fence` as preventing the
4530/// compiler from reordering certain types of memory operations around it, but that is a simplified
4531/// model which fails to capture some of the nuances. The only actual guarantee made by
4532/// `compiler_fence` is establishing synchronization with signal handlers and similar kinds of code,
4533/// under the rules described in the [`fence`] documentation.
4534///
4535/// `compiler_fence` corresponds to [`atomic_signal_fence`] in C and C++.
4536///
4537/// [`atomic_signal_fence`]: https://en.cppreference.com/w/cpp/atomic/atomic_signal_fence
4538///
4539/// # Panics
4540///
4541/// Panics if `order` is [`Relaxed`].
4542///
4543/// # Examples
4544///
4545/// Without the two `compiler_fence` calls, the read of `IMPORTANT_VARIABLE` in `signal_handler`
4546/// is *undefined behavior* due to a data race, despite everything happening in a single thread.
4547/// This is because the signal handler is considered to run concurrently with its associated
4548/// thread, and explicit synchronization is required to pass data between a thread and its
4549/// signal handler. The code below uses two `compiler_fence` calls to establish the usual
4550/// release-acquire synchronization pattern (see [`fence`] for an image).
4551///
4552/// ```
4553/// use std::sync::atomic::AtomicBool;
4554/// use std::sync::atomic::Ordering;
4555/// use std::sync::atomic::compiler_fence;
4556///
4557/// static mut IMPORTANT_VARIABLE: usize = 0;
4558/// static IS_READY: AtomicBool = AtomicBool::new(false);
4559///
4560/// fn main() {
4561///     unsafe { IMPORTANT_VARIABLE = 42 };
4562///     // Marks earlier writes as being released with future relaxed stores.
4563///     compiler_fence(Ordering::Release);
4564///     IS_READY.store(true, Ordering::Relaxed);
4565/// }
4566///
4567/// fn signal_handler() {
4568///     if IS_READY.load(Ordering::Relaxed) {
4569///         // Acquires writes that were released with relaxed stores that we read from.
4570///         compiler_fence(Ordering::Acquire);
4571///         assert_eq!(unsafe { IMPORTANT_VARIABLE }, 42);
4572///     }
4573/// }
4574/// ```
4575#[inline]
4576#[stable(feature = "compiler_fences", since = "1.21.0")]
4577#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4578#[rustc_diagnostic_item = "compiler_fence"]
4579#[doc(alias = "atomic_signal_fence")]
4580#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4581pub const fn compiler_fence(order: Ordering) {
4582    // SAFETY: using an atomic fence is safe.
4583    unsafe {
4584        match order {
4585            Acquire => intrinsics::atomic_singlethreadfence::<{ AO::Acquire }>(),
4586            Release => intrinsics::atomic_singlethreadfence::<{ AO::Release }>(),
4587            AcqRel => intrinsics::atomic_singlethreadfence::<{ AO::AcqRel }>(),
4588            SeqCst => intrinsics::atomic_singlethreadfence::<{ AO::SeqCst }>(),
4589            Relaxed => {
    crate::panicking::panic_fmt(format_args!("there is no such thing as a relaxed fence"));
}panic!("there is no such thing as a relaxed fence"),
4590        }
4591    }
4592}
4593
4594#[cfg(target_has_atomic_load_store = "8")]
4595#[stable(feature = "atomic_debug", since = "1.3.0")]
4596impl fmt::Debug for AtomicBool {
4597    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4598        fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)
4599    }
4600}
4601
4602#[cfg(target_has_atomic_load_store = "ptr")]
4603#[stable(feature = "atomic_debug", since = "1.3.0")]
4604impl<T> fmt::Debug for AtomicPtr<T> {
4605    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4606        fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)
4607    }
4608}
4609
4610#[cfg(target_has_atomic_load_store = "ptr")]
4611#[stable(feature = "atomic_pointer", since = "1.24.0")]
4612impl<T> fmt::Pointer for AtomicPtr<T> {
4613    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4614        fmt::Pointer::fmt(&self.load(Ordering::Relaxed), f)
4615    }
4616}
4617
4618/// Signals the processor that it is inside a busy-wait spin-loop ("spin lock").
4619///
4620/// This function is deprecated in favor of [`hint::spin_loop`].
4621///
4622/// [`hint::spin_loop`]: crate::hint::spin_loop
4623#[inline]
4624#[stable(feature = "spin_loop_hint", since = "1.24.0")]
4625#[deprecated(since = "1.51.0", note = "use hint::spin_loop instead")]
4626pub fn spin_loop_hint() {
4627    spin_loop()
4628}