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 targets (`thumbv6m-*`) only provide `load` and `store` operations, and do
139//!   not support Compare and Swap (CAS) operations, such as `swap`,
140//!   `fetch_add`, etc. Full CAS support is available on ARMv7-M and ARMv8-M
141//!   (`thumbv7m-*`, `thumbv7em*`, `thumbv8m.base-*` and `thumbv8m.main-*`).
142//!
143//! [use the kernel]: https://www.kernel.org/doc/Documentation/arm/kernel_user_helpers.txt
144//!
145//! Note that future platforms may be added that also do not have support for
146//! some atomic operations. Maximally portable code will want to be careful
147//! about which atomic types are used. `AtomicUsize` and `AtomicIsize` are
148//! generally the most portable, but even then they're not available everywhere.
149//! For reference, the `std` library requires `AtomicBool`s and pointer-sized atomics, although
150//! `core` does not.
151//!
152//! The `#[cfg(target_has_atomic)]` attribute can be used to conditionally
153//! compile based on the target's supported bit widths. It is a key-value
154//! option set for each supported size, with values "8", "16", "32", "64",
155//! "128", and "ptr" for pointer-sized atomics.
156//!
157//! [lock-free]: https://en.wikipedia.org/wiki/Non-blocking_algorithm
158//!
159//! # Atomic accesses to read-only memory
160//!
161//! In general, *all* atomic accesses on read-only memory are undefined behavior. For instance, attempting
162//! to do a `compare_exchange` that will definitely fail (making it conceptually a read-only
163//! operation) can still cause a segmentation fault if the underlying memory page is mapped read-only. Since
164//! atomic `load`s might be implemented using compare-exchange operations, even a `load` can fault
165//! on read-only memory.
166//!
167//! For the purpose of this section, "read-only memory" is defined as memory that is read-only in
168//! the underlying target, i.e., the pages are mapped with a read-only flag and any attempt to write
169//! will cause a page fault. In particular, an `&u128` reference that points to memory that is
170//! read-write mapped is *not* considered to point to "read-only memory". In Rust, almost all memory
171//! is read-write; the only exceptions are memory created by `const` items or `static` items without
172//! interior mutability, and memory that was specifically marked as read-only by the operating
173//! system via platform-specific APIs.
174//!
175//! As an exception from the general rule stated above, "sufficiently small" atomic loads with
176//! `Ordering::Relaxed` are implemented in a way that works on read-only memory, and are hence not
177//! undefined behavior. The exact size limit for what makes a load "sufficiently small" varies
178//! depending on the target:
179//!
180//! | `target_arch` | Size limit |
181//! |---------------|---------|
182//! | `x86`, `arm`, `loongarch32`, `mips`, `mips32r6`, `powerpc`, `riscv32`, `sparc`, `hexagon` | 4 bytes |
183//! | `x86_64`, `aarch64`, `loongarch64`, `mips64`, `mips64r6`, `powerpc64`, `riscv64`, `sparc64`, `s390x` | 8 bytes |
184//!
185//! Atomics loads that are larger than this limit as well as atomic loads with ordering other
186//! than `Relaxed`, as well as *all* atomic loads on targets not listed in the table, might still be
187//! read-only under certain conditions, but that is not a stable guarantee and should not be relied
188//! upon.
189//!
190//! If you need to do an acquire load on read-only memory, you can do a relaxed load followed by an
191//! acquire fence instead.
192//!
193//! # Examples
194//!
195//! A simple spinlock:
196//!
197//! ```ignore-wasm
198//! use std::sync::Arc;
199//! use std::sync::atomic::{AtomicUsize, Ordering};
200//! use std::{hint, thread};
201//!
202//! fn main() {
203//!     let spinlock = Arc::new(AtomicUsize::new(1));
204//!
205//!     let spinlock_clone = Arc::clone(&spinlock);
206//!
207//!     let thread = thread::spawn(move || {
208//!         spinlock_clone.store(0, Ordering::Release);
209//!     });
210//!
211//!     // Wait for the other thread to release the lock
212//!     while spinlock.load(Ordering::Acquire) != 0 {
213//!         hint::spin_loop();
214//!     }
215//!
216//!     if let Err(panic) = thread.join() {
217//!         println!("Thread had an error: {panic:?}");
218//!     }
219//! }
220//! ```
221//!
222//! Keep a global count of live threads:
223//!
224//! ```
225//! use std::sync::atomic::{AtomicUsize, Ordering};
226//!
227//! static GLOBAL_THREAD_COUNT: AtomicUsize = AtomicUsize::new(0);
228//!
229//! // Note that Relaxed ordering doesn't synchronize anything
230//! // except the global thread counter itself.
231//! let old_thread_count = GLOBAL_THREAD_COUNT.fetch_add(1, Ordering::Relaxed);
232//! // Note that this number may not be true at the moment of printing
233//! // because some other thread may have changed static value already.
234//! println!("live threads: {}", old_thread_count + 1);
235//! ```
236
237#![stable(feature = "rust1", since = "1.0.0")]
238#![cfg_attr(not(target_has_atomic_load_store = "8"), allow(dead_code))]
239#![cfg_attr(not(target_has_atomic_load_store = "8"), allow(unused_imports))]
240// Clippy complains about the pattern of "safe function calling unsafe function taking pointers".
241// This happens with AtomicPtr intrinsics but is fine, as the pointers clippy is concerned about
242// are just normal values that get loaded/stored, but not dereferenced.
243#![allow(clippy::not_unsafe_ptr_arg_deref)]
244
245use self::Ordering::*;
246use crate::cell::UnsafeCell;
247use crate::hint::spin_loop;
248use crate::intrinsics::AtomicOrdering as AO;
249use crate::mem::transmute;
250use crate::{fmt, intrinsics};
251
252#[unstable(
253    feature = "atomic_internals",
254    reason = "implementation detail which may disappear or be replaced at any time",
255    issue = "none"
256)]
257#[expect(missing_debug_implementations)]
258mod private {
259    #[cfg(target_has_atomic_load_store = "8")]
260    #[repr(C, align(1))]
261    pub struct Align1<T>(T);
262    #[cfg(target_has_atomic_load_store = "16")]
263    #[repr(C, align(2))]
264    pub struct Align2<T>(T);
265    #[cfg(target_has_atomic_load_store = "32")]
266    #[repr(C, align(4))]
267    pub struct Align4<T>(T);
268    #[cfg(target_has_atomic_load_store = "64")]
269    #[repr(C, align(8))]
270    pub struct Align8<T>(T);
271    #[cfg(any(target_has_atomic_load_store = "128", doc))]
272    #[repr(C, align(16))]
273    pub struct Align16<T>(T);
274}
275
276/// A marker trait for primitive types which can be modified atomically.
277///
278/// This is an implementation detail for <code>[Atomic]\<T></code> which may disappear or be replaced at any time.
279//
280// # Safety
281//
282// Types implementing this trait must be primitives that can be modified atomically.
283//
284// The associated `Self::Storage` type must have the same size, but may have fewer validity
285// invariants or a higher alignment requirement than `Self`.
286#[unstable(
287    feature = "atomic_internals",
288    reason = "implementation detail which may disappear or be replaced at any time",
289    issue = "none"
290)]
291pub impl(self) unsafe trait AtomicPrimitive: Sized + Copy {
292    /// Temporary implementation detail.
293    type Storage: Sized;
294}
295
296macro impl_atomic_primitive {
297    (
298        @impl [$($T:ident)?] $Primitive:ty as $Storage:ident<$Operand:ty>,
299        $cfg:meta
300    ) => {
301        #[unstable(
302            feature = "atomic_internals",
303            reason = "implementation detail which may disappear or be replaced at any time",
304            issue = "none"
305        )]
306        #[cfg($cfg)]
307        unsafe impl $(<$T>)? AtomicPrimitive for $Primitive {
308            type Storage = private::$Storage<$Operand>;
309        }
310    },
311
312    (
313        [$($T:ident)?] $Primitive:ty as $Storage:ident<$Operand:ty>,
314        size($size:literal)
315    ) => {
316        impl_atomic_primitive!(
317            @impl [$($T)?] $Primitive as $Storage<$Operand>,
318            target_has_atomic_load_store = $size
319        );
320    },
321
322    (
323        [$($T:ident)?] $Primitive:ty as $Storage:ident<$Operand:ty>,
324        size($size:literal),
325        doc
326    ) => {
327        impl_atomic_primitive!(
328            @impl [$($T)?] $Primitive as $Storage<$Operand>,
329            any(target_has_atomic_load_store = $size, doc)
330        );
331    },
332}
333
334#[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"));
335#[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"));
336#[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"));
337#[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"));
338#[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"));
339#[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"));
340#[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"));
341#[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"));
342#[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"));
343impl_atomic_primitive!([] i128 as Align16<i128>, size("128"), doc);
344impl_atomic_primitive!([] u128 as Align16<u128>, size("128"), doc);
345
346#[cfg(target_pointer_width = "16")]
347impl_atomic_primitive!([] isize as Align2<isize>, size("ptr"));
348#[cfg(target_pointer_width = "32")]
349impl_atomic_primitive!([] isize as Align4<isize>, size("ptr"));
350#[cfg(target_pointer_width = "64")]
351#[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"));
352
353#[cfg(target_pointer_width = "16")]
354impl_atomic_primitive!([] usize as Align2<usize>, size("ptr"));
355#[cfg(target_pointer_width = "32")]
356impl_atomic_primitive!([] usize as Align4<usize>, size("ptr"));
357#[cfg(target_pointer_width = "64")]
358#[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"));
359
360#[cfg(target_pointer_width = "16")]
361impl_atomic_primitive!([T] *mut T as Align2<*mut T>, size("ptr"));
362#[cfg(target_pointer_width = "32")]
363impl_atomic_primitive!([T] *mut T as Align4<*mut T>, size("ptr"));
364#[cfg(target_pointer_width = "64")]
365#[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"));
366
367/// A memory location which can be safely modified from multiple threads.
368///
369/// This has the same size and bit validity as the underlying type `T`. However,
370/// the alignment of this type is always equal to its size, even on targets where
371/// `T` has alignment less than its size.
372///
373/// For more about the differences between atomic types and non-atomic types as
374/// well as information about the portability of this type, please see the
375/// [module-level documentation].
376///
377/// **Note:** This type is only available on platforms that support atomic loads
378/// and stores of `T`.
379///
380/// [module-level documentation]: crate::sync::atomic
381#[unstable(feature = "generic_atomic", issue = "130539")]
382#[repr(C)]
383#[rustc_diagnostic_item = "Atomic"]
384pub struct Atomic<T: AtomicPrimitive> {
385    v: UnsafeCell<T::Storage>,
386}
387
388#[stable(feature = "rust1", since = "1.0.0")]
389unsafe impl<T: AtomicPrimitive> Send for Atomic<T> {}
390#[stable(feature = "rust1", since = "1.0.0")]
391unsafe impl<T: AtomicPrimitive> Sync for Atomic<T> {}
392
393// Some architectures don't have byte-sized atomics, which results in LLVM
394// emulating them using a LL/SC loop. However for AtomicBool we can take
395// advantage of the fact that it only ever contains 0 or 1 and use atomic OR/AND
396// instead, which LLVM can emulate using a larger atomic OR/AND operation.
397//
398// This list should only contain architectures which have word-sized atomic-or/
399// atomic-and instructions but don't natively support byte-sized atomics.
400#[cfg(target_has_atomic = "8")]
401const EMULATE_ATOMIC_BOOL: bool = falsecfg!(any(
402    target_arch = "riscv32",
403    target_arch = "riscv64",
404    target_arch = "loongarch32",
405    target_arch = "loongarch64"
406));
407
408/// A boolean type which can be safely shared between threads.
409///
410/// This type has the same size, alignment, and bit validity as a [`bool`].
411///
412/// **Note**: This type is only available on platforms that support atomic
413/// loads and stores of `u8`.
414#[cfg(target_has_atomic_load_store = "8")]
415#[stable(feature = "rust1", since = "1.0.0")]
416pub type AtomicBool = Atomic<bool>;
417
418#[cfg(target_has_atomic_load_store = "8")]
419#[stable(feature = "rust1", since = "1.0.0")]
420impl Default for AtomicBool {
421    /// Creates an `AtomicBool` initialized to `false`.
422    #[inline]
423    fn default() -> Self {
424        Self::new(false)
425    }
426}
427
428/// A raw pointer type which can be safely shared between threads.
429///
430/// This type has the same size and bit validity as a `*mut T`.
431///
432/// **Note**: This type is only available on platforms that support atomic
433/// loads and stores of pointers. Its size depends on the target pointer's size.
434#[cfg(target_has_atomic_load_store = "ptr")]
435#[stable(feature = "rust1", since = "1.0.0")]
436pub type AtomicPtr<T> = Atomic<*mut T>;
437
438#[cfg(target_has_atomic_load_store = "ptr")]
439#[stable(feature = "rust1", since = "1.0.0")]
440impl<T> Default for AtomicPtr<T> {
441    /// Creates a null `AtomicPtr<T>`.
442    fn default() -> AtomicPtr<T> {
443        AtomicPtr::new(crate::ptr::null_mut())
444    }
445}
446
447/// Atomic memory orderings
448///
449/// Memory orderings specify the way atomic operations synchronize memory.
450/// In its weakest [`Ordering::Relaxed`], only the memory directly touched by the
451/// operation is synchronized. On the other hand, a store-load pair of [`Ordering::SeqCst`]
452/// operations synchronize other memory while additionally preserving a total order of such
453/// operations across all threads.
454///
455/// Rust's memory orderings are [the same as those of
456/// C++20](https://en.cppreference.com/w/cpp/atomic/memory_order).
457///
458/// For more information see the [nomicon].
459///
460/// [nomicon]: ../../../nomicon/atomics.html
461#[stable(feature = "rust1", since = "1.0.0")]
462#[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) -> Self { *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 { }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: &Self) -> bool {
        crate::intrinsics::discriminant_value(self) ==
            crate::intrinsics::discriminant_value(other)
    }
}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) {
        crate::hash::Hash::hash(&crate::intrinsics::discriminant_value(self),
            state)
    }
}Hash)]
463#[non_exhaustive]
464#[rustc_diagnostic_item = "Ordering"]
465pub enum Ordering {
466    /// No ordering constraints, only atomic operations.
467    ///
468    /// Corresponds to [`memory_order_relaxed`] in C++20.
469    ///
470    /// [`memory_order_relaxed`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Relaxed_ordering
471    #[stable(feature = "rust1", since = "1.0.0")]
472    Relaxed,
473    /// When coupled with a store, all previous operations become ordered
474    /// before any load of this value with [`Acquire`] (or stronger) ordering.
475    /// In particular, all previous writes become visible to all threads
476    /// that perform an [`Acquire`] (or stronger) load of this value.
477    ///
478    /// Notice that using this ordering for an operation that combines loads
479    /// and stores leads to a [`Relaxed`] load operation!
480    ///
481    /// This ordering is only applicable for operations that can perform a store.
482    ///
483    /// Corresponds to [`memory_order_release`] in C++20.
484    ///
485    /// [`memory_order_release`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering
486    #[stable(feature = "rust1", since = "1.0.0")]
487    Release,
488    /// When coupled with a load, if the loaded value was written by a store operation with
489    /// [`Release`] (or stronger) ordering, then all subsequent operations
490    /// become ordered after that store. In particular, all subsequent loads will see data
491    /// written before the store.
492    ///
493    /// Notice that using this ordering for an operation that combines loads
494    /// and stores leads to a [`Relaxed`] store operation!
495    ///
496    /// This ordering is only applicable for operations that can perform a load.
497    ///
498    /// Corresponds to [`memory_order_acquire`] in C++20.
499    ///
500    /// [`memory_order_acquire`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering
501    #[stable(feature = "rust1", since = "1.0.0")]
502    Acquire,
503    /// Has the effects of both [`Acquire`] and [`Release`] together:
504    /// For loads it uses [`Acquire`] ordering. For stores it uses the [`Release`] ordering.
505    ///
506    /// Notice that in the case of `compare_and_swap`, it is possible that the operation ends up
507    /// not performing any store and hence it has just [`Acquire`] ordering. However,
508    /// `AcqRel` will never perform [`Relaxed`] accesses.
509    ///
510    /// This ordering is only applicable for operations that combine both loads and stores.
511    ///
512    /// Corresponds to [`memory_order_acq_rel`] in C++20.
513    ///
514    /// [`memory_order_acq_rel`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering
515    #[stable(feature = "rust1", since = "1.0.0")]
516    AcqRel,
517    /// Like [`Acquire`]/[`Release`]/[`AcqRel`] (for load, store, and load-with-store
518    /// operations, respectively) with the additional guarantee that all threads see all
519    /// sequentially consistent operations in the same order.
520    ///
521    /// Corresponds to [`memory_order_seq_cst`] in C++20.
522    ///
523    /// [`memory_order_seq_cst`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Sequentially-consistent_ordering
524    #[stable(feature = "rust1", since = "1.0.0")]
525    SeqCst,
526}
527
528/// An [`AtomicBool`] initialized to `false`.
529#[cfg(target_has_atomic_load_store = "8")]
530#[stable(feature = "rust1", since = "1.0.0")]
531#[deprecated(
532    since = "1.34.0",
533    note = "the `new` function is now preferred",
534    suggestion = "AtomicBool::new(false)"
535)]
536#[expect(clippy::declare_interior_mutable_const, reason = "legacy atomic initializer")]
537pub const ATOMIC_BOOL_INIT: AtomicBool = AtomicBool::new(false);
538
539#[cfg(target_has_atomic_load_store = "8")]
540impl AtomicBool {
541    /// Creates a new `AtomicBool`.
542    ///
543    /// # Examples
544    ///
545    /// ```
546    /// use std::sync::atomic::AtomicBool;
547    ///
548    /// let atomic_true = AtomicBool::new(true);
549    /// let atomic_false = AtomicBool::new(false);
550    /// ```
551    #[inline]
552    #[stable(feature = "rust1", since = "1.0.0")]
553    #[rustc_const_stable(feature = "const_atomic_new", since = "1.24.0")]
554    #[must_use]
555    pub const fn new(v: bool) -> AtomicBool {
556        // SAFETY:
557        // `Atomic<T>` is essentially a transparent wrapper around `T`.
558        unsafe { transmute(v) }
559    }
560
561    /// Creates a new `AtomicBool` from a pointer.
562    ///
563    /// # Examples
564    ///
565    /// ```
566    /// use std::sync::atomic::{self, AtomicBool};
567    ///
568    /// // Get a pointer to an allocated value
569    /// let ptr: *mut bool = Box::into_raw(Box::new(false));
570    ///
571    /// assert!(ptr.cast::<AtomicBool>().is_aligned());
572    ///
573    /// {
574    ///     // Create an atomic view of the allocated value
575    ///     let atomic = unsafe { AtomicBool::from_ptr(ptr) };
576    ///
577    ///     // Use `atomic` for atomic operations, possibly share it with other threads
578    ///     atomic.store(true, atomic::Ordering::Relaxed);
579    /// }
580    ///
581    /// // It's ok to non-atomically access the value behind `ptr`,
582    /// // since the reference to the atomic ended its lifetime in the block above
583    /// assert_eq!(unsafe { *ptr }, true);
584    ///
585    /// // Deallocate the value
586    /// unsafe { drop(Box::from_raw(ptr)) }
587    /// ```
588    ///
589    /// # Safety
590    ///
591    /// * `ptr` must be aligned to `align_of::<AtomicBool>()` (note that this is always true, since
592    ///   `align_of::<AtomicBool>() == 1`).
593    /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
594    /// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not
595    ///   allowed to mix conflicting atomic and non-atomic accesses, or atomic accesses of different
596    ///   sizes, without synchronization.
597    ///
598    /// [valid]: crate::ptr#safety
599    /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
600    #[inline]
601    #[stable(feature = "atomic_from_ptr", since = "1.75.0")]
602    #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")]
603    pub const unsafe fn from_ptr<'a>(ptr: *mut bool) -> &'a AtomicBool {
604        // SAFETY: guaranteed by the caller
605        unsafe { &*ptr.cast() }
606    }
607
608    /// Creates a new pointer to `AtomicBool` from a pointer.
609    ///
610    /// This is useful if you want to do volatile atomic accesses, and thus avoid creating
611    /// a reference to the destination.
612    #[inline]
613    #[unstable(feature = "atomic_volatile", issue = "158947")]
614    pub const fn from_ptr_raw(ptr: *mut bool) -> *const AtomicBool {
615        ptr.cast_const().cast()
616    }
617
618    /// Returns a mutable reference to the underlying [`bool`].
619    ///
620    /// This is safe because the mutable reference guarantees that no other threads are
621    /// concurrently accessing the atomic data.
622    ///
623    /// # Examples
624    ///
625    /// ```
626    /// use std::sync::atomic::{AtomicBool, Ordering};
627    ///
628    /// let mut some_bool = AtomicBool::new(true);
629    /// assert_eq!(*some_bool.get_mut(), true);
630    /// *some_bool.get_mut() = false;
631    /// assert_eq!(some_bool.load(Ordering::SeqCst), false);
632    /// ```
633    #[inline]
634    #[stable(feature = "atomic_access", since = "1.15.0")]
635    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
636    pub const fn get_mut(&mut self) -> &mut bool {
637        // SAFETY: the mutable reference guarantees unique ownership.
638        unsafe { &mut *self.as_ptr() }
639    }
640
641    /// Gets atomic access to a `&mut bool`.
642    ///
643    /// # Examples
644    ///
645    /// ```
646    /// use std::sync::atomic::{AtomicBool, Ordering};
647    ///
648    /// let mut some_bool = true;
649    /// let a = AtomicBool::from_mut(&mut some_bool);
650    /// a.store(false, Ordering::Relaxed);
651    /// assert_eq!(some_bool, false);
652    /// ```
653    #[inline]
654    #[cfg(target_has_atomic_primitive_alignment = "8")]
655    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
656    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
657    pub const fn from_mut(v: &mut bool) -> &mut Self {
658        // SAFETY: the mutable reference guarantees unique ownership, and
659        // alignment of both `bool` and `Self` is 1.
660        unsafe { &mut *(v as *mut bool as *mut Self) }
661    }
662
663    /// Gets non-atomic access to a `&mut [AtomicBool]` slice.
664    ///
665    /// This is safe because the mutable reference guarantees that no other threads are
666    /// concurrently accessing the atomic data.
667    ///
668    /// # Examples
669    ///
670    /// ```ignore-wasm
671    /// use std::sync::atomic::{AtomicBool, Ordering};
672    ///
673    /// let mut some_bools = [const { AtomicBool::new(false) }; 10];
674    ///
675    /// let view: &mut [bool] = AtomicBool::get_mut_slice(&mut some_bools);
676    /// assert_eq!(view, [false; 10]);
677    /// view[..5].copy_from_slice(&[true; 5]);
678    ///
679    /// std::thread::scope(|s| {
680    ///     for t in &some_bools[..5] {
681    ///         s.spawn(move || assert_eq!(t.load(Ordering::Relaxed), true));
682    ///     }
683    ///
684    ///     for f in &some_bools[5..] {
685    ///         s.spawn(move || assert_eq!(f.load(Ordering::Relaxed), false));
686    ///     }
687    /// });
688    /// ```
689    #[inline]
690    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
691    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
692    pub const fn get_mut_slice(this: &mut [Self]) -> &mut [bool] {
693        // SAFETY: the mutable reference guarantees unique ownership.
694        unsafe { &mut *(this as *mut [Self] as *mut [bool]) }
695    }
696
697    /// Gets atomic access to a `&mut [bool]` slice.
698    ///
699    /// # Examples
700    ///
701    /// ```rust,ignore-wasm
702    /// use std::sync::atomic::{AtomicBool, Ordering};
703    ///
704    /// let mut some_bools = [false; 10];
705    /// let a = &*AtomicBool::from_mut_slice(&mut some_bools);
706    /// std::thread::scope(|s| {
707    ///     for i in 0..a.len() {
708    ///         s.spawn(move || a[i].store(true, Ordering::Relaxed));
709    ///     }
710    /// });
711    /// assert_eq!(some_bools, [true; 10]);
712    /// ```
713    #[inline]
714    #[cfg(target_has_atomic_primitive_alignment = "8")]
715    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
716    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
717    pub const fn from_mut_slice(v: &mut [bool]) -> &mut [Self] {
718        // SAFETY: the mutable reference guarantees unique ownership, and
719        // alignment of both `bool` and `Self` is 1.
720        unsafe { &mut *(v as *mut [bool] as *mut [Self]) }
721    }
722
723    /// Consumes the atomic and returns the contained value.
724    ///
725    /// This is safe because passing `self` by value guarantees that no other threads are
726    /// concurrently accessing the atomic data.
727    ///
728    /// # Examples
729    ///
730    /// ```
731    /// use std::sync::atomic::AtomicBool;
732    ///
733    /// let some_bool = AtomicBool::new(true);
734    /// assert_eq!(some_bool.into_inner(), true);
735    /// ```
736    #[inline]
737    #[stable(feature = "atomic_access", since = "1.15.0")]
738    #[rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0")]
739    pub const fn into_inner(self) -> bool {
740        // SAFETY:
741        // * `Atomic<T>` is essentially a transparent wrapper around `T`.
742        // * all operations on `Atomic<bool>` ensure that `T::Storage` remains
743        //   a valid `bool`.
744        unsafe { transmute(self) }
745    }
746
747    /// Loads a value from the bool.
748    ///
749    /// `load` takes an [`Ordering`] argument which describes the memory ordering
750    /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
751    ///
752    /// # Panics
753    ///
754    /// Panics if `order` is [`Release`] or [`AcqRel`].
755    ///
756    /// # Examples
757    ///
758    /// ```
759    /// use std::sync::atomic::{AtomicBool, Ordering};
760    ///
761    /// let some_bool = AtomicBool::new(true);
762    ///
763    /// assert_eq!(some_bool.load(Ordering::Relaxed), true);
764    /// ```
765    #[inline]
766    #[stable(feature = "rust1", since = "1.0.0")]
767    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
768    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
769    pub const fn load(&self, order: Ordering) -> bool {
770        // SAFETY: any data races are prevented by atomic intrinsics and the raw
771        // pointer passed in is valid because we got it from a reference.
772        unsafe {
773            atomic_load::<_, /* VOLATILE */ false>(self.v.get().cast::<u8>(), order) != 0
774        }
775    }
776
777    /// Perform a volatile atomic load from the bool.
778    ///
779    /// `load_volatile` takes an [`Ordering`] argument which describes the memory ordering
780    /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
781    ///
782    #[doc = "Volatile operations are intended to act on I/O memory. As such, they are considered externally\nobservable events (just like syscalls, but less opaque), and are guaranteed to not be elided or\nreordered by the compiler across other externally observable events. With this in mind, there\nare two cases of usage that need to be distinguished:\n\n- When a volatile operation is used for memory inside an [allocation], it behaves exactly\n  like [`load`][Self::load], except for the additional guarantee that it won\'t be elided or\n  reordered across other externally observable events (see above). This implies that the\n  operation will actually access memory and not e.g. be lowered to reusing data from a\n  previous load. Other than that, all the usual rules for memory accesses apply (including\n  provenance).\n\n- Volatile operations, however, may also be used to access memory that is _outside_ of any Rust\n  allocation. In this use-case, the pointer does *not* have to be [valid] for reads. This is\n  typically used for CPU and peripheral registers that must be accessed via an I/O memory mapping,\n  most commonly at fixed addresses reserved by the hardware. These often have special semantics\n  associated to their manipulation, and cannot be used as general purpose memory. Here, any address\n  value is possible, including 0 and [`usize::MAX`], so long as the semantics of such a read are\n  well-defined by the target hardware. The provenance of the pointer is irrelevant, and it can be\n  created with [`without_provenance`][crate::ptr::without_provenance]. The access is allowed to\n  trap, which must immediately abort the process. It can also cause other side-effects, but those\n  must not affect Rust-allocated memory in any way.\n\nIn both cases, the access is also considered atomic with the given `order`. This allows\nsynchronization with other threads or devices that share memory with this program.\n\nWhen invoked during const evaluation, this behaves like a regular atomic load. In\nparticular, such reads must always follow the first of the two cases above.\n\n[allocation]: crate::ptr#allocated-object\n"include_str!("./atomic_load_volatile.md")]
783    ///
784    /// # Safety
785    ///
786    /// Behavior is undefined if any of the following conditions are violated:
787    ///
788    /// * `self` must be [valid] for reads, or `self` must point to memory
789    ///   outside of all Rust allocations and reading from that memory must:
790    ///   - not trap, and
791    ///   - not cause any memory inside a Rust allocation to be modified.
792    ///
793    /// * Reading from `self` must produce a properly initialized value of type `bool`.
794    ///
795    /// [valid]: core::ptr#safety
796    ///
797    /// # Panics
798    ///
799    /// Panics if `order` is [`Release`] or [`AcqRel`].
800    #[inline]
801    #[unstable(feature = "atomic_volatile", issue = "158947")]
802    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
803    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
804    pub const unsafe fn load_volatile(self: *const Self, order: Ordering) -> bool {
805        // SAFETY: follows from our own safety requirements.
806        unsafe {
807            atomic_load::<_, /* VOLATILE */ true>(self.cast::<u8>(), order) != 0
808        }
809    }
810
811    /// Stores a value into the bool.
812    ///
813    /// `store` takes an [`Ordering`] argument which describes the memory ordering
814    /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
815    ///
816    /// # Panics
817    ///
818    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
819    ///
820    /// # Examples
821    ///
822    /// ```
823    /// use std::sync::atomic::{AtomicBool, Ordering};
824    ///
825    /// let some_bool = AtomicBool::new(true);
826    ///
827    /// some_bool.store(false, Ordering::Relaxed);
828    /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
829    /// ```
830    #[inline]
831    #[stable(feature = "rust1", since = "1.0.0")]
832    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
833    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
834    #[rustc_should_not_be_called_on_const_items]
835    pub const fn store(&self, val: bool, order: Ordering) {
836        // SAFETY: any data races are prevented by atomic intrinsics and the raw
837        // pointer passed in is valid because we got it from a reference.
838        unsafe {
839            atomic_store::<_, /* VOLATILE */ false>(self.v.get().cast::<u8>(), val as u8, order);
840        }
841    }
842
843    /// Performs a volatile atomic store into the bool.
844    ///
845    /// `store_volatile` takes an [`Ordering`] argument which describes the memory ordering
846    /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
847    ///
848    #[doc = "Volatile operations are intended to act on I/O memory. As such, they are considered externally\nobservable events (just like syscalls), and are guaranteed to not be elided or reordered by the\ncompiler across other externally observable events. With this in mind, there are two cases of\nusage that need to be distinguished:\n\n- When a volatile operation is used for memory inside an [allocation], it behaves exactly like\n  [`store`][Self::store], except for the additional guarantee that it won\'t be elided or reordered\n  across other externally observable events (see above). This implies that the operation will\n  actually access memory and not e.g. be lowered to a register access. Other than that, all the\n  usual rules for memory accesses apply (including provenance).\n\n- Volatile operations, however, may also be used to access memory that is _outside_ of any Rust\n  allocation. In this use-case, the pointer does *not* have to be [valid] for writes. This is\n  typically used for CPU and peripheral registers that must be accessed via an I/O memory mapping,\n  most commonly at fixed addresses reserved by the hardware. These often have special semantics\n  associated to their manipulation, and cannot be used as general purpose memory. Here, any address\n  value is possible, including 0 and [`usize::MAX`], so long as the semantics of such a write are\n  well-defined by the target hardware. The provenance of the pointer is irrelevant, and it can be\n  created with [`without_provenance_mut`][crate::ptr::without_provenance_mut]. The access is allowed\n  to trap, which must immediately abort the process. It can also cause other side-effects, but those\n  must not affect Rust-allocated memory in any way.\n\nIn both cases, the access is also considered atomic with the given `order`. This allows\nsynchronization with other threads or devices that share memory with this program.\n\nWhen invoked during const evaluation, this behaves like a regular atomic store. In\nparticular, such reads must always follow the first of the two cases above.\n\n[allocation]: crate::ptr#allocated-object\n"include_str!("./atomic_store_volatile.md")]
849    ///
850    /// # Safety
851    ///
852    /// Behavior is undefined if any of the following conditions are violated:
853    ///
854    /// * `self` must be either [valid] for writes, or `self` must point to memory
855    ///   outside of all Rust allocations and writing to that memory must:
856    ///   - not trap, and
857    ///   - not cause any memory inside a Rust allocation to be modified.
858    ///
859    /// [valid]: core::ptr#safety
860    ///
861    /// # Panics
862    ///
863    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
864    #[inline]
865    #[unstable(feature = "atomic_volatile", issue = "158947")]
866    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
867    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
868    #[rustc_should_not_be_called_on_const_items]
869    pub const unsafe fn store_volatile(self: *const Self, val: bool, order: Ordering) {
870        // SAFETY: follows from our own safety requirements.
871        unsafe {
872            atomic_store::<_, /* VOLATILE */ true>(self.cast::<u8>().cast_mut(), val as u8, order);
873        }
874    }
875
876    /// Stores a value into the bool, returning the previous value.
877    ///
878    /// `swap` takes an [`Ordering`] argument which describes the memory ordering
879    /// of this operation. All ordering modes are possible. Note that using
880    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
881    /// using [`Release`] makes the load part [`Relaxed`].
882    ///
883    /// **Note:** This method is only available on platforms that support atomic
884    /// operations on `u8`.
885    ///
886    /// # Examples
887    ///
888    /// ```
889    /// use std::sync::atomic::{AtomicBool, Ordering};
890    ///
891    /// let some_bool = AtomicBool::new(true);
892    ///
893    /// assert_eq!(some_bool.swap(false, Ordering::Relaxed), true);
894    /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
895    /// ```
896    #[inline]
897    #[stable(feature = "rust1", since = "1.0.0")]
898    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
899    #[cfg(target_has_atomic = "8")]
900    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
901    #[rustc_should_not_be_called_on_const_items]
902    pub const fn swap(&self, val: bool, order: Ordering) -> bool {
903        if EMULATE_ATOMIC_BOOL {
904            if val { self.fetch_or(true, order) } else { self.fetch_and(false, order) }
905        } else {
906            // SAFETY: data races are prevented by atomic intrinsics.
907            unsafe { atomic_swap(self.v.get().cast::<u8>(), val as u8, order) != 0 }
908        }
909    }
910
911    /// Stores a value into the [`bool`] if the current value is the same as the `current` value.
912    ///
913    /// The return value is always the previous value. If it is equal to `current`, then the value
914    /// was updated.
915    ///
916    /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
917    /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
918    /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
919    /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
920    /// happens, and using [`Release`] makes the load part [`Relaxed`].
921    ///
922    /// **Note:** This method is only available on platforms that support atomic
923    /// operations on `u8`.
924    ///
925    /// # Migrating to `compare_exchange` and `compare_exchange_weak`
926    ///
927    /// `compare_and_swap` is equivalent to `compare_exchange` with the following mapping for
928    /// memory orderings:
929    ///
930    /// Original | Success | Failure
931    /// -------- | ------- | -------
932    /// Relaxed  | Relaxed | Relaxed
933    /// Acquire  | Acquire | Acquire
934    /// Release  | Release | Relaxed
935    /// AcqRel   | AcqRel  | Acquire
936    /// SeqCst   | SeqCst  | SeqCst
937    ///
938    /// `compare_and_swap` and `compare_exchange` also differ in their return type. You can use
939    /// `compare_exchange(...).unwrap_or_else(|x| x)` to recover the behavior of `compare_and_swap`,
940    /// but in most cases it is more idiomatic to check whether the return value is `Ok` or `Err`
941    /// rather than to infer success vs failure based on the value that was read.
942    ///
943    /// During migration, consider whether it makes sense to use `compare_exchange_weak` instead.
944    /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds,
945    /// which allows the compiler to generate better assembly code when the compare and swap
946    /// is used in a loop.
947    ///
948    /// # Examples
949    ///
950    /// ```
951    /// use std::sync::atomic::{AtomicBool, Ordering};
952    ///
953    /// let some_bool = AtomicBool::new(true);
954    ///
955    /// assert_eq!(some_bool.compare_and_swap(true, false, Ordering::Relaxed), true);
956    /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
957    ///
958    /// assert_eq!(some_bool.compare_and_swap(true, true, Ordering::Relaxed), false);
959    /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
960    /// ```
961    #[inline]
962    #[stable(feature = "rust1", since = "1.0.0")]
963    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
964    #[deprecated(
965        since = "1.50.0",
966        note = "Use `compare_exchange` or `compare_exchange_weak` instead"
967    )]
968    #[cfg(target_has_atomic = "8")]
969    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
970    #[rustc_should_not_be_called_on_const_items]
971    pub const fn compare_and_swap(&self, current: bool, new: bool, order: Ordering) -> bool {
972        match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) {
973            Ok(x) => x,
974            Err(x) => x,
975        }
976    }
977
978    /// Stores a value into the [`bool`] if the current value is the same as the `current` value.
979    ///
980    /// The return value is a result indicating whether the new value was written and containing
981    /// the previous value. On success this value is guaranteed to be equal to `current`.
982    ///
983    /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
984    /// ordering of this operation. `success` describes the required ordering for the
985    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
986    /// `failure` describes the required ordering for the load operation that takes place when
987    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
988    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
989    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
990    ///
991    /// **Note:** This method is only available on platforms that support atomic
992    /// operations on `u8`.
993    ///
994    /// # Examples
995    ///
996    /// ```
997    /// use std::sync::atomic::{AtomicBool, Ordering};
998    ///
999    /// let some_bool = AtomicBool::new(true);
1000    ///
1001    /// assert_eq!(some_bool.compare_exchange(true,
1002    ///                                       false,
1003    ///                                       Ordering::Acquire,
1004    ///                                       Ordering::Relaxed),
1005    ///            Ok(true));
1006    /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
1007    ///
1008    /// assert_eq!(some_bool.compare_exchange(true, true,
1009    ///                                       Ordering::SeqCst,
1010    ///                                       Ordering::Acquire),
1011    ///            Err(false));
1012    /// assert_eq!(some_bool.load(Ordering::Relaxed), false);
1013    /// ```
1014    ///
1015    /// # Considerations
1016    ///
1017    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
1018    /// of CAS operations. In particular, a load of the value followed by a successful
1019    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
1020    /// changed the value in the interim. This is usually important when the *equality* check in
1021    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
1022    /// does not necessarily imply identity. In this case, `compare_exchange` can lead to the
1023    /// [ABA problem].
1024    ///
1025    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
1026    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
1027    #[inline]
1028    #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
1029    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1030    #[doc(alias = "compare_and_swap")]
1031    #[cfg(target_has_atomic = "8")]
1032    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1033    #[rustc_should_not_be_called_on_const_items]
1034    pub const fn compare_exchange(
1035        &self,
1036        current: bool,
1037        new: bool,
1038        success: Ordering,
1039        failure: Ordering,
1040    ) -> Result<bool, bool> {
1041        if EMULATE_ATOMIC_BOOL {
1042            // Pick the strongest ordering from success and failure.
1043            let order = match (success, failure) {
1044                (SeqCst, _) => SeqCst,
1045                (_, SeqCst) => SeqCst,
1046                (AcqRel, _) => AcqRel,
1047                (_, AcqRel) => {
1048                    {
    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")
1049                }
1050                (Release, Acquire) => AcqRel,
1051                (Acquire, _) => Acquire,
1052                (_, Acquire) => Acquire,
1053                (Release, Relaxed) => Release,
1054                (_, 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"),
1055                (Relaxed, Relaxed) => Relaxed,
1056            };
1057            let old = if current == new {
1058                // This is a no-op, but we still need to perform the operation
1059                // for memory ordering reasons.
1060                self.fetch_or(false, order)
1061            } else {
1062                // This sets the value to the new one and returns the old one.
1063                self.swap(new, order)
1064            };
1065            if old == current { Ok(old) } else { Err(old) }
1066        } else {
1067            // SAFETY: data races are prevented by atomic intrinsics.
1068            match unsafe {
1069                atomic_compare_exchange(
1070                    self.v.get().cast::<u8>(),
1071                    current as u8,
1072                    new as u8,
1073                    success,
1074                    failure,
1075                )
1076            } {
1077                Ok(x) => Ok(x != 0),
1078                Err(x) => Err(x != 0),
1079            }
1080        }
1081    }
1082
1083    /// Stores a value into the [`bool`] if the current value is the same as the `current` value.
1084    ///
1085    /// Unlike [`AtomicBool::compare_exchange`], this function is allowed to spuriously fail even when the
1086    /// comparison succeeds, which can result in more efficient code on some platforms. The
1087    /// return value is a result indicating whether the new value was written and containing the
1088    /// previous value.
1089    ///
1090    /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
1091    /// ordering of this operation. `success` describes the required ordering for the
1092    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
1093    /// `failure` describes the required ordering for the load operation that takes place when
1094    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
1095    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
1096    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
1097    ///
1098    /// **Note:** This method is only available on platforms that support atomic
1099    /// operations on `u8`.
1100    ///
1101    /// # Examples
1102    ///
1103    /// ```
1104    /// use std::sync::atomic::{AtomicBool, Ordering};
1105    ///
1106    /// let val = AtomicBool::new(false);
1107    ///
1108    /// let new = true;
1109    /// let mut old = val.load(Ordering::Relaxed);
1110    /// loop {
1111    ///     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
1112    ///         Ok(_) => break,
1113    ///         Err(x) => old = x,
1114    ///     }
1115    /// }
1116    /// ```
1117    ///
1118    /// # Considerations
1119    ///
1120    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
1121    /// of CAS operations. In particular, a load of the value followed by a successful
1122    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
1123    /// changed the value in the interim. This is usually important when the *equality* check in
1124    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
1125    /// does not necessarily imply identity. In this case, `compare_exchange` can lead to the
1126    /// [ABA problem].
1127    ///
1128    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
1129    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
1130    #[inline]
1131    #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
1132    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1133    #[doc(alias = "compare_and_swap")]
1134    #[cfg(target_has_atomic = "8")]
1135    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1136    #[rustc_should_not_be_called_on_const_items]
1137    pub const fn compare_exchange_weak(
1138        &self,
1139        current: bool,
1140        new: bool,
1141        success: Ordering,
1142        failure: Ordering,
1143    ) -> Result<bool, bool> {
1144        if EMULATE_ATOMIC_BOOL {
1145            return self.compare_exchange(current, new, success, failure);
1146        }
1147
1148        // SAFETY: data races are prevented by atomic intrinsics.
1149        match unsafe {
1150            atomic_compare_exchange_weak(
1151                self.v.get().cast::<u8>(),
1152                current as u8,
1153                new as u8,
1154                success,
1155                failure,
1156            )
1157        } {
1158            Ok(x) => Ok(x != 0),
1159            Err(x) => Err(x != 0),
1160        }
1161    }
1162
1163    /// Logical "and" with a boolean value.
1164    ///
1165    /// Performs a logical "and" operation on the current value and the argument `val`, and sets
1166    /// the new value to the result.
1167    ///
1168    /// Returns the previous value.
1169    ///
1170    /// `fetch_and` takes an [`Ordering`] argument which describes the memory ordering
1171    /// of this operation. All ordering modes are possible. Note that using
1172    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
1173    /// using [`Release`] makes the load part [`Relaxed`].
1174    ///
1175    /// **Note:** This method is only available on platforms that support atomic
1176    /// operations on `u8`.
1177    ///
1178    /// # Examples
1179    ///
1180    /// ```
1181    /// use std::sync::atomic::{AtomicBool, Ordering};
1182    ///
1183    /// let foo = AtomicBool::new(true);
1184    /// assert_eq!(foo.fetch_and(false, Ordering::SeqCst), true);
1185    /// assert_eq!(foo.load(Ordering::SeqCst), false);
1186    ///
1187    /// let foo = AtomicBool::new(true);
1188    /// assert_eq!(foo.fetch_and(true, Ordering::SeqCst), true);
1189    /// assert_eq!(foo.load(Ordering::SeqCst), true);
1190    ///
1191    /// let foo = AtomicBool::new(false);
1192    /// assert_eq!(foo.fetch_and(false, Ordering::SeqCst), false);
1193    /// assert_eq!(foo.load(Ordering::SeqCst), false);
1194    /// ```
1195    #[inline]
1196    #[stable(feature = "rust1", since = "1.0.0")]
1197    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1198    #[cfg(target_has_atomic = "8")]
1199    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1200    #[rustc_should_not_be_called_on_const_items]
1201    pub const fn fetch_and(&self, val: bool, order: Ordering) -> bool {
1202        // SAFETY: data races are prevented by atomic intrinsics.
1203        unsafe { atomic_and(self.v.get().cast::<u8>(), val as u8, order) != 0 }
1204    }
1205
1206    /// Logical "nand" with a boolean value.
1207    ///
1208    /// Performs a logical "nand" operation on the current value and the argument `val`, and sets
1209    /// the new value to the result.
1210    ///
1211    /// Returns the previous value.
1212    ///
1213    /// `fetch_nand` takes an [`Ordering`] argument which describes the memory ordering
1214    /// of this operation. All ordering modes are possible. Note that using
1215    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
1216    /// using [`Release`] makes the load part [`Relaxed`].
1217    ///
1218    /// **Note:** This method is only available on platforms that support atomic
1219    /// operations on `u8`.
1220    ///
1221    /// # Examples
1222    ///
1223    /// ```
1224    /// use std::sync::atomic::{AtomicBool, Ordering};
1225    ///
1226    /// let foo = AtomicBool::new(true);
1227    /// assert_eq!(foo.fetch_nand(false, Ordering::SeqCst), true);
1228    /// assert_eq!(foo.load(Ordering::SeqCst), true);
1229    ///
1230    /// let foo = AtomicBool::new(true);
1231    /// assert_eq!(foo.fetch_nand(true, Ordering::SeqCst), true);
1232    /// assert_eq!(foo.load(Ordering::SeqCst) as usize, 0);
1233    /// assert_eq!(foo.load(Ordering::SeqCst), false);
1234    ///
1235    /// let foo = AtomicBool::new(false);
1236    /// assert_eq!(foo.fetch_nand(false, Ordering::SeqCst), false);
1237    /// assert_eq!(foo.load(Ordering::SeqCst), true);
1238    /// ```
1239    #[inline]
1240    #[stable(feature = "rust1", since = "1.0.0")]
1241    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1242    #[cfg(target_has_atomic = "8")]
1243    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1244    #[rustc_should_not_be_called_on_const_items]
1245    pub const fn fetch_nand(&self, val: bool, order: Ordering) -> bool {
1246        // We can't use atomic_nand here because it can result in a bool with
1247        // an invalid value. This happens because the atomic operation is done
1248        // with an 8-bit integer internally, which would set the upper 7 bits.
1249        // So we just use fetch_xor or swap instead.
1250        if val {
1251            // !(x & true) == !x
1252            // We must invert the bool.
1253            self.fetch_xor(true, order)
1254        } else {
1255            // !(x & false) == true
1256            // We must set the bool to true.
1257            self.swap(true, order)
1258        }
1259    }
1260
1261    /// Logical "or" with a boolean value.
1262    ///
1263    /// Performs a logical "or" operation on the current value and the argument `val`, and sets the
1264    /// new value to the result.
1265    ///
1266    /// Returns the previous value.
1267    ///
1268    /// `fetch_or` takes an [`Ordering`] argument which describes the memory ordering
1269    /// of this operation. All ordering modes are possible. Note that using
1270    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
1271    /// using [`Release`] makes the load part [`Relaxed`].
1272    ///
1273    /// **Note:** This method is only available on platforms that support atomic
1274    /// operations on `u8`.
1275    ///
1276    /// # Examples
1277    ///
1278    /// ```
1279    /// use std::sync::atomic::{AtomicBool, Ordering};
1280    ///
1281    /// let foo = AtomicBool::new(true);
1282    /// assert_eq!(foo.fetch_or(false, Ordering::SeqCst), true);
1283    /// assert_eq!(foo.load(Ordering::SeqCst), true);
1284    ///
1285    /// let foo = AtomicBool::new(false);
1286    /// assert_eq!(foo.fetch_or(true, Ordering::SeqCst), false);
1287    /// assert_eq!(foo.load(Ordering::SeqCst), true);
1288    ///
1289    /// let foo = AtomicBool::new(false);
1290    /// assert_eq!(foo.fetch_or(false, Ordering::SeqCst), false);
1291    /// assert_eq!(foo.load(Ordering::SeqCst), false);
1292    /// ```
1293    #[inline]
1294    #[stable(feature = "rust1", since = "1.0.0")]
1295    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1296    #[cfg(target_has_atomic = "8")]
1297    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1298    #[rustc_should_not_be_called_on_const_items]
1299    pub const fn fetch_or(&self, val: bool, order: Ordering) -> bool {
1300        // SAFETY: data races are prevented by atomic intrinsics.
1301        unsafe { atomic_or(self.v.get().cast::<u8>(), val as u8, order) != 0 }
1302    }
1303
1304    /// Logical "xor" with a boolean value.
1305    ///
1306    /// Performs a logical "xor" operation on the current value and the argument `val`, and sets
1307    /// the new value to the result.
1308    ///
1309    /// Returns the previous value.
1310    ///
1311    /// `fetch_xor` takes an [`Ordering`] argument which describes the memory ordering
1312    /// of this operation. All ordering modes are possible. Note that using
1313    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
1314    /// using [`Release`] makes the load part [`Relaxed`].
1315    ///
1316    /// **Note:** This method is only available on platforms that support atomic
1317    /// operations on `u8`.
1318    ///
1319    /// # Examples
1320    ///
1321    /// ```
1322    /// use std::sync::atomic::{AtomicBool, Ordering};
1323    ///
1324    /// let foo = AtomicBool::new(true);
1325    /// assert_eq!(foo.fetch_xor(false, Ordering::SeqCst), true);
1326    /// assert_eq!(foo.load(Ordering::SeqCst), true);
1327    ///
1328    /// let foo = AtomicBool::new(true);
1329    /// assert_eq!(foo.fetch_xor(true, Ordering::SeqCst), true);
1330    /// assert_eq!(foo.load(Ordering::SeqCst), false);
1331    ///
1332    /// let foo = AtomicBool::new(false);
1333    /// assert_eq!(foo.fetch_xor(false, Ordering::SeqCst), false);
1334    /// assert_eq!(foo.load(Ordering::SeqCst), false);
1335    /// ```
1336    #[inline]
1337    #[stable(feature = "rust1", since = "1.0.0")]
1338    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1339    #[cfg(target_has_atomic = "8")]
1340    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1341    #[rustc_should_not_be_called_on_const_items]
1342    pub const fn fetch_xor(&self, val: bool, order: Ordering) -> bool {
1343        // SAFETY: data races are prevented by atomic intrinsics.
1344        unsafe { atomic_xor(self.v.get().cast::<u8>(), val as u8, order) != 0 }
1345    }
1346
1347    /// Logical "not" with a boolean value.
1348    ///
1349    /// Performs a logical "not" operation on the current value, and sets
1350    /// the new value to the result.
1351    ///
1352    /// Returns the previous value.
1353    ///
1354    /// `fetch_not` takes an [`Ordering`] argument which describes the memory ordering
1355    /// of this operation. All ordering modes are possible. Note that using
1356    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
1357    /// using [`Release`] makes the load part [`Relaxed`].
1358    ///
1359    /// **Note:** This method is only available on platforms that support atomic
1360    /// operations on `u8`.
1361    ///
1362    /// # Examples
1363    ///
1364    /// ```
1365    /// use std::sync::atomic::{AtomicBool, Ordering};
1366    ///
1367    /// let foo = AtomicBool::new(true);
1368    /// assert_eq!(foo.fetch_not(Ordering::SeqCst), true);
1369    /// assert_eq!(foo.load(Ordering::SeqCst), false);
1370    ///
1371    /// let foo = AtomicBool::new(false);
1372    /// assert_eq!(foo.fetch_not(Ordering::SeqCst), false);
1373    /// assert_eq!(foo.load(Ordering::SeqCst), true);
1374    /// ```
1375    #[inline]
1376    #[stable(feature = "atomic_bool_fetch_not", since = "1.81.0")]
1377    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1378    #[cfg(target_has_atomic = "8")]
1379    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1380    #[rustc_should_not_be_called_on_const_items]
1381    pub const fn fetch_not(&self, order: Ordering) -> bool {
1382        self.fetch_xor(true, order)
1383    }
1384
1385    /// Returns a mutable pointer to the underlying [`bool`].
1386    ///
1387    /// Doing non-atomic reads and writes on the resulting boolean can be a data race.
1388    /// This method is mostly useful for FFI, where the function signature may use
1389    /// `*mut bool` instead of `&AtomicBool`.
1390    ///
1391    /// Returning an `*mut` pointer from a shared reference to this atomic is safe because the
1392    /// atomic types work with interior mutability. All modifications of an atomic change the value
1393    /// through a shared reference, and can do so safely as long as they use atomic operations. Any
1394    /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the
1395    /// requirements of the [memory model].
1396    ///
1397    /// # Examples
1398    ///
1399    /// ```ignore (extern-declaration)
1400    /// # fn main() {
1401    /// use std::sync::atomic::AtomicBool;
1402    ///
1403    /// extern "C" {
1404    ///     fn my_atomic_op(arg: *mut bool);
1405    /// }
1406    ///
1407    /// let mut atomic = AtomicBool::new(true);
1408    /// unsafe {
1409    ///     my_atomic_op(atomic.as_ptr());
1410    /// }
1411    /// # }
1412    /// ```
1413    ///
1414    /// [memory model]: self#memory-model-for-atomic-accesses
1415    #[inline]
1416    #[stable(feature = "atomic_as_ptr", since = "1.70.0")]
1417    #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")]
1418    #[rustc_never_returns_null_ptr]
1419    #[rustc_should_not_be_called_on_const_items]
1420    pub const fn as_ptr(&self) -> *mut bool {
1421        self.v.get().cast()
1422    }
1423
1424    /// An alias for [`AtomicBool::try_update`].
1425    #[inline]
1426    #[stable(feature = "atomic_fetch_update", since = "1.53.0")]
1427    #[cfg(target_has_atomic = "8")]
1428    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1429    #[rustc_should_not_be_called_on_const_items]
1430    #[deprecated(
1431        since = "1.99.0",
1432        note = "renamed to `try_update` for consistency",
1433        suggestion = "try_update"
1434    )]
1435    pub fn fetch_update<F>(
1436        &self,
1437        set_order: Ordering,
1438        fetch_order: Ordering,
1439        f: F,
1440    ) -> Result<bool, bool>
1441    where
1442        F: FnMut(bool) -> Option<bool>,
1443    {
1444        self.try_update(set_order, fetch_order, f)
1445    }
1446
1447    /// Fetches the value, and applies a function to it that returns an optional
1448    /// new value. Returns a `Result` of `Ok(previous_value)` if the function
1449    /// returned `Some(_)`, else `Err(previous_value)`.
1450    ///
1451    /// See also: [`update`](`AtomicBool::update`).
1452    ///
1453    /// Note: This may call the function multiple times if the value has been
1454    /// changed from other threads in the meantime, as long as the function
1455    /// returns `Some(_)`, but the function will have been applied only once to
1456    /// the stored value.
1457    ///
1458    /// `try_update` takes two [`Ordering`] arguments to describe the memory
1459    /// ordering of this operation. The first describes the required ordering for
1460    /// when the operation finally succeeds while the second describes the
1461    /// required ordering for loads. These correspond to the success and failure
1462    /// orderings of [`AtomicBool::compare_exchange`] respectively.
1463    ///
1464    /// Using [`Acquire`] as success ordering makes the store part of this
1465    /// operation [`Relaxed`], and using [`Release`] makes the final successful
1466    /// load [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`],
1467    /// [`Acquire`] or [`Relaxed`].
1468    ///
1469    /// **Note:** This method is only available on platforms that support atomic
1470    /// operations on `u8`.
1471    ///
1472    /// # Considerations
1473    ///
1474    /// This method is not magic; it is not provided by the hardware, and does not act like a
1475    /// critical section or mutex.
1476    ///
1477    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
1478    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem].
1479    ///
1480    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
1481    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
1482    ///
1483    /// # Examples
1484    ///
1485    /// ```rust
1486    /// use std::sync::atomic::{AtomicBool, Ordering};
1487    ///
1488    /// let x = AtomicBool::new(false);
1489    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(false));
1490    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(!x)), Ok(false));
1491    /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(!x)), Ok(true));
1492    /// assert_eq!(x.load(Ordering::SeqCst), false);
1493    /// ```
1494    #[inline]
1495    #[stable(feature = "atomic_try_update", since = "1.95.0")]
1496    #[cfg(target_has_atomic = "8")]
1497    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1498    #[rustc_should_not_be_called_on_const_items]
1499    pub fn try_update(
1500        &self,
1501        set_order: Ordering,
1502        fetch_order: Ordering,
1503        mut f: impl FnMut(bool) -> Option<bool>,
1504    ) -> Result<bool, bool> {
1505        let mut prev = self.load(fetch_order);
1506        while let Some(next) = f(prev) {
1507            match self.compare_exchange_weak(prev, next, set_order, fetch_order) {
1508                x @ Ok(_) => return x,
1509                Err(next_prev) => prev = next_prev,
1510            }
1511        }
1512        Err(prev)
1513    }
1514
1515    /// Fetches the value, and applies a function to it that returns a new value.
1516    /// The new value is stored and the old value is returned.
1517    ///
1518    /// See also: [`try_update`](`AtomicBool::try_update`).
1519    ///
1520    /// Note: This may call the function multiple times if the value has been changed from other threads in
1521    /// the meantime, but the function will have been applied only once to the stored value.
1522    ///
1523    /// `update` takes two [`Ordering`] arguments to describe the memory
1524    /// ordering of this operation. The first describes the required ordering for
1525    /// when the operation finally succeeds while the second describes the
1526    /// required ordering for loads. These correspond to the success and failure
1527    /// orderings of [`AtomicBool::compare_exchange`] respectively.
1528    ///
1529    /// Using [`Acquire`] as success ordering makes the store part
1530    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
1531    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
1532    ///
1533    /// **Note:** This method is only available on platforms that support atomic operations on `u8`.
1534    ///
1535    /// # Considerations
1536    ///
1537    /// This method is not magic; it is not provided by the hardware, and does not act like a
1538    /// critical section or mutex.
1539    ///
1540    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
1541    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem].
1542    ///
1543    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
1544    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
1545    ///
1546    /// # Examples
1547    ///
1548    /// ```rust
1549    ///
1550    /// use std::sync::atomic::{AtomicBool, Ordering};
1551    ///
1552    /// let x = AtomicBool::new(false);
1553    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| !x), false);
1554    /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| !x), true);
1555    /// assert_eq!(x.load(Ordering::SeqCst), false);
1556    /// ```
1557    #[inline]
1558    #[stable(feature = "atomic_try_update", since = "1.95.0")]
1559    #[cfg(target_has_atomic = "8")]
1560    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1561    #[rustc_should_not_be_called_on_const_items]
1562    pub fn update(
1563        &self,
1564        set_order: Ordering,
1565        fetch_order: Ordering,
1566        mut f: impl FnMut(bool) -> bool,
1567    ) -> bool {
1568        let mut prev = self.load(fetch_order);
1569        loop {
1570            match self.compare_exchange_weak(prev, f(prev), set_order, fetch_order) {
1571                Ok(x) => break x,
1572                Err(next_prev) => prev = next_prev,
1573            }
1574        }
1575    }
1576}
1577
1578#[cfg(target_has_atomic_load_store = "ptr")]
1579impl<T> AtomicPtr<T> {
1580    /// Creates a new `AtomicPtr`.
1581    ///
1582    /// # Examples
1583    ///
1584    /// ```
1585    /// use std::sync::atomic::AtomicPtr;
1586    ///
1587    /// let ptr = &mut 5;
1588    /// let atomic_ptr = AtomicPtr::new(ptr);
1589    /// ```
1590    #[inline]
1591    #[stable(feature = "rust1", since = "1.0.0")]
1592    #[rustc_const_stable(feature = "const_atomic_new", since = "1.24.0")]
1593    pub const fn new(p: *mut T) -> AtomicPtr<T> {
1594        // SAFETY:
1595        // `Atomic<T>` is essentially a transparent wrapper around `T`.
1596        unsafe { transmute(p) }
1597    }
1598
1599    /// Creates a new `AtomicPtr` from a pointer.
1600    ///
1601    /// # Examples
1602    ///
1603    /// ```
1604    /// use std::sync::atomic::{self, AtomicPtr};
1605    ///
1606    /// // Get a pointer to an allocated value
1607    /// let ptr: *mut *mut u8 = Box::into_raw(Box::new(std::ptr::null_mut()));
1608    ///
1609    /// assert!(ptr.cast::<AtomicPtr<u8>>().is_aligned());
1610    ///
1611    /// {
1612    ///     // Create an atomic view of the allocated value
1613    ///     let atomic = unsafe { AtomicPtr::from_ptr(ptr) };
1614    ///
1615    ///     // Use `atomic` for atomic operations, possibly share it with other threads
1616    ///     atomic.store(std::ptr::NonNull::dangling().as_ptr(), atomic::Ordering::Relaxed);
1617    /// }
1618    ///
1619    /// // It's ok to non-atomically access the value behind `ptr`,
1620    /// // since the reference to the atomic ended its lifetime in the block above
1621    /// assert!(!unsafe { *ptr }.is_null());
1622    ///
1623    /// // Deallocate the value
1624    /// unsafe { drop(Box::from_raw(ptr)) }
1625    /// ```
1626    ///
1627    /// # Safety
1628    ///
1629    /// * `ptr` must be aligned to `align_of::<AtomicPtr<T>>()` (note that on some platforms this
1630    ///   can be bigger than `align_of::<*mut T>()`).
1631    /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
1632    /// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not
1633    ///   allowed to mix conflicting atomic and non-atomic accesses, or atomic accesses of different
1634    ///   sizes, without synchronization.
1635    ///
1636    /// [valid]: crate::ptr#safety
1637    /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
1638    #[inline]
1639    #[stable(feature = "atomic_from_ptr", since = "1.75.0")]
1640    #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")]
1641    pub const unsafe fn from_ptr<'a>(ptr: *mut *mut T) -> &'a AtomicPtr<T> {
1642        // SAFETY: guaranteed by the caller
1643        unsafe { &*ptr.cast() }
1644    }
1645
1646    /// Creates a new pointer to `AtomicPtr` from a pointer.
1647    ///
1648    /// This is useful if you want to do volatile atomic accesses, and thus avoid creating
1649    /// a reference to the destination.
1650    #[inline]
1651    #[unstable(feature = "atomic_volatile", issue = "158947")]
1652    pub const fn from_ptr_raw(ptr: *mut *mut T) -> *const AtomicPtr<T> {
1653        ptr.cast_const().cast()
1654    }
1655
1656    /// Creates a new `AtomicPtr` initialized with a null pointer.
1657    ///
1658    /// # Examples
1659    ///
1660    /// ```
1661    /// #![feature(atomic_ptr_null)]
1662    /// use std::sync::atomic::{AtomicPtr, Ordering};
1663    ///
1664    /// let atomic_ptr = AtomicPtr::<()>::null();
1665    /// assert!(atomic_ptr.load(Ordering::Relaxed).is_null());
1666    /// ```
1667    #[inline]
1668    #[must_use]
1669    #[unstable(feature = "atomic_ptr_null", issue = "150733")]
1670    pub const fn null() -> AtomicPtr<T> {
1671        AtomicPtr::new(crate::ptr::null_mut())
1672    }
1673
1674    /// Returns a mutable reference to the underlying pointer.
1675    ///
1676    /// This is safe because the mutable reference guarantees that no other threads are
1677    /// concurrently accessing the atomic data.
1678    ///
1679    /// # Examples
1680    ///
1681    /// ```
1682    /// use std::sync::atomic::{AtomicPtr, Ordering};
1683    ///
1684    /// let mut data = 10;
1685    /// let mut atomic_ptr = AtomicPtr::new(&mut data);
1686    /// let mut other_data = 5;
1687    /// *atomic_ptr.get_mut() = &mut other_data;
1688    /// assert_eq!(unsafe { *atomic_ptr.load(Ordering::SeqCst) }, 5);
1689    /// ```
1690    #[inline]
1691    #[stable(feature = "atomic_access", since = "1.15.0")]
1692    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1693    pub const fn get_mut(&mut self) -> &mut *mut T {
1694        // SAFETY:
1695        // `Atomic<T>` is essentially a transparent wrapper around `T`.
1696        unsafe { &mut *self.as_ptr() }
1697    }
1698
1699    /// Gets atomic access to a pointer.
1700    ///
1701    /// **Note:** This function is only available on targets where `AtomicPtr<T>` has the same alignment as `*const T`
1702    ///
1703    /// # Examples
1704    ///
1705    /// ```
1706    /// use std::sync::atomic::{AtomicPtr, Ordering};
1707    ///
1708    /// let mut data = 123;
1709    /// let mut some_ptr = &mut data as *mut i32;
1710    /// let a = AtomicPtr::from_mut(&mut some_ptr);
1711    /// let mut other_data = 456;
1712    /// a.store(&mut other_data, Ordering::Relaxed);
1713    /// assert_eq!(unsafe { *some_ptr }, 456);
1714    /// ```
1715    #[inline]
1716    #[cfg(target_has_atomic_primitive_alignment = "ptr")]
1717    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
1718    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1719    pub const fn from_mut(v: &mut *mut T) -> &mut Self {
1720        let [] = [(); align_of::<AtomicPtr<()>>() - align_of::<*mut ()>()];
1721        // SAFETY:
1722        //  - the mutable reference guarantees unique ownership.
1723        //  - the alignment of `*mut T` and `Self` is the same on all platforms
1724        //    supported by rust, as verified above.
1725        unsafe { &mut *(v as *mut *mut T as *mut Self) }
1726    }
1727
1728    /// Gets non-atomic access to a `&mut [AtomicPtr]` slice.
1729    ///
1730    /// This is safe because the mutable reference guarantees that no other threads are
1731    /// concurrently accessing the atomic data.
1732    ///
1733    /// # Examples
1734    ///
1735    /// ```ignore-wasm
1736    /// use std::ptr::null_mut;
1737    /// use std::sync::atomic::{AtomicPtr, Ordering};
1738    ///
1739    /// let mut some_ptrs = [const { AtomicPtr::new(null_mut::<String>()) }; 10];
1740    ///
1741    /// let view: &mut [*mut String] = AtomicPtr::get_mut_slice(&mut some_ptrs);
1742    /// assert_eq!(view, [null_mut::<String>(); 10]);
1743    /// view
1744    ///     .iter_mut()
1745    ///     .enumerate()
1746    ///     .for_each(|(i, ptr)| *ptr = Box::into_raw(Box::new(format!("iteration#{i}"))));
1747    ///
1748    /// std::thread::scope(|s| {
1749    ///     for ptr in &some_ptrs {
1750    ///         s.spawn(move || {
1751    ///             let ptr = ptr.load(Ordering::Relaxed);
1752    ///             assert!(!ptr.is_null());
1753    ///
1754    ///             let name = unsafe { Box::from_raw(ptr) };
1755    ///             println!("Hello, {name}!");
1756    ///         });
1757    ///     }
1758    /// });
1759    /// ```
1760    #[inline]
1761    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
1762    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1763    pub const fn get_mut_slice(this: &mut [Self]) -> &mut [*mut T] {
1764        // SAFETY: the mutable reference guarantees unique ownership.
1765        unsafe { &mut *(this as *mut [Self] as *mut [*mut T]) }
1766    }
1767
1768    /// Gets atomic access to a slice of pointers.
1769    ///
1770    /// **Note:** This function is only available on targets where `AtomicPtr<T>` has the same alignment as `*const T`
1771    ///
1772    /// # Examples
1773    ///
1774    /// ```ignore-wasm
1775    /// use std::ptr::null_mut;
1776    /// use std::sync::atomic::{AtomicPtr, Ordering};
1777    ///
1778    /// let mut some_ptrs = [null_mut::<String>(); 10];
1779    /// let a = &*AtomicPtr::from_mut_slice(&mut some_ptrs);
1780    /// std::thread::scope(|s| {
1781    ///     for i in 0..a.len() {
1782    ///         s.spawn(move || {
1783    ///             let name = Box::new(format!("thread{i}"));
1784    ///             a[i].store(Box::into_raw(name), Ordering::Relaxed);
1785    ///         });
1786    ///     }
1787    /// });
1788    /// for p in some_ptrs {
1789    ///     assert!(!p.is_null());
1790    ///     let name = unsafe { Box::from_raw(p) };
1791    ///     println!("Hello, {name}!");
1792    /// }
1793    /// ```
1794    #[inline]
1795    #[cfg(target_has_atomic_primitive_alignment = "ptr")]
1796    #[stable(feature = "atomic_from_mut", since = "1.98.0")]
1797    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1798    pub const fn from_mut_slice(v: &mut [*mut T]) -> &mut [Self] {
1799        // SAFETY:
1800        //  - the mutable reference guarantees unique ownership.
1801        //  - the alignment of `*mut T` and `Self` is the same on all platforms
1802        //    supported by rust, as verified above.
1803        unsafe { &mut *(v as *mut [*mut T] as *mut [Self]) }
1804    }
1805
1806    /// Consumes the atomic and returns the contained value.
1807    ///
1808    /// This is safe because passing `self` by value guarantees that no other threads are
1809    /// concurrently accessing the atomic data.
1810    ///
1811    /// # Examples
1812    ///
1813    /// ```
1814    /// use std::sync::atomic::AtomicPtr;
1815    ///
1816    /// let mut data = 5;
1817    /// let atomic_ptr = AtomicPtr::new(&mut data);
1818    /// assert_eq!(unsafe { *atomic_ptr.into_inner() }, 5);
1819    /// ```
1820    #[inline]
1821    #[stable(feature = "atomic_access", since = "1.15.0")]
1822    #[rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0")]
1823    pub const fn into_inner(self) -> *mut T {
1824        // SAFETY:
1825        // `Atomic<T>` is essentially a transparent wrapper around `T`.
1826        unsafe { transmute(self) }
1827    }
1828
1829    /// Loads a value from the pointer.
1830    ///
1831    /// `load` takes an [`Ordering`] argument which describes the memory ordering
1832    /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
1833    ///
1834    /// # Panics
1835    ///
1836    /// Panics if `order` is [`Release`] or [`AcqRel`].
1837    ///
1838    /// # Examples
1839    ///
1840    /// ```
1841    /// use std::sync::atomic::{AtomicPtr, Ordering};
1842    ///
1843    /// let ptr = &mut 5;
1844    /// let some_ptr = AtomicPtr::new(ptr);
1845    ///
1846    /// let value = some_ptr.load(Ordering::Relaxed);
1847    /// ```
1848    #[inline]
1849    #[stable(feature = "rust1", since = "1.0.0")]
1850    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1851    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1852    pub const fn load(&self, order: Ordering) -> *mut T {
1853        // SAFETY: data races are prevented by atomic intrinsics.
1854        unsafe {
1855            atomic_load::<_, /* VOLATILE */ false>(self.as_ptr(), order)
1856        }
1857    }
1858
1859    /// Perform a volatile atomic load from the pointer.
1860    ///
1861    /// `load_volatile` takes an [`Ordering`] argument which describes the memory ordering
1862    /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
1863    ///
1864    #[doc = "Volatile operations are intended to act on I/O memory. As such, they are considered externally\nobservable events (just like syscalls, but less opaque), and are guaranteed to not be elided or\nreordered by the compiler across other externally observable events. With this in mind, there\nare two cases of usage that need to be distinguished:\n\n- When a volatile operation is used for memory inside an [allocation], it behaves exactly\n  like [`load`][Self::load], except for the additional guarantee that it won\'t be elided or\n  reordered across other externally observable events (see above). This implies that the\n  operation will actually access memory and not e.g. be lowered to reusing data from a\n  previous load. Other than that, all the usual rules for memory accesses apply (including\n  provenance).\n\n- Volatile operations, however, may also be used to access memory that is _outside_ of any Rust\n  allocation. In this use-case, the pointer does *not* have to be [valid] for reads. This is\n  typically used for CPU and peripheral registers that must be accessed via an I/O memory mapping,\n  most commonly at fixed addresses reserved by the hardware. These often have special semantics\n  associated to their manipulation, and cannot be used as general purpose memory. Here, any address\n  value is possible, including 0 and [`usize::MAX`], so long as the semantics of such a read are\n  well-defined by the target hardware. The provenance of the pointer is irrelevant, and it can be\n  created with [`without_provenance`][crate::ptr::without_provenance]. The access is allowed to\n  trap, which must immediately abort the process. It can also cause other side-effects, but those\n  must not affect Rust-allocated memory in any way.\n\nIn both cases, the access is also considered atomic with the given `order`. This allows\nsynchronization with other threads or devices that share memory with this program.\n\nWhen invoked during const evaluation, this behaves like a regular atomic load. In\nparticular, such reads must always follow the first of the two cases above.\n\n[allocation]: crate::ptr#allocated-object\n"include_str!("./atomic_load_volatile.md")]
1865    ///
1866    /// # Safety
1867    ///
1868    /// Behavior is undefined if any of the following conditions are violated:
1869    ///
1870    /// * `self` must be [valid] for reads, or `self` must point to memory
1871    ///   outside of all Rust allocations and reading from that memory must:
1872    ///   - not trap, and
1873    ///   - not cause any memory inside a Rust allocation to be modified.
1874    ///
1875    /// * `self` must be aligned to `align_of::<AtomicPtr<T>>()` (note that on some platforms this
1876    ///   can be bigger than `align_of::<*mut T>()`).
1877    ///
1878    /// * Reading from `self` must produce a properly initialized value of type `*mut T`.
1879    ///
1880    /// [valid]: core::ptr#safety
1881    ///
1882    /// # Panics
1883    ///
1884    /// Panics if `order` is [`Release`] or [`AcqRel`].
1885    ///
1886    /// # Examples
1887    ///
1888    /// Assuming an MMIO region at `MMIO_ADDR` that belongs to a device with direct memory
1889    /// access, we may receive a buffer in shared memory from that device as follows:
1890    ///
1891    /// ```rust,no_run
1892    /// #![feature(atomic_volatile)]
1893    /// use std::sync::atomic::{fence, AtomicPtr, Ordering};
1894    /// use std::ptr;
1895    ///
1896    /// const MMIO_ADDR: *mut *mut u8 = ptr::without_provenance_mut(0xCAF0);
1897    /// let atomic_ptr = AtomicPtr::<u8>::from_ptr_raw(MMIO_ADDR);
1898    ///
1899    /// // Spin until we see a non-zero value.
1900    /// let buf = 'buf: loop {
1901    ///     let buf = unsafe { atomic_ptr.load_volatile(Ordering::Relaxed) };
1902    ///     if !buf.is_null() {
1903    ///         break 'buf buf;
1904    ///     }
1905    /// };
1906    /// // Synchronize with the store whose value we just read.
1907    /// // Note: a standard acquire fence may not be sufficient to synchronize with DMA devices.
1908    /// // Depending on your target, you may have to use inline assembly to emit a special fence.
1909    /// fence(Ordering::Acquire);
1910    ///
1911    /// // Now process the data in `buf`.
1912    /// ```
1913    #[inline]
1914    #[unstable(feature = "atomic_volatile", issue = "158947")]
1915    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
1916    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1917    pub const unsafe fn load_volatile(self: *const Self, order: Ordering) -> *mut T {
1918        // SAFETY: follows from our own safety requirements.
1919        unsafe {
1920            atomic_load::<_, /* VOLATILE */ true>(self.cast::<*mut T>(), order)
1921        }
1922    }
1923
1924    /// Stores a value into the pointer.
1925    ///
1926    /// `store` takes an [`Ordering`] argument which describes the memory ordering
1927    /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
1928    ///
1929    /// # Panics
1930    ///
1931    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
1932    ///
1933    /// # Examples
1934    ///
1935    /// ```
1936    /// use std::sync::atomic::{AtomicPtr, Ordering};
1937    ///
1938    /// let ptr = &mut 5;
1939    /// let some_ptr = AtomicPtr::new(ptr);
1940    ///
1941    /// let other_ptr = &mut 10;
1942    ///
1943    /// some_ptr.store(other_ptr, Ordering::Relaxed);
1944    /// ```
1945    #[inline]
1946    #[stable(feature = "rust1", since = "1.0.0")]
1947    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
1948    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1949    #[rustc_should_not_be_called_on_const_items]
1950    pub const fn store(&self, ptr: *mut T, order: Ordering) {
1951        // SAFETY: data races are prevented by atomic intrinsics.
1952        unsafe {
1953            atomic_store::<_, /* VOLATILE */ false>(self.as_ptr(), ptr, order);
1954        }
1955    }
1956
1957    /// Performs a volatile atomic store into the pointer.
1958    ///
1959    /// `store_volatile` takes an [`Ordering`] argument which describes the memory ordering
1960    /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
1961    ///
1962    #[doc = "Volatile operations are intended to act on I/O memory. As such, they are considered externally\nobservable events (just like syscalls), and are guaranteed to not be elided or reordered by the\ncompiler across other externally observable events. With this in mind, there are two cases of\nusage that need to be distinguished:\n\n- When a volatile operation is used for memory inside an [allocation], it behaves exactly like\n  [`store`][Self::store], except for the additional guarantee that it won\'t be elided or reordered\n  across other externally observable events (see above). This implies that the operation will\n  actually access memory and not e.g. be lowered to a register access. Other than that, all the\n  usual rules for memory accesses apply (including provenance).\n\n- Volatile operations, however, may also be used to access memory that is _outside_ of any Rust\n  allocation. In this use-case, the pointer does *not* have to be [valid] for writes. This is\n  typically used for CPU and peripheral registers that must be accessed via an I/O memory mapping,\n  most commonly at fixed addresses reserved by the hardware. These often have special semantics\n  associated to their manipulation, and cannot be used as general purpose memory. Here, any address\n  value is possible, including 0 and [`usize::MAX`], so long as the semantics of such a write are\n  well-defined by the target hardware. The provenance of the pointer is irrelevant, and it can be\n  created with [`without_provenance_mut`][crate::ptr::without_provenance_mut]. The access is allowed\n  to trap, which must immediately abort the process. It can also cause other side-effects, but those\n  must not affect Rust-allocated memory in any way.\n\nIn both cases, the access is also considered atomic with the given `order`. This allows\nsynchronization with other threads or devices that share memory with this program.\n\nWhen invoked during const evaluation, this behaves like a regular atomic store. In\nparticular, such reads must always follow the first of the two cases above.\n\n[allocation]: crate::ptr#allocated-object\n"include_str!("./atomic_store_volatile.md")]
1963    ///
1964    /// # Safety
1965    ///
1966    /// Behavior is undefined if any of the following conditions are violated:
1967    ///
1968    /// * `self` must be either [valid] for writes, or `self` must point to memory
1969    ///   outside of all Rust allocations and writing to that memory must:
1970    ///   - not trap, and
1971    ///   - not cause any memory inside a Rust allocation to be modified.
1972    ///
1973    /// * `self` must be aligned to `align_of::<AtomicPtr<T>>()` (note that on some platforms this
1974    ///   can be bigger than `align_of::<*mut T>()`).
1975    ///
1976    /// [valid]: core::ptr#safety
1977    ///
1978    /// # Panics
1979    ///
1980    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
1981    ///
1982    /// # Examples
1983    ///
1984    /// Assuming an MMIO region at `MMIO_ADDR` that belongs to a device with direct memory
1985    /// access, we may submit a buffer in shared memory to that device as follows:
1986    ///
1987    /// ```rust,no_run
1988    /// #![feature(atomic_volatile)]
1989    /// use std::sync::atomic::{fence, AtomicPtr, Ordering};
1990    /// use std::ptr;
1991    ///
1992    /// const MMIO_ADDR: *mut *mut u8 = ptr::without_provenance_mut(0xCAF0);
1993    /// let atomic_ptr = AtomicPtr::<u8>::from_ptr_raw(MMIO_ADDR);
1994    ///
1995    /// // Prepare some data for the DMA device.
1996    /// # fn get_dma_buffer() -> *mut u8 { panic!() }
1997    /// let buf = get_dma_buffer();
1998    ///
1999    /// // Ensure the other side can synchronize with the store we do below.
2000    /// // Note: a standard release fence may not be sufficient to synchronize with DMA devices.
2001    /// // Depending on your target, you may have to use inline assembly to emit a special fence.
2002    /// fence(Ordering::Release);
2003    ///
2004    /// unsafe { atomic_ptr.store_volatile(buf, Ordering::Relaxed) };
2005    /// ```
2006    #[inline]
2007    #[unstable(feature = "atomic_volatile", issue = "158947")]
2008    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
2009    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2010    #[rustc_should_not_be_called_on_const_items]
2011    pub const unsafe fn store_volatile(self: *const Self, ptr: *mut T, order: Ordering) {
2012        // SAFETY: follows from our own safety requirements.
2013        unsafe {
2014            atomic_store::<_, /* VOLATILE */ true>(self.cast::<*mut T>().cast_mut(), ptr, order);
2015        }
2016    }
2017
2018    /// Stores a value into the pointer, returning the previous value.
2019    ///
2020    /// `swap` takes an [`Ordering`] argument which describes the memory ordering
2021    /// of this operation. All ordering modes are possible. Note that using
2022    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
2023    /// using [`Release`] makes the load part [`Relaxed`].
2024    ///
2025    /// **Note:** This method is only available on platforms that support atomic
2026    /// operations on pointers.
2027    ///
2028    /// # Examples
2029    ///
2030    /// ```
2031    /// use std::sync::atomic::{AtomicPtr, Ordering};
2032    ///
2033    /// let ptr = &mut 5;
2034    /// let some_ptr = AtomicPtr::new(ptr);
2035    ///
2036    /// let other_ptr = &mut 10;
2037    ///
2038    /// let value = some_ptr.swap(other_ptr, Ordering::Relaxed);
2039    /// ```
2040    #[inline]
2041    #[stable(feature = "rust1", since = "1.0.0")]
2042    #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
2043    #[cfg(target_has_atomic = "ptr")]
2044    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2045    #[rustc_should_not_be_called_on_const_items]
2046    pub const fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T {
2047        // SAFETY: data races are prevented by atomic intrinsics.
2048        unsafe { atomic_swap(self.as_ptr(), ptr, order) }
2049    }
2050
2051    /// Stores a value into the pointer if the current value is the same as the `current` value.
2052    ///
2053    /// The return value is always the previous value. If it is equal to `current`, then the value
2054    /// was updated.
2055    ///
2056    /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
2057    /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
2058    /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
2059    /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
2060    /// happens, and using [`Release`] makes the load part [`Relaxed`].
2061    ///
2062    /// **Note:** This method is only available on platforms that support atomic
2063    /// operations on pointers.
2064    ///
2065    /// # Migrating to `compare_exchange` and `compare_exchange_weak`
2066    ///
2067    /// `compare_and_swap` is equivalent to `compare_exchange` with the following mapping for
2068    /// memory orderings:
2069    ///
2070    /// Original | Success | Failure
2071    /// -------- | ------- | -------
2072    /// Relaxed  | Relaxed | Relaxed
2073    /// Acquire  | Acquire | Acquire
2074    /// Release  | Release | Relaxed
2075    /// AcqRel   | AcqRel  | Acquire
2076    /// SeqCst   | SeqCst  | SeqCst
2077    ///
2078    /// `compare_and_swap` and `compare_exchange` also differ in their return type. You can use
2079    /// `compare_exchange(...).unwrap_or_else(|x| x)` to recover the behavior of `compare_and_swap`,
2080    /// but in most cases it is more idiomatic to check whether the return value is `Ok` or `Err`
2081    /// rather than to infer success vs failure based on the value that was read.
2082    ///
2083    /// During migration, consider whether it makes sense to use `compare_exchange_weak` instead.
2084    /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds,
2085    /// which allows the compiler to generate better assembly code when the compare and swap
2086    /// is used in a loop.
2087    ///
2088    /// # Examples
2089    ///
2090    /// ```
2091    /// use std::sync::atomic::{AtomicPtr, Ordering};
2092    ///
2093    /// let ptr = &mut 5;
2094    /// let some_ptr = AtomicPtr::new(ptr);
2095    ///
2096    /// let other_ptr = &mut 10;
2097    ///
2098    /// let value = some_ptr.compare_and_swap(ptr, other_ptr, Ordering::Relaxed);
2099    /// ```
2100    #[inline]
2101    #[stable(feature = "rust1", since = "1.0.0")]
2102    #[deprecated(
2103        since = "1.50.0",
2104        note = "Use `compare_exchange` or `compare_exchange_weak` instead"
2105    )]
2106    #[cfg(target_has_atomic = "ptr")]
2107    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2108    #[rustc_should_not_be_called_on_const_items]
2109    pub fn compare_and_swap(&self, current: *mut T, new: *mut T, order: Ordering) -> *mut T {
2110        match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) {
2111            Ok(x) => x,
2112            Err(x) => x,
2113        }
2114    }
2115
2116    /// Stores a value into the pointer if the current value is the same as the `current` value.
2117    ///
2118    /// The return value is a result indicating whether the new value was written and containing
2119    /// the previous value. On success this value is guaranteed to be equal to `current`.
2120    ///
2121    /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
2122    /// ordering of this operation. `success` describes the required ordering for the
2123    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
2124    /// `failure` describes the required ordering for the load operation that takes place when
2125    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
2126    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
2127    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
2128    ///
2129    /// **Note:** This method is only available on platforms that support atomic
2130    /// operations on pointers.
2131    ///
2132    /// # Examples
2133    ///
2134    /// ```
2135    /// use std::sync::atomic::{AtomicPtr, Ordering};
2136    ///
2137    /// let ptr = &mut 5;
2138    /// let some_ptr = AtomicPtr::new(ptr);
2139    ///
2140    /// let other_ptr = &mut 10;
2141    ///
2142    /// let value = some_ptr.compare_exchange(ptr, other_ptr,
2143    ///                                       Ordering::SeqCst, Ordering::Relaxed);
2144    /// ```
2145    ///
2146    /// # Considerations
2147    ///
2148    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
2149    /// of CAS operations. In particular, a load of the value followed by a successful
2150    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
2151    /// changed the value in the interim. This is usually important when the *equality* check in
2152    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
2153    /// does not necessarily imply identity. This is a particularly common case for pointers, as
2154    /// a pointer holding the same address does not imply that the same object exists at that
2155    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
2156    ///
2157    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
2158    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
2159    #[inline]
2160    #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
2161    #[cfg(target_has_atomic = "ptr")]
2162    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2163    #[rustc_should_not_be_called_on_const_items]
2164    pub fn compare_exchange(
2165        &self,
2166        current: *mut T,
2167        new: *mut T,
2168        success: Ordering,
2169        failure: Ordering,
2170    ) -> Result<*mut T, *mut T> {
2171        // SAFETY: data races are prevented by atomic intrinsics.
2172        unsafe { atomic_compare_exchange(self.as_ptr(), current, new, success, failure) }
2173    }
2174
2175    /// Stores a value into the pointer if the current value is the same as the `current` value.
2176    ///
2177    /// Unlike [`AtomicPtr::compare_exchange`], this function is allowed to spuriously fail even when the
2178    /// comparison succeeds, which can result in more efficient code on some platforms. The
2179    /// return value is a result indicating whether the new value was written and containing the
2180    /// previous value.
2181    ///
2182    /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
2183    /// ordering of this operation. `success` describes the required ordering for the
2184    /// read-modify-write operation that takes place if the comparison with `current` succeeds.
2185    /// `failure` describes the required ordering for the load operation that takes place when
2186    /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
2187    /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
2188    /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
2189    ///
2190    /// **Note:** This method is only available on platforms that support atomic
2191    /// operations on pointers.
2192    ///
2193    /// # Examples
2194    ///
2195    /// ```
2196    /// use std::sync::atomic::{AtomicPtr, Ordering};
2197    ///
2198    /// let some_ptr = AtomicPtr::new(&mut 5);
2199    ///
2200    /// let new = &mut 10;
2201    /// let mut old = some_ptr.load(Ordering::Relaxed);
2202    /// loop {
2203    ///     match some_ptr.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
2204    ///         Ok(_) => break,
2205    ///         Err(x) => old = x,
2206    ///     }
2207    /// }
2208    /// ```
2209    ///
2210    /// # Considerations
2211    ///
2212    /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
2213    /// of CAS operations. In particular, a load of the value followed by a successful
2214    /// `compare_exchange` with the previous load *does not ensure* that other threads have not
2215    /// changed the value in the interim. This is usually important when the *equality* check in
2216    /// the `compare_exchange` is being used to check the *identity* of a value, but equality
2217    /// does not necessarily imply identity. This is a particularly common case for pointers, as
2218    /// a pointer holding the same address does not imply that the same object exists at that
2219    /// address! In this case, `compare_exchange` can lead to the [ABA problem].
2220    ///
2221    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
2222    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
2223    #[inline]
2224    #[stable(feature = "extended_compare_and_swap", since = "1.10.0")]
2225    #[cfg(target_has_atomic = "ptr")]
2226    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2227    #[rustc_should_not_be_called_on_const_items]
2228    pub fn compare_exchange_weak(
2229        &self,
2230        current: *mut T,
2231        new: *mut T,
2232        success: Ordering,
2233        failure: Ordering,
2234    ) -> Result<*mut T, *mut T> {
2235        // SAFETY: This intrinsic is unsafe because it operates on a raw pointer
2236        // but we know for sure that the pointer is valid (we just got it from
2237        // an `UnsafeCell` that we have by reference) and the atomic operation
2238        // itself allows us to safely mutate the `UnsafeCell` contents.
2239        unsafe { atomic_compare_exchange_weak(self.as_ptr(), current, new, success, failure) }
2240    }
2241
2242    /// An alias for [`AtomicPtr::try_update`].
2243    #[inline]
2244    #[stable(feature = "atomic_fetch_update", since = "1.53.0")]
2245    #[cfg(target_has_atomic = "ptr")]
2246    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2247    #[rustc_should_not_be_called_on_const_items]
2248    #[deprecated(
2249        since = "1.99.0",
2250        note = "renamed to `try_update` for consistency",
2251        suggestion = "try_update"
2252    )]
2253    pub fn fetch_update<F>(
2254        &self,
2255        set_order: Ordering,
2256        fetch_order: Ordering,
2257        f: F,
2258    ) -> Result<*mut T, *mut T>
2259    where
2260        F: FnMut(*mut T) -> Option<*mut T>,
2261    {
2262        self.try_update(set_order, fetch_order, f)
2263    }
2264    /// Fetches the value, and applies a function to it that returns an optional
2265    /// new value. Returns a `Result` of `Ok(previous_value)` if the function
2266    /// returned `Some(_)`, else `Err(previous_value)`.
2267    ///
2268    /// See also: [`update`](`AtomicPtr::update`).
2269    ///
2270    /// Note: This may call the function multiple times if the value has been
2271    /// changed from other threads in the meantime, as long as the function
2272    /// returns `Some(_)`, but the function will have been applied only once to
2273    /// the stored value.
2274    ///
2275    /// `try_update` takes two [`Ordering`] arguments to describe the memory
2276    /// ordering of this operation. The first describes the required ordering for
2277    /// when the operation finally succeeds while the second describes the
2278    /// required ordering for loads. These correspond to the success and failure
2279    /// orderings of [`AtomicPtr::compare_exchange`] respectively.
2280    ///
2281    /// Using [`Acquire`] as success ordering makes the store part of this
2282    /// operation [`Relaxed`], and using [`Release`] makes the final successful
2283    /// load [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`],
2284    /// [`Acquire`] or [`Relaxed`].
2285    ///
2286    /// **Note:** This method is only available on platforms that support atomic
2287    /// operations on pointers.
2288    ///
2289    /// # Considerations
2290    ///
2291    /// This method is not magic; it is not provided by the hardware, and does not act like a
2292    /// critical section or mutex.
2293    ///
2294    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
2295    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem],
2296    /// which is a particularly common pitfall for pointers!
2297    ///
2298    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
2299    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
2300    ///
2301    /// # Examples
2302    ///
2303    /// ```rust
2304    /// use std::sync::atomic::{AtomicPtr, Ordering};
2305    ///
2306    /// let ptr: *mut _ = &mut 5;
2307    /// let some_ptr = AtomicPtr::new(ptr);
2308    ///
2309    /// let new: *mut _ = &mut 10;
2310    /// assert_eq!(some_ptr.try_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(ptr));
2311    /// let result = some_ptr.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| {
2312    ///     if x == ptr {
2313    ///         Some(new)
2314    ///     } else {
2315    ///         None
2316    ///     }
2317    /// });
2318    /// assert_eq!(result, Ok(ptr));
2319    /// assert_eq!(some_ptr.load(Ordering::SeqCst), new);
2320    /// ```
2321    #[inline]
2322    #[stable(feature = "atomic_try_update", since = "1.95.0")]
2323    #[cfg(target_has_atomic = "ptr")]
2324    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2325    #[rustc_should_not_be_called_on_const_items]
2326    pub fn try_update(
2327        &self,
2328        set_order: Ordering,
2329        fetch_order: Ordering,
2330        mut f: impl FnMut(*mut T) -> Option<*mut T>,
2331    ) -> Result<*mut T, *mut T> {
2332        let mut prev = self.load(fetch_order);
2333        while let Some(next) = f(prev) {
2334            match self.compare_exchange_weak(prev, next, set_order, fetch_order) {
2335                x @ Ok(_) => return x,
2336                Err(next_prev) => prev = next_prev,
2337            }
2338        }
2339        Err(prev)
2340    }
2341
2342    /// Fetches the value, and applies a function to it that returns a new value.
2343    /// The new value is stored and the old value is returned.
2344    ///
2345    /// See also: [`try_update`](`AtomicPtr::try_update`).
2346    ///
2347    /// Note: This may call the function multiple times if the value has been changed from other threads in
2348    /// the meantime, but the function will have been applied only once to the stored value.
2349    ///
2350    /// `update` takes two [`Ordering`] arguments to describe the memory
2351    /// ordering of this operation. The first describes the required ordering for
2352    /// when the operation finally succeeds while the second describes the
2353    /// required ordering for loads. These correspond to the success and failure
2354    /// orderings of [`AtomicPtr::compare_exchange`] respectively.
2355    ///
2356    /// Using [`Acquire`] as success ordering makes the store part
2357    /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
2358    /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
2359    ///
2360    /// **Note:** This method is only available on platforms that support atomic
2361    /// operations on pointers.
2362    ///
2363    /// # Considerations
2364    ///
2365    /// This method is not magic; it is not provided by the hardware, and does not act like a
2366    /// critical section or mutex.
2367    ///
2368    /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
2369    /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem],
2370    /// which is a particularly common pitfall for pointers!
2371    ///
2372    /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
2373    /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
2374    ///
2375    /// # Examples
2376    ///
2377    /// ```rust
2378    ///
2379    /// use std::sync::atomic::{AtomicPtr, Ordering};
2380    ///
2381    /// let ptr: *mut _ = &mut 5;
2382    /// let some_ptr = AtomicPtr::new(ptr);
2383    ///
2384    /// let new: *mut _ = &mut 10;
2385    /// let result = some_ptr.update(Ordering::SeqCst, Ordering::SeqCst, |_| new);
2386    /// assert_eq!(result, ptr);
2387    /// assert_eq!(some_ptr.load(Ordering::SeqCst), new);
2388    /// ```
2389    #[inline]
2390    #[stable(feature = "atomic_try_update", since = "1.95.0")]
2391    #[cfg(target_has_atomic = "ptr")]
2392    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2393    #[rustc_should_not_be_called_on_const_items]
2394    pub fn update(
2395        &self,
2396        set_order: Ordering,
2397        fetch_order: Ordering,
2398        mut f: impl FnMut(*mut T) -> *mut T,
2399    ) -> *mut T {
2400        let mut prev = self.load(fetch_order);
2401        loop {
2402            match self.compare_exchange_weak(prev, f(prev), set_order, fetch_order) {
2403                Ok(x) => break x,
2404                Err(next_prev) => prev = next_prev,
2405            }
2406        }
2407    }
2408
2409    /// Offsets the pointer's address by adding `val` (in units of `T`),
2410    /// returning the previous pointer.
2411    ///
2412    /// This is equivalent to using [`wrapping_add`] to atomically perform the
2413    /// equivalent of `ptr = ptr.wrapping_add(val);`.
2414    ///
2415    /// This method operates in units of `T`, which means that it cannot be used
2416    /// to offset the pointer by an amount which is not a multiple of
2417    /// `size_of::<T>()`. This can sometimes be inconvenient, as you may want to
2418    /// work with a deliberately misaligned pointer. In such cases, you may use
2419    /// the [`fetch_byte_add`](Self::fetch_byte_add) method instead.
2420    ///
2421    /// `fetch_ptr_add` takes an [`Ordering`] argument which describes the
2422    /// memory ordering of this operation. All ordering modes are possible. Note
2423    /// that using [`Acquire`] makes the store part of this operation
2424    /// [`Relaxed`], and using [`Release`] makes the load part [`Relaxed`].
2425    ///
2426    /// **Note**: This method is only available on platforms that support atomic
2427    /// operations on [`AtomicPtr`].
2428    ///
2429    /// [`wrapping_add`]: pointer::wrapping_add
2430    ///
2431    /// # Examples
2432    ///
2433    /// ```
2434    /// use core::sync::atomic::{AtomicPtr, Ordering};
2435    ///
2436    /// let atom = AtomicPtr::<i64>::new(core::ptr::null_mut());
2437    /// assert_eq!(atom.fetch_ptr_add(1, Ordering::Relaxed).addr(), 0);
2438    /// // Note: units of `size_of::<i64>()`.
2439    /// assert_eq!(atom.load(Ordering::Relaxed).addr(), 8);
2440    /// ```
2441    #[inline]
2442    #[cfg(target_has_atomic = "ptr")]
2443    #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")]
2444    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2445    #[rustc_should_not_be_called_on_const_items]
2446    pub fn fetch_ptr_add(&self, val: usize, order: Ordering) -> *mut T {
2447        self.fetch_byte_add(val.wrapping_mul(size_of::<T>()), order)
2448    }
2449
2450    /// Offsets the pointer's address by subtracting `val` (in units of `T`),
2451    /// returning the previous pointer.
2452    ///
2453    /// This is equivalent to using [`wrapping_sub`] to atomically perform the
2454    /// equivalent of `ptr = ptr.wrapping_sub(val);`.
2455    ///
2456    /// This method operates in units of `T`, which means that it cannot be used
2457    /// to offset the pointer by an amount which is not a multiple of
2458    /// `size_of::<T>()`. This can sometimes be inconvenient, as you may want to
2459    /// work with a deliberately misaligned pointer. In such cases, you may use
2460    /// the [`fetch_byte_sub`](Self::fetch_byte_sub) method instead.
2461    ///
2462    /// `fetch_ptr_sub` takes an [`Ordering`] argument which describes the memory
2463    /// ordering of this operation. All ordering modes are possible. Note that
2464    /// using [`Acquire`] makes the store part of this operation [`Relaxed`],
2465    /// and using [`Release`] makes the load part [`Relaxed`].
2466    ///
2467    /// **Note**: This method is only available on platforms that support atomic
2468    /// operations on [`AtomicPtr`].
2469    ///
2470    /// [`wrapping_sub`]: pointer::wrapping_sub
2471    ///
2472    /// # Examples
2473    ///
2474    /// ```
2475    /// use core::sync::atomic::{AtomicPtr, Ordering};
2476    ///
2477    /// let array = [1i32, 2i32];
2478    /// let atom = AtomicPtr::new(array.as_ptr().wrapping_add(1) as *mut _);
2479    ///
2480    /// assert!(core::ptr::eq(
2481    ///     atom.fetch_ptr_sub(1, Ordering::Relaxed),
2482    ///     &array[1],
2483    /// ));
2484    /// assert!(core::ptr::eq(atom.load(Ordering::Relaxed), &array[0]));
2485    /// ```
2486    #[inline]
2487    #[cfg(target_has_atomic = "ptr")]
2488    #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")]
2489    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2490    #[rustc_should_not_be_called_on_const_items]
2491    pub fn fetch_ptr_sub(&self, val: usize, order: Ordering) -> *mut T {
2492        self.fetch_byte_sub(val.wrapping_mul(size_of::<T>()), order)
2493    }
2494
2495    /// Offsets the pointer's address by adding `val` *bytes*, returning the
2496    /// previous pointer.
2497    ///
2498    /// This is equivalent to using [`wrapping_byte_add`] to atomically
2499    /// perform `ptr = ptr.wrapping_byte_add(val)`.
2500    ///
2501    /// `fetch_byte_add` takes an [`Ordering`] argument which describes the
2502    /// memory ordering of this operation. All ordering modes are possible. Note
2503    /// that using [`Acquire`] makes the store part of this operation
2504    /// [`Relaxed`], and using [`Release`] makes the load part [`Relaxed`].
2505    ///
2506    /// **Note**: This method is only available on platforms that support atomic
2507    /// operations on [`AtomicPtr`].
2508    ///
2509    /// [`wrapping_byte_add`]: pointer::wrapping_byte_add
2510    ///
2511    /// # Examples
2512    ///
2513    /// ```
2514    /// use core::sync::atomic::{AtomicPtr, Ordering};
2515    ///
2516    /// let atom = AtomicPtr::<i64>::new(core::ptr::null_mut());
2517    /// assert_eq!(atom.fetch_byte_add(1, Ordering::Relaxed).addr(), 0);
2518    /// // Note: in units of bytes, not `size_of::<i64>()`.
2519    /// assert_eq!(atom.load(Ordering::Relaxed).addr(), 1);
2520    /// ```
2521    #[inline]
2522    #[cfg(target_has_atomic = "ptr")]
2523    #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")]
2524    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2525    #[rustc_should_not_be_called_on_const_items]
2526    pub fn fetch_byte_add(&self, val: usize, order: Ordering) -> *mut T {
2527        // SAFETY: data races are prevented by atomic intrinsics.
2528        unsafe { atomic_add(self.as_ptr(), val, order).cast() }
2529    }
2530
2531    /// Offsets the pointer's address by subtracting `val` *bytes*, returning the
2532    /// previous pointer.
2533    ///
2534    /// This is equivalent to using [`wrapping_byte_sub`] to atomically
2535    /// perform `ptr = ptr.wrapping_byte_sub(val)`.
2536    ///
2537    /// `fetch_byte_sub` takes an [`Ordering`] argument which describes the
2538    /// memory ordering of this operation. All ordering modes are possible. Note
2539    /// that using [`Acquire`] makes the store part of this operation
2540    /// [`Relaxed`], and using [`Release`] makes the load part [`Relaxed`].
2541    ///
2542    /// **Note**: This method is only available on platforms that support atomic
2543    /// operations on [`AtomicPtr`].
2544    ///
2545    /// [`wrapping_byte_sub`]: pointer::wrapping_byte_sub
2546    ///
2547    /// # Examples
2548    ///
2549    /// ```
2550    /// use core::sync::atomic::{AtomicPtr, Ordering};
2551    ///
2552    /// let mut arr = [0i64, 1];
2553    /// let atom = AtomicPtr::<i64>::new(&raw mut arr[1]);
2554    /// assert_eq!(atom.fetch_byte_sub(8, Ordering::Relaxed).addr(), (&raw const arr[1]).addr());
2555    /// assert_eq!(atom.load(Ordering::Relaxed).addr(), (&raw const arr[0]).addr());
2556    /// ```
2557    #[inline]
2558    #[cfg(target_has_atomic = "ptr")]
2559    #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")]
2560    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2561    #[rustc_should_not_be_called_on_const_items]
2562    pub fn fetch_byte_sub(&self, val: usize, order: Ordering) -> *mut T {
2563        // SAFETY: data races are prevented by atomic intrinsics.
2564        unsafe { atomic_sub(self.as_ptr(), val, order).cast() }
2565    }
2566
2567    /// Performs a bitwise "or" operation on the address of the current pointer,
2568    /// and the argument `val`, and stores a pointer with provenance of the
2569    /// current pointer and the resulting address.
2570    ///
2571    /// This is equivalent to using [`map_addr`] to atomically perform
2572    /// `ptr = ptr.map_addr(|a| a | val)`. This can be used in tagged
2573    /// pointer schemes to atomically set tag bits.
2574    ///
2575    /// **Caveat**: This operation returns the previous value. To compute the
2576    /// stored value without losing provenance, you may use [`map_addr`]. For
2577    /// example: `a.fetch_or(val).map_addr(|a| a | val)`.
2578    ///
2579    /// `fetch_or` takes an [`Ordering`] argument which describes the memory
2580    /// ordering of this operation. All ordering modes are possible. Note that
2581    /// using [`Acquire`] makes the store part of this operation [`Relaxed`],
2582    /// and using [`Release`] makes the load part [`Relaxed`].
2583    ///
2584    /// **Note**: This method is only available on platforms that support atomic
2585    /// operations on [`AtomicPtr`].
2586    ///
2587    /// This API and its claimed semantics are part of the Strict Provenance
2588    /// experiment, see the [module documentation for `ptr`][crate::ptr] for
2589    /// details.
2590    ///
2591    /// [`map_addr`]: pointer::map_addr
2592    ///
2593    /// # Examples
2594    ///
2595    /// ```
2596    /// use core::sync::atomic::{AtomicPtr, Ordering};
2597    ///
2598    /// let pointer = &mut 3i64 as *mut i64;
2599    ///
2600    /// let atom = AtomicPtr::<i64>::new(pointer);
2601    /// // Tag the bottom bit of the pointer.
2602    /// assert_eq!(atom.fetch_or(1, Ordering::Relaxed).addr() & 1, 0);
2603    /// // Extract and untag.
2604    /// let tagged = atom.load(Ordering::Relaxed);
2605    /// assert_eq!(tagged.addr() & 1, 1);
2606    /// assert_eq!(tagged.map_addr(|p| p & !1), pointer);
2607    /// ```
2608    #[inline]
2609    #[cfg(target_has_atomic = "ptr")]
2610    #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")]
2611    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2612    #[rustc_should_not_be_called_on_const_items]
2613    pub fn fetch_or(&self, val: usize, order: Ordering) -> *mut T {
2614        // SAFETY: data races are prevented by atomic intrinsics.
2615        unsafe { atomic_or(self.as_ptr(), val, order).cast() }
2616    }
2617
2618    /// Performs a bitwise "and" operation on the address of the current
2619    /// pointer, and the argument `val`, and stores a pointer with provenance of
2620    /// the current pointer and the resulting address.
2621    ///
2622    /// This is equivalent to using [`map_addr`] to atomically perform
2623    /// `ptr = ptr.map_addr(|a| a & val)`. This can be used in tagged
2624    /// pointer schemes to atomically unset tag bits.
2625    ///
2626    /// **Caveat**: This operation returns the previous value. To compute the
2627    /// stored value without losing provenance, you may use [`map_addr`]. For
2628    /// example: `a.fetch_and(val).map_addr(|a| a & val)`.
2629    ///
2630    /// `fetch_and` takes an [`Ordering`] argument which describes the memory
2631    /// ordering of this operation. All ordering modes are possible. Note that
2632    /// using [`Acquire`] makes the store part of this operation [`Relaxed`],
2633    /// and using [`Release`] makes the load part [`Relaxed`].
2634    ///
2635    /// **Note**: This method is only available on platforms that support atomic
2636    /// operations on [`AtomicPtr`].
2637    ///
2638    /// This API and its claimed semantics are part of the Strict Provenance
2639    /// experiment, see the [module documentation for `ptr`][crate::ptr] for
2640    /// details.
2641    ///
2642    /// [`map_addr`]: pointer::map_addr
2643    ///
2644    /// # Examples
2645    ///
2646    /// ```
2647    /// use core::sync::atomic::{AtomicPtr, Ordering};
2648    ///
2649    /// let pointer = &mut 3i64 as *mut i64;
2650    /// // A tagged pointer
2651    /// let atom = AtomicPtr::<i64>::new(pointer.map_addr(|a| a | 1));
2652    /// assert_eq!(atom.fetch_or(1, Ordering::Relaxed).addr() & 1, 1);
2653    /// // Untag, and extract the previously tagged pointer.
2654    /// let untagged = atom.fetch_and(!1, Ordering::Relaxed)
2655    ///     .map_addr(|a| a & !1);
2656    /// assert_eq!(untagged, pointer);
2657    /// ```
2658    #[inline]
2659    #[cfg(target_has_atomic = "ptr")]
2660    #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")]
2661    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2662    #[rustc_should_not_be_called_on_const_items]
2663    pub fn fetch_and(&self, val: usize, order: Ordering) -> *mut T {
2664        // SAFETY: data races are prevented by atomic intrinsics.
2665        unsafe { atomic_and(self.as_ptr(), val, order).cast() }
2666    }
2667
2668    /// Performs a bitwise "xor" operation on the address of the current
2669    /// pointer, and the argument `val`, and stores a pointer with provenance of
2670    /// the current pointer and the resulting address.
2671    ///
2672    /// This is equivalent to using [`map_addr`] to atomically perform
2673    /// `ptr = ptr.map_addr(|a| a ^ val)`. This can be used in tagged
2674    /// pointer schemes to atomically toggle tag bits.
2675    ///
2676    /// **Caveat**: This operation returns the previous value. To compute the
2677    /// stored value without losing provenance, you may use [`map_addr`]. For
2678    /// example: `a.fetch_xor(val).map_addr(|a| a ^ val)`.
2679    ///
2680    /// `fetch_xor` takes an [`Ordering`] argument which describes the memory
2681    /// ordering of this operation. All ordering modes are possible. Note that
2682    /// using [`Acquire`] makes the store part of this operation [`Relaxed`],
2683    /// and using [`Release`] makes the load part [`Relaxed`].
2684    ///
2685    /// **Note**: This method is only available on platforms that support atomic
2686    /// operations on [`AtomicPtr`].
2687    ///
2688    /// This API and its claimed semantics are part of the Strict Provenance
2689    /// experiment, see the [module documentation for `ptr`][crate::ptr] for
2690    /// details.
2691    ///
2692    /// [`map_addr`]: pointer::map_addr
2693    ///
2694    /// # Examples
2695    ///
2696    /// ```
2697    /// use core::sync::atomic::{AtomicPtr, Ordering};
2698    ///
2699    /// let pointer = &mut 3i64 as *mut i64;
2700    /// let atom = AtomicPtr::<i64>::new(pointer);
2701    ///
2702    /// // Toggle a tag bit on the pointer.
2703    /// atom.fetch_xor(1, Ordering::Relaxed);
2704    /// assert_eq!(atom.load(Ordering::Relaxed).addr() & 1, 1);
2705    /// ```
2706    #[inline]
2707    #[cfg(target_has_atomic = "ptr")]
2708    #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")]
2709    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2710    #[rustc_should_not_be_called_on_const_items]
2711    pub fn fetch_xor(&self, val: usize, order: Ordering) -> *mut T {
2712        // SAFETY: data races are prevented by atomic intrinsics.
2713        unsafe { atomic_xor(self.as_ptr(), val, order).cast() }
2714    }
2715
2716    /// Returns a mutable pointer to the underlying pointer.
2717    ///
2718    /// Doing non-atomic reads and writes on the resulting pointer can be a data race.
2719    /// This method is mostly useful for FFI, where the function signature may use
2720    /// `*mut *mut T` instead of `&AtomicPtr<T>`.
2721    ///
2722    /// Returning an `*mut` pointer from a shared reference to this atomic is safe because the
2723    /// atomic types work with interior mutability. All modifications of an atomic change the value
2724    /// through a shared reference, and can do so safely as long as they use atomic operations. Any
2725    /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the
2726    /// requirements of the [memory model].
2727    ///
2728    /// # Examples
2729    ///
2730    /// ```ignore (extern-declaration)
2731    /// use std::sync::atomic::AtomicPtr;
2732    ///
2733    /// extern "C" {
2734    ///     fn my_atomic_op(arg: *mut *mut u32);
2735    /// }
2736    ///
2737    /// let mut value = 17;
2738    /// let atomic = AtomicPtr::new(&mut value);
2739    ///
2740    /// // SAFETY: Safe as long as `my_atomic_op` is atomic.
2741    /// unsafe {
2742    ///     my_atomic_op(atomic.as_ptr());
2743    /// }
2744    /// ```
2745    ///
2746    /// [memory model]: self#memory-model-for-atomic-accesses
2747    #[inline]
2748    #[stable(feature = "atomic_as_ptr", since = "1.70.0")]
2749    #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")]
2750    #[rustc_never_returns_null_ptr]
2751    pub const fn as_ptr(&self) -> *mut *mut T {
2752        self.v.get().cast()
2753    }
2754}
2755
2756#[cfg(target_has_atomic_load_store = "8")]
2757#[stable(feature = "atomic_bool_from", since = "1.24.0")]
2758#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
2759const impl From<bool> for AtomicBool {
2760    /// Converts a `bool` into an `AtomicBool`.
2761    ///
2762    /// # Examples
2763    ///
2764    /// ```
2765    /// use std::sync::atomic::AtomicBool;
2766    /// let atomic_bool = AtomicBool::from(true);
2767    /// assert_eq!(format!("{atomic_bool:?}"), "true")
2768    /// ```
2769    #[inline]
2770    fn from(b: bool) -> Self {
2771        Self::new(b)
2772    }
2773}
2774
2775#[cfg(target_has_atomic_load_store = "ptr")]
2776#[stable(feature = "atomic_from", since = "1.23.0")]
2777#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
2778const impl<T> From<*mut T> for AtomicPtr<T> {
2779    /// Converts a `*mut T` into an `AtomicPtr<T>`.
2780    #[inline]
2781    fn from(p: *mut T) -> Self {
2782        Self::new(p)
2783    }
2784}
2785
2786#[allow(unused_macros)] // This macro ends up being unused on some architectures.
2787macro_rules! if_8_bit {
2788    (u8, $( yes = [$($yes:tt)*], )? $( no = [$($no:tt)*], )? ) => { concat!("", $($($yes)*)?) };
2789    (i8, $( yes = [$($yes:tt)*], )? $( no = [$($no:tt)*], )? ) => { concat!("", $($($yes)*)?) };
2790    ($_:ident, $( yes = [$($yes:tt)*], )? $( no = [$($no:tt)*], )? ) => { concat!("", $($($no)*)?) };
2791}
2792
2793#[cfg(target_has_atomic_load_store)]
2794macro_rules! atomic_int {
2795    ($cfg_base:meta,
2796     $cfg_cas:meta,
2797     $cfg_align:meta,
2798     $stable:meta,
2799     $stable_cxchg:meta,
2800     $stable_debug:meta,
2801     $stable_access:meta,
2802     $stable_from:meta,
2803     $stable_nand:meta,
2804     $const_stable_new:meta,
2805     $const_stable_into_inner:meta,
2806     $s_int_type:literal,
2807     $extra_feature:expr,
2808     $min_fn:ident, $max_fn:ident,
2809     $align:expr,
2810     $int_type:ident $atomic_type:ident) => {
2811        /// An integer type which can be safely shared between threads.
2812        ///
2813        /// This type has the same
2814        #[doc = if_8_bit!(
2815            $int_type,
2816            yes = ["size, alignment, and bit validity"],
2817            no = ["size and bit validity"],
2818        )]
2819        /// as the underlying integer type, [`
2820        #[doc = $s_int_type]
2821        /// `].
2822        #[doc = if_8_bit! {
2823            $int_type,
2824            no = [
2825                "However, the alignment of this type is always equal to its ",
2826                "size, even on targets where [`", $s_int_type, "`] has a ",
2827                "lesser alignment."
2828            ],
2829        }]
2830        ///
2831        /// For more about the differences between atomic types and
2832        /// non-atomic types as well as information about the portability of
2833        /// this type, please see the [module-level documentation].
2834        ///
2835        /// **Note:** This type is only available on platforms that support
2836        /// atomic loads and stores of [`
2837        #[doc = $s_int_type]
2838        /// `].
2839        ///
2840        /// [module-level documentation]: crate::sync::atomic
2841        #[$stable]
2842        pub type $atomic_type = Atomic<$int_type>;
2843
2844        #[$stable]
2845        impl Default for $atomic_type {
2846            #[inline]
2847            fn default() -> Self {
2848                Self::new(Default::default())
2849            }
2850        }
2851
2852        #[$stable_from]
2853        #[rustc_const_unstable(feature = "const_convert", issue = "143773")]
2854        const impl From<$int_type> for $atomic_type {
2855            #[doc = concat!("Converts an `", stringify!($int_type), "` into an `", stringify!($atomic_type), "`.")]
2856            #[inline]
2857            fn from(v: $int_type) -> Self { Self::new(v) }
2858        }
2859
2860        #[$stable_debug]
2861        impl fmt::Debug for $atomic_type {
2862            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2863                fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)
2864            }
2865        }
2866
2867        impl $atomic_type {
2868            /// Creates a new atomic integer.
2869            ///
2870            /// # Examples
2871            ///
2872            #[cfg_attr($cfg_base, doc = "```")]
2873            #[cfg_attr(not($cfg_base), doc = "```compile_fail")]
2874            #[doc = concat!($extra_feature, "use std::sync::atomic::", stringify!($atomic_type), ";")]
2875            ///
2876            #[doc = concat!("let atomic_forty_two = ", stringify!($atomic_type), "::new(42);")]
2877            /// ```
2878            #[inline]
2879            #[$stable]
2880            #[$const_stable_new]
2881            #[must_use]
2882            pub const fn new(v: $int_type) -> Self {
2883                // SAFETY:
2884                // `Atomic<T>` is essentially a transparent wrapper around `T`.
2885                unsafe { transmute(v) }
2886            }
2887
2888            /// Creates a new reference to an atomic integer from a pointer.
2889            ///
2890            /// # Examples
2891            ///
2892            #[cfg_attr($cfg_base, doc = "```rust")]
2893            #[cfg_attr(not($cfg_base), doc = "```rust,compile_fail")]
2894            #[doc = concat!($extra_feature, "use std::sync::atomic::{self, ", stringify!($atomic_type), "};")]
2895            ///
2896            /// // Get a pointer to an allocated value
2897            #[doc = concat!("let ptr: *mut ", stringify!($int_type), " = Box::into_raw(Box::new(0));")]
2898            ///
2899            #[doc = concat!("assert!(ptr.cast::<", stringify!($atomic_type), ">().is_aligned());")]
2900            ///
2901            /// {
2902            ///     // Create an atomic view of the allocated value
2903            // SAFETY: this is a doc comment, tidy, it can't hurt you (also guaranteed by the construction of `ptr` and the assert above)
2904            #[doc = concat!("    let atomic = unsafe {", stringify!($atomic_type), "::from_ptr(ptr) };")]
2905            ///
2906            ///     // Use `atomic` for atomic operations, possibly share it with other threads
2907            ///     atomic.store(1, atomic::Ordering::Relaxed);
2908            /// }
2909            ///
2910            /// // It's ok to non-atomically access the value behind `ptr`,
2911            /// // since the reference to the atomic ended its lifetime in the block above
2912            /// assert_eq!(unsafe { *ptr }, 1);
2913            ///
2914            /// // Deallocate the value
2915            /// unsafe { drop(Box::from_raw(ptr)) }
2916            /// ```
2917            ///
2918            /// # Safety
2919            ///
2920            /// * `ptr` must be aligned to
2921            #[doc = concat!("  `align_of::<", stringify!($atomic_type), ">()`")]
2922            #[doc = if_8_bit!{
2923                $int_type,
2924                yes = [
2925                    "  (note that this is always true, since `align_of::<",
2926                    stringify!($atomic_type), ">() == 1`)."
2927                ],
2928                no = [
2929                    "  (note that on some platforms this can be bigger than `align_of::<",
2930                    stringify!($int_type), ">()`)."
2931                ],
2932            }]
2933            /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
2934            /// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not
2935            ///   allowed to mix conflicting atomic and non-atomic accesses, or atomic accesses of different
2936            ///   sizes, without synchronization.
2937            ///
2938            /// [valid]: crate::ptr#safety
2939            /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses
2940            #[inline]
2941            #[stable(feature = "atomic_from_ptr", since = "1.75.0")]
2942            #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")]
2943            pub const unsafe fn from_ptr<'a>(ptr: *mut $int_type) -> &'a $atomic_type {
2944                // SAFETY: guaranteed by the caller
2945                unsafe { &*ptr.cast() }
2946            }
2947
2948            /// Creates a new pointer to an atomic integer from a pointer.
2949            ///
2950            /// This is useful if you want to do volatile atomic accesses, and thus avoid creating
2951            /// a reference to the destination.
2952            #[inline]
2953            #[unstable(feature = "atomic_volatile", issue = "158947")]
2954            pub const fn from_ptr_raw(ptr: *mut $int_type) -> *const $atomic_type {
2955                ptr.cast_const().cast()
2956            }
2957
2958            /// Returns a mutable reference to the underlying integer.
2959            ///
2960            /// This is safe because the mutable reference guarantees that no other threads are
2961            /// concurrently accessing the atomic data.
2962            ///
2963            /// # Examples
2964            ///
2965            #[cfg_attr($cfg_base, doc = "```")]
2966            #[cfg_attr(not($cfg_base), doc = "```compile_fail")]
2967            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2968            ///
2969            #[doc = concat!("let mut some_var = ", stringify!($atomic_type), "::new(10);")]
2970            /// assert_eq!(*some_var.get_mut(), 10);
2971            /// *some_var.get_mut() = 5;
2972            /// assert_eq!(some_var.load(Ordering::SeqCst), 5);
2973            /// ```
2974            #[inline]
2975            #[$stable_access]
2976            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
2977            pub const fn get_mut(&mut self) -> &mut $int_type {
2978                // SAFETY:
2979                // `Atomic<T>` is essentially a transparent wrapper around `T`.
2980                unsafe { &mut *self.as_ptr() }
2981            }
2982
2983            #[doc = concat!("Get atomic access to a `&mut ", stringify!($int_type), "`.")]
2984            ///
2985            #[doc = if_8_bit! {
2986                $int_type,
2987                no = [
2988                    "**Note:** This function is only available on targets where `",
2989                    stringify!($atomic_type), "` has the same alignment as `", stringify!($int_type), "`."
2990                ],
2991            }]
2992            ///
2993            /// # Examples
2994            ///
2995            #[cfg_attr($cfg_align, doc = "```rust")]
2996            #[cfg_attr(not($cfg_align), doc = "```rust,compile_fail")]
2997            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
2998            ///
2999            /// let mut some_int = 123;
3000            #[doc = concat!("let a = ", stringify!($atomic_type), "::from_mut(&mut some_int);")]
3001            /// a.store(100, Ordering::Relaxed);
3002            /// assert_eq!(some_int, 100);
3003            /// ```
3004            ///
3005            #[inline]
3006            #[cfg(any($cfg_align, doc))]
3007            #[stable(feature = "atomic_from_mut", since = "1.98.0")]
3008            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3009            pub const fn from_mut(v: &mut $int_type) -> &mut Self {
3010                let [] = [(); align_of::<Self>() - align_of::<$int_type>()];
3011                // SAFETY:
3012                //  - the mutable reference guarantees unique ownership.
3013                //  - the alignment of `$int_type` and `Self` is the
3014                //    same, as promised by $cfg_align and verified above.
3015                unsafe { &mut *(v as *mut $int_type as *mut Self) }
3016            }
3017
3018            #[doc = concat!("Get non-atomic access to a `&mut [", stringify!($atomic_type), "]` slice")]
3019            ///
3020            /// This is safe because the mutable reference guarantees that no other threads are
3021            /// concurrently accessing the atomic data.
3022            ///
3023            /// # Examples
3024            ///
3025            #[cfg_attr($cfg_base, doc = "```ignore-wasm")]
3026            #[cfg_attr(not($cfg_base), doc = "```ignore-wasm,compile_fail")]
3027            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3028            ///
3029            #[doc = concat!("let mut some_ints = [const { ", stringify!($atomic_type), "::new(0) }; 10];")]
3030            ///
3031            #[doc = concat!("let view: &mut [", stringify!($int_type), "] = ", stringify!($atomic_type), "::get_mut_slice(&mut some_ints);")]
3032            /// assert_eq!(view, [0; 10]);
3033            /// view
3034            ///     .iter_mut()
3035            ///     .enumerate()
3036            ///     .for_each(|(idx, int)| *int = idx as _);
3037            ///
3038            /// std::thread::scope(|s| {
3039            ///     some_ints
3040            ///         .iter()
3041            ///         .enumerate()
3042            ///         .for_each(|(idx, int)| {
3043            ///             s.spawn(move || assert_eq!(int.load(Ordering::Relaxed), idx as _));
3044            ///         })
3045            /// });
3046            /// ```
3047            #[inline]
3048            #[stable(feature = "atomic_from_mut", since = "1.98.0")]
3049            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3050            pub const fn get_mut_slice(this: &mut [Self]) -> &mut [$int_type] {
3051                // SAFETY: the mutable reference guarantees unique ownership.
3052                unsafe { &mut *(this as *mut [Self] as *mut [$int_type]) }
3053            }
3054
3055            #[doc = concat!("Get atomic access to a `&mut [", stringify!($int_type), "]` slice.")]
3056            ///
3057            #[doc = if_8_bit! {
3058                $int_type,
3059                no = [
3060                    "**Note:** This function is only available on targets where `",
3061                    stringify!($atomic_type), "` has the same alignment as `", stringify!($int_type), "`."
3062                ],
3063            }]
3064            ///
3065            /// # Examples
3066            ///
3067            #[cfg_attr($cfg_align, doc = "```ignore-wasm")]
3068            #[cfg_attr(not($cfg_align), doc = "```ignore-wasm,compile_fail")]
3069            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3070            ///
3071            /// let mut some_ints = [0; 10];
3072            #[doc = concat!("let a = &*", stringify!($atomic_type), "::from_mut_slice(&mut some_ints);")]
3073            /// std::thread::scope(|s| {
3074            ///     for i in 0..a.len() {
3075            ///         s.spawn(move || a[i].store(i as _, Ordering::Relaxed));
3076            ///     }
3077            /// });
3078            /// for (i, n) in some_ints.into_iter().enumerate() {
3079            ///     assert_eq!(i, n as usize);
3080            /// }
3081            /// ```
3082            #[inline]
3083            #[cfg(any($cfg_align, doc))]
3084            #[stable(feature = "atomic_from_mut", since = "1.98.0")]
3085            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3086            pub const fn from_mut_slice(v: &mut [$int_type]) -> &mut [Self] {
3087                let [] = [(); align_of::<Self>() - align_of::<$int_type>()];
3088                // SAFETY:
3089                //  - the mutable reference guarantees unique ownership.
3090                //  - the alignment of `$int_type` and `Self` is the
3091                //    same, as promised by $cfg_align and verified above.
3092                unsafe { &mut *(v as *mut [$int_type] as *mut [Self]) }
3093            }
3094
3095            /// Consumes the atomic and returns the contained value.
3096            ///
3097            /// This is safe because passing `self` by value guarantees that no other threads are
3098            /// concurrently accessing the atomic data.
3099            ///
3100            /// # Examples
3101            ///
3102            #[cfg_attr($cfg_base, doc = "```")]
3103            #[cfg_attr(not($cfg_base), doc = "```compile_fail")]
3104            #[doc = concat!($extra_feature, "use std::sync::atomic::", stringify!($atomic_type), ";")]
3105            ///
3106            #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
3107            /// assert_eq!(some_var.into_inner(), 5);
3108            /// ```
3109            #[inline]
3110            #[$stable_access]
3111            #[$const_stable_into_inner]
3112            pub const fn into_inner(self) -> $int_type {
3113                // SAFETY:
3114                // `Atomic<T>` is essentially a transparent wrapper around `T`.
3115                unsafe { transmute(self) }
3116            }
3117
3118            /// Loads a value from the atomic integer.
3119            ///
3120            /// `load` takes an [`Ordering`] argument which describes the memory ordering of this operation.
3121            /// Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
3122            ///
3123            /// # Panics
3124            ///
3125            /// Panics if `order` is [`Release`] or [`AcqRel`].
3126            ///
3127            /// # Examples
3128            ///
3129            #[cfg_attr($cfg_base, doc = "```")]
3130            #[cfg_attr(not($cfg_base), doc = "```compile_fail")]
3131            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3132            ///
3133            #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
3134            ///
3135            /// assert_eq!(some_var.load(Ordering::Relaxed), 5);
3136            /// ```
3137            #[inline]
3138            #[$stable]
3139            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3140            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3141            pub const fn load(&self, order: Ordering) -> $int_type {
3142                // SAFETY: data races are prevented by atomic intrinsics.
3143                unsafe { atomic_load::<_, /* VOLATILE */ false>(self.as_ptr(), order) }
3144            }
3145
3146            /// Perform a volatile load from the atomic integer.
3147            ///
3148            /// `load_volatile` takes an [`Ordering`] argument which describes the memory ordering
3149            /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
3150            ///
3151            #[doc = include_str!("./atomic_load_volatile.md")]
3152            ///
3153            /// # Safety
3154            ///
3155            /// Behavior is undefined if any of the following conditions are violated:
3156            ///
3157            /// * `self` must be [valid] for reads, or `self` must point to memory
3158            ///   outside of all Rust allocations and reading from that memory must:
3159            ///   - not trap, and
3160            ///   - not cause any memory inside a Rust allocation to be modified.
3161            ///
3162            /// * `self` must be aligned to
3163            #[doc = concat!("  `align_of::<", stringify!($atomic_type), ">()`")]
3164            #[doc = if_8_bit!{
3165                $int_type,
3166                yes = [
3167                    "  (note that this is always true, since `align_of::<",
3168                    stringify!($atomic_type), ">() == 1`)."
3169                ],
3170                no = [
3171                    "  (note that on some platforms this can be bigger than `align_of::<",
3172                    stringify!($int_type), ">()`)."
3173                ],
3174            }]
3175            ///
3176            /// * Reading from `self` must produce a properly initialized value of the underlying
3177            ///   integer type.
3178            ///
3179            /// [valid]: core::ptr#safety
3180            ///
3181            /// # Panics
3182            ///
3183            /// Panics if `order` is [`Release`] or [`AcqRel`].
3184            #[inline]
3185            #[unstable(feature = "atomic_volatile", issue = "158947")]
3186            #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
3187            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3188            pub const unsafe fn load_volatile(self: *const Self, order: Ordering) -> $int_type {
3189                // SAFETY: follows from our own safety requirements.
3190                unsafe {
3191                    atomic_load::<_, /* VOLATILE */ true>(self.cast::<$int_type>(), order)
3192                }
3193            }
3194
3195            /// Stores a value into the atomic integer.
3196            ///
3197            /// `store` takes an [`Ordering`] argument which describes the memory ordering of this operation.
3198            ///  Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
3199            ///
3200            /// # Panics
3201            ///
3202            /// Panics if `order` is [`Acquire`] or [`AcqRel`].
3203            ///
3204            /// # Examples
3205            ///
3206            #[cfg_attr($cfg_base, doc = "```")]
3207            #[cfg_attr(not($cfg_base), doc = "```compile_fail")]
3208            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3209            ///
3210            #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
3211            ///
3212            /// some_var.store(10, Ordering::Relaxed);
3213            /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
3214            /// ```
3215            #[inline]
3216            #[$stable]
3217            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3218            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3219            #[rustc_should_not_be_called_on_const_items]
3220            pub const fn store(&self, val: $int_type, order: Ordering) {
3221                // SAFETY: data races are prevented by atomic intrinsics.
3222                unsafe { atomic_store::<_, /* VOLATILE */ false>(self.as_ptr(), val, order); }
3223            }
3224
3225            /// Performs a volatile store into the atomic integer.
3226            ///
3227            /// `store_volatile` takes an [`Ordering`] argument which describes the memory ordering
3228            /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
3229            ///
3230            #[doc = include_str!("./atomic_store_volatile.md")]
3231            ///
3232            /// # Safety
3233            ///
3234            /// Behavior is undefined if any of the following conditions are violated:
3235            ///
3236            /// * `self` must be either [valid] for writes, or `self` must point to memory
3237            ///   outside of all Rust allocations and writing to that memory must:
3238            ///   - not trap, and
3239            ///   - not cause any memory inside a Rust allocation to be modified.
3240            ///
3241            /// * `self` must be aligned to
3242            #[doc = concat!("  `align_of::<", stringify!($atomic_type), ">()`")]
3243            #[doc = if_8_bit!{
3244                $int_type,
3245                yes = [
3246                    "  (note that this is always true, since `align_of::<",
3247                    stringify!($atomic_type), ">() == 1`)."
3248                ],
3249                no = [
3250                    "  (note that on some platforms this can be bigger than `align_of::<",
3251                    stringify!($int_type), ">()`)."
3252                ],
3253            }]
3254            ///
3255            /// [valid]: core::ptr#safety
3256            ///
3257            /// # Panics
3258            ///
3259            /// Panics if `order` is [`Acquire`] or [`AcqRel`].
3260            #[inline]
3261            #[unstable(feature = "atomic_volatile", issue = "158947")]
3262            #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
3263            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3264            #[rustc_should_not_be_called_on_const_items]
3265            pub const unsafe fn store_volatile(self: *const Self, val: $int_type, order: Ordering) {
3266                // SAFETY: follows from our own safety requirements.
3267                unsafe {
3268                    atomic_store::<_, /* VOLATILE */ true>(self.cast::<$int_type>().cast_mut(), val, order);
3269                }
3270            }
3271
3272            /// Stores a value into the atomic integer, returning the previous value.
3273            ///
3274            /// `swap` takes an [`Ordering`] argument which describes the memory ordering
3275            /// of this operation. All ordering modes are possible. Note that using
3276            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3277            /// using [`Release`] makes the load part [`Relaxed`].
3278            ///
3279            /// **Note**: This method is only available on platforms that support atomic operations on
3280            #[doc = concat!("[`", $s_int_type, "`].")]
3281            ///
3282            /// # Examples
3283            ///
3284            #[cfg_attr($cfg_cas, doc = "```")]
3285            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3286            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3287            ///
3288            #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
3289            ///
3290            /// assert_eq!(some_var.swap(10, Ordering::Relaxed), 5);
3291            /// ```
3292            #[inline]
3293            #[$stable]
3294            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3295            #[cfg(any($cfg_cas, doc))]
3296            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3297            #[rustc_should_not_be_called_on_const_items]
3298            pub const fn swap(&self, val: $int_type, order: Ordering) -> $int_type {
3299                // SAFETY: data races are prevented by atomic intrinsics.
3300                unsafe { atomic_swap(self.as_ptr(), val, order) }
3301            }
3302
3303            /// Stores a value into the atomic integer if the current value is the same as
3304            /// the `current` value.
3305            ///
3306            /// The return value is always the previous value. If it is equal to `current`, then the
3307            /// value was updated.
3308            ///
3309            /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
3310            /// ordering of this operation. Notice that even when using [`AcqRel`], the operation
3311            /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics.
3312            /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it
3313            /// happens, and using [`Release`] makes the load part [`Relaxed`].
3314            ///
3315            /// **Note**: This method is only available on platforms that support atomic operations on
3316            #[doc = concat!("[`", $s_int_type, "`].")]
3317            ///
3318            /// # Migrating to `compare_exchange` and `compare_exchange_weak`
3319            ///
3320            /// `compare_and_swap` is equivalent to `compare_exchange` with the following mapping for
3321            /// memory orderings:
3322            ///
3323            /// Original | Success | Failure
3324            /// -------- | ------- | -------
3325            /// Relaxed  | Relaxed | Relaxed
3326            /// Acquire  | Acquire | Acquire
3327            /// Release  | Release | Relaxed
3328            /// AcqRel   | AcqRel  | Acquire
3329            /// SeqCst   | SeqCst  | SeqCst
3330            ///
3331            /// `compare_and_swap` and `compare_exchange` also differ in their return type. You can use
3332            /// `compare_exchange(...).unwrap_or_else(|x| x)` to recover the behavior of `compare_and_swap`,
3333            /// but in most cases it is more idiomatic to check whether the return value is `Ok` or `Err`
3334            /// rather than to infer success vs failure based on the value that was read.
3335            ///
3336            /// During migration, consider whether it makes sense to use `compare_exchange_weak` instead.
3337            /// `compare_exchange_weak` is allowed to fail spuriously even when the comparison succeeds,
3338            /// which allows the compiler to generate better assembly code when the compare and swap
3339            /// is used in a loop.
3340            ///
3341            /// # Examples
3342            ///
3343            #[cfg_attr($cfg_cas, doc = "```")]
3344            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3345            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3346            ///
3347            #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
3348            ///
3349            /// assert_eq!(some_var.compare_and_swap(5, 10, Ordering::Relaxed), 5);
3350            /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
3351            ///
3352            /// assert_eq!(some_var.compare_and_swap(6, 12, Ordering::Relaxed), 10);
3353            /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
3354            /// ```
3355            #[inline]
3356            #[$stable]
3357            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3358            #[deprecated(
3359                since = "1.50.0",
3360                note = "Use `compare_exchange` or `compare_exchange_weak` instead")
3361            ]
3362            #[cfg(any($cfg_cas, doc))]
3363            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3364            #[rustc_should_not_be_called_on_const_items]
3365            pub const fn compare_and_swap(&self,
3366                                    current: $int_type,
3367                                    new: $int_type,
3368                                    order: Ordering) -> $int_type {
3369                match self.compare_exchange(current,
3370                                            new,
3371                                            order,
3372                                            strongest_failure_ordering(order)) {
3373                    Ok(x) => x,
3374                    Err(x) => x,
3375                }
3376            }
3377
3378            /// Stores a value into the atomic integer if the current value is the same as
3379            /// the `current` value.
3380            ///
3381            /// The return value is a result indicating whether the new value was written and
3382            /// containing the previous value. On success this value is guaranteed to be equal to
3383            /// `current`.
3384            ///
3385            /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
3386            /// ordering of this operation. `success` describes the required ordering for the
3387            /// read-modify-write operation that takes place if the comparison with `current` succeeds.
3388            /// `failure` describes the required ordering for the load operation that takes place when
3389            /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
3390            /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
3391            /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
3392            ///
3393            /// **Note**: This method is only available on platforms that support atomic operations on
3394            #[doc = concat!("[`", $s_int_type, "`].")]
3395            ///
3396            /// # Examples
3397            ///
3398            #[cfg_attr($cfg_cas, doc = "```")]
3399            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3400            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3401            ///
3402            #[doc = concat!("let some_var = ", stringify!($atomic_type), "::new(5);")]
3403            ///
3404            /// assert_eq!(some_var.compare_exchange(5, 10,
3405            ///                                      Ordering::Acquire,
3406            ///                                      Ordering::Relaxed),
3407            ///            Ok(5));
3408            /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
3409            ///
3410            /// assert_eq!(some_var.compare_exchange(6, 12,
3411            ///                                      Ordering::SeqCst,
3412            ///                                      Ordering::Acquire),
3413            ///            Err(10));
3414            /// assert_eq!(some_var.load(Ordering::Relaxed), 10);
3415            /// ```
3416            ///
3417            /// # Considerations
3418            ///
3419            /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
3420            /// of CAS operations. In particular, a load of the value followed by a successful
3421            /// `compare_exchange` with the previous load *does not ensure* that other threads have not
3422            /// changed the value in the interim! This is usually important when the *equality* check in
3423            /// the `compare_exchange` is being used to check the *identity* of a value, but equality
3424            /// does not necessarily imply identity. This is a particularly common case for pointers, as
3425            /// a pointer holding the same address does not imply that the same object exists at that
3426            /// address! In this case, `compare_exchange` can lead to the [ABA problem].
3427            ///
3428            /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
3429            /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
3430            #[inline]
3431            #[$stable_cxchg]
3432            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3433            #[cfg(any($cfg_cas, doc))]
3434            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3435            #[rustc_should_not_be_called_on_const_items]
3436            pub const fn compare_exchange(&self,
3437                                    current: $int_type,
3438                                    new: $int_type,
3439                                    success: Ordering,
3440                                    failure: Ordering) -> Result<$int_type, $int_type> {
3441                // SAFETY: data races are prevented by atomic intrinsics.
3442                unsafe { atomic_compare_exchange(self.as_ptr(), current, new, success, failure) }
3443            }
3444
3445            /// Stores a value into the atomic integer if the current value is the same as
3446            /// the `current` value.
3447            ///
3448            #[doc = concat!("Unlike [`", stringify!($atomic_type), "::compare_exchange`],")]
3449            /// this function is allowed to spuriously fail even
3450            /// when the comparison succeeds, which can result in more efficient code on some
3451            /// platforms. The return value is a result indicating whether the new value was
3452            /// written and containing the previous value.
3453            ///
3454            /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
3455            /// ordering of this operation. `success` describes the required ordering for the
3456            /// read-modify-write operation that takes place if the comparison with `current` succeeds.
3457            /// `failure` describes the required ordering for the load operation that takes place when
3458            /// the comparison fails. Using [`Acquire`] as success ordering makes the store part
3459            /// of this operation [`Relaxed`], and using [`Release`] makes the successful load
3460            /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
3461            ///
3462            /// **Note**: This method is only available on platforms that support atomic operations on
3463            #[doc = concat!("[`", $s_int_type, "`].")]
3464            ///
3465            /// # Examples
3466            ///
3467            #[cfg_attr($cfg_cas, doc = "```")]
3468            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3469            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3470            ///
3471            #[doc = concat!("let val = ", stringify!($atomic_type), "::new(4);")]
3472            ///
3473            /// let mut old = val.load(Ordering::Relaxed);
3474            /// loop {
3475            ///     let new = old * 2;
3476            ///     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
3477            ///         Ok(_) => break,
3478            ///         Err(x) => old = x,
3479            ///     }
3480            /// }
3481            /// ```
3482            ///
3483            /// # Considerations
3484            ///
3485            /// `compare_exchange` is a [compare-and-swap operation] and thus exhibits the usual downsides
3486            /// of CAS operations. In particular, a load of the value followed by a successful
3487            /// `compare_exchange` with the previous load *does not ensure* that other threads have not
3488            /// changed the value in the interim. This is usually important when the *equality* check in
3489            /// the `compare_exchange` is being used to check the *identity* of a value, but equality
3490            /// does not necessarily imply identity. This is a particularly common case for pointers, as
3491            /// a pointer holding the same address does not imply that the same object exists at that
3492            /// address! In this case, `compare_exchange` can lead to the [ABA problem].
3493            ///
3494            /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
3495            /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
3496            #[inline]
3497            #[$stable_cxchg]
3498            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3499            #[cfg(any($cfg_cas, doc))]
3500            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3501            #[rustc_should_not_be_called_on_const_items]
3502            pub const fn compare_exchange_weak(&self,
3503                                         current: $int_type,
3504                                         new: $int_type,
3505                                         success: Ordering,
3506                                         failure: Ordering) -> Result<$int_type, $int_type> {
3507                // SAFETY: data races are prevented by atomic intrinsics.
3508                unsafe {
3509                    atomic_compare_exchange_weak(self.as_ptr(), current, new, success, failure)
3510                }
3511            }
3512
3513            /// Adds to the current value, returning the previous value.
3514            ///
3515            /// This operation wraps around on overflow.
3516            ///
3517            /// `fetch_add` takes an [`Ordering`] argument which describes the memory ordering
3518            /// of this operation. All ordering modes are possible. Note that using
3519            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3520            /// using [`Release`] makes the load part [`Relaxed`].
3521            ///
3522            /// **Note**: This method is only available on platforms that support atomic operations on
3523            #[doc = concat!("[`", $s_int_type, "`].")]
3524            ///
3525            /// # Examples
3526            ///
3527            #[cfg_attr($cfg_cas, doc = "```")]
3528            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3529            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3530            ///
3531            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0);")]
3532            /// assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0);
3533            /// assert_eq!(foo.load(Ordering::SeqCst), 10);
3534            /// ```
3535            #[inline]
3536            #[$stable]
3537            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3538            #[cfg(any($cfg_cas, doc))]
3539            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3540            #[rustc_should_not_be_called_on_const_items]
3541            pub const fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type {
3542                // SAFETY: data races are prevented by atomic intrinsics.
3543                unsafe { atomic_add(self.as_ptr(), val, order) }
3544            }
3545
3546            /// Subtracts from the current value, returning the previous value.
3547            ///
3548            /// This operation wraps around on overflow.
3549            ///
3550            /// `fetch_sub` takes an [`Ordering`] argument which describes the memory ordering
3551            /// of this operation. All ordering modes are possible. Note that using
3552            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3553            /// using [`Release`] makes the load part [`Relaxed`].
3554            ///
3555            /// **Note**: This method is only available on platforms that support atomic operations on
3556            #[doc = concat!("[`", $s_int_type, "`].")]
3557            ///
3558            /// # Examples
3559            ///
3560            #[cfg_attr($cfg_cas, doc = "```")]
3561            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3562            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3563            ///
3564            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(20);")]
3565            /// assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 20);
3566            /// assert_eq!(foo.load(Ordering::SeqCst), 10);
3567            /// ```
3568            #[inline]
3569            #[$stable]
3570            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3571            #[cfg(any($cfg_cas, doc))]
3572            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3573            #[rustc_should_not_be_called_on_const_items]
3574            pub const fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type {
3575                // SAFETY: data races are prevented by atomic intrinsics.
3576                unsafe { atomic_sub(self.as_ptr(), val, order) }
3577            }
3578
3579            /// Bitwise "and" with the current value.
3580            ///
3581            /// Performs a bitwise "and" operation on the current value and the argument `val`, and
3582            /// sets the new value to the result.
3583            ///
3584            /// Returns the previous value.
3585            ///
3586            /// `fetch_and` takes an [`Ordering`] argument which describes the memory ordering
3587            /// of this operation. All ordering modes are possible. Note that using
3588            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3589            /// using [`Release`] makes the load part [`Relaxed`].
3590            ///
3591            /// **Note**: This method is only available on platforms that support atomic operations on
3592            #[doc = concat!("[`", $s_int_type, "`].")]
3593            ///
3594            /// # Examples
3595            ///
3596            #[cfg_attr($cfg_cas, doc = "```")]
3597            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3598            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3599            ///
3600            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0b101101);")]
3601            /// assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101);
3602            /// assert_eq!(foo.load(Ordering::SeqCst), 0b100001);
3603            /// ```
3604            #[inline]
3605            #[$stable]
3606            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3607            #[cfg(any($cfg_cas, doc))]
3608            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3609            #[rustc_should_not_be_called_on_const_items]
3610            pub const fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type {
3611                // SAFETY: data races are prevented by atomic intrinsics.
3612                unsafe { atomic_and(self.as_ptr(), val, order) }
3613            }
3614
3615            /// Bitwise "nand" with the current value.
3616            ///
3617            /// Performs a bitwise "nand" operation on the current value and the argument `val`, and
3618            /// sets the new value to the result.
3619            ///
3620            /// Returns the previous value.
3621            ///
3622            /// `fetch_nand` takes an [`Ordering`] argument which describes the memory ordering
3623            /// of this operation. All ordering modes are possible. Note that using
3624            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3625            /// using [`Release`] makes the load part [`Relaxed`].
3626            ///
3627            /// **Note**: This method is only available on platforms that support atomic operations on
3628            #[doc = concat!("[`", $s_int_type, "`].")]
3629            ///
3630            /// # Examples
3631            ///
3632            #[cfg_attr($cfg_cas, doc = "```")]
3633            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3634            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3635            ///
3636            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0x13);")]
3637            /// assert_eq!(foo.fetch_nand(0x31, Ordering::SeqCst), 0x13);
3638            /// assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31));
3639            /// ```
3640            #[inline]
3641            #[$stable_nand]
3642            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3643            #[cfg(any($cfg_cas, doc))]
3644            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3645            #[rustc_should_not_be_called_on_const_items]
3646            pub const fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type {
3647                // SAFETY: data races are prevented by atomic intrinsics.
3648                unsafe { atomic_nand(self.as_ptr(), val, order) }
3649            }
3650
3651            /// Bitwise "or" with the current value.
3652            ///
3653            /// Performs a bitwise "or" operation on the current value and the argument `val`, and
3654            /// sets the new value to the result.
3655            ///
3656            /// Returns the previous value.
3657            ///
3658            /// `fetch_or` takes an [`Ordering`] argument which describes the memory ordering
3659            /// of this operation. All ordering modes are possible. Note that using
3660            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3661            /// using [`Release`] makes the load part [`Relaxed`].
3662            ///
3663            /// **Note**: This method is only available on platforms that support atomic operations on
3664            #[doc = concat!("[`", $s_int_type, "`].")]
3665            ///
3666            /// # Examples
3667            ///
3668            #[cfg_attr($cfg_cas, doc = "```")]
3669            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3670            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3671            ///
3672            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0b101101);")]
3673            /// assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101);
3674            /// assert_eq!(foo.load(Ordering::SeqCst), 0b111111);
3675            /// ```
3676            #[inline]
3677            #[$stable]
3678            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3679            #[cfg(any($cfg_cas, doc))]
3680            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3681            #[rustc_should_not_be_called_on_const_items]
3682            pub const fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type {
3683                // SAFETY: data races are prevented by atomic intrinsics.
3684                unsafe { atomic_or(self.as_ptr(), val, order) }
3685            }
3686
3687            /// Bitwise "xor" with the current value.
3688            ///
3689            /// Performs a bitwise "xor" operation on the current value and the argument `val`, and
3690            /// sets the new value to the result.
3691            ///
3692            /// Returns the previous value.
3693            ///
3694            /// `fetch_xor` takes an [`Ordering`] argument which describes the memory ordering
3695            /// of this operation. All ordering modes are possible. Note that using
3696            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3697            /// using [`Release`] makes the load part [`Relaxed`].
3698            ///
3699            /// **Note**: This method is only available on platforms that support atomic operations on
3700            #[doc = concat!("[`", $s_int_type, "`].")]
3701            ///
3702            /// # Examples
3703            ///
3704            #[cfg_attr($cfg_cas, doc = "```")]
3705            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3706            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3707            ///
3708            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(0b101101);")]
3709            /// assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101);
3710            /// assert_eq!(foo.load(Ordering::SeqCst), 0b011110);
3711            /// ```
3712            #[inline]
3713            #[$stable]
3714            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3715            #[cfg(any($cfg_cas, doc))]
3716            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3717            #[rustc_should_not_be_called_on_const_items]
3718            pub const fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type {
3719                // SAFETY: data races are prevented by atomic intrinsics.
3720                unsafe { atomic_xor(self.as_ptr(), val, order) }
3721            }
3722
3723            /// An alias for
3724            #[doc = concat!("[`", stringify!($atomic_type), "::try_update`]")]
3725            /// .
3726            #[inline]
3727            #[stable(feature = "no_more_cas", since = "1.45.0")]
3728            #[cfg(any($cfg_cas, doc))]
3729            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3730            #[rustc_should_not_be_called_on_const_items]
3731            #[deprecated(
3732                since = "1.99.0",
3733                note = "renamed to `try_update` for consistency",
3734                suggestion = "try_update"
3735            )]
3736            pub fn fetch_update<F>(&self,
3737                                   set_order: Ordering,
3738                                   fetch_order: Ordering,
3739                                   f: F) -> Result<$int_type, $int_type>
3740            where F: FnMut($int_type) -> Option<$int_type> {
3741                self.try_update(set_order, fetch_order, f)
3742            }
3743
3744            /// Fetches the value, and applies a function to it that returns an optional
3745            /// new value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else
3746            /// `Err(previous_value)`.
3747            ///
3748            #[doc = concat!("See also: [`update`](`", stringify!($atomic_type), "::update`).")]
3749            ///
3750            /// Note: This may call the function multiple times if the value has been changed from other threads in
3751            /// the meantime, as long as the function returns `Some(_)`, but the function will have been applied
3752            /// only once to the stored value.
3753            ///
3754            /// `try_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
3755            /// The first describes the required ordering for when the operation finally succeeds while the second
3756            /// describes the required ordering for loads. These correspond to the success and failure orderings of
3757            #[doc = concat!("[`", stringify!($atomic_type), "::compare_exchange`]")]
3758            /// respectively.
3759            ///
3760            /// Using [`Acquire`] as success ordering makes the store part
3761            /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
3762            /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
3763            ///
3764            /// **Note**: This method is only available on platforms that support atomic operations on
3765            #[doc = concat!("[`", $s_int_type, "`].")]
3766            ///
3767            /// # Considerations
3768            ///
3769            /// This method is not magic; it is not provided by the hardware, and does not act like a
3770            /// critical section or mutex.
3771            ///
3772            /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
3773            /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
3774            /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
3775            /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
3776            ///
3777            /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
3778            /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
3779            ///
3780            /// # Examples
3781            ///
3782            #[cfg_attr($cfg_cas, doc = "```rust")]
3783            #[cfg_attr(not($cfg_cas), doc = "```rust,compile_fail")]
3784            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3785            ///
3786            #[doc = concat!("let x = ", stringify!($atomic_type), "::new(7);")]
3787            /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(7));
3788            /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(7));
3789            /// assert_eq!(x.try_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(8));
3790            /// assert_eq!(x.load(Ordering::SeqCst), 9);
3791            /// ```
3792            #[inline]
3793            #[stable(feature = "atomic_try_update", since = "1.95.0")]
3794            #[cfg(any($cfg_cas, doc))]
3795            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3796            #[rustc_should_not_be_called_on_const_items]
3797            pub fn try_update(
3798                &self,
3799                set_order: Ordering,
3800                fetch_order: Ordering,
3801                mut f: impl FnMut($int_type) -> Option<$int_type>,
3802            ) -> Result<$int_type, $int_type> {
3803                let mut prev = self.load(fetch_order);
3804                while let Some(next) = f(prev) {
3805                    match self.compare_exchange_weak(prev, next, set_order, fetch_order) {
3806                        x @ Ok(_) => return x,
3807                        Err(next_prev) => prev = next_prev
3808                    }
3809                }
3810                Err(prev)
3811            }
3812
3813            /// Fetches the value, and applies a function to it that returns a new value.
3814            /// The new value is stored and the old value is returned.
3815            ///
3816            #[doc = concat!("See also: [`try_update`](`", stringify!($atomic_type), "::try_update`).")]
3817            ///
3818            /// Note: This may call the function multiple times if the value has been changed from other threads in
3819            /// the meantime, but the function will have been applied only once to the stored value.
3820            ///
3821            /// `update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
3822            /// The first describes the required ordering for when the operation finally succeeds while the second
3823            /// describes the required ordering for loads. These correspond to the success and failure orderings of
3824            #[doc = concat!("[`", stringify!($atomic_type), "::compare_exchange`]")]
3825            /// respectively.
3826            ///
3827            /// Using [`Acquire`] as success ordering makes the store part
3828            /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
3829            /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
3830            ///
3831            /// **Note**: This method is only available on platforms that support atomic operations on
3832            #[doc = concat!("[`", $s_int_type, "`].")]
3833            ///
3834            /// # Considerations
3835            ///
3836            /// [CAS operation]: https://en.wikipedia.org/wiki/Compare-and-swap
3837            /// This method is not magic; it is not provided by the hardware, and does not act like a
3838            /// critical section or mutex.
3839            ///
3840            /// It is implemented on top of an atomic [compare-and-swap operation], and thus is subject to
3841            /// the usual drawbacks of CAS operations. In particular, be careful of the [ABA problem]
3842            /// if this atomic integer is an index or more generally if knowledge of only the *bitwise value*
3843            /// of the atomic is not in and of itself sufficient to ensure any required preconditions.
3844            ///
3845            /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
3846            /// [compare-and-swap operation]: https://en.wikipedia.org/wiki/Compare-and-swap
3847            ///
3848            /// # Examples
3849            ///
3850            #[cfg_attr($cfg_cas, doc = "```rust")]
3851            #[cfg_attr(not($cfg_cas), doc = "```rust,compile_fail")]
3852            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3853            ///
3854            #[doc = concat!("let x = ", stringify!($atomic_type), "::new(7);")]
3855            /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 7);
3856            /// assert_eq!(x.update(Ordering::SeqCst, Ordering::SeqCst, |x| x + 1), 8);
3857            /// assert_eq!(x.load(Ordering::SeqCst), 9);
3858            /// ```
3859            #[inline]
3860            #[stable(feature = "atomic_try_update", since = "1.95.0")]
3861            #[cfg(any($cfg_cas, doc))]
3862            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3863            #[rustc_should_not_be_called_on_const_items]
3864            pub fn update(
3865                &self,
3866                set_order: Ordering,
3867                fetch_order: Ordering,
3868                mut f: impl FnMut($int_type) -> $int_type,
3869            ) -> $int_type {
3870                let mut prev = self.load(fetch_order);
3871                loop {
3872                    match self.compare_exchange_weak(prev, f(prev), set_order, fetch_order) {
3873                        Ok(x) => break x,
3874                        Err(next_prev) => prev = next_prev,
3875                    }
3876                }
3877            }
3878
3879            /// Maximum with the current value.
3880            ///
3881            /// Finds the maximum of the current value and the argument `val`, and
3882            /// sets the new value to the result.
3883            ///
3884            /// Returns the previous value.
3885            ///
3886            /// `fetch_max` takes an [`Ordering`] argument which describes the memory ordering
3887            /// of this operation. All ordering modes are possible. Note that using
3888            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3889            /// using [`Release`] makes the load part [`Relaxed`].
3890            ///
3891            /// **Note**: This method is only available on platforms that support atomic operations on
3892            #[doc = concat!("[`", $s_int_type, "`].")]
3893            ///
3894            /// # Examples
3895            ///
3896            #[cfg_attr($cfg_cas, doc = "```")]
3897            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3898            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3899            ///
3900            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(23);")]
3901            /// assert_eq!(foo.fetch_max(42, Ordering::SeqCst), 23);
3902            /// assert_eq!(foo.load(Ordering::SeqCst), 42);
3903            /// ```
3904            ///
3905            /// If you want to obtain the maximum value in one step, you can use the following:
3906            ///
3907            #[cfg_attr($cfg_cas, doc = "```")]
3908            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3909            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3910            ///
3911            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(23);")]
3912            /// let bar = 42;
3913            /// let max_foo = foo.fetch_max(bar, Ordering::SeqCst).max(bar);
3914            /// assert!(max_foo == 42);
3915            /// ```
3916            #[inline]
3917            #[stable(feature = "atomic_min_max", since = "1.45.0")]
3918            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3919            #[cfg(any($cfg_cas, doc))]
3920            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3921            #[rustc_should_not_be_called_on_const_items]
3922            pub const fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type {
3923                // SAFETY: data races are prevented by atomic intrinsics.
3924                unsafe { $max_fn(self.as_ptr(), val, order) }
3925            }
3926
3927            /// Minimum with the current value.
3928            ///
3929            /// Finds the minimum of the current value and the argument `val`, and
3930            /// sets the new value to the result.
3931            ///
3932            /// Returns the previous value.
3933            ///
3934            /// `fetch_min` takes an [`Ordering`] argument which describes the memory ordering
3935            /// of this operation. All ordering modes are possible. Note that using
3936            /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
3937            /// using [`Release`] makes the load part [`Relaxed`].
3938            ///
3939            /// **Note**: This method is only available on platforms that support atomic operations on
3940            #[doc = concat!("[`", $s_int_type, "`].")]
3941            ///
3942            /// # Examples
3943            ///
3944            #[cfg_attr($cfg_cas, doc = "```")]
3945            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3946            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3947            ///
3948            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(23);")]
3949            /// assert_eq!(foo.fetch_min(42, Ordering::Relaxed), 23);
3950            /// assert_eq!(foo.load(Ordering::Relaxed), 23);
3951            /// assert_eq!(foo.fetch_min(22, Ordering::Relaxed), 23);
3952            /// assert_eq!(foo.load(Ordering::Relaxed), 22);
3953            /// ```
3954            ///
3955            /// If you want to obtain the minimum value in one step, you can use the following:
3956            ///
3957            #[cfg_attr($cfg_cas, doc = "```")]
3958            #[cfg_attr(not($cfg_cas), doc = "```compile_fail")]
3959            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
3960            ///
3961            #[doc = concat!("let foo = ", stringify!($atomic_type), "::new(23);")]
3962            /// let bar = 12;
3963            /// let min_foo = foo.fetch_min(bar, Ordering::SeqCst).min(bar);
3964            /// assert_eq!(min_foo, 12);
3965            /// ```
3966            #[inline]
3967            #[stable(feature = "atomic_min_max", since = "1.45.0")]
3968            #[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
3969            #[cfg(any($cfg_cas, doc))]
3970            #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3971            #[rustc_should_not_be_called_on_const_items]
3972            pub const fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type {
3973                // SAFETY: data races are prevented by atomic intrinsics.
3974                unsafe { $min_fn(self.as_ptr(), val, order) }
3975            }
3976
3977            /// Returns a mutable pointer to the underlying integer.
3978            ///
3979            /// Doing non-atomic reads and writes on the resulting integer can be a data race.
3980            /// This method is mostly useful for FFI, where the function signature may use
3981            #[doc = concat!("`*mut ", stringify!($int_type), "` instead of `&", stringify!($atomic_type), "`.")]
3982            ///
3983            /// Returning an `*mut` pointer from a shared reference to this atomic is safe because the
3984            /// atomic types work with interior mutability. All modifications of an atomic change the value
3985            /// through a shared reference, and can do so safely as long as they use atomic operations. Any
3986            /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the
3987            /// requirements of the [memory model].
3988            ///
3989            /// # Examples
3990            ///
3991            /// ```ignore (extern-declaration)
3992            /// # fn main() {
3993            #[doc = concat!($extra_feature, "use std::sync::atomic::", stringify!($atomic_type), ";")]
3994            ///
3995            /// extern "C" {
3996            #[doc = concat!("    fn my_atomic_op(arg: *mut ", stringify!($int_type), ");")]
3997            /// }
3998            ///
3999            #[doc = concat!("let atomic = ", stringify!($atomic_type), "::new(1);")]
4000            ///
4001            /// // SAFETY: Safe as long as `my_atomic_op` is atomic.
4002            /// unsafe {
4003            ///     my_atomic_op(atomic.as_ptr());
4004            /// }
4005            /// # }
4006            /// ```
4007            ///
4008            /// [memory model]: self#memory-model-for-atomic-accesses
4009            #[inline]
4010            #[stable(feature = "atomic_as_ptr", since = "1.70.0")]
4011            #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")]
4012            #[rustc_never_returns_null_ptr]
4013            pub const fn as_ptr(&self) -> *mut $int_type {
4014                self.v.get().cast()
4015            }
4016        }
4017    }
4018}
4019
4020#[cfg(target_has_atomic_load_store = "8")]
4021/// 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() }
    }
    /// Creates a new pointer to an atomic integer from a pointer.
    ///
    /// This is useful if you want to do volatile atomic accesses, and thus avoid creating
    /// a reference to the destination.
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    pub const fn from_ptr_raw(ptr: *mut i8) -> *const AtomicI8 {
        ptr.cast_const().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) }
    }
    /// Perform a volatile load from the atomic integer.
    ///
    /// `load_volatile` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
    ///
    #[doc =
    "Volatile operations are intended to act on I/O memory. As such, they are considered externally\nobservable events (just like syscalls, but less opaque), and are guaranteed to not be elided or\nreordered by the compiler across other externally observable events. With this in mind, there\nare two cases of usage that need to be distinguished:\n\n- When a volatile operation is used for memory inside an [allocation], it behaves exactly\n  like [`load`][Self::load], except for the additional guarantee that it won\'t be elided or\n  reordered across other externally observable events (see above). This implies that the\n  operation will actually access memory and not e.g. be lowered to reusing data from a\n  previous load. Other than that, all the usual rules for memory accesses apply (including\n  provenance).\n\n- Volatile operations, however, may also be used to access memory that is _outside_ of any Rust\n  allocation. In this use-case, the pointer does *not* have to be [valid] for reads. This is\n  typically used for CPU and peripheral registers that must be accessed via an I/O memory mapping,\n  most commonly at fixed addresses reserved by the hardware. These often have special semantics\n  associated to their manipulation, and cannot be used as general purpose memory. Here, any address\n  value is possible, including 0 and [`usize::MAX`], so long as the semantics of such a read are\n  well-defined by the target hardware. The provenance of the pointer is irrelevant, and it can be\n  created with [`without_provenance`][crate::ptr::without_provenance]. The access is allowed to\n  trap, which must immediately abort the process. It can also cause other side-effects, but those\n  must not affect Rust-allocated memory in any way.\n\nIn both cases, the access is also considered atomic with the given `order`. This allows\nsynchronization with other threads or devices that share memory with this program.\n\nWhen invoked during const evaluation, this behaves like a regular atomic load. In\nparticular, such reads must always follow the first of the two cases above.\n\n[allocation]: crate::ptr#allocated-object\n"]
    ///
    /// # Safety
    ///
    /// Behavior is undefined if any of the following conditions are violated:
    ///
    /// * `self` must be [valid] for reads, or `self` must point to memory
    ///   outside of all Rust allocations and reading from that memory must:
    ///   - not trap, and
    ///   - not cause any memory inside a Rust allocation to be modified.
    ///
    /// * `self` must be aligned to
    #[doc = "  `align_of::<AtomicI8>()`"]
    #[doc =
    "  (note that this is always true, since `align_of::<AtomicI8>() == 1`)."]
    ///
    /// * Reading from `self` must produce a properly initialized value of the underlying
    ///   integer type.
    ///
    /// [valid]: core::ptr#safety
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Release`] or [`AcqRel`].
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
    pub const unsafe fn load_volatile(self: *const Self, order: Ordering)
        -> i8 {
        unsafe { atomic_load::<_, true>(self.cast::<i8>(), 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); }
    }
    /// Performs a volatile store into the atomic integer.
    ///
    /// `store_volatile` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
    ///
    #[doc =
    "Volatile operations are intended to act on I/O memory. As such, they are considered externally\nobservable events (just like syscalls), and are guaranteed to not be elided or reordered by the\ncompiler across other externally observable events. With this in mind, there are two cases of\nusage that need to be distinguished:\n\n- When a volatile operation is used for memory inside an [allocation], it behaves exactly like\n  [`store`][Self::store], except for the additional guarantee that it won\'t be elided or reordered\n  across other externally observable events (see above). This implies that the operation will\n  actually access memory and not e.g. be lowered to a register access. Other than that, all the\n  usual rules for memory accesses apply (including provenance).\n\n- Volatile operations, however, may also be used to access memory that is _outside_ of any Rust\n  allocation. In this use-case, the pointer does *not* have to be [valid] for writes. This is\n  typically used for CPU and peripheral registers that must be accessed via an I/O memory mapping,\n  most commonly at fixed addresses reserved by the hardware. These often have special semantics\n  associated to their manipulation, and cannot be used as general purpose memory. Here, any address\n  value is possible, including 0 and [`usize::MAX`], so long as the semantics of such a write are\n  well-defined by the target hardware. The provenance of the pointer is irrelevant, and it can be\n  created with [`without_provenance_mut`][crate::ptr::without_provenance_mut]. The access is allowed\n  to trap, which must immediately abort the process. It can also cause other side-effects, but those\n  must not affect Rust-allocated memory in any way.\n\nIn both cases, the access is also considered atomic with the given `order`. This allows\nsynchronization with other threads or devices that share memory with this program.\n\nWhen invoked during const evaluation, this behaves like a regular atomic store. In\nparticular, such reads must always follow the first of the two cases above.\n\n[allocation]: crate::ptr#allocated-object\n"]
    ///
    /// # Safety
    ///
    /// Behavior is undefined if any of the following conditions are violated:
    ///
    /// * `self` must be either [valid] for writes, or `self` must point to memory
    ///   outside of all Rust allocations and writing to that memory must:
    ///   - not trap, and
    ///   - not cause any memory inside a Rust allocation to be modified.
    ///
    /// * `self` must be aligned to
    #[doc = "  `align_of::<AtomicI8>()`"]
    #[doc =
    "  (note that this is always true, since `align_of::<AtomicI8>() == 1`)."]
    ///
    /// [valid]: core::ptr#safety
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_should_not_be_called_on_const_items]
    pub const unsafe fn store_volatile(self: *const Self, val: i8,
        order: Ordering) {
        unsafe {
            atomic_store::<_, true>(self.cast::<i8>().cast_mut(), 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, and applies a function to it that returns 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! {
4022    target_has_atomic_load_store = "8",
4023    target_has_atomic = "8",
4024    target_has_atomic_primitive_alignment = "8",
4025    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4026    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4027    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4028    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4029    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4030    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4031    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
4032    rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
4033    "i8",
4034    "",
4035    atomic_min, atomic_max,
4036    1,
4037    i8 AtomicI8
4038}
4039#[cfg(target_has_atomic_load_store = "8")]
4040/// 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() }
    }
    /// Creates a new pointer to an atomic integer from a pointer.
    ///
    /// This is useful if you want to do volatile atomic accesses, and thus avoid creating
    /// a reference to the destination.
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    pub const fn from_ptr_raw(ptr: *mut u8) -> *const AtomicU8 {
        ptr.cast_const().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) }
    }
    /// Perform a volatile load from the atomic integer.
    ///
    /// `load_volatile` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
    ///
    #[doc =
    "Volatile operations are intended to act on I/O memory. As such, they are considered externally\nobservable events (just like syscalls, but less opaque), and are guaranteed to not be elided or\nreordered by the compiler across other externally observable events. With this in mind, there\nare two cases of usage that need to be distinguished:\n\n- When a volatile operation is used for memory inside an [allocation], it behaves exactly\n  like [`load`][Self::load], except for the additional guarantee that it won\'t be elided or\n  reordered across other externally observable events (see above). This implies that the\n  operation will actually access memory and not e.g. be lowered to reusing data from a\n  previous load. Other than that, all the usual rules for memory accesses apply (including\n  provenance).\n\n- Volatile operations, however, may also be used to access memory that is _outside_ of any Rust\n  allocation. In this use-case, the pointer does *not* have to be [valid] for reads. This is\n  typically used for CPU and peripheral registers that must be accessed via an I/O memory mapping,\n  most commonly at fixed addresses reserved by the hardware. These often have special semantics\n  associated to their manipulation, and cannot be used as general purpose memory. Here, any address\n  value is possible, including 0 and [`usize::MAX`], so long as the semantics of such a read are\n  well-defined by the target hardware. The provenance of the pointer is irrelevant, and it can be\n  created with [`without_provenance`][crate::ptr::without_provenance]. The access is allowed to\n  trap, which must immediately abort the process. It can also cause other side-effects, but those\n  must not affect Rust-allocated memory in any way.\n\nIn both cases, the access is also considered atomic with the given `order`. This allows\nsynchronization with other threads or devices that share memory with this program.\n\nWhen invoked during const evaluation, this behaves like a regular atomic load. In\nparticular, such reads must always follow the first of the two cases above.\n\n[allocation]: crate::ptr#allocated-object\n"]
    ///
    /// # Safety
    ///
    /// Behavior is undefined if any of the following conditions are violated:
    ///
    /// * `self` must be [valid] for reads, or `self` must point to memory
    ///   outside of all Rust allocations and reading from that memory must:
    ///   - not trap, and
    ///   - not cause any memory inside a Rust allocation to be modified.
    ///
    /// * `self` must be aligned to
    #[doc = "  `align_of::<AtomicU8>()`"]
    #[doc =
    "  (note that this is always true, since `align_of::<AtomicU8>() == 1`)."]
    ///
    /// * Reading from `self` must produce a properly initialized value of the underlying
    ///   integer type.
    ///
    /// [valid]: core::ptr#safety
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Release`] or [`AcqRel`].
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
    pub const unsafe fn load_volatile(self: *const Self, order: Ordering)
        -> u8 {
        unsafe { atomic_load::<_, true>(self.cast::<u8>(), 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); }
    }
    /// Performs a volatile store into the atomic integer.
    ///
    /// `store_volatile` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
    ///
    #[doc =
    "Volatile operations are intended to act on I/O memory. As such, they are considered externally\nobservable events (just like syscalls), and are guaranteed to not be elided or reordered by the\ncompiler across other externally observable events. With this in mind, there are two cases of\nusage that need to be distinguished:\n\n- When a volatile operation is used for memory inside an [allocation], it behaves exactly like\n  [`store`][Self::store], except for the additional guarantee that it won\'t be elided or reordered\n  across other externally observable events (see above). This implies that the operation will\n  actually access memory and not e.g. be lowered to a register access. Other than that, all the\n  usual rules for memory accesses apply (including provenance).\n\n- Volatile operations, however, may also be used to access memory that is _outside_ of any Rust\n  allocation. In this use-case, the pointer does *not* have to be [valid] for writes. This is\n  typically used for CPU and peripheral registers that must be accessed via an I/O memory mapping,\n  most commonly at fixed addresses reserved by the hardware. These often have special semantics\n  associated to their manipulation, and cannot be used as general purpose memory. Here, any address\n  value is possible, including 0 and [`usize::MAX`], so long as the semantics of such a write are\n  well-defined by the target hardware. The provenance of the pointer is irrelevant, and it can be\n  created with [`without_provenance_mut`][crate::ptr::without_provenance_mut]. The access is allowed\n  to trap, which must immediately abort the process. It can also cause other side-effects, but those\n  must not affect Rust-allocated memory in any way.\n\nIn both cases, the access is also considered atomic with the given `order`. This allows\nsynchronization with other threads or devices that share memory with this program.\n\nWhen invoked during const evaluation, this behaves like a regular atomic store. In\nparticular, such reads must always follow the first of the two cases above.\n\n[allocation]: crate::ptr#allocated-object\n"]
    ///
    /// # Safety
    ///
    /// Behavior is undefined if any of the following conditions are violated:
    ///
    /// * `self` must be either [valid] for writes, or `self` must point to memory
    ///   outside of all Rust allocations and writing to that memory must:
    ///   - not trap, and
    ///   - not cause any memory inside a Rust allocation to be modified.
    ///
    /// * `self` must be aligned to
    #[doc = "  `align_of::<AtomicU8>()`"]
    #[doc =
    "  (note that this is always true, since `align_of::<AtomicU8>() == 1`)."]
    ///
    /// [valid]: core::ptr#safety
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_should_not_be_called_on_const_items]
    pub const unsafe fn store_volatile(self: *const Self, val: u8,
        order: Ordering) {
        unsafe {
            atomic_store::<_, true>(self.cast::<u8>().cast_mut(), 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, and applies a function to it that returns 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! {
4041    target_has_atomic_load_store = "8",
4042    target_has_atomic = "8",
4043    target_has_atomic_primitive_alignment = "8",
4044    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4045    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4046    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4047    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4048    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4049    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4050    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
4051    rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
4052    "u8",
4053    "",
4054    atomic_umin, atomic_umax,
4055    1,
4056    u8 AtomicU8
4057}
4058#[cfg(target_has_atomic_load_store = "16")]
4059/// 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() }
    }
    /// Creates a new pointer to an atomic integer from a pointer.
    ///
    /// This is useful if you want to do volatile atomic accesses, and thus avoid creating
    /// a reference to the destination.
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    pub const fn from_ptr_raw(ptr: *mut i16) -> *const AtomicI16 {
        ptr.cast_const().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) }
    }
    /// Perform a volatile load from the atomic integer.
    ///
    /// `load_volatile` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
    ///
    #[doc =
    "Volatile operations are intended to act on I/O memory. As such, they are considered externally\nobservable events (just like syscalls, but less opaque), and are guaranteed to not be elided or\nreordered by the compiler across other externally observable events. With this in mind, there\nare two cases of usage that need to be distinguished:\n\n- When a volatile operation is used for memory inside an [allocation], it behaves exactly\n  like [`load`][Self::load], except for the additional guarantee that it won\'t be elided or\n  reordered across other externally observable events (see above). This implies that the\n  operation will actually access memory and not e.g. be lowered to reusing data from a\n  previous load. Other than that, all the usual rules for memory accesses apply (including\n  provenance).\n\n- Volatile operations, however, may also be used to access memory that is _outside_ of any Rust\n  allocation. In this use-case, the pointer does *not* have to be [valid] for reads. This is\n  typically used for CPU and peripheral registers that must be accessed via an I/O memory mapping,\n  most commonly at fixed addresses reserved by the hardware. These often have special semantics\n  associated to their manipulation, and cannot be used as general purpose memory. Here, any address\n  value is possible, including 0 and [`usize::MAX`], so long as the semantics of such a read are\n  well-defined by the target hardware. The provenance of the pointer is irrelevant, and it can be\n  created with [`without_provenance`][crate::ptr::without_provenance]. The access is allowed to\n  trap, which must immediately abort the process. It can also cause other side-effects, but those\n  must not affect Rust-allocated memory in any way.\n\nIn both cases, the access is also considered atomic with the given `order`. This allows\nsynchronization with other threads or devices that share memory with this program.\n\nWhen invoked during const evaluation, this behaves like a regular atomic load. In\nparticular, such reads must always follow the first of the two cases above.\n\n[allocation]: crate::ptr#allocated-object\n"]
    ///
    /// # Safety
    ///
    /// Behavior is undefined if any of the following conditions are violated:
    ///
    /// * `self` must be [valid] for reads, or `self` must point to memory
    ///   outside of all Rust allocations and reading from that memory must:
    ///   - not trap, and
    ///   - not cause any memory inside a Rust allocation to be modified.
    ///
    /// * `self` must be aligned to
    #[doc = "  `align_of::<AtomicI16>()`"]
    #[doc =
    "  (note that on some platforms this can be bigger than `align_of::<i16>()`)."]
    ///
    /// * Reading from `self` must produce a properly initialized value of the underlying
    ///   integer type.
    ///
    /// [valid]: core::ptr#safety
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Release`] or [`AcqRel`].
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
    pub const unsafe fn load_volatile(self: *const Self, order: Ordering)
        -> i16 {
        unsafe { atomic_load::<_, true>(self.cast::<i16>(), 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); }
    }
    /// Performs a volatile store into the atomic integer.
    ///
    /// `store_volatile` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
    ///
    #[doc =
    "Volatile operations are intended to act on I/O memory. As such, they are considered externally\nobservable events (just like syscalls), and are guaranteed to not be elided or reordered by the\ncompiler across other externally observable events. With this in mind, there are two cases of\nusage that need to be distinguished:\n\n- When a volatile operation is used for memory inside an [allocation], it behaves exactly like\n  [`store`][Self::store], except for the additional guarantee that it won\'t be elided or reordered\n  across other externally observable events (see above). This implies that the operation will\n  actually access memory and not e.g. be lowered to a register access. Other than that, all the\n  usual rules for memory accesses apply (including provenance).\n\n- Volatile operations, however, may also be used to access memory that is _outside_ of any Rust\n  allocation. In this use-case, the pointer does *not* have to be [valid] for writes. This is\n  typically used for CPU and peripheral registers that must be accessed via an I/O memory mapping,\n  most commonly at fixed addresses reserved by the hardware. These often have special semantics\n  associated to their manipulation, and cannot be used as general purpose memory. Here, any address\n  value is possible, including 0 and [`usize::MAX`], so long as the semantics of such a write are\n  well-defined by the target hardware. The provenance of the pointer is irrelevant, and it can be\n  created with [`without_provenance_mut`][crate::ptr::without_provenance_mut]. The access is allowed\n  to trap, which must immediately abort the process. It can also cause other side-effects, but those\n  must not affect Rust-allocated memory in any way.\n\nIn both cases, the access is also considered atomic with the given `order`. This allows\nsynchronization with other threads or devices that share memory with this program.\n\nWhen invoked during const evaluation, this behaves like a regular atomic store. In\nparticular, such reads must always follow the first of the two cases above.\n\n[allocation]: crate::ptr#allocated-object\n"]
    ///
    /// # Safety
    ///
    /// Behavior is undefined if any of the following conditions are violated:
    ///
    /// * `self` must be either [valid] for writes, or `self` must point to memory
    ///   outside of all Rust allocations and writing to that memory must:
    ///   - not trap, and
    ///   - not cause any memory inside a Rust allocation to be modified.
    ///
    /// * `self` must be aligned to
    #[doc = "  `align_of::<AtomicI16>()`"]
    #[doc =
    "  (note that on some platforms this can be bigger than `align_of::<i16>()`)."]
    ///
    /// [valid]: core::ptr#safety
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_should_not_be_called_on_const_items]
    pub const unsafe fn store_volatile(self: *const Self, val: i16,
        order: Ordering) {
        unsafe {
            atomic_store::<_,
                    true>(self.cast::<i16>().cast_mut(), 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, and applies a function to it that returns 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! {
4060    target_has_atomic_load_store = "16",
4061    target_has_atomic = "16",
4062    target_has_atomic_primitive_alignment = "16",
4063    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4064    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4065    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4066    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4067    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4068    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4069    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
4070    rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
4071    "i16",
4072    "",
4073    atomic_min, atomic_max,
4074    2,
4075    i16 AtomicI16
4076}
4077#[cfg(target_has_atomic_load_store = "16")]
4078/// 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() }
    }
    /// Creates a new pointer to an atomic integer from a pointer.
    ///
    /// This is useful if you want to do volatile atomic accesses, and thus avoid creating
    /// a reference to the destination.
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    pub const fn from_ptr_raw(ptr: *mut u16) -> *const AtomicU16 {
        ptr.cast_const().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) }
    }
    /// Perform a volatile load from the atomic integer.
    ///
    /// `load_volatile` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
    ///
    #[doc =
    "Volatile operations are intended to act on I/O memory. As such, they are considered externally\nobservable events (just like syscalls, but less opaque), and are guaranteed to not be elided or\nreordered by the compiler across other externally observable events. With this in mind, there\nare two cases of usage that need to be distinguished:\n\n- When a volatile operation is used for memory inside an [allocation], it behaves exactly\n  like [`load`][Self::load], except for the additional guarantee that it won\'t be elided or\n  reordered across other externally observable events (see above). This implies that the\n  operation will actually access memory and not e.g. be lowered to reusing data from a\n  previous load. Other than that, all the usual rules for memory accesses apply (including\n  provenance).\n\n- Volatile operations, however, may also be used to access memory that is _outside_ of any Rust\n  allocation. In this use-case, the pointer does *not* have to be [valid] for reads. This is\n  typically used for CPU and peripheral registers that must be accessed via an I/O memory mapping,\n  most commonly at fixed addresses reserved by the hardware. These often have special semantics\n  associated to their manipulation, and cannot be used as general purpose memory. Here, any address\n  value is possible, including 0 and [`usize::MAX`], so long as the semantics of such a read are\n  well-defined by the target hardware. The provenance of the pointer is irrelevant, and it can be\n  created with [`without_provenance`][crate::ptr::without_provenance]. The access is allowed to\n  trap, which must immediately abort the process. It can also cause other side-effects, but those\n  must not affect Rust-allocated memory in any way.\n\nIn both cases, the access is also considered atomic with the given `order`. This allows\nsynchronization with other threads or devices that share memory with this program.\n\nWhen invoked during const evaluation, this behaves like a regular atomic load. In\nparticular, such reads must always follow the first of the two cases above.\n\n[allocation]: crate::ptr#allocated-object\n"]
    ///
    /// # Safety
    ///
    /// Behavior is undefined if any of the following conditions are violated:
    ///
    /// * `self` must be [valid] for reads, or `self` must point to memory
    ///   outside of all Rust allocations and reading from that memory must:
    ///   - not trap, and
    ///   - not cause any memory inside a Rust allocation to be modified.
    ///
    /// * `self` must be aligned to
    #[doc = "  `align_of::<AtomicU16>()`"]
    #[doc =
    "  (note that on some platforms this can be bigger than `align_of::<u16>()`)."]
    ///
    /// * Reading from `self` must produce a properly initialized value of the underlying
    ///   integer type.
    ///
    /// [valid]: core::ptr#safety
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Release`] or [`AcqRel`].
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
    pub const unsafe fn load_volatile(self: *const Self, order: Ordering)
        -> u16 {
        unsafe { atomic_load::<_, true>(self.cast::<u16>(), 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); }
    }
    /// Performs a volatile store into the atomic integer.
    ///
    /// `store_volatile` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
    ///
    #[doc =
    "Volatile operations are intended to act on I/O memory. As such, they are considered externally\nobservable events (just like syscalls), and are guaranteed to not be elided or reordered by the\ncompiler across other externally observable events. With this in mind, there are two cases of\nusage that need to be distinguished:\n\n- When a volatile operation is used for memory inside an [allocation], it behaves exactly like\n  [`store`][Self::store], except for the additional guarantee that it won\'t be elided or reordered\n  across other externally observable events (see above). This implies that the operation will\n  actually access memory and not e.g. be lowered to a register access. Other than that, all the\n  usual rules for memory accesses apply (including provenance).\n\n- Volatile operations, however, may also be used to access memory that is _outside_ of any Rust\n  allocation. In this use-case, the pointer does *not* have to be [valid] for writes. This is\n  typically used for CPU and peripheral registers that must be accessed via an I/O memory mapping,\n  most commonly at fixed addresses reserved by the hardware. These often have special semantics\n  associated to their manipulation, and cannot be used as general purpose memory. Here, any address\n  value is possible, including 0 and [`usize::MAX`], so long as the semantics of such a write are\n  well-defined by the target hardware. The provenance of the pointer is irrelevant, and it can be\n  created with [`without_provenance_mut`][crate::ptr::without_provenance_mut]. The access is allowed\n  to trap, which must immediately abort the process. It can also cause other side-effects, but those\n  must not affect Rust-allocated memory in any way.\n\nIn both cases, the access is also considered atomic with the given `order`. This allows\nsynchronization with other threads or devices that share memory with this program.\n\nWhen invoked during const evaluation, this behaves like a regular atomic store. In\nparticular, such reads must always follow the first of the two cases above.\n\n[allocation]: crate::ptr#allocated-object\n"]
    ///
    /// # Safety
    ///
    /// Behavior is undefined if any of the following conditions are violated:
    ///
    /// * `self` must be either [valid] for writes, or `self` must point to memory
    ///   outside of all Rust allocations and writing to that memory must:
    ///   - not trap, and
    ///   - not cause any memory inside a Rust allocation to be modified.
    ///
    /// * `self` must be aligned to
    #[doc = "  `align_of::<AtomicU16>()`"]
    #[doc =
    "  (note that on some platforms this can be bigger than `align_of::<u16>()`)."]
    ///
    /// [valid]: core::ptr#safety
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_should_not_be_called_on_const_items]
    pub const unsafe fn store_volatile(self: *const Self, val: u16,
        order: Ordering) {
        unsafe {
            atomic_store::<_,
                    true>(self.cast::<u16>().cast_mut(), 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, and applies a function to it that returns 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! {
4079    target_has_atomic_load_store = "16",
4080    target_has_atomic = "16",
4081    target_has_atomic_primitive_alignment = "16",
4082    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4083    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4084    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4085    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4086    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4087    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4088    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
4089    rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
4090    "u16",
4091    "",
4092    atomic_umin, atomic_umax,
4093    2,
4094    u16 AtomicU16
4095}
4096#[cfg(target_has_atomic_load_store = "32")]
4097/// 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() }
    }
    /// Creates a new pointer to an atomic integer from a pointer.
    ///
    /// This is useful if you want to do volatile atomic accesses, and thus avoid creating
    /// a reference to the destination.
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    pub const fn from_ptr_raw(ptr: *mut i32) -> *const AtomicI32 {
        ptr.cast_const().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) }
    }
    /// Perform a volatile load from the atomic integer.
    ///
    /// `load_volatile` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
    ///
    #[doc =
    "Volatile operations are intended to act on I/O memory. As such, they are considered externally\nobservable events (just like syscalls, but less opaque), and are guaranteed to not be elided or\nreordered by the compiler across other externally observable events. With this in mind, there\nare two cases of usage that need to be distinguished:\n\n- When a volatile operation is used for memory inside an [allocation], it behaves exactly\n  like [`load`][Self::load], except for the additional guarantee that it won\'t be elided or\n  reordered across other externally observable events (see above). This implies that the\n  operation will actually access memory and not e.g. be lowered to reusing data from a\n  previous load. Other than that, all the usual rules for memory accesses apply (including\n  provenance).\n\n- Volatile operations, however, may also be used to access memory that is _outside_ of any Rust\n  allocation. In this use-case, the pointer does *not* have to be [valid] for reads. This is\n  typically used for CPU and peripheral registers that must be accessed via an I/O memory mapping,\n  most commonly at fixed addresses reserved by the hardware. These often have special semantics\n  associated to their manipulation, and cannot be used as general purpose memory. Here, any address\n  value is possible, including 0 and [`usize::MAX`], so long as the semantics of such a read are\n  well-defined by the target hardware. The provenance of the pointer is irrelevant, and it can be\n  created with [`without_provenance`][crate::ptr::without_provenance]. The access is allowed to\n  trap, which must immediately abort the process. It can also cause other side-effects, but those\n  must not affect Rust-allocated memory in any way.\n\nIn both cases, the access is also considered atomic with the given `order`. This allows\nsynchronization with other threads or devices that share memory with this program.\n\nWhen invoked during const evaluation, this behaves like a regular atomic load. In\nparticular, such reads must always follow the first of the two cases above.\n\n[allocation]: crate::ptr#allocated-object\n"]
    ///
    /// # Safety
    ///
    /// Behavior is undefined if any of the following conditions are violated:
    ///
    /// * `self` must be [valid] for reads, or `self` must point to memory
    ///   outside of all Rust allocations and reading from that memory must:
    ///   - not trap, and
    ///   - not cause any memory inside a Rust allocation to be modified.
    ///
    /// * `self` must be aligned to
    #[doc = "  `align_of::<AtomicI32>()`"]
    #[doc =
    "  (note that on some platforms this can be bigger than `align_of::<i32>()`)."]
    ///
    /// * Reading from `self` must produce a properly initialized value of the underlying
    ///   integer type.
    ///
    /// [valid]: core::ptr#safety
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Release`] or [`AcqRel`].
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
    pub const unsafe fn load_volatile(self: *const Self, order: Ordering)
        -> i32 {
        unsafe { atomic_load::<_, true>(self.cast::<i32>(), 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); }
    }
    /// Performs a volatile store into the atomic integer.
    ///
    /// `store_volatile` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
    ///
    #[doc =
    "Volatile operations are intended to act on I/O memory. As such, they are considered externally\nobservable events (just like syscalls), and are guaranteed to not be elided or reordered by the\ncompiler across other externally observable events. With this in mind, there are two cases of\nusage that need to be distinguished:\n\n- When a volatile operation is used for memory inside an [allocation], it behaves exactly like\n  [`store`][Self::store], except for the additional guarantee that it won\'t be elided or reordered\n  across other externally observable events (see above). This implies that the operation will\n  actually access memory and not e.g. be lowered to a register access. Other than that, all the\n  usual rules for memory accesses apply (including provenance).\n\n- Volatile operations, however, may also be used to access memory that is _outside_ of any Rust\n  allocation. In this use-case, the pointer does *not* have to be [valid] for writes. This is\n  typically used for CPU and peripheral registers that must be accessed via an I/O memory mapping,\n  most commonly at fixed addresses reserved by the hardware. These often have special semantics\n  associated to their manipulation, and cannot be used as general purpose memory. Here, any address\n  value is possible, including 0 and [`usize::MAX`], so long as the semantics of such a write are\n  well-defined by the target hardware. The provenance of the pointer is irrelevant, and it can be\n  created with [`without_provenance_mut`][crate::ptr::without_provenance_mut]. The access is allowed\n  to trap, which must immediately abort the process. It can also cause other side-effects, but those\n  must not affect Rust-allocated memory in any way.\n\nIn both cases, the access is also considered atomic with the given `order`. This allows\nsynchronization with other threads or devices that share memory with this program.\n\nWhen invoked during const evaluation, this behaves like a regular atomic store. In\nparticular, such reads must always follow the first of the two cases above.\n\n[allocation]: crate::ptr#allocated-object\n"]
    ///
    /// # Safety
    ///
    /// Behavior is undefined if any of the following conditions are violated:
    ///
    /// * `self` must be either [valid] for writes, or `self` must point to memory
    ///   outside of all Rust allocations and writing to that memory must:
    ///   - not trap, and
    ///   - not cause any memory inside a Rust allocation to be modified.
    ///
    /// * `self` must be aligned to
    #[doc = "  `align_of::<AtomicI32>()`"]
    #[doc =
    "  (note that on some platforms this can be bigger than `align_of::<i32>()`)."]
    ///
    /// [valid]: core::ptr#safety
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_should_not_be_called_on_const_items]
    pub const unsafe fn store_volatile(self: *const Self, val: i32,
        order: Ordering) {
        unsafe {
            atomic_store::<_,
                    true>(self.cast::<i32>().cast_mut(), 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, and applies a function to it that returns 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! {
4098    target_has_atomic_load_store = "32",
4099    target_has_atomic = "32",
4100    target_has_atomic_primitive_alignment = "32",
4101    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4102    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4103    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4104    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4105    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4106    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4107    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
4108    rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
4109    "i32",
4110    "",
4111    atomic_min, atomic_max,
4112    4,
4113    i32 AtomicI32
4114}
4115#[cfg(target_has_atomic_load_store = "32")]
4116/// 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() }
    }
    /// Creates a new pointer to an atomic integer from a pointer.
    ///
    /// This is useful if you want to do volatile atomic accesses, and thus avoid creating
    /// a reference to the destination.
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    pub const fn from_ptr_raw(ptr: *mut u32) -> *const AtomicU32 {
        ptr.cast_const().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) }
    }
    /// Perform a volatile load from the atomic integer.
    ///
    /// `load_volatile` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
    ///
    #[doc =
    "Volatile operations are intended to act on I/O memory. As such, they are considered externally\nobservable events (just like syscalls, but less opaque), and are guaranteed to not be elided or\nreordered by the compiler across other externally observable events. With this in mind, there\nare two cases of usage that need to be distinguished:\n\n- When a volatile operation is used for memory inside an [allocation], it behaves exactly\n  like [`load`][Self::load], except for the additional guarantee that it won\'t be elided or\n  reordered across other externally observable events (see above). This implies that the\n  operation will actually access memory and not e.g. be lowered to reusing data from a\n  previous load. Other than that, all the usual rules for memory accesses apply (including\n  provenance).\n\n- Volatile operations, however, may also be used to access memory that is _outside_ of any Rust\n  allocation. In this use-case, the pointer does *not* have to be [valid] for reads. This is\n  typically used for CPU and peripheral registers that must be accessed via an I/O memory mapping,\n  most commonly at fixed addresses reserved by the hardware. These often have special semantics\n  associated to their manipulation, and cannot be used as general purpose memory. Here, any address\n  value is possible, including 0 and [`usize::MAX`], so long as the semantics of such a read are\n  well-defined by the target hardware. The provenance of the pointer is irrelevant, and it can be\n  created with [`without_provenance`][crate::ptr::without_provenance]. The access is allowed to\n  trap, which must immediately abort the process. It can also cause other side-effects, but those\n  must not affect Rust-allocated memory in any way.\n\nIn both cases, the access is also considered atomic with the given `order`. This allows\nsynchronization with other threads or devices that share memory with this program.\n\nWhen invoked during const evaluation, this behaves like a regular atomic load. In\nparticular, such reads must always follow the first of the two cases above.\n\n[allocation]: crate::ptr#allocated-object\n"]
    ///
    /// # Safety
    ///
    /// Behavior is undefined if any of the following conditions are violated:
    ///
    /// * `self` must be [valid] for reads, or `self` must point to memory
    ///   outside of all Rust allocations and reading from that memory must:
    ///   - not trap, and
    ///   - not cause any memory inside a Rust allocation to be modified.
    ///
    /// * `self` must be aligned to
    #[doc = "  `align_of::<AtomicU32>()`"]
    #[doc =
    "  (note that on some platforms this can be bigger than `align_of::<u32>()`)."]
    ///
    /// * Reading from `self` must produce a properly initialized value of the underlying
    ///   integer type.
    ///
    /// [valid]: core::ptr#safety
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Release`] or [`AcqRel`].
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
    pub const unsafe fn load_volatile(self: *const Self, order: Ordering)
        -> u32 {
        unsafe { atomic_load::<_, true>(self.cast::<u32>(), 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); }
    }
    /// Performs a volatile store into the atomic integer.
    ///
    /// `store_volatile` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
    ///
    #[doc =
    "Volatile operations are intended to act on I/O memory. As such, they are considered externally\nobservable events (just like syscalls), and are guaranteed to not be elided or reordered by the\ncompiler across other externally observable events. With this in mind, there are two cases of\nusage that need to be distinguished:\n\n- When a volatile operation is used for memory inside an [allocation], it behaves exactly like\n  [`store`][Self::store], except for the additional guarantee that it won\'t be elided or reordered\n  across other externally observable events (see above). This implies that the operation will\n  actually access memory and not e.g. be lowered to a register access. Other than that, all the\n  usual rules for memory accesses apply (including provenance).\n\n- Volatile operations, however, may also be used to access memory that is _outside_ of any Rust\n  allocation. In this use-case, the pointer does *not* have to be [valid] for writes. This is\n  typically used for CPU and peripheral registers that must be accessed via an I/O memory mapping,\n  most commonly at fixed addresses reserved by the hardware. These often have special semantics\n  associated to their manipulation, and cannot be used as general purpose memory. Here, any address\n  value is possible, including 0 and [`usize::MAX`], so long as the semantics of such a write are\n  well-defined by the target hardware. The provenance of the pointer is irrelevant, and it can be\n  created with [`without_provenance_mut`][crate::ptr::without_provenance_mut]. The access is allowed\n  to trap, which must immediately abort the process. It can also cause other side-effects, but those\n  must not affect Rust-allocated memory in any way.\n\nIn both cases, the access is also considered atomic with the given `order`. This allows\nsynchronization with other threads or devices that share memory with this program.\n\nWhen invoked during const evaluation, this behaves like a regular atomic store. In\nparticular, such reads must always follow the first of the two cases above.\n\n[allocation]: crate::ptr#allocated-object\n"]
    ///
    /// # Safety
    ///
    /// Behavior is undefined if any of the following conditions are violated:
    ///
    /// * `self` must be either [valid] for writes, or `self` must point to memory
    ///   outside of all Rust allocations and writing to that memory must:
    ///   - not trap, and
    ///   - not cause any memory inside a Rust allocation to be modified.
    ///
    /// * `self` must be aligned to
    #[doc = "  `align_of::<AtomicU32>()`"]
    #[doc =
    "  (note that on some platforms this can be bigger than `align_of::<u32>()`)."]
    ///
    /// [valid]: core::ptr#safety
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_should_not_be_called_on_const_items]
    pub const unsafe fn store_volatile(self: *const Self, val: u32,
        order: Ordering) {
        unsafe {
            atomic_store::<_,
                    true>(self.cast::<u32>().cast_mut(), 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, and applies a function to it that returns 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! {
4117    target_has_atomic_load_store = "32",
4118    target_has_atomic = "32",
4119    target_has_atomic_primitive_alignment = "32",
4120    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4121    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4122    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4123    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4124    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4125    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4126    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
4127    rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
4128    "u32",
4129    "",
4130    atomic_umin, atomic_umax,
4131    4,
4132    u32 AtomicU32
4133}
4134#[cfg(target_has_atomic_load_store = "64")]
4135/// 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() }
    }
    /// Creates a new pointer to an atomic integer from a pointer.
    ///
    /// This is useful if you want to do volatile atomic accesses, and thus avoid creating
    /// a reference to the destination.
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    pub const fn from_ptr_raw(ptr: *mut i64) -> *const AtomicI64 {
        ptr.cast_const().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) }
    }
    /// Perform a volatile load from the atomic integer.
    ///
    /// `load_volatile` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
    ///
    #[doc =
    "Volatile operations are intended to act on I/O memory. As such, they are considered externally\nobservable events (just like syscalls, but less opaque), and are guaranteed to not be elided or\nreordered by the compiler across other externally observable events. With this in mind, there\nare two cases of usage that need to be distinguished:\n\n- When a volatile operation is used for memory inside an [allocation], it behaves exactly\n  like [`load`][Self::load], except for the additional guarantee that it won\'t be elided or\n  reordered across other externally observable events (see above). This implies that the\n  operation will actually access memory and not e.g. be lowered to reusing data from a\n  previous load. Other than that, all the usual rules for memory accesses apply (including\n  provenance).\n\n- Volatile operations, however, may also be used to access memory that is _outside_ of any Rust\n  allocation. In this use-case, the pointer does *not* have to be [valid] for reads. This is\n  typically used for CPU and peripheral registers that must be accessed via an I/O memory mapping,\n  most commonly at fixed addresses reserved by the hardware. These often have special semantics\n  associated to their manipulation, and cannot be used as general purpose memory. Here, any address\n  value is possible, including 0 and [`usize::MAX`], so long as the semantics of such a read are\n  well-defined by the target hardware. The provenance of the pointer is irrelevant, and it can be\n  created with [`without_provenance`][crate::ptr::without_provenance]. The access is allowed to\n  trap, which must immediately abort the process. It can also cause other side-effects, but those\n  must not affect Rust-allocated memory in any way.\n\nIn both cases, the access is also considered atomic with the given `order`. This allows\nsynchronization with other threads or devices that share memory with this program.\n\nWhen invoked during const evaluation, this behaves like a regular atomic load. In\nparticular, such reads must always follow the first of the two cases above.\n\n[allocation]: crate::ptr#allocated-object\n"]
    ///
    /// # Safety
    ///
    /// Behavior is undefined if any of the following conditions are violated:
    ///
    /// * `self` must be [valid] for reads, or `self` must point to memory
    ///   outside of all Rust allocations and reading from that memory must:
    ///   - not trap, and
    ///   - not cause any memory inside a Rust allocation to be modified.
    ///
    /// * `self` must be aligned to
    #[doc = "  `align_of::<AtomicI64>()`"]
    #[doc =
    "  (note that on some platforms this can be bigger than `align_of::<i64>()`)."]
    ///
    /// * Reading from `self` must produce a properly initialized value of the underlying
    ///   integer type.
    ///
    /// [valid]: core::ptr#safety
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Release`] or [`AcqRel`].
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
    pub const unsafe fn load_volatile(self: *const Self, order: Ordering)
        -> i64 {
        unsafe { atomic_load::<_, true>(self.cast::<i64>(), 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); }
    }
    /// Performs a volatile store into the atomic integer.
    ///
    /// `store_volatile` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
    ///
    #[doc =
    "Volatile operations are intended to act on I/O memory. As such, they are considered externally\nobservable events (just like syscalls), and are guaranteed to not be elided or reordered by the\ncompiler across other externally observable events. With this in mind, there are two cases of\nusage that need to be distinguished:\n\n- When a volatile operation is used for memory inside an [allocation], it behaves exactly like\n  [`store`][Self::store], except for the additional guarantee that it won\'t be elided or reordered\n  across other externally observable events (see above). This implies that the operation will\n  actually access memory and not e.g. be lowered to a register access. Other than that, all the\n  usual rules for memory accesses apply (including provenance).\n\n- Volatile operations, however, may also be used to access memory that is _outside_ of any Rust\n  allocation. In this use-case, the pointer does *not* have to be [valid] for writes. This is\n  typically used for CPU and peripheral registers that must be accessed via an I/O memory mapping,\n  most commonly at fixed addresses reserved by the hardware. These often have special semantics\n  associated to their manipulation, and cannot be used as general purpose memory. Here, any address\n  value is possible, including 0 and [`usize::MAX`], so long as the semantics of such a write are\n  well-defined by the target hardware. The provenance of the pointer is irrelevant, and it can be\n  created with [`without_provenance_mut`][crate::ptr::without_provenance_mut]. The access is allowed\n  to trap, which must immediately abort the process. It can also cause other side-effects, but those\n  must not affect Rust-allocated memory in any way.\n\nIn both cases, the access is also considered atomic with the given `order`. This allows\nsynchronization with other threads or devices that share memory with this program.\n\nWhen invoked during const evaluation, this behaves like a regular atomic store. In\nparticular, such reads must always follow the first of the two cases above.\n\n[allocation]: crate::ptr#allocated-object\n"]
    ///
    /// # Safety
    ///
    /// Behavior is undefined if any of the following conditions are violated:
    ///
    /// * `self` must be either [valid] for writes, or `self` must point to memory
    ///   outside of all Rust allocations and writing to that memory must:
    ///   - not trap, and
    ///   - not cause any memory inside a Rust allocation to be modified.
    ///
    /// * `self` must be aligned to
    #[doc = "  `align_of::<AtomicI64>()`"]
    #[doc =
    "  (note that on some platforms this can be bigger than `align_of::<i64>()`)."]
    ///
    /// [valid]: core::ptr#safety
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_should_not_be_called_on_const_items]
    pub const unsafe fn store_volatile(self: *const Self, val: i64,
        order: Ordering) {
        unsafe {
            atomic_store::<_,
                    true>(self.cast::<i64>().cast_mut(), 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, and applies a function to it that returns 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! {
4136    target_has_atomic_load_store = "64",
4137    target_has_atomic = "64",
4138    target_has_atomic_primitive_alignment = "64",
4139    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4140    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4141    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4142    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4143    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4144    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4145    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
4146    rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
4147    "i64",
4148    "",
4149    atomic_min, atomic_max,
4150    8,
4151    i64 AtomicI64
4152}
4153#[cfg(target_has_atomic_load_store = "64")]
4154/// 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() }
    }
    /// Creates a new pointer to an atomic integer from a pointer.
    ///
    /// This is useful if you want to do volatile atomic accesses, and thus avoid creating
    /// a reference to the destination.
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    pub const fn from_ptr_raw(ptr: *mut u64) -> *const AtomicU64 {
        ptr.cast_const().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) }
    }
    /// Perform a volatile load from the atomic integer.
    ///
    /// `load_volatile` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
    ///
    #[doc =
    "Volatile operations are intended to act on I/O memory. As such, they are considered externally\nobservable events (just like syscalls, but less opaque), and are guaranteed to not be elided or\nreordered by the compiler across other externally observable events. With this in mind, there\nare two cases of usage that need to be distinguished:\n\n- When a volatile operation is used for memory inside an [allocation], it behaves exactly\n  like [`load`][Self::load], except for the additional guarantee that it won\'t be elided or\n  reordered across other externally observable events (see above). This implies that the\n  operation will actually access memory and not e.g. be lowered to reusing data from a\n  previous load. Other than that, all the usual rules for memory accesses apply (including\n  provenance).\n\n- Volatile operations, however, may also be used to access memory that is _outside_ of any Rust\n  allocation. In this use-case, the pointer does *not* have to be [valid] for reads. This is\n  typically used for CPU and peripheral registers that must be accessed via an I/O memory mapping,\n  most commonly at fixed addresses reserved by the hardware. These often have special semantics\n  associated to their manipulation, and cannot be used as general purpose memory. Here, any address\n  value is possible, including 0 and [`usize::MAX`], so long as the semantics of such a read are\n  well-defined by the target hardware. The provenance of the pointer is irrelevant, and it can be\n  created with [`without_provenance`][crate::ptr::without_provenance]. The access is allowed to\n  trap, which must immediately abort the process. It can also cause other side-effects, but those\n  must not affect Rust-allocated memory in any way.\n\nIn both cases, the access is also considered atomic with the given `order`. This allows\nsynchronization with other threads or devices that share memory with this program.\n\nWhen invoked during const evaluation, this behaves like a regular atomic load. In\nparticular, such reads must always follow the first of the two cases above.\n\n[allocation]: crate::ptr#allocated-object\n"]
    ///
    /// # Safety
    ///
    /// Behavior is undefined if any of the following conditions are violated:
    ///
    /// * `self` must be [valid] for reads, or `self` must point to memory
    ///   outside of all Rust allocations and reading from that memory must:
    ///   - not trap, and
    ///   - not cause any memory inside a Rust allocation to be modified.
    ///
    /// * `self` must be aligned to
    #[doc = "  `align_of::<AtomicU64>()`"]
    #[doc =
    "  (note that on some platforms this can be bigger than `align_of::<u64>()`)."]
    ///
    /// * Reading from `self` must produce a properly initialized value of the underlying
    ///   integer type.
    ///
    /// [valid]: core::ptr#safety
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Release`] or [`AcqRel`].
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
    pub const unsafe fn load_volatile(self: *const Self, order: Ordering)
        -> u64 {
        unsafe { atomic_load::<_, true>(self.cast::<u64>(), 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); }
    }
    /// Performs a volatile store into the atomic integer.
    ///
    /// `store_volatile` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
    ///
    #[doc =
    "Volatile operations are intended to act on I/O memory. As such, they are considered externally\nobservable events (just like syscalls), and are guaranteed to not be elided or reordered by the\ncompiler across other externally observable events. With this in mind, there are two cases of\nusage that need to be distinguished:\n\n- When a volatile operation is used for memory inside an [allocation], it behaves exactly like\n  [`store`][Self::store], except for the additional guarantee that it won\'t be elided or reordered\n  across other externally observable events (see above). This implies that the operation will\n  actually access memory and not e.g. be lowered to a register access. Other than that, all the\n  usual rules for memory accesses apply (including provenance).\n\n- Volatile operations, however, may also be used to access memory that is _outside_ of any Rust\n  allocation. In this use-case, the pointer does *not* have to be [valid] for writes. This is\n  typically used for CPU and peripheral registers that must be accessed via an I/O memory mapping,\n  most commonly at fixed addresses reserved by the hardware. These often have special semantics\n  associated to their manipulation, and cannot be used as general purpose memory. Here, any address\n  value is possible, including 0 and [`usize::MAX`], so long as the semantics of such a write are\n  well-defined by the target hardware. The provenance of the pointer is irrelevant, and it can be\n  created with [`without_provenance_mut`][crate::ptr::without_provenance_mut]. The access is allowed\n  to trap, which must immediately abort the process. It can also cause other side-effects, but those\n  must not affect Rust-allocated memory in any way.\n\nIn both cases, the access is also considered atomic with the given `order`. This allows\nsynchronization with other threads or devices that share memory with this program.\n\nWhen invoked during const evaluation, this behaves like a regular atomic store. In\nparticular, such reads must always follow the first of the two cases above.\n\n[allocation]: crate::ptr#allocated-object\n"]
    ///
    /// # Safety
    ///
    /// Behavior is undefined if any of the following conditions are violated:
    ///
    /// * `self` must be either [valid] for writes, or `self` must point to memory
    ///   outside of all Rust allocations and writing to that memory must:
    ///   - not trap, and
    ///   - not cause any memory inside a Rust allocation to be modified.
    ///
    /// * `self` must be aligned to
    #[doc = "  `align_of::<AtomicU64>()`"]
    #[doc =
    "  (note that on some platforms this can be bigger than `align_of::<u64>()`)."]
    ///
    /// [valid]: core::ptr#safety
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_should_not_be_called_on_const_items]
    pub const unsafe fn store_volatile(self: *const Self, val: u64,
        order: Ordering) {
        unsafe {
            atomic_store::<_,
                    true>(self.cast::<u64>().cast_mut(), 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, and applies a function to it that returns 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! {
4155    target_has_atomic_load_store = "64",
4156    target_has_atomic = "64",
4157    target_has_atomic_primitive_alignment = "64",
4158    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4159    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4160    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4161    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4162    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4163    stable(feature = "integer_atomics_stable", since = "1.34.0"),
4164    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
4165    rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
4166    "u64",
4167    "",
4168    atomic_umin, atomic_umax,
4169    8,
4170    u64 AtomicU64
4171}
4172#[cfg(any(target_has_atomic_load_store = "128", doc))]
4173atomic_int! {
4174    target_has_atomic_load_store = "128",
4175    target_has_atomic = "128",
4176    target_has_atomic_primitive_alignment = "128",
4177    unstable(feature = "integer_atomics", issue = "99069"),
4178    unstable(feature = "integer_atomics", issue = "99069"),
4179    unstable(feature = "integer_atomics", issue = "99069"),
4180    unstable(feature = "integer_atomics", issue = "99069"),
4181    unstable(feature = "integer_atomics", issue = "99069"),
4182    unstable(feature = "integer_atomics", issue = "99069"),
4183    rustc_const_unstable(feature = "integer_atomics", issue = "99069"),
4184    rustc_const_unstable(feature = "integer_atomics", issue = "99069"),
4185    "i128",
4186    "#![feature(integer_atomics)]\n\n",
4187    atomic_min, atomic_max,
4188    16,
4189    i128 AtomicI128
4190}
4191#[cfg(any(target_has_atomic_load_store = "128", doc))]
4192atomic_int! {
4193    target_has_atomic_load_store = "128",
4194    target_has_atomic = "128",
4195    target_has_atomic_primitive_alignment = "128",
4196    unstable(feature = "integer_atomics", issue = "99069"),
4197    unstable(feature = "integer_atomics", issue = "99069"),
4198    unstable(feature = "integer_atomics", issue = "99069"),
4199    unstable(feature = "integer_atomics", issue = "99069"),
4200    unstable(feature = "integer_atomics", issue = "99069"),
4201    unstable(feature = "integer_atomics", issue = "99069"),
4202    rustc_const_unstable(feature = "integer_atomics", issue = "99069"),
4203    rustc_const_unstable(feature = "integer_atomics", issue = "99069"),
4204    "u128",
4205    "#![feature(integer_atomics)]\n\n",
4206    atomic_umin, atomic_umax,
4207    16,
4208    u128 AtomicU128
4209}
4210
4211#[cfg(target_has_atomic_load_store = "ptr")]
4212macro_rules! atomic_int_ptr_sized {
4213    ( $($target_pointer_width:literal $align:literal)* ) => { $(
4214        #[cfg(target_pointer_width = $target_pointer_width)]
4215        atomic_int! {
4216            target_has_atomic_load_store = "ptr",
4217            target_has_atomic = "ptr",
4218            target_has_atomic_primitive_alignment = "ptr",
4219            stable(feature = "rust1", since = "1.0.0"),
4220            stable(feature = "extended_compare_and_swap", since = "1.10.0"),
4221            stable(feature = "atomic_debug", since = "1.3.0"),
4222            stable(feature = "atomic_access", since = "1.15.0"),
4223            stable(feature = "atomic_from", since = "1.23.0"),
4224            stable(feature = "atomic_nand", since = "1.27.0"),
4225            rustc_const_stable(feature = "const_ptr_sized_atomics", since = "1.24.0"),
4226            rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
4227            "isize",
4228            "",
4229            atomic_min, atomic_max,
4230            $align,
4231            isize AtomicIsize
4232        }
4233        #[cfg(target_pointer_width = $target_pointer_width)]
4234        atomic_int! {
4235            target_has_atomic_load_store = "ptr",
4236            target_has_atomic = "ptr",
4237            target_has_atomic_primitive_alignment = "ptr",
4238            stable(feature = "rust1", since = "1.0.0"),
4239            stable(feature = "extended_compare_and_swap", since = "1.10.0"),
4240            stable(feature = "atomic_debug", since = "1.3.0"),
4241            stable(feature = "atomic_access", since = "1.15.0"),
4242            stable(feature = "atomic_from", since = "1.23.0"),
4243            stable(feature = "atomic_nand", since = "1.27.0"),
4244            rustc_const_stable(feature = "const_ptr_sized_atomics", since = "1.24.0"),
4245            rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"),
4246            "usize",
4247            "",
4248            atomic_umin, atomic_umax,
4249            $align,
4250            usize AtomicUsize
4251        }
4252
4253        /// An [`AtomicIsize`] initialized to `0`.
4254        #[cfg(target_pointer_width = $target_pointer_width)]
4255        #[stable(feature = "rust1", since = "1.0.0")]
4256        #[deprecated(
4257            since = "1.34.0",
4258            note = "the `new` function is now preferred",
4259            suggestion = "AtomicIsize::new(0)",
4260        )]
4261        #[expect(clippy::declare_interior_mutable_const, reason = "legacy atomic initializer")]
4262        pub const ATOMIC_ISIZE_INIT: AtomicIsize = AtomicIsize::new(0);
4263
4264        /// An [`AtomicUsize`] initialized to `0`.
4265        #[cfg(target_pointer_width = $target_pointer_width)]
4266        #[stable(feature = "rust1", since = "1.0.0")]
4267        #[deprecated(
4268            since = "1.34.0",
4269            note = "the `new` function is now preferred",
4270            suggestion = "AtomicUsize::new(0)",
4271        )]
4272        #[expect(clippy::declare_interior_mutable_const, reason = "legacy atomic initializer")]
4273        pub const ATOMIC_USIZE_INIT: AtomicUsize = AtomicUsize::new(0);
4274    )* };
4275}
4276
4277#[cfg(target_has_atomic_load_store = "ptr")]
4278/// 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() }
    }
    /// Creates a new pointer to an atomic integer from a pointer.
    ///
    /// This is useful if you want to do volatile atomic accesses, and thus avoid creating
    /// a reference to the destination.
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    pub const fn from_ptr_raw(ptr: *mut isize) -> *const AtomicIsize {
        ptr.cast_const().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) }
    }
    /// Perform a volatile load from the atomic integer.
    ///
    /// `load_volatile` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
    ///
    #[doc =
    "Volatile operations are intended to act on I/O memory. As such, they are considered externally\nobservable events (just like syscalls, but less opaque), and are guaranteed to not be elided or\nreordered by the compiler across other externally observable events. With this in mind, there\nare two cases of usage that need to be distinguished:\n\n- When a volatile operation is used for memory inside an [allocation], it behaves exactly\n  like [`load`][Self::load], except for the additional guarantee that it won\'t be elided or\n  reordered across other externally observable events (see above). This implies that the\n  operation will actually access memory and not e.g. be lowered to reusing data from a\n  previous load. Other than that, all the usual rules for memory accesses apply (including\n  provenance).\n\n- Volatile operations, however, may also be used to access memory that is _outside_ of any Rust\n  allocation. In this use-case, the pointer does *not* have to be [valid] for reads. This is\n  typically used for CPU and peripheral registers that must be accessed via an I/O memory mapping,\n  most commonly at fixed addresses reserved by the hardware. These often have special semantics\n  associated to their manipulation, and cannot be used as general purpose memory. Here, any address\n  value is possible, including 0 and [`usize::MAX`], so long as the semantics of such a read are\n  well-defined by the target hardware. The provenance of the pointer is irrelevant, and it can be\n  created with [`without_provenance`][crate::ptr::without_provenance]. The access is allowed to\n  trap, which must immediately abort the process. It can also cause other side-effects, but those\n  must not affect Rust-allocated memory in any way.\n\nIn both cases, the access is also considered atomic with the given `order`. This allows\nsynchronization with other threads or devices that share memory with this program.\n\nWhen invoked during const evaluation, this behaves like a regular atomic load. In\nparticular, such reads must always follow the first of the two cases above.\n\n[allocation]: crate::ptr#allocated-object\n"]
    ///
    /// # Safety
    ///
    /// Behavior is undefined if any of the following conditions are violated:
    ///
    /// * `self` must be [valid] for reads, or `self` must point to memory
    ///   outside of all Rust allocations and reading from that memory must:
    ///   - not trap, and
    ///   - not cause any memory inside a Rust allocation to be modified.
    ///
    /// * `self` must be aligned to
    #[doc = "  `align_of::<AtomicIsize>()`"]
    #[doc =
    "  (note that on some platforms this can be bigger than `align_of::<isize>()`)."]
    ///
    /// * Reading from `self` must produce a properly initialized value of the underlying
    ///   integer type.
    ///
    /// [valid]: core::ptr#safety
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Release`] or [`AcqRel`].
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
    pub const unsafe fn load_volatile(self: *const Self, order: Ordering)
        -> isize {
        unsafe { atomic_load::<_, true>(self.cast::<isize>(), 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); }
    }
    /// Performs a volatile store into the atomic integer.
    ///
    /// `store_volatile` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
    ///
    #[doc =
    "Volatile operations are intended to act on I/O memory. As such, they are considered externally\nobservable events (just like syscalls), and are guaranteed to not be elided or reordered by the\ncompiler across other externally observable events. With this in mind, there are two cases of\nusage that need to be distinguished:\n\n- When a volatile operation is used for memory inside an [allocation], it behaves exactly like\n  [`store`][Self::store], except for the additional guarantee that it won\'t be elided or reordered\n  across other externally observable events (see above). This implies that the operation will\n  actually access memory and not e.g. be lowered to a register access. Other than that, all the\n  usual rules for memory accesses apply (including provenance).\n\n- Volatile operations, however, may also be used to access memory that is _outside_ of any Rust\n  allocation. In this use-case, the pointer does *not* have to be [valid] for writes. This is\n  typically used for CPU and peripheral registers that must be accessed via an I/O memory mapping,\n  most commonly at fixed addresses reserved by the hardware. These often have special semantics\n  associated to their manipulation, and cannot be used as general purpose memory. Here, any address\n  value is possible, including 0 and [`usize::MAX`], so long as the semantics of such a write are\n  well-defined by the target hardware. The provenance of the pointer is irrelevant, and it can be\n  created with [`without_provenance_mut`][crate::ptr::without_provenance_mut]. The access is allowed\n  to trap, which must immediately abort the process. It can also cause other side-effects, but those\n  must not affect Rust-allocated memory in any way.\n\nIn both cases, the access is also considered atomic with the given `order`. This allows\nsynchronization with other threads or devices that share memory with this program.\n\nWhen invoked during const evaluation, this behaves like a regular atomic store. In\nparticular, such reads must always follow the first of the two cases above.\n\n[allocation]: crate::ptr#allocated-object\n"]
    ///
    /// # Safety
    ///
    /// Behavior is undefined if any of the following conditions are violated:
    ///
    /// * `self` must be either [valid] for writes, or `self` must point to memory
    ///   outside of all Rust allocations and writing to that memory must:
    ///   - not trap, and
    ///   - not cause any memory inside a Rust allocation to be modified.
    ///
    /// * `self` must be aligned to
    #[doc = "  `align_of::<AtomicIsize>()`"]
    #[doc =
    "  (note that on some platforms this can be bigger than `align_of::<isize>()`)."]
    ///
    /// [valid]: core::ptr#safety
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_should_not_be_called_on_const_items]
    pub const unsafe fn store_volatile(self: *const Self, val: isize,
        order: Ordering) {
        unsafe {
            atomic_store::<_,
                    true>(self.cast::<isize>().cast_mut(), 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, and applies a function to it that returns 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() }
    }
    /// Creates a new pointer to an atomic integer from a pointer.
    ///
    /// This is useful if you want to do volatile atomic accesses, and thus avoid creating
    /// a reference to the destination.
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    pub const fn from_ptr_raw(ptr: *mut usize) -> *const AtomicUsize {
        ptr.cast_const().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) }
    }
    /// Perform a volatile load from the atomic integer.
    ///
    /// `load_volatile` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`].
    ///
    #[doc =
    "Volatile operations are intended to act on I/O memory. As such, they are considered externally\nobservable events (just like syscalls, but less opaque), and are guaranteed to not be elided or\nreordered by the compiler across other externally observable events. With this in mind, there\nare two cases of usage that need to be distinguished:\n\n- When a volatile operation is used for memory inside an [allocation], it behaves exactly\n  like [`load`][Self::load], except for the additional guarantee that it won\'t be elided or\n  reordered across other externally observable events (see above). This implies that the\n  operation will actually access memory and not e.g. be lowered to reusing data from a\n  previous load. Other than that, all the usual rules for memory accesses apply (including\n  provenance).\n\n- Volatile operations, however, may also be used to access memory that is _outside_ of any Rust\n  allocation. In this use-case, the pointer does *not* have to be [valid] for reads. This is\n  typically used for CPU and peripheral registers that must be accessed via an I/O memory mapping,\n  most commonly at fixed addresses reserved by the hardware. These often have special semantics\n  associated to their manipulation, and cannot be used as general purpose memory. Here, any address\n  value is possible, including 0 and [`usize::MAX`], so long as the semantics of such a read are\n  well-defined by the target hardware. The provenance of the pointer is irrelevant, and it can be\n  created with [`without_provenance`][crate::ptr::without_provenance]. The access is allowed to\n  trap, which must immediately abort the process. It can also cause other side-effects, but those\n  must not affect Rust-allocated memory in any way.\n\nIn both cases, the access is also considered atomic with the given `order`. This allows\nsynchronization with other threads or devices that share memory with this program.\n\nWhen invoked during const evaluation, this behaves like a regular atomic load. In\nparticular, such reads must always follow the first of the two cases above.\n\n[allocation]: crate::ptr#allocated-object\n"]
    ///
    /// # Safety
    ///
    /// Behavior is undefined if any of the following conditions are violated:
    ///
    /// * `self` must be [valid] for reads, or `self` must point to memory
    ///   outside of all Rust allocations and reading from that memory must:
    ///   - not trap, and
    ///   - not cause any memory inside a Rust allocation to be modified.
    ///
    /// * `self` must be aligned to
    #[doc = "  `align_of::<AtomicUsize>()`"]
    #[doc =
    "  (note that on some platforms this can be bigger than `align_of::<usize>()`)."]
    ///
    /// * Reading from `self` must produce a properly initialized value of the underlying
    ///   integer type.
    ///
    /// [valid]: core::ptr#safety
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Release`] or [`AcqRel`].
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
    pub const unsafe fn load_volatile(self: *const Self, order: Ordering)
        -> usize {
        unsafe { atomic_load::<_, true>(self.cast::<usize>(), 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); }
    }
    /// Performs a volatile store into the atomic integer.
    ///
    /// `store_volatile` takes an [`Ordering`] argument which describes the memory ordering
    /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`].
    ///
    #[doc =
    "Volatile operations are intended to act on I/O memory. As such, they are considered externally\nobservable events (just like syscalls), and are guaranteed to not be elided or reordered by the\ncompiler across other externally observable events. With this in mind, there are two cases of\nusage that need to be distinguished:\n\n- When a volatile operation is used for memory inside an [allocation], it behaves exactly like\n  [`store`][Self::store], except for the additional guarantee that it won\'t be elided or reordered\n  across other externally observable events (see above). This implies that the operation will\n  actually access memory and not e.g. be lowered to a register access. Other than that, all the\n  usual rules for memory accesses apply (including provenance).\n\n- Volatile operations, however, may also be used to access memory that is _outside_ of any Rust\n  allocation. In this use-case, the pointer does *not* have to be [valid] for writes. This is\n  typically used for CPU and peripheral registers that must be accessed via an I/O memory mapping,\n  most commonly at fixed addresses reserved by the hardware. These often have special semantics\n  associated to their manipulation, and cannot be used as general purpose memory. Here, any address\n  value is possible, including 0 and [`usize::MAX`], so long as the semantics of such a write are\n  well-defined by the target hardware. The provenance of the pointer is irrelevant, and it can be\n  created with [`without_provenance_mut`][crate::ptr::without_provenance_mut]. The access is allowed\n  to trap, which must immediately abort the process. It can also cause other side-effects, but those\n  must not affect Rust-allocated memory in any way.\n\nIn both cases, the access is also considered atomic with the given `order`. This allows\nsynchronization with other threads or devices that share memory with this program.\n\nWhen invoked during const evaluation, this behaves like a regular atomic store. In\nparticular, such reads must always follow the first of the two cases above.\n\n[allocation]: crate::ptr#allocated-object\n"]
    ///
    /// # Safety
    ///
    /// Behavior is undefined if any of the following conditions are violated:
    ///
    /// * `self` must be either [valid] for writes, or `self` must point to memory
    ///   outside of all Rust allocations and writing to that memory must:
    ///   - not trap, and
    ///   - not cause any memory inside a Rust allocation to be modified.
    ///
    /// * `self` must be aligned to
    #[doc = "  `align_of::<AtomicUsize>()`"]
    #[doc =
    "  (note that on some platforms this can be bigger than `align_of::<usize>()`)."]
    ///
    /// [valid]: core::ptr#safety
    ///
    /// # Panics
    ///
    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
    #[inline]
    #[unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_const_unstable(feature = "atomic_volatile", issue = "158947")]
    #[rustc_should_not_be_called_on_const_items]
    pub const unsafe fn store_volatile(self: *const Self, val: usize,
        order: Ordering) {
        unsafe {
            atomic_store::<_,
                    true>(self.cast::<usize>().cast_mut(), 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, and applies a function to it that returns 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! {
4279    "16" 2
4280    "32" 4
4281    "64" 8
4282}
4283
4284#[inline]
4285#[cfg(target_has_atomic)]
4286const fn strongest_failure_ordering(order: Ordering) -> Ordering {
4287    match order {
4288        Release => Relaxed,
4289        Relaxed => Relaxed,
4290        SeqCst => SeqCst,
4291        Acquire => Acquire,
4292        AcqRel => Acquire,
4293    }
4294}
4295
4296#[inline]
4297#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4298#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4299const unsafe fn atomic_store<T: Copy, const VOLATILE: bool>(dst: *mut T, val: T, order: Ordering) {
4300    // SAFETY: the caller must uphold the safety contract for `atomic_store`.
4301    unsafe {
4302        match order {
4303            Relaxed => intrinsics::atomic_store::<T, { AO::Relaxed }, VOLATILE>(dst, val),
4304            Release => intrinsics::atomic_store::<T, { AO::Release }, VOLATILE>(dst, val),
4305            SeqCst => intrinsics::atomic_store::<T, { AO::SeqCst }, VOLATILE>(dst, val),
4306            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"),
4307            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"),
4308        }
4309    }
4310}
4311
4312#[inline]
4313#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4314#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4315const unsafe fn atomic_load<T: Copy, const VOLATILE: bool>(dst: *const T, order: Ordering) -> T {
4316    // SAFETY: the caller must uphold the safety contract for `atomic_load`.
4317    unsafe {
4318        match order {
4319            Relaxed => intrinsics::atomic_load::<T, { AO::Relaxed }, VOLATILE>(dst),
4320            Acquire => intrinsics::atomic_load::<T, { AO::Acquire }, VOLATILE>(dst),
4321            SeqCst => intrinsics::atomic_load::<T, { AO::SeqCst }, VOLATILE>(dst),
4322            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"),
4323            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"),
4324        }
4325    }
4326}
4327
4328#[inline]
4329#[cfg(target_has_atomic)]
4330#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4331#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4332const unsafe fn atomic_swap<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
4333    // SAFETY: the caller must uphold the safety contract for `atomic_swap`.
4334    unsafe {
4335        match order {
4336            Relaxed => intrinsics::atomic_xchg::<T, { AO::Relaxed }>(dst, val),
4337            Acquire => intrinsics::atomic_xchg::<T, { AO::Acquire }>(dst, val),
4338            Release => intrinsics::atomic_xchg::<T, { AO::Release }>(dst, val),
4339            AcqRel => intrinsics::atomic_xchg::<T, { AO::AcqRel }>(dst, val),
4340            SeqCst => intrinsics::atomic_xchg::<T, { AO::SeqCst }>(dst, val),
4341        }
4342    }
4343}
4344
4345/// Returns the previous value (like __sync_fetch_and_add).
4346#[inline]
4347#[cfg(target_has_atomic)]
4348#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4349#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4350const unsafe fn atomic_add<T: Copy, U: Copy>(dst: *mut T, val: U, order: Ordering) -> T {
4351    // SAFETY: the caller must uphold the safety contract for `atomic_add`.
4352    unsafe {
4353        match order {
4354            Relaxed => intrinsics::atomic_xadd::<T, U, { AO::Relaxed }>(dst, val),
4355            Acquire => intrinsics::atomic_xadd::<T, U, { AO::Acquire }>(dst, val),
4356            Release => intrinsics::atomic_xadd::<T, U, { AO::Release }>(dst, val),
4357            AcqRel => intrinsics::atomic_xadd::<T, U, { AO::AcqRel }>(dst, val),
4358            SeqCst => intrinsics::atomic_xadd::<T, U, { AO::SeqCst }>(dst, val),
4359        }
4360    }
4361}
4362
4363/// Returns the previous value (like __sync_fetch_and_sub).
4364#[inline]
4365#[cfg(target_has_atomic)]
4366#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4367#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4368const unsafe fn atomic_sub<T: Copy, U: Copy>(dst: *mut T, val: U, order: Ordering) -> T {
4369    // SAFETY: the caller must uphold the safety contract for `atomic_sub`.
4370    unsafe {
4371        match order {
4372            Relaxed => intrinsics::atomic_xsub::<T, U, { AO::Relaxed }>(dst, val),
4373            Acquire => intrinsics::atomic_xsub::<T, U, { AO::Acquire }>(dst, val),
4374            Release => intrinsics::atomic_xsub::<T, U, { AO::Release }>(dst, val),
4375            AcqRel => intrinsics::atomic_xsub::<T, U, { AO::AcqRel }>(dst, val),
4376            SeqCst => intrinsics::atomic_xsub::<T, U, { AO::SeqCst }>(dst, val),
4377        }
4378    }
4379}
4380
4381/// Publicly exposed for stdarch; nobody else should use this.
4382#[inline]
4383#[cfg(target_has_atomic)]
4384#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4385#[unstable(feature = "core_intrinsics", issue = "none")]
4386#[doc(hidden)]
4387#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4388pub const unsafe fn atomic_compare_exchange<T: Copy>(
4389    dst: *mut T,
4390    old: T,
4391    new: T,
4392    success: Ordering,
4393    failure: Ordering,
4394) -> Result<T, T> {
4395    // SAFETY: the caller must uphold the safety contract for `atomic_compare_exchange`.
4396    let (val, ok) = unsafe {
4397        match (success, failure) {
4398            (Relaxed, Relaxed) => {
4399                intrinsics::atomic_cxchg::<T, { AO::Relaxed }, { AO::Relaxed }>(dst, old, new)
4400            }
4401            (Relaxed, Acquire) => {
4402                intrinsics::atomic_cxchg::<T, { AO::Relaxed }, { AO::Acquire }>(dst, old, new)
4403            }
4404            (Relaxed, SeqCst) => {
4405                intrinsics::atomic_cxchg::<T, { AO::Relaxed }, { AO::SeqCst }>(dst, old, new)
4406            }
4407            (Acquire, Relaxed) => {
4408                intrinsics::atomic_cxchg::<T, { AO::Acquire }, { AO::Relaxed }>(dst, old, new)
4409            }
4410            (Acquire, Acquire) => {
4411                intrinsics::atomic_cxchg::<T, { AO::Acquire }, { AO::Acquire }>(dst, old, new)
4412            }
4413            (Acquire, SeqCst) => {
4414                intrinsics::atomic_cxchg::<T, { AO::Acquire }, { AO::SeqCst }>(dst, old, new)
4415            }
4416            (Release, Relaxed) => {
4417                intrinsics::atomic_cxchg::<T, { AO::Release }, { AO::Relaxed }>(dst, old, new)
4418            }
4419            (Release, Acquire) => {
4420                intrinsics::atomic_cxchg::<T, { AO::Release }, { AO::Acquire }>(dst, old, new)
4421            }
4422            (Release, SeqCst) => {
4423                intrinsics::atomic_cxchg::<T, { AO::Release }, { AO::SeqCst }>(dst, old, new)
4424            }
4425            (AcqRel, Relaxed) => {
4426                intrinsics::atomic_cxchg::<T, { AO::AcqRel }, { AO::Relaxed }>(dst, old, new)
4427            }
4428            (AcqRel, Acquire) => {
4429                intrinsics::atomic_cxchg::<T, { AO::AcqRel }, { AO::Acquire }>(dst, old, new)
4430            }
4431            (AcqRel, SeqCst) => {
4432                intrinsics::atomic_cxchg::<T, { AO::AcqRel }, { AO::SeqCst }>(dst, old, new)
4433            }
4434            (SeqCst, Relaxed) => {
4435                intrinsics::atomic_cxchg::<T, { AO::SeqCst }, { AO::Relaxed }>(dst, old, new)
4436            }
4437            (SeqCst, Acquire) => {
4438                intrinsics::atomic_cxchg::<T, { AO::SeqCst }, { AO::Acquire }>(dst, old, new)
4439            }
4440            (SeqCst, SeqCst) => {
4441                intrinsics::atomic_cxchg::<T, { AO::SeqCst }, { AO::SeqCst }>(dst, old, new)
4442            }
4443            (_, 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"),
4444            (_, 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"),
4445        }
4446    };
4447    if ok { Ok(val) } else { Err(val) }
4448}
4449
4450#[inline]
4451#[cfg(target_has_atomic)]
4452#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4453#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4454const unsafe fn atomic_compare_exchange_weak<T: Copy>(
4455    dst: *mut T,
4456    old: T,
4457    new: T,
4458    success: Ordering,
4459    failure: Ordering,
4460) -> Result<T, T> {
4461    // SAFETY: the caller must uphold the safety contract for `atomic_compare_exchange_weak`.
4462    let (val, ok) = unsafe {
4463        match (success, failure) {
4464            (Relaxed, Relaxed) => {
4465                intrinsics::atomic_cxchgweak::<T, { AO::Relaxed }, { AO::Relaxed }>(dst, old, new)
4466            }
4467            (Relaxed, Acquire) => {
4468                intrinsics::atomic_cxchgweak::<T, { AO::Relaxed }, { AO::Acquire }>(dst, old, new)
4469            }
4470            (Relaxed, SeqCst) => {
4471                intrinsics::atomic_cxchgweak::<T, { AO::Relaxed }, { AO::SeqCst }>(dst, old, new)
4472            }
4473            (Acquire, Relaxed) => {
4474                intrinsics::atomic_cxchgweak::<T, { AO::Acquire }, { AO::Relaxed }>(dst, old, new)
4475            }
4476            (Acquire, Acquire) => {
4477                intrinsics::atomic_cxchgweak::<T, { AO::Acquire }, { AO::Acquire }>(dst, old, new)
4478            }
4479            (Acquire, SeqCst) => {
4480                intrinsics::atomic_cxchgweak::<T, { AO::Acquire }, { AO::SeqCst }>(dst, old, new)
4481            }
4482            (Release, Relaxed) => {
4483                intrinsics::atomic_cxchgweak::<T, { AO::Release }, { AO::Relaxed }>(dst, old, new)
4484            }
4485            (Release, Acquire) => {
4486                intrinsics::atomic_cxchgweak::<T, { AO::Release }, { AO::Acquire }>(dst, old, new)
4487            }
4488            (Release, SeqCst) => {
4489                intrinsics::atomic_cxchgweak::<T, { AO::Release }, { AO::SeqCst }>(dst, old, new)
4490            }
4491            (AcqRel, Relaxed) => {
4492                intrinsics::atomic_cxchgweak::<T, { AO::AcqRel }, { AO::Relaxed }>(dst, old, new)
4493            }
4494            (AcqRel, Acquire) => {
4495                intrinsics::atomic_cxchgweak::<T, { AO::AcqRel }, { AO::Acquire }>(dst, old, new)
4496            }
4497            (AcqRel, SeqCst) => {
4498                intrinsics::atomic_cxchgweak::<T, { AO::AcqRel }, { AO::SeqCst }>(dst, old, new)
4499            }
4500            (SeqCst, Relaxed) => {
4501                intrinsics::atomic_cxchgweak::<T, { AO::SeqCst }, { AO::Relaxed }>(dst, old, new)
4502            }
4503            (SeqCst, Acquire) => {
4504                intrinsics::atomic_cxchgweak::<T, { AO::SeqCst }, { AO::Acquire }>(dst, old, new)
4505            }
4506            (SeqCst, SeqCst) => {
4507                intrinsics::atomic_cxchgweak::<T, { AO::SeqCst }, { AO::SeqCst }>(dst, old, new)
4508            }
4509            (_, 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"),
4510            (_, 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"),
4511        }
4512    };
4513    if ok { Ok(val) } else { Err(val) }
4514}
4515
4516#[inline]
4517#[cfg(target_has_atomic)]
4518#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4519#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4520const unsafe fn atomic_and<T: Copy, U: Copy>(dst: *mut T, val: U, order: Ordering) -> T {
4521    // SAFETY: the caller must uphold the safety contract for `atomic_and`
4522    unsafe {
4523        match order {
4524            Relaxed => intrinsics::atomic_and::<T, U, { AO::Relaxed }>(dst, val),
4525            Acquire => intrinsics::atomic_and::<T, U, { AO::Acquire }>(dst, val),
4526            Release => intrinsics::atomic_and::<T, U, { AO::Release }>(dst, val),
4527            AcqRel => intrinsics::atomic_and::<T, U, { AO::AcqRel }>(dst, val),
4528            SeqCst => intrinsics::atomic_and::<T, U, { AO::SeqCst }>(dst, val),
4529        }
4530    }
4531}
4532
4533#[inline]
4534#[cfg(target_has_atomic)]
4535#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4536#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4537const unsafe fn atomic_nand<T: Copy, U: Copy>(dst: *mut T, val: U, order: Ordering) -> T {
4538    // SAFETY: the caller must uphold the safety contract for `atomic_nand`
4539    unsafe {
4540        match order {
4541            Relaxed => intrinsics::atomic_nand::<T, U, { AO::Relaxed }>(dst, val),
4542            Acquire => intrinsics::atomic_nand::<T, U, { AO::Acquire }>(dst, val),
4543            Release => intrinsics::atomic_nand::<T, U, { AO::Release }>(dst, val),
4544            AcqRel => intrinsics::atomic_nand::<T, U, { AO::AcqRel }>(dst, val),
4545            SeqCst => intrinsics::atomic_nand::<T, U, { AO::SeqCst }>(dst, val),
4546        }
4547    }
4548}
4549
4550#[inline]
4551#[cfg(target_has_atomic)]
4552#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4553#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4554const unsafe fn atomic_or<T: Copy, U: Copy>(dst: *mut T, val: U, order: Ordering) -> T {
4555    // SAFETY: the caller must uphold the safety contract for `atomic_or`
4556    unsafe {
4557        match order {
4558            SeqCst => intrinsics::atomic_or::<T, U, { AO::SeqCst }>(dst, val),
4559            Acquire => intrinsics::atomic_or::<T, U, { AO::Acquire }>(dst, val),
4560            Release => intrinsics::atomic_or::<T, U, { AO::Release }>(dst, val),
4561            AcqRel => intrinsics::atomic_or::<T, U, { AO::AcqRel }>(dst, val),
4562            Relaxed => intrinsics::atomic_or::<T, U, { AO::Relaxed }>(dst, val),
4563        }
4564    }
4565}
4566
4567#[inline]
4568#[cfg(target_has_atomic)]
4569#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4570#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4571const unsafe fn atomic_xor<T: Copy, U: Copy>(dst: *mut T, val: U, order: Ordering) -> T {
4572    // SAFETY: the caller must uphold the safety contract for `atomic_xor`
4573    unsafe {
4574        match order {
4575            SeqCst => intrinsics::atomic_xor::<T, U, { AO::SeqCst }>(dst, val),
4576            Acquire => intrinsics::atomic_xor::<T, U, { AO::Acquire }>(dst, val),
4577            Release => intrinsics::atomic_xor::<T, U, { AO::Release }>(dst, val),
4578            AcqRel => intrinsics::atomic_xor::<T, U, { AO::AcqRel }>(dst, val),
4579            Relaxed => intrinsics::atomic_xor::<T, U, { AO::Relaxed }>(dst, val),
4580        }
4581    }
4582}
4583
4584/// Updates `*dst` to the max value of `val` and the old value (signed comparison)
4585#[inline]
4586#[cfg(target_has_atomic)]
4587#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4588#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4589const unsafe fn atomic_max<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
4590    // SAFETY: the caller must uphold the safety contract for `atomic_max`
4591    unsafe {
4592        match order {
4593            Relaxed => intrinsics::atomic_max::<T, { AO::Relaxed }>(dst, val),
4594            Acquire => intrinsics::atomic_max::<T, { AO::Acquire }>(dst, val),
4595            Release => intrinsics::atomic_max::<T, { AO::Release }>(dst, val),
4596            AcqRel => intrinsics::atomic_max::<T, { AO::AcqRel }>(dst, val),
4597            SeqCst => intrinsics::atomic_max::<T, { AO::SeqCst }>(dst, val),
4598        }
4599    }
4600}
4601
4602/// Updates `*dst` to the min value of `val` and the old value (signed comparison)
4603#[inline]
4604#[cfg(target_has_atomic)]
4605#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4606#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4607const unsafe fn atomic_min<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
4608    // SAFETY: the caller must uphold the safety contract for `atomic_min`
4609    unsafe {
4610        match order {
4611            Relaxed => intrinsics::atomic_min::<T, { AO::Relaxed }>(dst, val),
4612            Acquire => intrinsics::atomic_min::<T, { AO::Acquire }>(dst, val),
4613            Release => intrinsics::atomic_min::<T, { AO::Release }>(dst, val),
4614            AcqRel => intrinsics::atomic_min::<T, { AO::AcqRel }>(dst, val),
4615            SeqCst => intrinsics::atomic_min::<T, { AO::SeqCst }>(dst, val),
4616        }
4617    }
4618}
4619
4620/// Updates `*dst` to the max value of `val` and the old value (unsigned comparison)
4621#[inline]
4622#[cfg(target_has_atomic)]
4623#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4624#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4625const unsafe fn atomic_umax<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
4626    // SAFETY: the caller must uphold the safety contract for `atomic_umax`
4627    unsafe {
4628        match order {
4629            Relaxed => intrinsics::atomic_umax::<T, { AO::Relaxed }>(dst, val),
4630            Acquire => intrinsics::atomic_umax::<T, { AO::Acquire }>(dst, val),
4631            Release => intrinsics::atomic_umax::<T, { AO::Release }>(dst, val),
4632            AcqRel => intrinsics::atomic_umax::<T, { AO::AcqRel }>(dst, val),
4633            SeqCst => intrinsics::atomic_umax::<T, { AO::SeqCst }>(dst, val),
4634        }
4635    }
4636}
4637
4638/// Updates `*dst` to the min value of `val` and the old value (unsigned comparison)
4639#[inline]
4640#[cfg(target_has_atomic)]
4641#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4642#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4643const unsafe fn atomic_umin<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
4644    // SAFETY: the caller must uphold the safety contract for `atomic_umin`
4645    unsafe {
4646        match order {
4647            Relaxed => intrinsics::atomic_umin::<T, { AO::Relaxed }>(dst, val),
4648            Acquire => intrinsics::atomic_umin::<T, { AO::Acquire }>(dst, val),
4649            Release => intrinsics::atomic_umin::<T, { AO::Release }>(dst, val),
4650            AcqRel => intrinsics::atomic_umin::<T, { AO::AcqRel }>(dst, val),
4651            SeqCst => intrinsics::atomic_umin::<T, { AO::SeqCst }>(dst, val),
4652        }
4653    }
4654}
4655
4656/// An atomic fence.
4657///
4658/// Fences create synchronization between themselves and atomic operations or fences in other
4659/// threads. It can be helpful to think of a fence as preventing the compiler and CPU from
4660/// reordering certain types of memory operations around it, but that is a simplified model which
4661/// fails to capture some of the nuances.
4662///
4663/// There are 3 different ways to use an atomic fence:
4664///
4665/// - atomic - fence synchronization: an atomic operation with (at least) [`Release`] ordering
4666///   semantics synchronizes with a fence with (at least) [`Acquire`] ordering semantics.
4667/// - fence - atomic synchronization: a fence with (at least) [`Release`] ordering semantics
4668///   synchronizes with an atomic operation with (at least) [`Acquire`] ordering semantics.
4669/// - fence - fence synchronization: a fence with (at least) [`Release`] ordering semantics
4670///   synchronizes with a fence with (at least) [`Acquire`] ordering semantics.
4671///
4672/// These 3 ways complement the regular, fence-less, atomic - atomic synchronization.
4673///
4674/// ## Atomic - Fence
4675///
4676/// An atomic operation on one thread will synchronize with a fence on another thread when:
4677///
4678/// -   on thread 1:
4679///     -   an atomic operation 'X' with (at least) [`Release`] ordering semantics on some atomic
4680///         object 'm',
4681///
4682/// -   is paired on thread 2 with:
4683///     -   an atomic read 'Y' with any order on 'm',
4684///     -   followed by a fence 'B' with (at least) [`Acquire`] ordering semantics.
4685///
4686/// This provides a happens-before dependence between X and B.
4687///
4688/// ```text
4689///     Thread 1                                          Thread 2
4690///
4691/// m.store(3, Release); X ---------
4692///                                |
4693///                                |
4694///                                -------------> Y  if m.load(Relaxed) == 3 {
4695///                                               B      fence(Acquire);
4696///                                                      ...
4697///                                                  }
4698/// ```
4699///
4700/// ## Fence - Atomic
4701///
4702/// A fence on one thread will synchronize with an atomic operation on another thread when:
4703///
4704/// -   on thread:
4705///     -   a fence 'A' with (at least) [`Release`] ordering semantics,
4706///     -   followed by an atomic write 'X' with any ordering on some atomic object 'm',
4707///
4708/// -   is paired on thread 2 with:
4709///     -   an atomic operation 'Y' with (at least) [`Acquire`] ordering semantics.
4710///
4711/// This provides a happens-before dependence between A and Y.
4712///
4713/// ```text
4714///     Thread 1                                          Thread 2
4715///
4716/// fence(Release);      A
4717/// m.store(3, Relaxed); X ---------
4718///                                |
4719///                                |
4720///                                -------------> Y  if m.load(Acquire) == 3 {
4721///                                                      ...
4722///                                                  }
4723/// ```
4724///
4725/// ## Fence - Fence
4726///
4727/// A fence on one thread will synchronize with a fence on another thread when:
4728///
4729/// -   on thread 1:
4730///     -   a fence 'A' which has (at least) [`Release`] ordering semantics,
4731///     -   followed by an atomic write 'X' with any ordering on some atomic object 'm',
4732///
4733/// -   is paired on thread 2 with:
4734///     -   an atomic read 'Y' with any ordering on 'm',
4735///     -   followed by a fence 'B' with (at least) [`Acquire`] ordering semantics.
4736///
4737/// This provides a happens-before dependence between A and B.
4738///
4739/// ```text
4740///     Thread 1                                          Thread 2
4741///
4742/// fence(Release);      A --------------
4743/// m.store(3, Relaxed); X ---------    |
4744///                                |    |
4745///                                |    |
4746///                                -------------> Y  if m.load(Relaxed) == 3 {
4747///                                     |-------> B      fence(Acquire);
4748///                                                      ...
4749///                                                  }
4750/// ```
4751///
4752/// ## Mandatory Atomic
4753///
4754/// Note that in the examples above, it is crucial that the access to `m` are atomic. Fences cannot
4755/// be used to establish synchronization between non-atomic accesses in different threads. However,
4756/// thanks to the happens-before relationship, any non-atomic access that happen-before the atomic
4757/// operation or fence with (at least) [`Release`] ordering semantics are now also properly
4758/// synchronized with any non-atomic accesses that happen-after the atomic operation or fence with
4759/// (at least) [`Acquire`] ordering semantics.
4760///
4761/// ## Memory Ordering
4762///
4763/// A fence which has [`SeqCst`] ordering, in addition to having both [`Acquire`] and [`Release`]
4764/// semantics, participates in the global program order of the other [`SeqCst`] operations and/or
4765/// fences.
4766///
4767/// Accepts [`Acquire`], [`Release`], [`AcqRel`] and [`SeqCst`] orderings.
4768///
4769/// # Panics
4770///
4771/// Panics if `order` is [`Relaxed`].
4772///
4773/// # Examples
4774///
4775/// ```
4776/// use std::sync::atomic::AtomicBool;
4777/// use std::sync::atomic::fence;
4778/// use std::sync::atomic::Ordering;
4779///
4780/// // A mutual exclusion primitive based on spinlock.
4781/// pub struct Mutex {
4782///     flag: AtomicBool,
4783/// }
4784///
4785/// impl Mutex {
4786///     pub fn new() -> Mutex {
4787///         Mutex {
4788///             flag: AtomicBool::new(false),
4789///         }
4790///     }
4791///
4792///     pub fn lock(&self) {
4793///         // Wait until the old value is `false`.
4794///         while self
4795///             .flag
4796///             .compare_exchange_weak(false, true, Ordering::Relaxed, Ordering::Relaxed)
4797///             .is_err()
4798///         {}
4799///         // This fence synchronizes-with store in `unlock`.
4800///         fence(Ordering::Acquire);
4801///     }
4802///
4803///     pub fn unlock(&self) {
4804///         self.flag.store(false, Ordering::Release);
4805///     }
4806/// }
4807/// ```
4808#[inline]
4809#[stable(feature = "rust1", since = "1.0.0")]
4810#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4811#[rustc_diagnostic_item = "fence"]
4812#[doc(alias = "atomic_thread_fence")]
4813#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4814pub const fn fence(order: Ordering) {
4815    // SAFETY: using an atomic fence is safe.
4816    unsafe {
4817        match order {
4818            Acquire => intrinsics::atomic_fence::<{ AO::Acquire }>(),
4819            Release => intrinsics::atomic_fence::<{ AO::Release }>(),
4820            AcqRel => intrinsics::atomic_fence::<{ AO::AcqRel }>(),
4821            SeqCst => intrinsics::atomic_fence::<{ AO::SeqCst }>(),
4822            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"),
4823        }
4824    }
4825}
4826
4827/// An atomic fence for synchronization within a single thread.
4828///
4829/// Like [`fence`], this function establishes synchronization with other atomic operations and
4830/// fences. However, unlike [`fence`], `compiler_fence` only establishes synchronization with
4831/// operations *in the same thread*. This may at first sound rather useless, since code within a
4832/// thread is typically already totally ordered and does not need any further synchronization.
4833/// However, there are cases where code can run on the same thread without being synchronized:
4834/// - The most common case is that of a *signal handler*: a signal handler runs in the same thread
4835///   as the code it interrupted, but it is not synchronized with that code. `compiler_fence`
4836///   can be used to establish synchronization between a thread and its signal handler, the same way
4837///   that `fence` can be used to establish synchronization across threads.
4838/// - Similar situations can arise in embedded programming with interrupt handlers, or in custom
4839///   implementations of preemptive green threads. In general, `compiler_fence` can establish
4840///   synchronization with code that is guaranteed to run on the same hardware CPU.
4841///
4842/// See [`fence`] for how a fence can be used to achieve synchronization. Note that just like
4843/// [`fence`], synchronization still requires atomic operations to be used in both threads -- it is
4844/// not possible to perform synchronization entirely with fences and non-atomic operations.
4845///
4846/// `compiler_fence` does not emit any machine code. However, note that `compiler_fence` is also
4847/// *not* a "compiler barrier". It can be helpful to think of a `compiler_fence` as preventing the
4848/// compiler from reordering certain types of memory operations around it, but that is a simplified
4849/// model which fails to capture some of the nuances. The only actual guarantee made by
4850/// `compiler_fence` is establishing synchronization with signal handlers and similar kinds of code,
4851/// under the rules described in the [`fence`] documentation.
4852///
4853/// `compiler_fence` corresponds to [`atomic_signal_fence`] in C and C++.
4854///
4855/// [`atomic_signal_fence`]: https://en.cppreference.com/w/cpp/atomic/atomic_signal_fence
4856///
4857/// # Panics
4858///
4859/// Panics if `order` is [`Relaxed`].
4860///
4861/// # Examples
4862///
4863/// Without the two `compiler_fence` calls, the read of `IMPORTANT_VARIABLE` in `signal_handler`
4864/// is *undefined behavior* due to a data race, despite everything happening in a single thread.
4865/// This is because the signal handler is considered to run concurrently with its associated
4866/// thread, and explicit synchronization is required to pass data between a thread and its
4867/// signal handler. The code below uses two `compiler_fence` calls to establish the usual
4868/// release-acquire synchronization pattern (see [`fence`] for an image).
4869///
4870/// ```
4871/// use std::sync::atomic::AtomicBool;
4872/// use std::sync::atomic::Ordering;
4873/// use std::sync::atomic::compiler_fence;
4874///
4875/// static mut IMPORTANT_VARIABLE: usize = 0;
4876/// static IS_READY: AtomicBool = AtomicBool::new(false);
4877///
4878/// fn main() {
4879///     unsafe { IMPORTANT_VARIABLE = 42 };
4880///     // Marks earlier writes as being released with future relaxed stores.
4881///     compiler_fence(Ordering::Release);
4882///     IS_READY.store(true, Ordering::Relaxed);
4883/// }
4884///
4885/// fn signal_handler() {
4886///     if IS_READY.load(Ordering::Relaxed) {
4887///         // Acquires writes that were released with relaxed stores that we read from.
4888///         compiler_fence(Ordering::Acquire);
4889///         assert_eq!(unsafe { IMPORTANT_VARIABLE }, 42);
4890///     }
4891/// }
4892/// ```
4893#[inline]
4894#[stable(feature = "compiler_fences", since = "1.21.0")]
4895#[rustc_const_unstable(feature = "const_atomic", issue = "160078")]
4896#[rustc_diagnostic_item = "compiler_fence"]
4897#[doc(alias = "atomic_signal_fence")]
4898#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
4899pub const fn compiler_fence(order: Ordering) {
4900    // SAFETY: using an atomic fence is safe.
4901    unsafe {
4902        match order {
4903            Acquire => intrinsics::atomic_singlethreadfence::<{ AO::Acquire }>(),
4904            Release => intrinsics::atomic_singlethreadfence::<{ AO::Release }>(),
4905            AcqRel => intrinsics::atomic_singlethreadfence::<{ AO::AcqRel }>(),
4906            SeqCst => intrinsics::atomic_singlethreadfence::<{ AO::SeqCst }>(),
4907            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"),
4908        }
4909    }
4910}
4911
4912#[cfg(target_has_atomic_load_store = "8")]
4913#[stable(feature = "atomic_debug", since = "1.3.0")]
4914impl fmt::Debug for AtomicBool {
4915    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4916        fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)
4917    }
4918}
4919
4920#[cfg(target_has_atomic_load_store = "ptr")]
4921#[stable(feature = "atomic_debug", since = "1.3.0")]
4922impl<T> fmt::Debug for AtomicPtr<T> {
4923    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4924        fmt::Debug::fmt(&self.load(Ordering::Relaxed), f)
4925    }
4926}
4927
4928#[cfg(target_has_atomic_load_store = "ptr")]
4929#[stable(feature = "atomic_pointer", since = "1.24.0")]
4930impl<T> fmt::Pointer for AtomicPtr<T> {
4931    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4932        fmt::Pointer::fmt(&self.load(Ordering::Relaxed), f)
4933    }
4934}
4935
4936/// Signals the processor that it is inside a busy-wait spin-loop ("spin lock").
4937///
4938/// This function is deprecated in favor of [`hint::spin_loop`].
4939///
4940/// [`hint::spin_loop`]: crate::hint::spin_loop
4941#[inline]
4942#[stable(feature = "spin_loop_hint", since = "1.24.0")]
4943#[deprecated(since = "1.51.0", note = "use hint::spin_loop instead")]
4944pub fn spin_loop_hint() {
4945    spin_loop()
4946}